Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@spectrum-web-components/overlay

Package Overview
Dependencies
Maintainers
6
Versions
319
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@spectrum-web-components/overlay

Overlays in Spectrum Web Components are created via the `Overlay` class system, which prepares an "overlay stack" that can manage the deployment of one or more overlays onto a page. Whether it's needed for transient content like a tooltip, for extended in

  • 0.11.1
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
6.8K
decreased by-21.53%
Maintainers
6
Weekly downloads
 
Created
Source

Description

Overlays in Spectrum Web Components are created via the Overlay class system, which prepares an "overlay stack" that can manage the deployment of one or more overlays onto a page. Whether it's needed for transient content like a tooltip, for extended interactions like selecting a value from a picker, or for blocking content like a modal, the imperative APIs outlined below or the declarative APIs delivered by <overlay-trigger> should cover your overlay delivery needs.

Usage

See it on NPM! How big is this package in your project?

yarn add @spectrum-web-components/overlay

Import the Overlay class to leverage its capabilities within your application or custom element:

import { Overlay } from '@spectrum-web-components/overlay';

Primarily, this class gives you access to the open method that will allow you to open an overlay:

Overlay.open(
    (owner: HTMLElement), // the element to open the overlay in reference to, "trigger"
    (interaction: TriggerInteractions), // the type of interaction type that opened the overlay
    (overlayElement: HTMLElement), // the element that will be projected into the overlay, "content"
    (options: OverlayOptions) // options to customize the overlay
);

Overlay.open() is an asynchronous method that returns a function for closing the overlay, so it is common to leverage this functionality like the following:

(async () => {
    const trigger = document.querySelector('#trigger');
    const interaction = 'click';
    const content = document.querySelector('#content');
    const options = {
        offset: 0,
        placement: 'bottom',
    };
    const closeOverlay = await Overlay.open(
        trigger,
        interaction,
        content,
        options
    );
})();

Types

TriggerInteractions

This outlines the user experience that is to be delivered through the process of opening and closing an overlay.

type TriggerInteractions =
    | 'click'
    | 'custom',
    | 'hover'
    | 'inline'
    | 'modal'
    | 'replace';

click will open an overlay that will close immediately on the next click that is not on an element within the overlay.

custom is less opinionated and allows for some customization of the process from the outside.

hover will close the overlay as soon as the pointer leaves the trigger to which the overlay is connected.

inline places the overlay after the trigger but before the next element in the logical tab order. This means the shift + tab keyboard stroke will return to the trigger.

modal manages the overlay like a modal and will trap the tab order within its contents only.

replace will position the overlay directly in the position of the trigger in the logical tab order. This means the shift + tab keyboard stroke will return the focusable element immediately prior to the trigger.

OverlayOptions

type OverlayOptions = {
    delayed?: boolean;
    placement?: Placement;
    offset?: number;
    receivesFocus?: 'auto';
}

delayed allows for the overlay to open the overlay with warmup/cooldown behaviors as described at https://spectrum.adobe.com/page/tooltip/#Immediate-or-delayed-appearance

placement outlines where the overlay system should attempt to position the overlay in relation to the trigger. When the layout of the page and/or current scroll positioning prevents the successful placement of the content in this way, the placement will be automatically applied as the value best suited for those conditions. Placements available include: "auto" | "auto-start" | "auto-end" | "top" | "bottom" | "right" | "left" | "top-start" | "top-end" | "bottom-start" | "bottom-end" | "right-start" | "right-end" | "left-start" | "left-end" | "none".

offset defines the distance of the overlay content from the trigger, measured in pixels.

receivesFocus tells the overlay stack to throw focus into the overlay after it has opened.

Example

<sp-button
    onclick="
        const trigger = this;
        const interaction = 'click';
        const content = this.nextElementSibling;
        if (!content) return;
        const options = {
            offset: 0,
            placement: 'right',
        };
        content.open = true;
        const closeOverlayPromise = Overlay.open(
            trigger, 
            interaction,
            content,
            options
        );
        setTimeout(function () {
            closeOverlayPromise.then(function(close) {
                close();
                content.open = false;
            });
        }, 5000);
    "
>
    Click me for a 5 second overlay!
</sp-button>
<sp-popover>
    <sp-dialog size="medium">
        <h2 slot="heading">Demo</h2>
        Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
        tempor incididunt ut labore et dolore magna aliqua. Auctor augue mauris
        augue neque gravida. Libero volutpat sed ornare arcu. Quisque egestas
        diam in arcu cursus euismod quis viverra. Posuere ac ut consequat semper
        viverra nam libero justo laoreet. Enim ut tellus elementum sagittis
        vitae et leo duis ut. Neque laoreet suspendisse interdum consectetur
        libero id faucibus nisl. Diam volutpat commodo sed egestas egestas.
        Dolor magna eget est lorem ipsum dolor. Vitae suscipit tellus mauris a
        diam maecenas sed. Turpis in eu mi bibendum neque egestas congue.
        Rhoncus est pellentesque elit ullamcorper dignissim cras lobortis.
    </sp-dialog>
</sp-popover>

Advanced Usage

When working with the DOM-based APIs of custom elements, it is sometimes preferred to project content into an overlay from a different shadow root (eg projecting a single-slotted element into the overlay). To ensure that the content can be marshalled through any number of <slot> elements which are addressed into subsequent <slot> elements, be sure to use the flatten: true option when querying slot.asignedNodes():

const trigger = shadowRoot.querySelector('#trigger');
const slot = shadowRoot.querySeletor('slot');
const interaction = 'click';
const content = slot
    .assignedNodes({ flatten: true })
    .find((node) => node instanceof HTMLElement);
const options = {
    offset: 0,
    placement: 'bottom',
};
const closeOverlay = await Overlay.open(trigger, interaction, content, options);

Other times, you may want to compose content from multiple shadow roots into a single overlay. This is a pattern seen in the <sp-dropdown> element: its <sp-menu> light DOM child is wrapped by its <sp-popover> shadow DOM child before being projected into an overlay. What follows is a more trivial example, where content in the light DOM of an element is injected into an element in the shadow DOM of the same element and then projected into an overlay. Notice the added work here of setting a comment node into the light DOM as a placeholder for the "stolen" content, and then swapping that content back into the light DOM when the overlay is closed.

const trigger = this.shadowRoot.querySelector('#trigger');
const outterContent = this.shadowRoot.querySelector('#outter-content');
const innerContent = this.querySelector('#inner-content');
const innerContentParent =
    innerContent.parentElement || innerContent.getRootNode();
const placeholder = document.createComment('placeholder for inner content');
innerContentParent.replaceChild(placeholder, innerContent);
outterContent.append(innerContent);
const interaction = 'click';
const options = {
    offset: 0,
    placement: 'bottom',
};
const closeOverlayPromise = Overlay.open(
    trigger,
    interaction,
    outterContent,
    options
);
const closeOverlay = function () {
    closeOverlayPromise.then((close) => close());
    innerContentParent.replaceChild(placeholder, innerContent);
};

Keywords

FAQs

Package last updated on 22 Mar 2021

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc