/*! * SPDX-License-Identifier: Apache-2.0 * * The OpenSearch Contributors require contributions made to * this file be licensed under the Apache-2.0 license or a * compatible open source license. * * Modifications Copyright OpenSearch Contributors. See * GitHub history for details. */ // Because of the animations and positioning involved, this code gets pretty // repetitive. What you generally need to know if you work in here is that // the positioning of the popovers (and the arrows attached to them) // is handled through absolute positioning and then animated through the use // of transforms. .ouiPopover { display: inline-block; position: relative; vertical-align: middle; max-width: 100%; } .ouiPopover__anchor { display: inline-block; } .ouiPopover--displayBlock { display: block; .ouiPopover__anchor { display: block; } } /** * 1. Can expand further, but it looks weird if it's smaller than the originating button. * 2. Animation happens on the panel. But don't animate when using the attached mode like for inputs * 3. Make sure the panel stays within the window. */ .ouiPopover__panel { // Ignore linting for legibility of transition property, and the mixin performs an overwrite // sass-lint:disable-block indentation @include ouiBottomShadow($adjustBorders: true); position: absolute; min-width: $ouiButtonMinWidth; /* 1 */ max-width: calc(100vw - #{$ouiSizeXL}); /* 3 */ backface-visibility: hidden; pointer-events: none; opacity: 0; /* 2 */ visibility: hidden; /* 2 */ transition: /* 2 */ opacity $ouiAnimSlightBounce $ouiAnimSpeedSlow, visibility $ouiAnimSlightBounce $ouiAnimSpeedSlow; // Don't animate when using the attached mode like for inputs &:not(.ouiPopover__panel-isAttached) { transform: translateY(0) translateX(0) translateZ(0); /* 2 */ transition: /* 2 */ opacity $ouiAnimSlightBounce $ouiAnimSpeedSlow, visibility $ouiAnimSlightBounce $ouiAnimSpeedSlow, transform $ouiAnimSlightBounce ($ouiAnimSpeedSlow + 100ms); } &.ouiPopover__panel-isOpen { opacity: 1; visibility: visible; pointer-events: auto; } .ouiPopover__panelArrow { position: absolute; width: 0; height: 0; // This fakes a border on the arrow. &:before { position: absolute; content: ''; height: 0; width: 0; } // This part of the arrow matches the panel. &:after { position: absolute; content: ''; height: 0; width: 0; } &.ouiPopover__panelArrow--top { &:before { bottom: -$ouiPopoverArrowSize + 2; border-left: $ouiPopoverArrowSize solid transparent; border-right: $ouiPopoverArrowSize solid transparent; border-top: $ouiPopoverArrowSize solid $ouiBorderColor; } &:after { bottom: -$ouiPopoverArrowSize + 3; border-left: $ouiPopoverArrowSize solid transparent; border-right: $ouiPopoverArrowSize solid transparent; border-top: $ouiPopoverArrowSize solid $ouiColorEmptyShade; } } &.ouiPopover__panelArrow--right { &:before { left: -$ouiPopoverArrowSize; top: 50%; border-top: $ouiPopoverArrowSize solid transparent; border-bottom: $ouiPopoverArrowSize solid transparent; border-right: $ouiPopoverArrowSize solid $ouiBorderColor; } &:after { left: -$ouiPopoverArrowSize + 1; top: 50%; border-top: $ouiPopoverArrowSize solid transparent; border-bottom: $ouiPopoverArrowSize solid transparent; border-right: $ouiPopoverArrowSize solid $ouiColorEmptyShade; } } &.ouiPopover__panelArrow--bottom { &:before { top: -$ouiPopoverArrowSize; border-left: $ouiPopoverArrowSize solid transparent; border-right: $ouiPopoverArrowSize solid transparent; border-bottom: $ouiPopoverArrowSize solid $ouiBorderColor; } &:after { top: -$ouiPopoverArrowSize + 1; border-left: $ouiPopoverArrowSize solid transparent; border-right: $ouiPopoverArrowSize solid transparent; border-bottom: $ouiPopoverArrowSize solid $ouiColorEmptyShade; } } &.ouiPopover__panelArrow--left { &:before { right: -$ouiPopoverArrowSize + 1; top: 50%; border-top: $ouiPopoverArrowSize solid transparent; border-bottom: $ouiPopoverArrowSize solid transparent; border-left: $ouiPopoverArrowSize solid $ouiBorderColor; } &:after { right: -$ouiPopoverArrowSize + 2; top: 50%; border-top: $ouiPopoverArrowSize solid transparent; border-bottom: $ouiPopoverArrowSize solid transparent; border-left: $ouiPopoverArrowSize solid $ouiColorEmptyShade; } } } &.ouiPopover__panel-noArrow .ouiPopover__panelArrow { display: none; } &.ouiPopover__panel-isAttached.ouiPopover__panel--bottom { border-top-color: transparentize($ouiBorderColor, .2); border-top-right-radius: 0; border-top-left-radius: 0; } &.ouiPopover__panel-isAttached.ouiPopover__panel--top { @include ouiBottomShadowFlat; border-bottom-color: transparentize($ouiBorderColor, .2); border-bottom-right-radius: 0; border-bottom-left-radius: 0; } } .ouiPopover__panel.ouiPopover__panel-isAttached.ouiPopover__panel--top, /* 2 */ .ouiPopover__panel.ouiPopover__panel-isOpen.ouiPopover__panel--top { transform: translateY($ouiPopoverTranslateDistance) translateZ(0); } .ouiPopover__panel.ouiPopover__panel-isAttached.ouiPopover__panel--bottom, /* 2 */ .ouiPopover__panel.ouiPopover__panel-isOpen.ouiPopover__panel--bottom { transform: translateY(-$ouiPopoverTranslateDistance) translateZ(0); } .ouiPopover__panel.ouiPopover__panel-isOpen.ouiPopover__panel--left { transform: translateX($ouiPopoverTranslateDistance) translateZ(0); } .ouiPopover__panel.ouiPopover__panel-isOpen.ouiPopover__panel--right { transform: translateX(-$ouiPopoverTranslateDistance) translateZ(0); }