Layers

Every UI has stackable layers and it's important to have control over how the layers play together. Some examples of the stackable layers are tooltips, modals, popovers, select dropdowns or menus. The issues that come up along the layers usage are z-index and visibility handling, what layer goes on top. There are many other layer related issues that include focus management, hover management, keyboard navigation, click events and hotkeys usage.

LayersManager

In order to start leveraging the layers approach add a BaseProvider to your application. It needs to be added at the root of the application. It will add the LayersManager. Make sure you add the BaseProvider at the root of your application.

LayersManager creates two adjacent divs. Your pplication will be mounted into the first div. The second div is used to host rendered layers.

Please note: If you don't wrap the application in a BaseProvider all layers will be added directly to the body element and may create conflicts with other libraries that may add children to body.

Do not add the BaseProvider or LayersManager anywhere in the middle of your application since the host element for layers added within its context will be positioned at the point where the LayersManager is added and it will effect the layers stacking order.

Layer

Layer component renders its children into a host element, instead of the body element, using createPortal. The application needs to be wrapped in a LayersManager in order to handle the rendering into a container. If no LayersManager is added the content will be added to the body. With layers there is no need for z-index css property usage as layers completely rely on the stacking context.

Layer basic usage

Things you need to know when using z-index in an application

In general try to avoid using z-index in your component based application. If you need to have a z-index added to some element on a page make sure it's within an ordered stacking context. Read more on how to create a stacking context in the MDN documentation.

Please note: z-indexes within separate stacking contexts are not compared and children within a stacking context that goes last will overlay those with a higher z-index but within a separate stacking context that goes earlier in the stacking order. In order to support applications that have stacking contexts with z-index set to a value other than auto LayersManager accepts zIndex number. When a zIndex value is passed it will set it as a z-index value for all the layers within its context.

What LayersManager's z-index value should be set to? There is no need to pass millions or thousands as its value. In fact, you can build your application in a way that all top level stacking contexts have the z-index value set to no more than 1 so the value you'd need to pass to the LayersManager will be zIndex={1} or zIndex={2}. If your application is build in a less structured way you'd need to pass a zIndex value that is equal or greated than the highest z-index value of all top level stacking contexts in your application (note it may be not the highest z-index value across your application).

Layers with z-index

Element with z-index set

Tether behavior

Tether component provides a behavior where its content positioned relatively to a provided anchor element. Popover component is a good example of the Tether component usage.

Tether basic usage

Layer API

children Node required

Content to be rendered in the Layer.

Node

host nullable HTMLElement

A DOM element where the Layer will be inserted into as a child. The host value comes from the layers context provider. If there is no LayersManager added and therefore no host element in the context, document.body will be used as a container element.

HTMLElement

index number

Defines the location (child order) at which the layer will be inserted in the host element.

mountNode HTMLElement

A custom DOM element where the layer is inserted to as a child. Note that the index prop does not work with a custom mountNode.

HTMLElement

onMount function

A handler that is called when the Layer is mounted.

() => mixed

onUnmount function

A handler that is called when the Layer is unmounted.

() => mixed

zIndex number

A value of z-index to be set on the layer. The zIndex value comes from the layers context provider.

LayersManager API

children Node required

Node

zIndex number

z-index to be set for all the layers.

Tether API

anchorRef nullable HTMLElement = null

The reference element used to position the popper.

HTMLElement

arrowRef nullable HTMLElement

The arrow element that is passed as an arrow modifier to alter the popper positioning.

HTMLElement

popperRef nullable HTMLElement = null

The element used as a popper.

HTMLElement

children Node required

Content to be rendered in the Popper.

Node

onPopperUpdate function = () => undefined

A handler that is called when popper positioning changes.

function
arrow
top number required
left number required
popper required
top number required
left number required
,
offsets object required
arrow
top union One of
number,
null
left union One of
number,
null
popper required
top union One of
number,
null
left union One of
number,
null
placement string required
=> mixed

placement $Keys<typeof TETHER_PLACEMENT> =

Recommended placement of the popper.

$Keys{ auto: "auto", topLeft: "topLeft", top: "top", topRight: "topRight", rightTop: "rightTop", right: "right", rightBottom: "rightBottom", bottomRight: "bottomRight", bottom: "bottom", bottomLeft: "bottomLeft", leftBottom: "leftBottom", left: "left", leftTop: "leftTop" }

popperOptions any = {}

Options to be passes to the Popper on its initialization. Refer to the Popper documentation for the full list of available options. eslint-disable-next-line flowtype/no-weak-types