diff --git a/UNRELEASED.md b/UNRELEASED.md
index fdd01ace6bb..5862f997fe8 100644
--- a/UNRELEASED.md
+++ b/UNRELEASED.md
@@ -8,6 +8,8 @@ Use [the changelog guidelines](https://git.io/polaris-changelog-guidelines) to f
- Added helper hooks `useIndexTableRowHovered`, `useIndexTableRowSelected`, and `useIndexTableContainerScroll` to `IndexTable` ([#4286](https://github.com/Shopify/polaris-react/pull/4286))
- Added token for slim border radius ([#4573](https://github.com/Shopify/polaris-react/pull/4573))
+- Improves `Popover` component and its animation ([#4580](https://github.com/Shopify/polaris-react/pull/4580))
+- Improves `base` easing curve ([#4580](https://github.com/Shopify/polaris-react/pull/4580))
### Bug fixes
diff --git a/src/components/Popover/Popover.scss b/src/components/Popover/Popover.scss
index 91df01d12ab..acd50dba5bc 100644
--- a/src/components/Popover/Popover.scss
+++ b/src/components/Popover/Popover.scss
@@ -2,8 +2,9 @@
$arrow-size: rem(14px);
$visible-portion-of-arrow: rem(5px);
-$content-max-height: rem(295px);
+$content-max-height: rem(500px);
$content-max-width: rem(400px);
+$vertical-motion-offset: rem(-5px);
.Popover {
max-width: calc(100vw - #{2 * spacing()});
@@ -14,26 +15,30 @@ $content-max-width: rem(400px);
}
.PopoverOverlay {
- will-change: opacity;
opacity: 0;
- transition: opacity duration() easing(in);
+ transition: opacity duration(fast) easing(), transform duration(fast) easing();
+ transform: translateY($vertical-motion-offset);
}
.PopoverOverlay-entering {
opacity: 1;
+ transform: translateY(0);
}
.PopoverOverlay-open {
opacity: 1;
+ transform: translateY(0);
}
.PopoverOverlay-exiting {
- opacity: 0;
- transition-timing-function: easing(out);
+ opacity: 1;
+ transform: translateY(0);
+ transition-duration: 0ms;
}
.measuring:not(.PopoverOverlay-exiting) {
opacity: 0;
+ transform: translateY($vertical-motion-offset);
}
.fullWidth {
diff --git a/src/components/Popover/components/Pane/Pane.tsx b/src/components/Popover/components/Pane/Pane.tsx
index f6c0d2cb70e..d90f4f21f95 100644
--- a/src/components/Popover/components/Pane/Pane.tsx
+++ b/src/components/Popover/components/Pane/Pane.tsx
@@ -32,7 +32,6 @@ export function Pane({
{content}
) : (
{
this.clearTransitionTimeout();
this.enteringTimer = window.setTimeout(() => {
this.setState({transitionStatus: TransitionStatus.Entered});
- }, durationBase);
+ }, durationFast);
});
}
@@ -111,7 +111,7 @@ export class PopoverOverlay extends PureComponent {
this.clearTransitionTimeout();
this.exitingTimer = window.setTimeout(() => {
this.setState({transitionStatus: TransitionStatus.Exited});
- }, durationBase);
+ }, 0);
});
}
}
diff --git a/src/components/PositionedOverlay/PositionedOverlay.tsx b/src/components/PositionedOverlay/PositionedOverlay.tsx
index 12cf5989e32..501757554d3 100644
--- a/src/components/PositionedOverlay/PositionedOverlay.tsx
+++ b/src/components/PositionedOverlay/PositionedOverlay.tsx
@@ -4,7 +4,7 @@ import {classNames} from '../../utilities/css';
import {getRectForNode, Rect} from '../../utilities/geometry';
import {EventListener} from '../EventListener';
import {Scrollable} from '../Scrollable';
-import {layer} from '../shared';
+import {layer, dataPolarisTopBar} from '../shared';
import {
PreferredPosition,
@@ -239,6 +239,14 @@ export class PositionedOverlay extends PureComponent<
scrollableContainerRect.height = document.body.scrollHeight;
}
+ let topBarOffset = 0;
+ const topBarElement = scrollableElement.querySelector(
+ `${dataPolarisTopBar.selector}`,
+ );
+ if (topBarElement) {
+ topBarOffset = topBarElement.clientHeight;
+ }
+
const overlayMargins =
this.overlay.firstElementChild &&
this.overlay.firstChild instanceof HTMLElement
@@ -257,6 +265,7 @@ export class PositionedOverlay extends PureComponent<
containerRect,
preferredPosition,
fixed,
+ topBarOffset,
);
const horizontalPosition = calculateHorizontalPosition(
activatorRect,
diff --git a/src/components/PositionedOverlay/utilities/math.ts b/src/components/PositionedOverlay/utilities/math.ts
index 962f101d92b..df4c8ae59be 100644
--- a/src/components/PositionedOverlay/utilities/math.ts
+++ b/src/components/PositionedOverlay/utilities/math.ts
@@ -18,10 +18,11 @@ export function calculateVerticalPosition(
containerRect: Rect,
preferredPosition: PreferredPosition,
fixed: boolean | undefined,
+ topBarOffset = 0,
) {
const activatorTop = activatorRect.top;
const activatorBottom = activatorTop + activatorRect.height;
- const spaceAbove = activatorRect.top;
+ const spaceAbove = activatorRect.top - topBarOffset;
const spaceBelow =
containerRect.height - activatorRect.top - activatorRect.height;
diff --git a/src/styles/foundation/_easing.scss b/src/styles/foundation/_easing.scss
index 36dce19168e..1495bda1831 100644
--- a/src/styles/foundation/_easing.scss
+++ b/src/styles/foundation/_easing.scss
@@ -1,5 +1,5 @@
$easing-data: (
- base: cubic-bezier(0.64, 0, 0.35, 1),
+ base: cubic-bezier(0.25, 0.1, 0.25, 1),
in: cubic-bezier(0.36, 0, 1, 1),
out: cubic-bezier(0, 0, 0.42, 1),
excite: cubic-bezier(0.18, 0.67, 0.6, 1.22),