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 application 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.
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-index
es 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).
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.
API
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, nullleft union One of number, nullpopper required top union One of number, nullleft union One of number, nullplacement 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