Positioning

This commit is contained in:
Tanya Fomina 2024-04-30 23:24:10 +03:00
parent 53a6cbdce5
commit 95685db200
3 changed files with 75 additions and 19 deletions

View file

@ -21,6 +21,11 @@ export class PopoverDesktop extends PopoverAbstract {
*/
public flipper: Flipper;
/**
* Popover nesting level. 0 value means that it is a root popover
*/
protected nestingLevel = 0;
/**
* Reference to nested popover if exists.
* Undefined by default, PopoverDesktop when exists and null after destroyed.
@ -34,11 +39,6 @@ export class PopoverDesktop extends PopoverAbstract {
*/
private previouslyHoveredItem: PopoverItem | null = null;
/**
* Popover nesting level. 0 value means that it is a root popover
*/
private nestingLevel = 0;
/**
* Element of the page that creates 'scope' of the popover.
* If possible, popover will not cross specified element's borders when opening.
@ -198,6 +198,21 @@ export class PopoverDesktop extends PopoverAbstract {
this.showNestedPopoverForItem(item);
}
/**
* Sets CSS variable with position of item near which nested popover should be displayed.
* Is used for correct positioning of the nested popover
*
* @param nestedPopoverEl - nested popover element
* @param item item near which nested popover should be displayed
*/
protected setTriggerItemPositionProperty(nestedPopoverEl: HTMLElement, item: PopoverItemDefault): void {
const itemEl = item.getElement();
const itemOffsetTop = (itemEl ? itemEl.offsetTop : 0) - this.scrollTop;
const topOffset = this.offsetTop + itemOffsetTop;
nestedPopoverEl.style.setProperty('--trigger-item-top', topOffset + 'px');
}
/**
* Additionaly handles input inside search field.
* Updates flipper items considering search query applied.
@ -259,7 +274,7 @@ export class PopoverDesktop extends PopoverAbstract {
* Renders invisible clone of popover to get actual size.
*/
@cacheable
private get size(): {height: number; width: number} {
protected get size(): {height: number; width: number} {
const size = {
height: 0,
width: 0,
@ -348,11 +363,9 @@ export class PopoverDesktop extends PopoverAbstract {
const nestedPopoverEl = this.nestedPopover.getElement();
this.nodes.popover.appendChild(nestedPopoverEl);
const itemEl = item.getElement();
const itemOffsetTop = (itemEl ? itemEl.offsetTop : 0) - this.scrollTop;
const topOffset = this.offsetTop + itemOffsetTop;
nestedPopoverEl.style.setProperty('--trigger-item-top', topOffset + 'px');
this.setTriggerItemPositionProperty(nestedPopoverEl, item);
nestedPopoverEl.style.setProperty('--nesting-level', this.nestedPopover.nestingLevel.toString());
nestedPopoverEl.classList.add(css.getPopoverNestedClass(this.nestedPopover.nestingLevel));

View file

@ -1,15 +1,16 @@
import { PopoverItem, PopoverItemDefault, PopoverItemParams } from './components/popover-item';
import { PopoverItemDefault } from './components/popover-item';
import { PopoverDesktop } from './popover-desktop';
import { css } from './popover.const';
import { PopoverEvent, PopoverParams } from './popover.types';
import { PopoverParams } from './popover.types';
/**
*
*/
export class PopoverInline extends PopoverDesktop {
/**
* Constructs the instance
*
* @param params
* @param params - instance parameters
*/
constructor(params: PopoverParams) {
super({
@ -18,11 +19,50 @@ export class PopoverInline extends PopoverDesktop {
});
}
/**
*
* @param event
* Returns visible element offset top
*/
protected override handleHover(event: Event): void {
// do nothing
public get offsetLeft(): number {
if (this.nodes.popoverContainer === null) {
return 0;
}
return this.nodes.popoverContainer.offsetLeft;
}
/**
* Open popover
*/
public override show(): void {
/**
* If this is not a nested popover, set CSS variable with width of the popover
*/
if (this.nestingLevel === 0) {
this.nodes.popover.style.setProperty('--inline-popover-width', this.size.width + 'px');
}
super.show();
}
/**
* Disable hover event handling
*/
protected override handleHover(): void {
// Do nothing
}
/**
* Sets CSS variable with position of item near which nested popover should be displayed.
* Is used for correct positioning of the nested popover
*
* @param nestedPopoverEl - nested popover element
* @param item item near which nested popover should be displayed
*/
protected override setTriggerItemPositionProperty(nestedPopoverEl: HTMLElement, item: PopoverItemDefault): void {
const itemEl = item.getElement();
const itemOffsetLeft = itemEl ? itemEl.offsetLeft : 0;
const totalLeftOffset = this.offsetLeft + itemOffsetLeft;
nestedPopoverEl.style.setProperty('--trigger-item-left', totalLeftOffset + 'px');
}
}

View file

@ -55,12 +55,15 @@
.ce-popover--nested-level-1 {
.ce-popover__container {
right: 0;
left: min(var(--trigger-item-left), calc(var(--inline-popover-width) - var(--width)));
top: var(--height);
}
}
.ce-popover--nested {
.ce-popover__container {
min-width: var(--width);
width: var(--width);
}
}
}