Skip to content

Commit

Permalink
fix(popover): offset from source, animation distance matches spec
Browse files Browse the repository at this point in the history
  • Loading branch information
mdt2 committed Nov 6, 2023
1 parent ed24ed4 commit f69b84b
Show file tree
Hide file tree
Showing 5 changed files with 142 additions and 32 deletions.
56 changes: 47 additions & 9 deletions components/popover/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ governing permissions and limitations under the License.
--flow-direction: -1;
}

/* change to offset from source */
--spectrum-popover-offset: 0px;
/* animation distance is equal to and responsible for popover offset */
--spectrum-popover-animation-distance: var(--spectrum-spacing-100);

--spectrum-popover-background-color: var(--spectrum-background-layer-2-color);
--spectrum-popover-border-color: var(--spectrum-gray-400);
Expand Down Expand Up @@ -111,9 +111,15 @@ governing permissions and limitations under the License.
.spectrum-Popover--top-right,
.spectrum-Popover--top-start,
.spectrum-Popover--top-end {
margin-bottom: var(--mod-popover-offset, var(--spectrum-popover-offset));
/* spacing to include tip in calculation of offset from source */
&.spectrum-Popover--withTip {
/* tip size minus where it overlaps with popover border */
margin-bottom: calc(var(--mod-popover-pointer-height, var(--spectrum-popover-pointer-height)) - var(--mod-popover-border-width, var(--spectrum-popover-border-width)));
}

/* popover animates upward ⬆ */
&.is-open {
--spectrum-overlay-animation-distance: var(--mod-popover-animation-distance, var(--spectrum-popover-animation-distance));
@inherit: %spectrum-overlay--top--open;
}
}
Expand All @@ -124,9 +130,15 @@ governing permissions and limitations under the License.
.spectrum-Popover--bottom-right,
.spectrum-Popover--bottom-start,
.spectrum-Popover--bottom-end {
margin-top: var(--mod-popover-offset, var(--spectrum-popover-offset));
/* spacing to include tip in calculation of offset from source */
&.spectrum-Popover--withTip {
/* tip size minus where it overlaps with popover border */
margin-top: calc(var(--mod-popover-pointer-height, var(--spectrum-popover-pointer-height)) - var(--mod-popover-border-width, var(--spectrum-popover-border-width)));
}

/* popover animates downward ⬇ */
&.is-open {
--spectrum-overlay-animation-distance: var(--mod-popover-animation-distance, var(--spectrum-popover-animation-distance));
@inherit: %spectrum-overlay--bottom--open;
}
}
Expand All @@ -135,9 +147,15 @@ governing permissions and limitations under the License.
.spectrum-Popover--right,
.spectrum-Popover--right-bottom,
.spectrum-Popover--right-top {
margin-left: var(--mod-popover-offset, var(--spectrum-popover-offset));
/* spacing to include tip in calculation of offset from source */
&.spectrum-Popover--withTip {
/* tip size minus where it overlaps with popover border */
margin-left: calc(var(--mod-popover-pointer-width, var(--spectrum-popover-pointer-width)) - var(--mod-popover-border-width, var(--spectrum-popover-border-width)));
}

/* popover animates towards right ⮕ */
&.is-open {
--spectrum-overlay-animation-distance: var(--mod-popover-animation-distance, var(--spectrum-popover-animation-distance));
@inherit: %spectrum-overlay--right--open;
}
}
Expand All @@ -146,9 +164,15 @@ governing permissions and limitations under the License.
.spectrum-Popover--left,
.spectrum-Popover--left-bottom,
.spectrum-Popover--left-top {
margin-right: var(--mod-popover-offset, var(--spectrum-popover-offset));
/* spacing to include tip in calculation of offset from source */
&.spectrum-Popover--withTip {
/* tip size minus where it overlaps with popover border */
margin-right: calc(var(--mod-popover-pointer-width, var(--spectrum-popover-pointer-width)) - var(--mod-popover-border-width, var(--spectrum-popover-border-width)));
}

/* popover animates towards left ⬅ */
&.is-open {
--spectrum-overlay-animation-distance: var(--mod-popover-animation-distance, var(--spectrum-popover-animation-distance));
@inherit: %spectrum-overlay--left--open;
}
}
Expand All @@ -157,15 +181,22 @@ governing permissions and limitations under the License.
.spectrum-Popover--start,
.spectrum-Popover--start-top,
.spectrum-Popover--start-bottom {
margin-inline-end: var(--mod-popover-offset, var(--spectrum-popover-offset));
/* spacing to include tip in calculation of offset from source */
&.spectrum-Popover--withTip {
/* tip size minus where it overlaps with popover border */
margin-inline-end: calc(var(--mod-popover-pointer-width, var(--spectrum-popover-pointer-width)) - var(--mod-popover-border-width, var(--spectrum-popover-border-width)));
}

/* LTR read, popover animates towards left ⬅ */
&.is-open {
--spectrum-overlay-animation-distance: var(--mod-popover-animation-distance, var(--spectrum-popover-animation-distance));
@inherit: %spectrum-overlay--left--open;
}

/* RTL read, popover animates towards right ⮕ */
[dir="rtl"] & {
&.is-open {
--spectrum-overlay-animation-distance: var(--mod-popover-animation-distance, var(--spectrum-popover-animation-distance));
@inherit: %spectrum-overlay--right--open;
}
}
Expand All @@ -175,15 +206,22 @@ governing permissions and limitations under the License.
.spectrum-Popover--end,
.spectrum-Popover--end-top,
.spectrum-Popover--end-bottom {
margin-inline-start: var(--mod-popover-offset, var(--spectrum-popover-offset));
/* spacing to include tip in calculation of offset from source */
&.spectrum-Popover--withTip {
/* tip size minus where it overlaps with popover border */
margin-inline-start: calc(var(--mod-popover-pointer-width, var(--spectrum-popover-pointer-width)) - var(--mod-popover-border-width, var(--spectrum-popover-border-width)));
}

/* LTR read, popover animates towards right ⮕ */
&.is-open {
--spectrum-overlay-animation-distance: var(--mod-popover-animation-distance, var(--spectrum-popover-animation-distance));
@inherit: %spectrum-overlay--right--open;
}

/* RTL read, popover animates towards left ⬅ */
[dir="rtl"] & {
&.is-open {
--spectrum-overlay-animation-distance: var(--mod-popover-animation-distance, var(--spectrum-popover-animation-distance));
@inherit: %spectrum-overlay--left--open;
}
}
Expand Down Expand Up @@ -333,7 +371,7 @@ governing permissions and limitations under the License.
}
}


/* popover with tip at top */
&.spectrum-Popover--right-top,
&.spectrum-Popover--left-top,
Expand Down
2 changes: 1 addition & 1 deletion components/popover/metadata/mods.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
| Modifiable Custom Properties |
| --------------------------------------------- |
| `--mod-popover-animation-distance` |
| `--mod-popover-background-color` |
| `--mod-popover-border-color` |
| `--mod-popover-border-width` |
| `--mod-popover-content-area-spacing-vertical` |
| `--mod-popover-corner-radius` |
| `--mod-popover-filter` |
| `--mod-popover-offset` |
| `--mod-popover-pointer-edge-spacing` |
| `--mod-popover-pointer-height` |
| `--mod-popover-pointer-width` |
Expand Down
91 changes: 76 additions & 15 deletions components/popover/metadata/popover.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ sections:
#### Position Class Naming
- First position term is popover position, second term is source position.
- Example: --top-left = popover is to top and source is to left.
- Popover does not have any spacing between the source by default.
- Popover has 8px spacing from the source by default.
#### Position of Tip
- Default tip position is centered on the edge for top/bottom/left/right/start/end positions.
Expand All @@ -34,7 +34,8 @@ examples:
<div class="spectrum-Examples">
<div class="spectrum-Examples-item">
<h4 class="spectrum-Heading spectrum-Heading--sizeXS spectrum-Examples-itemHeading" style="margin-bottom: 16px;">Default</h4>
<div class="spectrum-Popover is-open">
<br>
<div class="spectrum-Popover spectrum-Popover--top is-open" id="popover-default">
<ul class="spectrum-Menu" role="listbox">
<li class="spectrum-Menu-item is-selected" role="option" aria-selected="true" tabindex="0">
<span class="spectrum-Menu-itemLabel">Ballard</span>
Expand All @@ -51,12 +52,16 @@ examples:
</li>
</ul>
</div>
<div class="dummy-spacing" style="position: relative; height: 162px; min-width: 200px; max-width: 50%;"></div>
<div class="dummy-spacing" style="position: relative; height: 146px; min-width: 166px; max-width: 50%;"></div>
<button class="spectrum-Button spectrum-Button--sizeM spectrum-Button--outline spectrum-Button--secondary spectrum-ButtonGroup-item" type="button" onclick="toggleSpectrumPopover(document.getElementById('popover-default'))" style="position: relative; display: flex; align-items: center; justify-content: center; box-sizing: border-box;">
<span>Source 50x100</span>
</button>
</div>
<div class="spectrum-Examples-item">
<h4 class="spectrum-Heading spectrum-Heading--sizeXS spectrum-Examples-itemHeading" style="margin-bottom: 16px;">With Tip</h4>
<div class="spectrum-Popover spectrum-Popover--withTip is-open">
<br>
<div class="spectrum-Popover spectrum-Popover--top spectrum-Popover--withTip is-open" id="popover-tip">
<ul class="spectrum-Menu" role="listbox">
<li class="spectrum-Menu-item is-selected" role="option" aria-selected="true" tabindex="0">
<span class="spectrum-Menu-itemLabel">Ballard</span>
Expand All @@ -76,18 +81,73 @@ examples:
<path class="spectrum-Popover-tip-triangle" d="M-1,-1 8,8 17,-1">
</svg>
</div>
<div class="dummy-spacing" style="position: relative; height: 170px; min-width: 200px; max-width: 50%;"></div>
<div class="dummy-spacing" style="position: relative; height: 153px; min-width: 166px; max-width: 50%;"></div>
<button class="spectrum-Button spectrum-Button--sizeM spectrum-Button--outline spectrum-Button--secondary spectrum-ButtonGroup-item" type="button" onclick="toggleSpectrumPopover(document.getElementById('popover-tip'))" style="position: relative; display: flex; align-items: center; justify-content: center; box-sizing: border-box;">
<span>Source 50x100</span>
</button>
</div>
</div>
- id: popover-offset-animation
name: Popover - Offset and Animation
description: Spectrum Popover has an offset default of 8px distance from the source that is applied with an animation transform when the `.is-open` class is added.
markup: |
<div class="spectrum-Examples">
<div class="spectrum-Examples-item">
<h4 class="spectrum-Heading spectrum-Heading--sizeXS spectrum-Examples-itemHeading" style="margin-bottom: 16px;">Top with Tip</h4>
<br>
<div class="spectrum-Popover spectrum-Popover--top-start spectrum-Popover--withTip is-open" role="presentation" id="popover-top">
<section class="spectrum-Dialog spectrum-Dialog--small" role="dialog" tabindex="-1" aria-modal="true">
<div class="spectrum-Dialog-grid" style="display: grid;">
<h1 class="spectrum-Dialog-heading spectrum-Dialog-heading--noHeader">Popover Title</h1>
<hr class="spectrum-Divider spectrum-Divider--sizeM spectrum-Divider--horizontal spectrum-Dialog-divider">
<section class="spectrum-Dialog-content">Cupcake ipsum dolor sit amet jelly beans. Chocolate jelly caramels. Icing soufflé chupa chups donut cheesecake. Jelly-o chocolate cake sweet roll cake danish candy biscuit halvah.</section>
</div>
</section>
<svg class="spectrum-Popover-tip" viewBox="0 -0.5 16 9">
<path class="spectrum-Popover-tip-triangle" d="M-1,-1 8,8 17,-1">
</svg>
</div>
<div class="dummy-spacing" style="position: relative; box-sizing: border-box; height: 231px; min-width: 402px; max-width: 50%;"></div>
<button class="spectrum-Button spectrum-Button--sizeM spectrum-Button--outline spectrum-Button--secondary spectrum-ButtonGroup-item" type="button" onclick="toggleSpectrumPopover(document.getElementById('popover-top'))" style="position: relative; display: flex; align-items: center; justify-content: center; box-sizing: border-box;">
<span>Source 50x100</span>
</button>
<br>
</div>
<div class="spectrum-Examples-item" style="position: relative;">
<h4 class="spectrum-Heading spectrum-Heading--sizeXS spectrum-Examples-itemHeading" style="margin-bottom: 16px;">Bottom with Tip</h4>
<button class="spectrum-Button spectrum-Button--sizeM spectrum-Button--outline spectrum-Button--secondary spectrum-ButtonGroup-item" type="button" onclick="toggleSpectrumPopover(this.nextElementSibling)" style="position: relative; margin-left: auto; display: flex; align-items: center; justify-content: center; box-sizing: border-box;">
<span class="spectrum-Button-label">Source 50x100</span>
</button>
<div class="spectrum-Popover spectrum-Popover--bottom-end spectrum-Popover--withTip is-open" role="presentation">
<section class="spectrum-Dialog spectrum-Dialog--small" role="dialog" tabindex="-1" aria-modal="true">
<div class="spectrum-Dialog-grid" style="display: grid;">
<h1 class="spectrum-Dialog-heading spectrum-Dialog-heading--noHeader">Popover Title</h1>
<hr class="spectrum-Divider spectrum-Divider--sizeM spectrum-Divider--horizontal spectrum-Dialog-divider">
<section class="spectrum-Dialog-content">Cupcake ipsum dolor sit amet jelly beans. Chocolate jelly caramels. Icing soufflé chupa chups donut cheesecake. Jelly-o chocolate cake sweet roll cake danish candy biscuit halvah.</section>
</div>
</section>
<svg class="spectrum-Popover-tip" viewBox="0 -0.5 16 9">
<path class="spectrum-Popover-tip-triangle" d="M-1,-1 8,8 17,-1">
</svg>
</div>
<div class="dummy-spacing" style="position: relative; box-sizing: border-box; height: 224px; min-width: 402px; max-width: 50%;"></div>
</div>
</div>
- id: popover-offset
- id: popover-cross-offset
name: Popover - Cross Offset
description: Spectrum Popover tip distance to edge can be overridden in implementation by setting the property to half of the source width or height. This results in the tip centering with the center of the source.
markup: |
<div class="spectrum-Examples">
<div class="spectrum-Examples-item">
<h4 class="spectrum-Heading spectrum-Heading--sizeXS spectrum-Examples-itemHeading" style="margin-bottom: 16px;">Cross Offset of Tip = 50px</h4>
<div class="spectrum-Popover spectrum-Popover--top-start spectrum-Popover--withTip is-open" role="presentation" style="--spectrum-popover-pointer-edge-offset: 50px;">
<br>
<div class="spectrum-Popover spectrum-Popover--top-start spectrum-Popover--withTip is-open" role="presentation" style="--spectrum-popover-pointer-edge-offset: 50px;" id="popover1">
<section class="spectrum-Dialog spectrum-Dialog--small" role="dialog" tabindex="-1" aria-modal="true">
<div class="spectrum-Dialog-grid" style="display: grid;">
<h1 class="spectrum-Dialog-heading spectrum-Dialog-heading--noHeader">Popover Title</h1>
Expand All @@ -99,19 +159,20 @@ examples:
<path class="spectrum-Popover-tip-triangle" d="M-1,-1 8,8 17,-1">
</svg>
</div>
<div class="dummy-spacing" style="position: relative; box-sizing: border-box; height: 235px; min-width: 400px; max-width: 50%;"></div>
<div class="dummy-spacing" style="position: relative; box-sizing: border-box; height: 232px; min-width: 402px; max-width: 50%;"></div>
<div class="dummy-source" style="position: relative; display: flex; align-items: center; justify-content: center; width: 100px; height: 50px; background: #E6E6E6; border-radius: 8px; box-sizing: border-box;">
<span><em>Source 50x100</em></span>
</div>
<button class="spectrum-Button spectrum-Button--sizeM spectrum-Button--outline spectrum-Button--secondary spectrum-ButtonGroup-item" type="button" onclick="toggleSpectrumPopover(document.getElementById('popover1'))" style="position: relative; display: flex; align-items: center; justify-content: center; box-sizing: border-box;">
<span>Source 50x100</span>
</button>
<br>
</div>
<div class="spectrum-Examples-item" style="position: relative;">
<h4 class="spectrum-Heading spectrum-Heading--sizeXS spectrum-Examples-itemHeading" style="margin-bottom: 16px;">Cross Offset of Tip = 50px</h4>
<div class="dummy-source" style="position: relative; margin-left: auto; display: flex; align-items: center; justify-content: center; width: 100px; height: 50px; background: #E6E6E6; border-radius: 8px; box-sizing: border-box; margin-bottom: 16px;">
<span><em>Source 50x100</em></span>
</div>
<button class="spectrum-Button spectrum-Button--sizeM spectrum-Button--outline spectrum-Button--secondary spectrum-ButtonGroup-item" type="button" onclick="toggleSpectrumPopover(this.nextElementSibling)" style="position: relative; margin-left: auto; display: flex; align-items: center; justify-content: center; box-sizing: border-box;">
<span class="spectrum-Button-label">Source 50x100</span>
</button>
<div class="spectrum-Popover spectrum-Popover--bottom-end spectrum-Popover--withTip is-open" role="presentation" style="--spectrum-popover-pointer-edge-offset: 50px;">
<section class="spectrum-Dialog spectrum-Dialog--small" role="dialog" tabindex="-1" aria-modal="true">
Expand All @@ -125,7 +186,7 @@ examples:
<path class="spectrum-Popover-tip-triangle" d="M-1,-1 8,8 17,-1">
</svg>
</div>
<div class="dummy-spacing" style="position: relative; box-sizing: border-box; height: 224px; min-width: 400px; max-width: 50%;"></div>
<div class="dummy-spacing" style="position: relative; box-sizing: border-box; height: 224px; min-width: 402px; max-width: 50%;"></div>
</div>
</div>
Expand Down
19 changes: 12 additions & 7 deletions components/popover/stories/template.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ export const Template = ({
testId,
triggerId = "trigger",
customStyles = {
"--spectrum-popover-offset": "8px",
"inset-inline-start": "0px",
"inset-block-start": "0px",
},
Expand Down Expand Up @@ -78,25 +77,31 @@ export const Template = ({
}
if (position.includes("top") && !position.includes("-top")) {
y = rect.top - popHeight;
yOffset = "- var(--spectrum-popover-offset)";
yOffset = withTip
? "- (var(--spectrum-popover-pointer-height) + var(--spectrum-popover-animation-distance) - 1px)"
: "- var(--spectrum-popover-animation-distance)";
} else if (position.includes("bottom") && !position.includes("-bottom")) {
y = rect.bottom;
yOffset = "+ var(--spectrum-popover-offset)";
yOffset = "+ (var(--spectrum-popover-animation-distance))";
} else if (position.includes("left")) {
if (textDir == 'rtl') {
x = rect.right;
xOffset = "+ var(--spectrum-popover-offset)";
xOffset = withTip ? "+ 0px" : "+ var(--spectrum-popover-animation-distance)";
} else {
x = rect.left - popWidth;
xOffset = "- var(--spectrum-popover-offset)";
xOffset = withTip
? "- ((var(--spectrum-popover-pointer-width) / 2) + var(--spectrum-popover-animation-distance) - 2px)"
: "- var(--spectrum-popover-animation-distance)";
}
} else if (position.includes("right")) {
if (textDir == 'rtl') {
x = rect.left - popWidth;
xOffset = "- var(--spectrum-popover-offset)";
xOffset = withTip
? "- ((var(--spectrum-popover-pointer-width) / 2) + var(--spectrum-popover-animation-distance) - 2px)"
: "- var(--spectrum-popover-animation-distance)";
} else {
x = rect.right;
xOffset = "+ var(--spectrum-popover-offset)";
xOffset = withTip ? "+ 0px" : "+ var(--spectrum-popover-animation-distance)";
}
}
Expand Down
Loading

0 comments on commit f69b84b

Please sign in to comment.