diff --git a/src/components/Popover/Popover.jsx b/src/components/Popover/Popover.jsx index 5a5940413..48af4cf0d 100644 --- a/src/components/Popover/Popover.jsx +++ b/src/components/Popover/Popover.jsx @@ -105,6 +105,7 @@ Popover.propTypes = { top: PropTypes.string, 'transform-origin': PropTypes.string, translate: PropTypes.string, + visibility: PropTypes.string, }), /** * If set, the popover will become controlled, meaning it will be hidden by default and will need a trigger to open. diff --git a/src/components/Popover/Popover.module.scss b/src/components/Popover/Popover.module.scss index b9b554be4..2a1ef729a 100644 --- a/src/components/Popover/Popover.module.scss +++ b/src/components/Popover/Popover.module.scss @@ -13,6 +13,7 @@ @layer components.popover { .root { position: absolute; + z-index: theme.$z-index; width: max-content; max-width: theme.$max-width; padding: theme.$padding; diff --git a/src/components/Popover/README.md b/src/components/Popover/README.md index 5f434102b..c4c7ef266 100644 --- a/src/components/Popover/README.md +++ b/src/components/Popover/README.md @@ -178,10 +178,15 @@ position the popover. The allowed props are: - `left` - `translate` - `transform-origin` +- `visibility` ⚠️ [`inset`][mdn-inset] is a shorthand for `top right bottom left`, not for `inset-*` properties. +ℹ️ `visibility` can be used to hide the Popover before its initial position is +computed, preventing a flash of the Popover in a wrong position. Set it to +`hidden` initially, then remove or update it once the position is ready. + As opposed to `top right bottom left` and the `inset` shorthand, `inset-*` properties are writing-direction aware. @@ -307,6 +312,29 @@ React.createElement(() => { }); ``` +## z-index + +By default, the Popover's `z-index` is `auto`, which means it participates in +the stacking context of its nearest positioned ancestor. This works well in most +cases, but can cause the Popover to appear behind other positioned elements such +as sticky headers, fixed toolbars, or modals. + +When that happens, set `--rui-Popover__z-index` to a numeric value high enough +to place the Popover above the conflicting layer. The override can be applied +globally or scoped to a specific context: + +```css +/* Global override */ +:root { + --rui-Popover__z-index: 1000; +} + +/* Scoped override */ +.my-context { + --rui-Popover__z-index: 1000; +} +``` + ## Controlled Popover Popover API can be used to control visibility of Popover component. You need to @@ -379,6 +407,7 @@ which enables [Advanced Positioning](#advanced-positioning). | `--rui-Popover__color` | Text color | | `--rui-Popover__background-color` | Background color | | `--rui-Popover__box-shadow` | Popover box shadow | +| `--rui-Popover__z-index` | Popover z-index (default: `auto`) | [div-attributes]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/div#attributes [Floating UI]: https://floating-ui.com/docs/react-dom diff --git a/src/components/Popover/_helpers/cleanPlacementStyle.js b/src/components/Popover/_helpers/cleanPlacementStyle.js index 123ae504c..761d20716 100644 --- a/src/components/Popover/_helpers/cleanPlacementStyle.js +++ b/src/components/Popover/_helpers/cleanPlacementStyle.js @@ -12,6 +12,7 @@ export default (placementStyle) => { 'left', 'translate', 'transform-origin', + 'visibility', ]; return Object.fromEntries( diff --git a/src/components/Popover/_theme.scss b/src/components/Popover/_theme.scss index 59b40e545..4142f1d1b 100644 --- a/src/components/Popover/_theme.scss +++ b/src/components/Popover/_theme.scss @@ -2,6 +2,7 @@ @use "sass:math"; +$z-index: var(--rui-Popover__z-index); $max-width: var(--rui-Popover__max-width); $padding: var(--rui-Popover__padding); $border-width: var(--rui-Popover__border-width); diff --git a/src/theme.scss b/src/theme.scss index 700b04954..a112ff57f 100644 --- a/src/theme.scss +++ b/src/theme.scss @@ -1090,6 +1090,7 @@ --rui-Popover__color: var(--rui-color-text-primary); --rui-Popover__background-color: var(--rui-color-background-layer-2); --rui-Popover__box-shadow: var(--rui-shadow-layer-2); + --rui-Popover__z-index: auto; // // Tabs