popover

A popover is a larger variant of the tooltip. It can optionally have a button, a close button, or a headline, and one of 12 arrow positions.

The popover component has a JS API to attach the popover to any element. The arrow position determines the popover position, so be careful to not place it off-screen. See the gallery example and the API description below for details.

For accessibility reasons, a keyboard trap is highly recommended in this component. However, to prevent some unpredictable side effects (the page freezing, the user is stuck in an infinite loop, etc.), the keyboard trap was not set for this page to work correctly. Therefore it needs to be set by the developer.

component variations

Default

Paragraph Text View standard regular Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy.
<div class="m-popover -detached">
  <div class="a-box -floating">
    <div class="m-popover__content">
      <div class="m-popover__paragraph">
        Paragraph Text View standard regular Lorem ipsum dolor sit amet,
        consetetur sadipscing elitr, sed diam nonumy.
      </div>
    </div>
  </div>
</div>

With headline

Optional headline lorem ipsum
Paragraph Text View standard regular Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy.
<div class="m-popover -with-headline -detached">
  <div class="a-box -floating">
    <div class="m-popover__content">
      <div class="m-popover__head">Optional headline lorem ipsum</div>
      <div class="m-popover__paragraph">
        Paragraph Text View standard regular Lorem ipsum dolor sit amet,
        consetetur sadipscing elitr, sed diam nonumy.
      </div>
    </div>
  </div>
</div>

With headline and close button

Optional headline lorem ipsum
Paragraph Text View standard regular Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy.
<div class="m-popover -with-headline -close-button -detached">
  <div class="a-box -floating">
    <div class="m-popover__content">
      <div class="m-popover__head">Optional headline lorem ipsum</div>
      <button
        type="button"
        class="a-button a-button--integrated -without-label"
        data-frok-action="close"
        aria-label="close popover"
      >
        <i class="a-icon a-button__icon ui-ic-close"></i>
      </button>
      <div class="m-popover__paragraph">
        Paragraph Text View standard regular Lorem ipsum dolor sit amet,
        consetetur sadipscing elitr, sed diam nonumy.
      </div>
    </div>
  </div>
</div>

With close button and primary action

Paragraph Text View standard regular Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy.
<div class="m-popover -close-button -detached">
  <div class="a-box -floating">
    <div class="m-popover__content">
      <button
        type="button"
        class="a-button a-button--integrated -without-label"
        data-frok-action="close"
        aria-label="close popover"
      >
        <i class="a-icon a-button__icon ui-ic-close"></i>
      </button>
      <div class="m-popover__paragraph">
        Paragraph Text View standard regular Lorem ipsum dolor sit amet,
        consetetur sadipscing elitr, sed diam nonumy.
      </div>
      <div class="m-popover__buttons">
        <button
          type="button"
          class="a-button a-button--primary -without-icon"
          data-frok-action="confirm"
        >
          <span class="a-button__label">Learn more</span>
        </button>
      </div>
    </div>
  </div>
</div>

With close button and primary and secondary action

Paragraph Text View standard regular Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy.
<div class="m-popover -close-button -detached">
  <div class="a-box -floating">
    <div class="m-popover__content">
      <button
        type="button"
        class="a-button a-button--integrated -without-label"
        data-frok-action="close"
        aria-label="close popover"
      >
        <i class="a-icon a-button__icon ui-ic-close"></i>
      </button>
      <div class="m-popover__paragraph">
        Paragraph Text View standard regular Lorem ipsum dolor sit amet,
        consetetur sadipscing elitr, sed diam nonumy.
      </div>
      <div class="m-popover__buttons">
        <button
          type="button"
          class="a-button a-button--primary -without-icon"
          data-frok-action="confirm"
        >
          <span class="a-button__label">Learn more</span>
        </button>
        <button
          type="button"
          class="a-button a-button--secondary -without-icon"
          data-frok-action="cancel"
        >
          <span class="a-button__label">Cancel</span>
        </button>
      </div>
    </div>
  </div>
</div>

With arrow top left

Paragraph Text View standard regular Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy.
<div class="m-popover -top-left -detached">
  <div class="a-box -floating">
    <div class="m-popover__content">
      <div class="m-popover__paragraph">
        Paragraph Text View standard regular Lorem ipsum dolor sit amet,
        consetetur sadipscing elitr, sed diam nonumy.
      </div>
    </div>
  </div>
</div>

With arrow top right

Paragraph Text View standard regular Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy.
<div class="m-popover -top-right -detached">
  <div class="a-box -floating">
    <div class="m-popover__content">
      <div class="m-popover__paragraph">
        Paragraph Text View standard regular Lorem ipsum dolor sit amet,
        consetetur sadipscing elitr, sed diam nonumy.
      </div>
    </div>
  </div>
</div>

With arrow left center

Paragraph Text View standard regular Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy.
<div class="m-popover -left-center -detached">
  <div class="a-box -floating">
    <div class="m-popover__content">
      <div class="m-popover__paragraph">
        Paragraph Text View standard regular Lorem ipsum dolor sit amet,
        consetetur sadipscing elitr, sed diam nonumy.
      </div>
    </div>
  </div>
</div>

With arrow left top

Paragraph Text View standard regular Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy.
<div class="m-popover -left-top -detached">
  <div class="a-box -floating">
    <div class="m-popover__content">
      <div class="m-popover__paragraph">
        Paragraph Text View standard regular Lorem ipsum dolor sit amet,
        consetetur sadipscing elitr, sed diam nonumy.
      </div>
    </div>
  </div>
</div>

With arrow left bottom

Paragraph Text View standard regular Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy.
<div class="m-popover -left-bottom -detached">
  <div class="a-box -floating">
    <div class="m-popover__content">
      <div class="m-popover__paragraph">
        Paragraph Text View standard regular Lorem ipsum dolor sit amet,
        consetetur sadipscing elitr, sed diam nonumy.
      </div>
    </div>
  </div>
</div>

With arrow bottom center

Paragraph Text View standard regular Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy.
<div class="m-popover -bottom-center -detached">
  <div class="a-box -floating">
    <div class="m-popover__content">
      <div class="m-popover__paragraph">
        Paragraph Text View standard regular Lorem ipsum dolor sit amet,
        consetetur sadipscing elitr, sed diam nonumy.
      </div>
    </div>
  </div>
</div>

With arrow bottom left

Paragraph Text View standard regular Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy.
<div class="m-popover -bottom-left -detached">
  <div class="a-box -floating">
    <div class="m-popover__content">
      <div class="m-popover__paragraph">
        Paragraph Text View standard regular Lorem ipsum dolor sit amet,
        consetetur sadipscing elitr, sed diam nonumy.
      </div>
    </div>
  </div>
</div>

With arrow bottom right

Paragraph Text View standard regular Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy.
<div class="m-popover -bottom-right -detached">
  <div class="a-box -floating">
    <div class="m-popover__content">
      <div class="m-popover__paragraph">
        Paragraph Text View standard regular Lorem ipsum dolor sit amet,
        consetetur sadipscing elitr, sed diam nonumy.
      </div>
    </div>
  </div>
</div>

With arrow right center

Paragraph Text View standard regular Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy.
<div class="m-popover -right-center -detached">
  <div class="a-box -floating">
    <div class="m-popover__content">
      <div class="m-popover__paragraph">
        Paragraph Text View standard regular Lorem ipsum dolor sit amet,
        consetetur sadipscing elitr, sed diam nonumy.
      </div>
    </div>
  </div>
</div>

With arrow right top

Paragraph Text View standard regular Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy.
<div class="m-popover -right-top -detached">
  <div class="a-box -floating">
    <div class="m-popover__content">
      <div class="m-popover__paragraph">
        Paragraph Text View standard regular Lorem ipsum dolor sit amet,
        consetetur sadipscing elitr, sed diam nonumy.
      </div>
    </div>
  </div>
</div>

With arrow right bottom

Paragraph Text View standard regular Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy.
<div class="m-popover -right-bottom -detached">
  <div class="a-box -floating">
    <div class="m-popover__content">
      <div class="m-popover__paragraph">
        Paragraph Text View standard regular Lorem ipsum dolor sit amet,
        consetetur sadipscing elitr, sed diam nonumy.
      </div>
    </div>
  </div>
</div>

Without arrow

Optional headline lorem ipsum
Paragraph Text View standard regular Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy.
<div class="m-popover -with-headline -detached -without-arrow">
  <div class="a-box -floating">
    <div class="m-popover__content">
      <div class="m-popover__head">Optional headline lorem ipsum</div>
      <div class="m-popover__paragraph">
        Paragraph Text View standard regular Lorem ipsum dolor sit amet,
        consetetur sadipscing elitr, sed diam nonumy.
      </div>
    </div>
  </div>
</div>

Attached example

An attached popover will be positioned absolutely to point to a given DOM element.

On page load, attached popover components will move to the end of the DOM automatically. This is needed to ensure the correct positioning.
This component is only meant to be used in a full page and won't render / behave correctly here. Please use the button below (Open on blank page) to see the component in action.
<div class="frontend-kit-example_attached-popover">
  <button
    type="button"
    class="a-button a-button--primary -without-icon"
    data-frok-action="show"
  >
    <span class="a-button__label">click me</span>
  </button>
  <div class="m-popover -close-button">
    <div class="a-box -floating">
      <div class="m-popover__content">
        <button
          type="button"
          class="a-button a-button--integrated -without-label"
          data-frok-action="close"
          aria-label="close popover"
        >
          <i class="a-icon a-button__icon ui-ic-close"></i>
        </button>
        <div class="m-popover__paragraph">
          Paragraph Text View standard regular Lorem ipsum dolor sit amet,
          consetetur sadipscing elitr, sed diam nonumy.
        </div>
        <div class="m-popover__buttons">
          <button
            type="button"
            class="a-button a-button--primary -without-icon"
            data-frok-action="confirm"
          >
            <span class="a-button__label">close me</span>
          </button>
        </div>
      </div>
    </div>
  </div>
</div>

Nested Popover example

This is a Popover that includes another Popover.

Click on the button below to open the nested popover

This is a nested popover with different attributes like the arrow position.
<div class="frontend-kit-example_nested-popover">
  <button
    type="button"
    class="a-button a-button--primary -without-icon"
    data-frok-action="show"
  >
    <span class="a-button__label">open base popover</span>
  </button>
  <div class="m-popover -left-center -close-button">
    <div class="a-box -floating">
      <div class="m-popover__content">
        <button
          type="button"
          class="a-button a-button--integrated -without-label"
          data-frok-action="close"
          aria-label="close popover"
        >
          <i class="a-icon a-button__icon ui-ic-close"></i>
        </button>
        <div class="m-popover__paragraph">
          This is a Popover that includes another Popover.
        </div>
        <div class="m-popover__buttons">
          <button
            type="button"
            class="a-button a-button--primary -without-icon"
            data-frok-action="confirm"
          >
            <span class="a-button__label">close base popover</span>
          </button>
        </div>
        <p>Click on the button below to open the nested popover</p>
        <button
          type="button"
          class="a-button a-button--primary -without-icon"
          data-frok-action="show"
        >
          <span class="a-button__label">open nested popover</span>
        </button>
        <div class="m-popover -top-left -close-button">
          <div class="a-box -floating">
            <div class="m-popover__content">
              <button
                type="button"
                class="a-button a-button--integrated -without-label"
                data-frok-action="close"
                aria-label="close popover"
              >
                <i class="a-icon a-button__icon ui-ic-close"></i>
              </button>
              <div class="m-popover__paragraph">
                This is a nested popover with different attributes like the
                arrow position.
              </div>
              <div class="m-popover__buttons">
                <button
                  type="button"
                  class="a-button a-button--primary -without-icon"
                  data-frok-action="confirm"
                >
                  <span class="a-button__label">close nested popover</span>
                </button>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>
This component is only meant to be used in a full page and won't render / behave correctly here. Please use the button below (Open on blank page) to see the component in action.
<div class="frontend-kit-example_attached-popover-gallery">
  <div style="display:block;margin-bottom:1rem;text-align:center">
    <button
      type="button"
      class="a-button a-button--primary -without-icon"
      data-frok-action="top-left"
    >
      <span class="a-button__label">top-left</span>
    </button>
    <div class="m-popover -top-left -close-button">
      <div class="a-box -floating">
        <div class="m-popover__content">
          <button
            type="button"
            class="a-button a-button--integrated -without-label"
            data-frok-action="close"
            aria-label="close popover"
          >
            <i class="a-icon a-button__icon ui-ic-close"></i>
          </button>
          <div class="m-popover__paragraph">
            Paragraph Text View standard regular Lorem ipsum dolor sit amet,
            consetetur sadipscing elitr, sed diam nonumy.
          </div>
          <div class="m-popover__buttons">
            <button
              type="button"
              class="a-button a-button--primary -without-icon"
              data-frok-action="confirm"
            >
              <span class="a-button__label">close me</span>
            </button>
          </div>
        </div>
      </div>
    </div>
  </div>
  <div style="display:block;margin-bottom:1rem;text-align:center">
    <button
      type="button"
      class="a-button a-button--primary -without-icon"
      data-frok-action="top-center"
    >
      <span class="a-button__label">top-center</span>
    </button>
    <div class="m-popover -top-center -close-button">
      <div class="a-box -floating">
        <div class="m-popover__content">
          <button
            type="button"
            class="a-button a-button--integrated -without-label"
            data-frok-action="close"
            aria-label="close popover"
          >
            <i class="a-icon a-button__icon ui-ic-close"></i>
          </button>
          <div class="m-popover__paragraph">
            Paragraph Text View standard regular Lorem ipsum dolor sit amet,
            consetetur sadipscing elitr, sed diam nonumy.
          </div>
          <div class="m-popover__buttons">
            <button
              type="button"
              class="a-button a-button--primary -without-icon"
              data-frok-action="confirm"
            >
              <span class="a-button__label">close me</span>
            </button>
          </div>
        </div>
      </div>
    </div>
  </div>
  <div style="display:block;margin-bottom:1rem;text-align:center">
    <button
      type="button"
      class="a-button a-button--primary -without-icon"
      data-frok-action="top-right"
    >
      <span class="a-button__label">top-right</span>
    </button>
    <div class="m-popover -top-right -close-button">
      <div class="a-box -floating">
        <div class="m-popover__content">
          <button
            type="button"
            class="a-button a-button--integrated -without-label"
            data-frok-action="close"
            aria-label="close popover"
          >
            <i class="a-icon a-button__icon ui-ic-close"></i>
          </button>
          <div class="m-popover__paragraph">
            Paragraph Text View standard regular Lorem ipsum dolor sit amet,
            consetetur sadipscing elitr, sed diam nonumy.
          </div>
          <div class="m-popover__buttons">
            <button
              type="button"
              class="a-button a-button--primary -without-icon"
              data-frok-action="confirm"
            >
              <span class="a-button__label">close me</span>
            </button>
          </div>
        </div>
      </div>
    </div>
  </div>
  <div style="display:block;margin-bottom:1rem;text-align:center">
    <button
      type="button"
      class="a-button a-button--primary -without-icon"
      data-frok-action="left-top"
    >
      <span class="a-button__label">left-top</span>
    </button>
    <div class="m-popover -left-top -close-button">
      <div class="a-box -floating">
        <div class="m-popover__content">
          <button
            type="button"
            class="a-button a-button--integrated -without-label"
            data-frok-action="close"
            aria-label="close popover"
          >
            <i class="a-icon a-button__icon ui-ic-close"></i>
          </button>
          <div class="m-popover__paragraph">
            Paragraph Text View standard regular Lorem ipsum dolor sit amet,
            consetetur sadipscing elitr, sed diam nonumy.
          </div>
          <div class="m-popover__buttons">
            <button
              type="button"
              class="a-button a-button--primary -without-icon"
              data-frok-action="confirm"
            >
              <span class="a-button__label">close me</span>
            </button>
          </div>
        </div>
      </div>
    </div>
  </div>
  <div style="display:block;margin-bottom:1rem;text-align:center">
    <button
      type="button"
      class="a-button a-button--primary -without-icon"
      data-frok-action="left-center"
    >
      <span class="a-button__label">left-center</span>
    </button>
    <div class="m-popover -left-center -close-button">
      <div class="a-box -floating">
        <div class="m-popover__content">
          <button
            type="button"
            class="a-button a-button--integrated -without-label"
            data-frok-action="close"
            aria-label="close popover"
          >
            <i class="a-icon a-button__icon ui-ic-close"></i>
          </button>
          <div class="m-popover__paragraph">
            Paragraph Text View standard regular Lorem ipsum dolor sit amet,
            consetetur sadipscing elitr, sed diam nonumy.
          </div>
          <div class="m-popover__buttons">
            <button
              type="button"
              class="a-button a-button--primary -without-icon"
              data-frok-action="confirm"
            >
              <span class="a-button__label">close me</span>
            </button>
          </div>
        </div>
      </div>
    </div>
  </div>
  <div style="display:block;margin-bottom:1rem;text-align:center">
    <button
      type="button"
      class="a-button a-button--primary -without-icon"
      data-frok-action="left-bottom"
    >
      <span class="a-button__label">left-bottom</span>
    </button>
    <div class="m-popover -left-bottom -close-button">
      <div class="a-box -floating">
        <div class="m-popover__content">
          <button
            type="button"
            class="a-button a-button--integrated -without-label"
            data-frok-action="close"
            aria-label="close popover"
          >
            <i class="a-icon a-button__icon ui-ic-close"></i>
          </button>
          <div class="m-popover__paragraph">
            Paragraph Text View standard regular Lorem ipsum dolor sit amet,
            consetetur sadipscing elitr, sed diam nonumy.
          </div>
          <div class="m-popover__buttons">
            <button
              type="button"
              class="a-button a-button--primary -without-icon"
              data-frok-action="confirm"
            >
              <span class="a-button__label">close me</span>
            </button>
          </div>
        </div>
      </div>
    </div>
  </div>
  <div style="display:block;margin-bottom:1rem;text-align:center">
    <button
      type="button"
      class="a-button a-button--primary -without-icon"
      data-frok-action="bottom-left"
    >
      <span class="a-button__label">bottom-left</span>
    </button>
    <div class="m-popover -bottom-left -close-button">
      <div class="a-box -floating">
        <div class="m-popover__content">
          <button
            type="button"
            class="a-button a-button--integrated -without-label"
            data-frok-action="close"
            aria-label="close popover"
          >
            <i class="a-icon a-button__icon ui-ic-close"></i>
          </button>
          <div class="m-popover__paragraph">
            Paragraph Text View standard regular Lorem ipsum dolor sit amet,
            consetetur sadipscing elitr, sed diam nonumy.
          </div>
          <div class="m-popover__buttons">
            <button
              type="button"
              class="a-button a-button--primary -without-icon"
              data-frok-action="confirm"
            >
              <span class="a-button__label">close me</span>
            </button>
          </div>
        </div>
      </div>
    </div>
  </div>
  <div style="display:block;margin-bottom:1rem;text-align:center">
    <button
      type="button"
      class="a-button a-button--primary -without-icon"
      data-frok-action="bottom-center"
    >
      <span class="a-button__label">bottom-center</span>
    </button>
    <div class="m-popover -bottom-center -close-button">
      <div class="a-box -floating">
        <div class="m-popover__content">
          <button
            type="button"
            class="a-button a-button--integrated -without-label"
            data-frok-action="close"
            aria-label="close popover"
          >
            <i class="a-icon a-button__icon ui-ic-close"></i>
          </button>
          <div class="m-popover__paragraph">
            Paragraph Text View standard regular Lorem ipsum dolor sit amet,
            consetetur sadipscing elitr, sed diam nonumy.
          </div>
          <div class="m-popover__buttons">
            <button
              type="button"
              class="a-button a-button--primary -without-icon"
              data-frok-action="confirm"
            >
              <span class="a-button__label">close me</span>
            </button>
          </div>
        </div>
      </div>
    </div>
  </div>
  <div style="display:block;margin-bottom:1rem;text-align:center">
    <button
      type="button"
      class="a-button a-button--primary -without-icon"
      data-frok-action="bottom-right"
    >
      <span class="a-button__label">bottom-right</span>
    </button>
    <div class="m-popover -bottom-right -close-button">
      <div class="a-box -floating">
        <div class="m-popover__content">
          <button
            type="button"
            class="a-button a-button--integrated -without-label"
            data-frok-action="close"
            aria-label="close popover"
          >
            <i class="a-icon a-button__icon ui-ic-close"></i>
          </button>
          <div class="m-popover__paragraph">
            Paragraph Text View standard regular Lorem ipsum dolor sit amet,
            consetetur sadipscing elitr, sed diam nonumy.
          </div>
          <div class="m-popover__buttons">
            <button
              type="button"
              class="a-button a-button--primary -without-icon"
              data-frok-action="confirm"
            >
              <span class="a-button__label">close me</span>
            </button>
          </div>
        </div>
      </div>
    </div>
  </div>
  <div style="display:block;margin-bottom:1rem;text-align:center">
    <button
      type="button"
      class="a-button a-button--primary -without-icon"
      data-frok-action="right-bottom"
    >
      <span class="a-button__label">right-bottom</span>
    </button>
    <div class="m-popover -right-bottom -close-button">
      <div class="a-box -floating">
        <div class="m-popover__content">
          <button
            type="button"
            class="a-button a-button--integrated -without-label"
            data-frok-action="close"
            aria-label="close popover"
          >
            <i class="a-icon a-button__icon ui-ic-close"></i>
          </button>
          <div class="m-popover__paragraph">
            Paragraph Text View standard regular Lorem ipsum dolor sit amet,
            consetetur sadipscing elitr, sed diam nonumy.
          </div>
          <div class="m-popover__buttons">
            <button
              type="button"
              class="a-button a-button--primary -without-icon"
              data-frok-action="confirm"
            >
              <span class="a-button__label">close me</span>
            </button>
          </div>
        </div>
      </div>
    </div>
  </div>
  <div style="display:block;margin-bottom:1rem;text-align:center">
    <button
      type="button"
      class="a-button a-button--primary -without-icon"
      data-frok-action="right-center"
    >
      <span class="a-button__label">right-center</span>
    </button>
    <div class="m-popover -right-center -close-button">
      <div class="a-box -floating">
        <div class="m-popover__content">
          <button
            type="button"
            class="a-button a-button--integrated -without-label"
            data-frok-action="close"
            aria-label="close popover"
          >
            <i class="a-icon a-button__icon ui-ic-close"></i>
          </button>
          <div class="m-popover__paragraph">
            Paragraph Text View standard regular Lorem ipsum dolor sit amet,
            consetetur sadipscing elitr, sed diam nonumy.
          </div>
          <div class="m-popover__buttons">
            <button
              type="button"
              class="a-button a-button--primary -without-icon"
              data-frok-action="confirm"
            >
              <span class="a-button__label">close me</span>
            </button>
          </div>
        </div>
      </div>
    </div>
  </div>
  <div style="display:block;margin-bottom:1rem;text-align:center">
    <button
      type="button"
      class="a-button a-button--primary -without-icon"
      data-frok-action="right-top"
    >
      <span class="a-button__label">right-top</span>
    </button>
    <div class="m-popover -right-top -close-button">
      <div class="a-box -floating">
        <div class="m-popover__content">
          <button
            type="button"
            class="a-button a-button--integrated -without-label"
            data-frok-action="close"
            aria-label="close popover"
          >
            <i class="a-icon a-button__icon ui-ic-close"></i>
          </button>
          <div class="m-popover__paragraph">
            Paragraph Text View standard regular Lorem ipsum dolor sit amet,
            consetetur sadipscing elitr, sed diam nonumy.
          </div>
          <div class="m-popover__buttons">
            <button
              type="button"
              class="a-button a-button--primary -without-icon"
              data-frok-action="confirm"
            >
              <span class="a-button__label">close me</span>
            </button>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

additional content

Instance API

The instance API can be accessed by the component property of the dialog element.

Method description
attach(target: HTMLElement, moveToContainer?: HTMLElement) Will attach this popover to the given target element. If moveToContaineris given, the popover will become a childNode of moveToContainer. defaults to document.body. If you supply your own container in the second argument, please provide a container with position: relative to ensure correct visual display.
show() Will show this popover.
hide() Will hide this popover.
setPosition(position: ArrowPosition) Will set the arrow's position; valid values are top-left, top-center, top-right, left-top, left-center, left-bottom, bottom-left, bottom-center, bottom-right, right-top, right-center and right-bottom.

Event API

Event Handlers can be registered by calling component.addEventListener(name, callback). They can be removed by calling component.removeEventListener(name, callback) with the same arguments. Also, addEventListener returns an unsubscription function that, once called, achieves the same.

Event Name parameters description
buttonClicked none Will be triggered when the button is clicked.
closeButtonClicked none Will be triggered when the close button is clicked.

demo

import ElementWithComponent from '../../ElementWithComponent';
import Popover from '.';

export default (): void => {
  // every button with the right class will show the "demo" modal on click
  const examples = document.getElementsByClassName(
    'frontend-kit-example_attached-popover',
  );
  [...examples].forEach(container => {
    const showTrigger = container.querySelector(
      '.a-button[data-frok-action="show"]',
    ) as HTMLElement;

    const popoverElement = container.querySelector(
      '.m-popover',
    ) as ElementWithComponent<Popover>;

    if (!popoverElement) {
      console.warn('Could not find a popover inside the example - skipping.');
      return;
    }

    const popover = popoverElement.component;

    popover.attach(showTrigger);

    showTrigger.addEventListener('click', () => popover.show());

    popover.addEventListener('buttonClicked', () => popover.hide());
    popover.addEventListener('closeButtonClicked', () => popover.hide());
  });

  // every button with the right class will show the "demo" modal on click
  // nested popovers: when a popover is used within another popover
  const examples = document.getElementsByClassName(
    'frontend-kit-example_nested-popover',
  );
  [...examples].forEach(container => {
    const showTriggerBase = container.querySelector(
      ':scope > .a-button[data-frok-action="show"]',
    ) as HTMLElement;

    const showTriggerNested = container.querySelector(
      ':scope > .m-popover .a-button[data-frok-action="show"]',
    ) as HTMLElement;

    const popoverElementBase = container.querySelector(
      ':scope > .m-popover',
    ) as ElementWithComponent<Popover>;

    const popoverElementNested = container.querySelector(
      ':scope > .m-popover .m-popover',
    ) as ElementWithComponent<Popover>;

    if (!popoverElementBase) {
      console.warn('Could not find a popover inside the example - skipping.');
      return;
    }

    if (!popoverElementNested) {
      console.warn('Could not find a popover inside the popover - skipping.');
      return;
    }

    const popoverBase = popoverElementBase.component;
    const popoverNested = popoverElementNested.component;

    popoverBase.attach(showTriggerBase);

    // nesting the inner popover within the popoverElementBase
    popoverNested.attach(showTriggerNested, popoverElementBase);

    showTriggerBase.addEventListener('click', () => popoverBase.show());
    showTriggerNested.addEventListener('click', () => popoverNested.show());

    // when closing the base popover, the nested popover will also be closed
    popoverBase.addEventListener('buttonClicked', () => {
      popoverBase.hide();
      popoverNested.hide();
    });
    popoverBase.addEventListener('closeButtonClicked', () => {
      popoverBase.hide();
      popoverNested.hide();
    });

    popoverNested.addEventListener('buttonClicked', () => popoverNested.hide());
    popoverNested.addEventListener('closeButtonClicked', () =>
      popoverNested.hide(),
    );
  });

  const galleryExamples = document.querySelectorAll(
    '.frontend-kit-example_attached-popover-gallery',
  );
  [...galleryExamples].forEach(galleryExample => {
    const singleExamples = galleryExample.children;

    [...singleExamples].forEach(example => {
      const trigger = [...example.children].filter(child =>
        child.classList.contains('a-button'),
      )[0] as HTMLElement;

      const popoverElement = [...example.children].filter(child =>
        child.classList.contains('m-popover'),
      )[0] as ElementWithComponent<Popover>;

      if (!popoverElement) {
        console.warn(
          'Could not find a popover inside the gallery example - skipping.',
        );
        return;
      }

      const popover = popoverElement.component;

      popover.attach(trigger);

      trigger.addEventListener('click', () => {
        if (popoverElement.classList.contains('-show')) {
          popover.hide();
        } else {
          popover.show();
        }
      });

      popover.addEventListener('buttonClicked', () => popover.hide());
      popover.addEventListener('closeButtonClicked', () => popover.hide());
    });
  });
};

styles SCSS

/* stylelint-disable-next-line a11y/no-display-none */
.m-popover {
  max-width: 24rem;
  width: max-content;
  @include floating-outline;

  &__content {
    @include box-shadow;

    background-color: inherit;
    padding: 1rem;
    position: relative;
  }

  &__paragraph {
    @include size-m;
    margin-bottom: 1rem;
  }

  &__buttons {
    display: flex;
    justify-content: end;
    gap: 1rem;
  }

  &__head {
    display: flex;
    margin-bottom: 0.5rem;
    min-height: 1.5rem;

    @include text-highlight;
    @include size-l;
  }

  .a-button--integrated {
    position: absolute;
    top: 0;
    right: 0;
  }

  :last-child {
    margin-bottom: 0;
  }

  &.-close-button &__head,
  &.-close-button &__paragraph {
    // 16px basic padding + 32px for the close button
    padding-right: 2rem;
  }

  &.-with-headline &__paragraph {
    padding-right: 0;
  }

  > .a-box {
    position: relative;
    box-shadow: none;

    &::before,
    &::after {
      @include box-shadow;

      content: '';
      position: absolute;
      top: -11px;
      right: auto;
      bottom: auto;
      left: calc(50% - 11px);
      display: block;
      height: 22px;
      width: 22px;
      transform-origin: center;
      transform: rotate(45deg);
    }

    &::before {
      @include floating-outline;
      background-color: transparent;
    }

    &::after {
      background-color: inherit;
      box-shadow: none;
    }
  }

  // arrow variants clockwise from -top-left to -left-top
  &.-top-left {
    > .a-box {
      &::before,
      &::after {
        top: -22px;
        right: auto;
        bottom: auto;
        left: 1rem;
        transform-origin: bottom left;
        transform: rotate(45deg);
      }
    }
  }

  &.-top-center {
    > .a-box {
      &::before,
      &::after {
        top: -11px;
        right: auto;
        bottom: auto;
        left: calc(50% - 11px);
        transform-origin: center;
        transform: rotate(45deg);
      }
    }
  }

  &.-top-right {
    > .a-box {
      &::before,
      &::after {
        top: -22px;
        right: 1rem;
        bottom: 0;
        left: auto;
        transform-origin: bottom right;
        transform: rotate(-45deg);
      }
    }
  }

  &.-right-top {
    > .a-box {
      &::before,
      &::after {
        top: 1rem;
        right: -22px;
        bottom: auto;
        left: auto;
        transform-origin: top left;
        transform: rotate(45deg);
      }
    }
  }

  &.-right-center {
    > .a-box {
      &::before,
      &::after {
        top: calc(50% - 11px);
        right: -11px;
        bottom: 0;
        left: auto;
        transform-origin: center;
        transform: rotate(45deg);
      }
    }
  }

  &.-right-bottom {
    > .a-box {
      &::before,
      &::after {
        top: auto;
        right: -22px;
        bottom: 1rem;
        left: auto;
        transform-origin: bottom left;
        transform: rotate(-45deg);
      }
    }
  }

  &.-bottom-right {
    > .a-box {
      &::before,
      &::after {
        top: auto;
        right: 1rem;
        bottom: -22px;
        left: auto;
        transform-origin: top right;
        transform: rotate(45deg);
      }
    }
  }

  &.-bottom-center {
    > .a-box {
      &::before,
      &::after {
        top: auto;
        right: 0;
        bottom: -11px;
        left: calc(50% - 11px);
        transform-origin: center;
        transform: rotate(45deg);
      }
    }
  }

  &.-bottom-left {
    > .a-box {
      &::before,
      &::after {
        top: auto;
        right: 0;
        bottom: -22px;
        left: 1rem;
        transform-origin: top left;
        transform: rotate(-45deg);
      }
    }
  }

  &.-left-bottom {
    > .a-box {
      &::before,
      &::after {
        top: auto;
        right: 0;
        bottom: 1rem;
        left: -22px;
        transform-origin: bottom right;
        transform: rotate(45deg);
      }
    }
  }

  &.-left-center {
    > .a-box {
      &::before,
      &::after {
        top: calc(50% - 11px);
        right: 0;
        bottom: 0;
        left: -11px;
        transform-origin: center;
        transform: rotate(45deg);
      }
    }
  }

  &.-left-top {
    > .a-box {
      &::before,
      &::after {
        top: 1rem;
        right: 0;
        bottom: 0;
        left: -22px;
        transform-origin: top right;
        transform: rotate(-45deg);
      }
    }
  }

  &.-without-arrow {
    > .a-box {
      /* stylelint-disable a11y/content-property-no-static-value */
      &::before,
      &::after {
        content: none;
      }
    }
  }

  display: none;
  position: absolute;

  &.-detached {
    position: static;
    display: block;
  }

  &.-show {
    display: block;
  }
}