Skip to content

Commit

Permalink
feat: Popover popper styles (#1366)
Browse files Browse the repository at this point in the history
* Added styles for popovers using popper.js

* Added playground examples of popover using popper.js

* Removed fd-popover-background-color css variable and just used fd-color-background-2

* Added notes about popper-specific popover classes to docs

* Empty commit to force rebuild
  • Loading branch information
greg-a-smith authored Apr 4, 2019
1 parent 2290821 commit c756cc4
Show file tree
Hide file tree
Showing 5 changed files with 199 additions and 8 deletions.
17 changes: 14 additions & 3 deletions docs/pages/components/popover.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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.

<br>

## 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

<br>

Expand Down Expand Up @@ -193,3 +194,13 @@ style="background-image: url('https://placeimg.com/400/400/nature');"></span>

{% endcapture %}
{% include display-component.html component=default-popoverwmenu %}

<br>

## 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)
121 changes: 118 additions & 3 deletions scss/components/popover.scss
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
}
Expand Down Expand Up @@ -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);
}
}
}
}
}
3 changes: 2 additions & 1 deletion scss/components/time-picker.scss
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ $block: #{$fd-namespace}-time-picker;

.#{$block} {
.#{$fd-namespace}-popover {
&__body {
&__body,
&__popper {
padding: fd-space(s);
}
}
Expand Down
14 changes: 14 additions & 0 deletions test/templates/popover/component.njk
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@ popover:
</div>
{%- endmacro -%}

{%- macro popover_popperjs(properties={}, modifier={}, state={}, aria={ hidden: true }) -%}
<div class="fd-popover{{ modifier.block | modifier('popover') }}">
{{ popover_control({ control: properties.control }) | indent(2) }}
{{ popover_popper(properties={ body: properties.body, id: properties.id }, modifier={ block: modifier.block }) }}
</div>
{%- endmacro -%}

{%- macro popover_control(properties={}, modifier={}, state={}) -%}
<div class="fd-popover__control"{{ aria | aria }}>{{properties.control}}</div>
{%- endmacro -%}
Expand All @@ -23,3 +30,10 @@ popover:
{{properties.body}}
</div>
{%- endmacro -%}

{%- macro popover_popper(properties={}, modifier={}, state={}, aria={ hidden: true }) -%}
<div class="fd-popover__popper{{ modifier.block | modifier('popover__popper') }}" {{ aria | aria }} id="{{ properties.id }}" data-placement="bottom">
{{properties.body}}
<div class="fd-popover__arrow"></div>
</div>
{%- endmacro -%}
52 changes: 51 additions & 1 deletion test/templates/popover/index.njk
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{% extends "layout.njk" %}
{% import "./../utils.njk" as utils %}
{% from "./../format.njk" import format %}
{% from "./component.njk" import popover %}
{% from "./component.njk" import popover, popover_popperjs %}
{% from "./../menu/component.njk" import menu %}

<!-- include add'tl css from src/styles/, e.g., ['helpers','components/button'] -->
Expand All @@ -18,6 +18,8 @@
{%- set _id2 = utils.id() %}
{%- set _id3 = utils.id() %}
{%- set _id4 = utils.id() %}
{%- set _id5 = utils.id() %}
{%- set _id6 = utils.id() %}

{%- macro sample_control(properties={}) -%}
<span class="fd-popover__control{{ modifier.control | modifier('popover__control') }} fd-image--m fd-image--circle" aria-label="Image label" aria-controls="{{ properties.id }}" aria-expanded="false" aria-haspopup="true"{{ " disabled" if state.disabled }}{{ aria | aria }} style="background-image: url('https://placeimg.com/400/400/nature');"></span>
Expand Down Expand Up @@ -105,5 +107,53 @@
{% endset %}
{{ format(example) }}

<br><br><br><br>

<h2>Use with popper.js</h2>
<p>NOTE: This will not be functional as the popper.js library is not being used here so this
is simply a styling example.</p>
{% 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) }}

<br><br><br><br>

<h2>No Arrow with popper.js</h2>
<p>NOTE: This will not be functional as the popper.js library is not being used here so this
is simply a styling example.</p>
{% 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 %}

0 comments on commit c756cc4

Please sign in to comment.