diff --git a/docs/pages/components/popover.md b/docs/pages/components/popover.md
index 6079c372b..fb089c609 100644
--- a/docs/pages/components/popover.md
+++ b/docs/pages/components/popover.md
@@ -9,7 +9,7 @@ folder: components
summary:
---
-The popover is a wrapping component that accepts a "control" as well as a "body.
+The popover is a wrapping component that accepts a "control" as well as a "body".
{: .docs-intro}
A control can be anything that you want to trigger the interaction from. The body will be the contents of what you reveal on the page after triggering the popover. Commonly used as the interaction/wrapping component when composing "dropdowns", "contextual menus", "mega menu", etc, when paired with the menu component.
@@ -23,13 +23,14 @@ The basic wrapping structure of a popover.
* `fd-popover` - wrapper for the whole container
* `fd-popover__control` - control element to toggle the display of the popover
-* `fd-popover__body` - wrapper that contains the popover content
+* `fd-popover__body` - wrapper that contains the popover content for CSS-only implementations
+* `fd-popover__popper` - wrapper that contains the popover content when implemented using [popper.js](https://github.com/FezVrasta/popper.js) (use this instead of `fd-popover__body`). See [Implementation Options](#implementation-options) for more information.
## Modifiers
* `--left`, `--right` - modifier classes for `fd-popover__body` placement
-* `--no-arrow` - modifier to render `popover__body` without an arrow
+* `--no-arrow` - modifier to render `fd-popover__body` or `fd-popover__popper` without an arrow
@@ -193,3 +194,13 @@ style="background-image: url('https://placeimg.com/400/400/nature');">
{% endcapture %}
{% include display-component.html component=default-popoverwmenu %}
+
+
+
+## Implementation Options
+
+Using [popper.js](https://github.com/FezVrasta/popper.js) allows for programmatic positioning, but requires slightly different styling. Use the `fd-popover__popper` class for wrapping the popover content instead of `fd-popover__body`. See the implementation libraries for specifc details:
+
+* [Fundamental React](https://sap.github.io/fundamental-react/popover)
+* [Fundamental NGX](https://sap.github.io/fundamental-ngx/popover)
+* [Fundamental Vue](https://sap.github.io/fundamental-vue/#/example/popover)
diff --git a/scss/components/popover.scss b/scss/components/popover.scss
index 571e54ebb..57894e4d6 100644
--- a/scss/components/popover.scss
+++ b/scss/components/popover.scss
@@ -18,11 +18,13 @@ $block: #{$fd-namespace}-popover;
$fd-popover-arrow-right: 14px !default;
$fd-popover-arrow-x-offset: fd-space(2.5) !default;
+ $fd-popover-arrow-width: 13px;
+ $fd-popover-arrow-height: 8px;
+ $fd-popover-arrow-width-half: $fd-popover-arrow-width/2;
+
$fd-popover-transition-params: $fd-animation--speed !default;
$fd-popover-transition-distance: -15px !default;
- --fd-popover-background-color: var(--fd-color-background-2);
-
// Consider removing this reset, look into its use and seeing font-size/line-height/color...
// @include fd-reset;
position: relative;
@@ -39,7 +41,7 @@ $block: #{$fd-namespace}-popover;
white-space: nowrap;
z-index: $fd-popover-z-index;
border-radius: $fd-border-radius;
- @include fd-var-color("background-color", $fd-popover-background-color, --fd-popover-background-color);
+ @include fd-var-color("background-color", $fd-popover-background-color, --fd-color-background-2);
@if $fd-support-css-var-fallback {
box-shadow: 0 5px 20px 0 fd-color("neutral", 3), 0 2px 8px 0 fd-color("neutral", 2);
}
@@ -140,4 +142,117 @@ $block: #{$fd-namespace}-popover;
transform: translateY($fd-popover-transition-distance);
}
}
+
+ &__popper {
+ border: $fd-popover-border;
+ position: absolute;
+ white-space: nowrap;
+ z-index: $fd-popover-z-index;
+ border-radius: $fd-border-radius;
+ @include fd-var-color("background-color", $fd-popover-background-color, --fd-color-background-2);
+ @if $fd-support-css-var-fallback {
+ box-shadow: 0 5px 20px 0 fd-color("neutral", 3), 0 2px 8px 0 fd-color("neutral", 2);
+ }
+ box-shadow: 0 5px 20px 0 var(--fd-color-neutral-3), 0 2px 8px 0 var(--fd-color-neutral-2);
+ opacity: 1;
+
+ &--no-arrow {
+ margin: 0 !important;
+
+ .fd-popover__arrow {
+ display: none;
+ }
+ }
+
+ .fd-popover__arrow {
+ position: absolute;
+ width: 0;
+ height: 0;
+ border-style: solid;
+ border-color: transparent;
+
+ &::after {
+ position: absolute;
+ content: "";
+ border-style: solid;
+ border-color: transparent;
+ }
+ }
+
+ &[data-x-out-of-boundaries] {
+ display: none;
+ }
+
+ &[data-placement^="top"] {
+ margin-bottom: $fd-popover-arrow-height;
+
+ .fd-popover__arrow {
+ bottom: -$fd-popover-arrow-height;
+ margin: 0 $fd-popover-arrow-width-half;
+ border-width: $fd-popover-arrow-height $fd-popover-arrow-width-half 0 $fd-popover-arrow-width-half;
+ @include fd-var-color("border-top-color", $fd-forms-border-color, --fd-color-neutral-4);
+
+ &::after {
+ bottom: 1px;
+ margin: 0 (-$fd-popover-arrow-width-half);
+ border-width: $fd-popover-arrow-height $fd-popover-arrow-width-half 0 $fd-popover-arrow-width-half;
+ @include fd-var-color("border-top-color", $fd-popover-background-color, --fd-color-background-2);
+ }
+ }
+ }
+
+ &[data-placement^="bottom"] {
+ margin-top: $fd-popover-arrow-height;
+
+ .fd-popover__arrow {
+ top: -$fd-popover-arrow-height;
+ margin: 0 $fd-popover-arrow-width-half;
+ border-width: 0 $fd-popover-arrow-width-half $fd-popover-arrow-height $fd-popover-arrow-width-half;
+ @include fd-var-color("border-bottom-color", $fd-forms-border-color, --fd-color-neutral-4);
+
+ &::after {
+ top: 1px;
+ margin: 0 (-$fd-popover-arrow-width-half);
+ border-width: 0 $fd-popover-arrow-width-half $fd-popover-arrow-height $fd-popover-arrow-width-half;
+ @include fd-var-color("border-bottom-color", $fd-popover-background-color, --fd-color-background-2);
+ }
+ }
+ }
+
+ &[data-placement^="left"] {
+ margin-right: $fd-popover-arrow-height;
+
+ .fd-popover__arrow {
+ right: -$fd-popover-arrow-height;
+ margin: $fd-popover-arrow-width-half 0;
+ border-width: $fd-popover-arrow-width-half 0 $fd-popover-arrow-width-half $fd-popover-arrow-height;
+ @include fd-var-color("border-left-color", $fd-forms-border-color, --fd-color-neutral-4);
+
+ &::after {
+ right: 1px;
+ margin: -$fd-popover-arrow-width-half 0;
+ border-width: $fd-popover-arrow-width-half 0 $fd-popover-arrow-width-half $fd-popover-arrow-height;
+ @include fd-var-color("border-left-color", $fd-popover-background-color, --fd-color-background-2);
+ }
+ }
+ }
+
+ &[data-placement^="right"] {
+ margin-left: $fd-popover-arrow-height;
+
+ .fd-popover__arrow {
+ left: -$fd-popover-arrow-height;
+ margin: $fd-popover-arrow-width-half 0;
+ border-width: $fd-popover-arrow-width-half $fd-popover-arrow-height $fd-popover-arrow-width-half 0;
+ @include fd-var-color("border-right-color", $fd-forms-border-color, --fd-color-neutral-4);
+
+ &::after {
+ left: 1px;
+ margin: -$fd-popover-arrow-width-half 0;
+ border-width: $fd-popover-arrow-width-half $fd-popover-arrow-height $fd-popover-arrow-width-half 0;
+ @include fd-var-color("border-right-color", $fd-popover-background-color, --fd-color-background-2);
+ }
+ }
+ }
+ }
}
diff --git a/scss/components/time-picker.scss b/scss/components/time-picker.scss
index bd8edf4d3..7e2746b00 100644
--- a/scss/components/time-picker.scss
+++ b/scss/components/time-picker.scss
@@ -11,7 +11,8 @@ $block: #{$fd-namespace}-time-picker;
.#{$block} {
.#{$fd-namespace}-popover {
- &__body {
+ &__body,
+ &__popper {
padding: fd-space(s);
}
}
diff --git a/test/templates/popover/component.njk b/test/templates/popover/component.njk
index 926f4897d..6d2259a42 100644
--- a/test/templates/popover/component.njk
+++ b/test/templates/popover/component.njk
@@ -14,6 +14,13 @@ popover:
{%- endmacro -%}
+{%- macro popover_popperjs(properties={}, modifier={}, state={}, aria={ hidden: true }) -%}
+
NOTE: This will not be functional as the popper.js library is not being used here so this +is simply a styling example.
+{% set example %} + +{{ popover_popperjs(properties={ + id: _id5, + control: sample_control(properties={id: _id5}), + body: menu(properties={ + items: [ + { "label": "Option 1" }, + { "label": "Option 2" }, + { "label": "Option 3" }, + { "label": "Option 4" } + ] + }) + }, modifier={ block: []}) +}} + +{% endset %} +{{ format(example) }} + +NOTE: This will not be functional as the popper.js library is not being used here so this +is simply a styling example.
+{% set example %} + +{{ popover_popperjs(properties={ + id: _id6, + control: sample_control(properties={id: _id6}), + body: menu(properties={ + items: [ + { "label": "Option 1" }, + { "label": "Option 2" }, + { "label": "Option 3" }, + { "label": "Option 4" } + ] + }) + }, modifier={ block: ['no-arrow']}) +}} + +{% endset %} +{{ format(example) }} + {% endblock %}