The page navigation is complete. You may now navigate the page content as you wish.
Skip to main content

AppFrame

A layout component used as top-level “frame“ for the application.

How to use this component

The AppFrame is a pure layout component that can be used to build the top-level “frame” of an application. The frame’s child containers (“header”, “sidebar”, “main”, “footer”) are agnostic of the content, and don’t have intrinsic sizes (apart from the ones that are required to make it work as top-level application frame).

“Main” container

The AppFrame::Main child component includes a default id with the value hds-main on the HTML <main> element it renders. This serves as a target for the hasA11yRefocus feature skip links which are built into the AppHeader and the standalone SideNav components.

Basic use

The most basic invocation of an application “frame” looks like this:

header
main
footer
<div class="doc-app-frame-mock-viewport">
  <Hds::AppFrame as |Frame|>
    <Frame.Header>
      {{! your "header" content goes here, this is just a mock placeholder }}
      <Doc::Placeholder @height="60px" @text="header" @background="#e5ffd2" />
    </Frame.Header>
    <Frame.Sidebar>
      {{! your "sidebar" content goes here, this is just a mock placeholder }}
      <Doc::Placeholder @width="120px" @height="100%" @text="sidebar" @background="#e4c5f3" />
    </Frame.Sidebar>
    <Frame.Main>
      {{! your "main" content goes here, this is just a mock placeholder }}
      <Doc::Placeholder @height="100%" @text="main" @background="#d2f4ff" />
    </Frame.Main>
    <Frame.Footer>
      {{! your "footer" content goes here, this is just a mock placeholder }}
      <Doc::Placeholder @height="60px" @text="footer" @background="#fff8d2" />
    </Frame.Footer>
  </Hds::AppFrame>
</div>

Optional containers

Depending on the UI implementation of the product where the component is used, it's possible to omit certain containers simply by not yielding them. For example, this would be the “frame” of an application that doesn't have a “header”:

main
footer
<div class="doc-app-frame-mock-viewport">
  <Hds::AppFrame as |Frame|>
    <Frame.Sidebar>
      <Doc::Placeholder @width="120px" @height="100%" @text="sidebar" @background="#e4c5f3" />
    </Frame.Sidebar>
    <Frame.Main>
      <Doc::Placeholder @height="100%" @text="main" @background="#d2f4ff" />
    </Frame.Main>
    <Frame.Footer>
      <Doc::Placeholder @height="60px" @text="footer" @background="#fff8d2" />
    </Frame.Footer>
  </Hds::AppFrame>
</div>

Programmatic control of the containers’ rendering

Using the exposed API of the component, it's possible to programmatically control the rendering of some of the containers. An example of programmatic control of the rendering of the sidebar could be this:

main
footer
<div class="doc-app-frame-mock-viewport">
  <Hds::AppFrame as |Frame|>
    {{! conditional control of the rendering of the "sidebar" }}
    {{#if this.yourSidebarBooleanFlag}}
      <Frame.Sidebar>
        <Doc::Placeholder @width="120px" @height="100%" @text="sidebar" @background="#e4c5f3" />
      </Frame.Sidebar>
    {{/if}}
    <Frame.Main>
      <Doc::Placeholder @height="100%" @text="main" @background="#d2f4ff" />
    </Frame.Main>
    <Frame.Footer>
      <Doc::Placeholder @height="60px" @text="footer" @background="#fff8d2" />
    </Frame.Footer>
  </Hds::AppFrame>
</div>

If for some reason it's not possible to use conditional logic to control the yielding of the containers, we provide an alternative way using special has[Container] arguments to programmatically control the rendering (see the component API specifications for details):

main
footer
<div class="doc-app-frame-mock-viewport">
  <Hds::AppFrame @hasSidebar={{false}} as |Frame|>
    <Frame.Sidebar>
      <Doc::Placeholder @width="120px" @height="100%" @text="sidebar" @background="#e4c5f3" />
    </Frame.Sidebar>
    <Frame.Main>
      <Doc::Placeholder @height="100%" @text="main" @background="#d2f4ff" />
    </Frame.Main>
    <Frame.Footer>
      <Doc::Placeholder @height="60px" @text="footer" @background="#fff8d2" />
    </Frame.Footer>
  </Hds::AppFrame>
</div>

Modals container

We also provide an extra container that can be used to display content that sits on top of all the other elements of the page (typically modal elements):

If the “modal“ container is empty, a display: none style is applied to it.

header
modal
main
footer
<div class="doc-app-frame-mock-viewport">
  <Hds::AppFrame as |Frame|>
    <Frame.Header>
      <Doc::Placeholder @height="60px" @text="header" @background="#e5ffd2" />
    </Frame.Header>
    <Frame.Sidebar>
      <Doc::Placeholder @width="120px" @height="100%" @text="sidebar" @background="#e4c5f3" />
    </Frame.Sidebar>
    <Frame.Main>
      <Doc::Placeholder @height="100%" @text="main" @background="#d2f4ff" />
    </Frame.Main>
    <Frame.Footer>
      <Doc::Placeholder @height="60px" @text="footer" @background="#fff8d2" />
    </Frame.Footer>
    <Frame.Modals>
      {{! your "modal" content goes here, this is just a mock placeholder }}
      <div class="doc-app-frame-fake-overlay" />
      <div class="doc-app-frame-fake-modal">
        <Doc::Placeholder @width="100%" @height="100%" @text="modal" @background="#ffffffb5" />
      </div>
    </Frame.Modals>
  </Hds::AppFrame>
</div>

If the content is injected dynamically—eg. via JavaScript or via Ember "portals"—you can assign an ID to the HTML element so that it can be targeted in the DOM by the code:

<div class="doc-app-frame-mock-viewport">
  <Hds::AppFrame as |Frame|>
    <Frame.Sidebar>
      ...
    </Frame.Sidebar>
    <Frame.Main>
      ...
    </Frame.Main>
    {{! assign an ID to the element to target it in the DOM }}
    <Frame.Modals id="app-frame-modals" data-test-modals-container />
  </Hds::AppFrame>
</div>

Component API

AppFrame

<[AF].Header> yielded component
AppFrame::Header yielded as contextual component (see below).
<[AF].Sidebar> yielded component
AppFrame::Sidebar yielded as contextual component (see below).
<[AF].Main> yielded component
AppFrame::Main yielded as contextual component (see below).
<[AF].Footer> yielded component
AppFrame::Footer yielded as contextual component (see below).
<[AF].Modals> yielded component
AppFrame::Modals yielded as contextual component (see below).
hasHeader boolean
  • true (default)
Controls the rendering of the header container.
hasSidebar boolean
  • true (default)
Controls the rendering of the sidebar container.
hasFooter boolean
  • true (default)
Controls the rendering of the footer container.
hasModals boolean
  • true (default)
Controls the rendering of the modals container.
…attributes
This component supports use of ...attributes.

Contextual components

[AF].Header

The AppFrame::Header component, yielded as contextual component.

To be used as container for the application's top navigation.

yield
Elements passed as children are yielded as inner content of an <header> HTML element.
…attributes
This component supports use of ...attributes.

[AF].Sidebar

The AppFrame::Sidebar component, yielded as contextual component.

To be used as container for the application's sidebar navigation.

yield
Elements passed as children are yielded as inner content of an <aside> HTML element.
…attributes
This component supports use of ...attributes.

[AF].Main

The AppFrame::Main component, yielded as contextual component.

To be used as container for the application's main page content.

yield
Elements passed as children are yielded as inner content of a <main> HTML element.
id
  • "hds-main" (default)
A default id value is set which serves as the target of the skip link included in the AppHeader and standalone SideNav components. This id can be overridden if needed but be sure to update the a11yRefocusSkipTo argument of the AppHeader or SideNav to match.
…attributes
This component supports use of ...attributes.

[AF].Footer

The AppFrame::Footer component, yielded as contextual component.

To be used as container for the application's footer.

yield
Elements passed as children are yielded as inner content of a <footer> HTML element.
…attributes
This component supports use of ...attributes.

[AF].Modals

The AppFrame::Modals component, yielded as contextual component.

To be used as container for modal elements.

yield
Elements passed as children are yielded as inner content of a <div> HTML element.
…attributes
This component supports use of ...attributes.

4.10.0

Updated

AppFrame

  • Modified sticky/fixed position to turn off when viewport height is under 480px in height
  • Refactored styles to make AppFrame responsible for sticky/fixed layout of SideNav and AppHeader

AppFrame::Main

  • Added id with default value of "hds-main" which the SideNav and AppHeader a11yRefocusSkipTo arguments point to.