Skip to content

Commit

Permalink
Update to PopperJs 2.x; fix #28
Browse files Browse the repository at this point in the history
  • Loading branch information
vrimar committed Jun 3, 2023
1 parent c15aade commit 5a0d5b6
Show file tree
Hide file tree
Showing 6 changed files with 173 additions and 112 deletions.
87 changes: 63 additions & 24 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,10 @@
"mithril": ">=2.0.4"
},
"dependencies": {
"@popperjs/core": "^2.11.8",
"feather-icons": "^4.29.0",
"lodash.debounce": "^4.0.8",
"mithril-transition-group": "^0.2.0",
"popper.js": "^1.16.1",
"simplestatemanager": "^4.1.1",
"tslib": "^2.5.3"
},
Expand Down
91 changes: 45 additions & 46 deletions src/components/popover/Popover.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import m from 'mithril';
import classnames from 'classnames';
import PopperJS, { Boundary } from 'popper.js';
import { createPopper, StrictModifiers, Instance, Placement } from '@popperjs/core';
import { Classes, IAttrs, Style, safeCall, elementIsOrContains } from '../../_shared';
import { AbstractComponent } from '../abstract-component';
import { IOverlayableAttrs, Overlay } from '../overlay';
Expand All @@ -9,10 +9,9 @@ import { PopoverInteraction, PopoverPosition } from './popoverTypes';
export interface IPopoverAttrs extends IOverlayableAttrs, IAttrs {
/**
* Set the bounding box.
* see <a href="https://popper.js.org/popper-documentation.html#modifiers..preventOverflow">Here</a> for more details
* @default 'window'
*/
boundariesEl?: Boundary | Element;
boundariesEl?: 'window' | 'scrollParent' | Element;

/** Close the popover on inner content click */
closeOnContentClick?: boolean;
Expand Down Expand Up @@ -57,9 +56,9 @@ export interface IPopoverAttrs extends IOverlayableAttrs, IAttrs {

/**
* Options to pass to the PopperJS instance;
* see <a href="https://popper.js.org/popper-documentation.html#modifiers">HERE</a> for more details
* see <a href="https://popper.js.org/docs/v2/modifiers/">HERE</a> for more details
*/
modifiers?: PopperJS.Modifiers;
modifiers?: StrictModifiers[];

/**
* Position relative to trigger element
Expand Down Expand Up @@ -103,7 +102,7 @@ export interface IPopoverTriggerAttrs extends IAttrs {

export class Popover extends AbstractComponent<IPopoverAttrs> {
private isOpen: boolean;
private popper?: PopperJS & { options?: PopperJS.PopperOptions };
private popper?: Instance;
private trigger: m.VnodeDOM<IPopoverTriggerAttrs>;

public getDefaultAttrs() {
Expand Down Expand Up @@ -141,8 +140,9 @@ export class Popover extends AbstractComponent<IPopoverAttrs> {

public onupdate() {
if (this.popper) {
this.popper.options.placement = this.attrs.position as PopperJS.Placement;
this.popper.scheduleUpdate();
this.popper.setOptions({
placement: this.attrs.position as Placement
});
}
}

Expand Down Expand Up @@ -221,33 +221,41 @@ export class Popover extends AbstractComponent<IPopoverAttrs> {
};

private createPopper(el: HTMLElement) {
const { position, hasArrow, boundariesEl, modifiers } = this.attrs;

const options = {
placement: position,
modifiers: {
arrow: {
enabled: hasArrow,
element: `.${Classes.POPOVER_ARROW}`
},
offset: {
enabled: hasArrow,
fn: (data) => this.getContentOffset(data, el)
},
preventOverflow: {
enabled: true,
boundariesElement: boundariesEl,
padding: 0
},
...modifiers
const { position, hasArrow, boundariesEl, modifiers = [] } = this.attrs;

const defaultModifiers: StrictModifiers[] = [{
name: 'arrow',
enabled: hasArrow,
options: {
element: `.${Classes.POPOVER_ARROW}`,
padding: 0
}
}, {
name: 'offset',
options: {
offset: ({ placement }) => this.getContentOffset(placement, el)
}
} as PopperJS.PopperOptions;
}, {
name: 'preventOverflow',
enabled: true,
options: {
padding: 0,
boundary: typeof boundariesEl === 'string' ? 'clippingParents' : boundariesEl,
altBoundary: boundariesEl == 'scrollParent'
}
}];

const combinedModifiers =
defaultModifiers
//.filter(cm => modifiers.some(m => m.name !== cm.name))
.concat(modifiers);

this.popper = new PopperJS(
this.popper = createPopper<StrictModifiers>(
this.trigger.dom,
el,
options
);
el, {
placement: position,
modifiers: combinedModifiers
});
}

private destroyPopper() {
Expand Down Expand Up @@ -400,20 +408,11 @@ export class Popover extends AbstractComponent<IPopoverAttrs> {
return this.attrs.isOpen != null;
}

private getContentOffset = (data: PopperJS.Data, containerEl: HTMLElement) => {
if (!this.attrs.hasArrow) {
return data;
}

const placement = data.placement;
const isHorizontal = placement.includes('left') || placement.includes('right');
const position = isHorizontal ? 'left' : 'top';
const arrowSize = (containerEl.children[0] as HTMLElement).clientHeight + 1;

const offset = placement.includes('top') || placement.includes('left') ? -arrowSize : arrowSize;

data.offsets.popper[position] += offset;
private getContentOffset = (placement: Placement, containerEl: HTMLElement) => {
if (!this.attrs.hasArrow || this.popper?.state.placement != placement)
return [0, 0] as [number, number];

return data;
const arrowSize = (containerEl.children[0] as HTMLElement).clientWidth;
return [0, arrowSize] as [number, number];
};
}
Loading

0 comments on commit 5a0d5b6

Please sign in to comment.