Separate position and transition

This commit is contained in:
Cory LaViska
2020-08-25 17:51:52 -04:00
parent a69063934c
commit 8f2efa848b
2 changed files with 43 additions and 17 deletions

View File

@@ -12,9 +12,12 @@
display: block;
}
.dropdown__panel {
.dropdown__panel-positioner {
position: absolute;
z-index: var(--sl-z-index-dropdown);
}
.dropdown__panel {
max-height: 50vh;
font-family: var(--sl-font-sans);
font-size: var(--sl-font-size-medium);
@@ -27,9 +30,27 @@
opacity: 0;
overflow: auto;
overscroll-behavior: none;
transition: var(--sl-transition-fast) opacity;
&.popover-visible {
opacity: 1;
}
transform: scale(0.9);
transition: var(--sl-transition-fast) opacity, var(--sl-transition-fast) transform;
}
[data-popper-placement^='top'] .dropdown__panel {
transform-origin: bottom;
}
[data-popper-placement^='bottom'] .dropdown__panel {
transform-origin: top;
}
[data-popper-placement^='left'] .dropdown__panel {
transform-origin: right;
}
[data-popper-placement^='right'] .dropdown__panel {
transform-origin: left;
}
.popover-visible .dropdown__panel {
opacity: 1;
transform: scale(1);
}

View File

@@ -25,6 +25,7 @@ export class Dropdown {
componentId = `dropdown-${++id}`;
isShowing = false;
panel: HTMLElement;
panelPositioner: HTMLElement;
popover: Popover;
trigger: HTMLElement;
@@ -113,11 +114,12 @@ export class Dropdown {
}
componentDidLoad() {
this.popover = new Popover(this.trigger, this.panel, {
this.popover = new Popover(this.trigger, this.panelPositioner, {
strategy: this.hoist ? 'fixed' : 'absolute',
placement: this.placement,
distance: this.distance,
skidding: this.skidding,
transitionElement: this.panel,
onAfterHide: () => this.slAfterHide.emit(),
onAfterShow: () => this.slAfterShow.emit(),
onTransitionEnd: () => {
@@ -307,16 +309,19 @@ export class Dropdown {
<slot name="trigger" />
</span>
<div
ref={el => (this.panel = el)}
part="panel"
class="dropdown__panel"
role="menu"
aria-hidden={!this.open}
aria-labelledby={this.componentId}
hidden
>
<slot />
{/* Position the panel with a wrapper, since the popover uses `translate`. This lets us expose the panel so the
user can style it without interfering with the position. */}
<div ref={el => (this.panelPositioner = el)} class="dropdown__panel-positioner">
<div
ref={el => (this.panel = el)}
part="panel"
class="dropdown__panel"
role="menu"
aria-hidden={!this.open}
aria-labelledby={this.componentId}
>
<slot />
</div>
</div>
</div>
);