Fix positioning on desktop

This commit is contained in:
Tanya Fomina 2024-03-16 18:16:26 +03:00
commit 2f9d0fb9ab
3 changed files with 47 additions and 17 deletions

View file

@ -75,6 +75,11 @@ export default class Popover extends EventsDispatcher<PopoverEventMap> {
*/
private previouslyHoveredItem: PopoverItem | undefined | null;
/**
* Popover nesting level. 0 value means that it is a root popover
*/
private nestingLevel = 0;
/**
* Popover CSS classes
*/
@ -140,6 +145,10 @@ export default class Popover extends EventsDispatcher<PopoverEventMap> {
this.scopeElement = params.scopeElement;
}
if (params.nestingLevel) {
this.nestingLevel = params.nestingLevel;
}
if (params.messages) {
this.messages = {
...this.messages,
@ -188,12 +197,20 @@ export default class Popover extends EventsDispatcher<PopoverEventMap> {
return this.nodes.items.scrollTop;
}
/**
* Returns visible element offset top
*/
public get offsetTop(): number {
return this.nodes.popoverContainer.offsetTop;
}
/**
* Open popover
*/
public show(): void {
this.nodes.popover.style.setProperty('--popover-height', this.height + 'px');
if (!this.shouldOpenBottom) {
this.nodes.popover.style.setProperty('--popover-height', this.height + 'px');
this.nodes.popover.classList.add(Popover.CSS.popoverOpenTop);
}
@ -271,7 +288,12 @@ export default class Popover extends EventsDispatcher<PopoverEventMap> {
this.listeners.on(this.nodes.popoverContainer, 'mouseover', (event: PointerEvent) => this.handleHover(event));
}
this.nodes.popover = Dom.make('div', [Popover.CSS.popover, this.params.class]);
this.nodes.popover = Dom.make('div', [
Popover.CSS.popover,
this.nestingLevel > 0 ? Popover.CSS.popoverNested : undefined,
this.params.class,
]);
this.nodes.overlay = Dom.make('div', [Popover.CSS.overlay, Popover.CSS.overlayHidden]);
this.listeners.on(this.nodes.overlay, 'click', () => {
@ -448,22 +470,26 @@ export default class Popover extends EventsDispatcher<PopoverEventMap> {
/**
* Creates and displays nested popover for specified item
* Creates and displays nested popover for specified item.
* Is used only on desktop
*
* @param item - item to display nested popover by
*/
private showNestedPopoverForItem(item: PopoverItem): void {
this.nestedPopover = new Popover({
items: item.children,
class: Popover.CSS.popoverNested,
nestingLevel: this.nestingLevel + 1,
});
const nestedPopoverEl = this.nestedPopover.getElement();
this.nodes.popover.appendChild(nestedPopoverEl);
const itemOffsetTop = item.getElement().offsetTop - this.scrollTop;
// eslint-disable-next-line @typescript-eslint/no-magic-numbers
const topOffset = this.offsetTop + itemOffsetTop - 4;
nestedPopoverEl.style.setProperty('--nesting-popover-item-top', itemOffsetTop + 'px');
nestedPopoverEl.style.setProperty('--nested-popover-top', topOffset + 'px');
nestedPopoverEl.style.setProperty('--nesting-level', this.nestedPopover.nestingLevel.toString());
this.nestedPopover.show();
this.flipper.deactivate();

View file

@ -38,6 +38,11 @@ export interface PopoverParams {
* CSS class name for popover root element
*/
class?: string;
/**
* Popover nesting level. 0 value means that it is a root popover
*/
nestingLevel?: number;
}
/**

View file

@ -48,7 +48,6 @@
}
&--opened {
.ce-popover__container {
opacity: 1;
padding: var(--padding);
@ -64,6 +63,12 @@
}
&--open-top {
.ce-popover__container {
--popover-top: calc(-1 * (var(--offset-from-target) + var(--popover-height)));
}
}
&__items {
overflow-y: auto;
overscroll-behavior: contain;
@ -89,11 +94,6 @@
}
}
&--open-top {
.ce-popover__container {
--popover-top: calc(-1 * (var(--offset-from-target) + var(--popover-height)));
}
}
@media (--mobile) {
@ -149,21 +149,20 @@
}
&--nested {
.ce-popover__container {
left: calc(var(--width) - 4px);
top: calc(var(--nesting-popover-item-top) + var(--popover-top) - 4px);
/* Variable --nesting-level is set via js in showNestedPopoverForItem() method */
left: calc(var(--nesting-level) * var(--width) - 4px);
/* Variable --nested-popover-top is set via js in showNestedPopoverForItem() method */
top: var(--nested-popover-top);
position: absolute;
}
}
&--open-top {
--parent-popover-height: var(--popover-height);
.ce-popover--nested {
.ce-popover__container {
/** Bottom edge of nested popover should not be lower than bottom edge of parent popover when opened upwards */
top: calc(var(--popover-top) - var(--popover-height) + var(--parent-popover-height));
top: min(var(--popover-top), var(--nested-popover-top))
}
}
}