@lion/overlays
Advanced tools
Comparing version 0.22.8 to 0.23.0
# Change Log | ||
## 0.23.0 | ||
### Minor Changes | ||
- 1f62ed8b: **BREAKING:** Upgrade to popper v2. Has breaking changes for overlays config.popperConfig which is now aligned with v2 of Popper. See their [migration guidelines](https://popper.js.org/docs/v2/migration-guide/). | ||
### Patch Changes | ||
- 98f1bb7e: Ensure all lit imports are imported from @lion/core. Remove devDependencies in all subpackages and move to root package.json. Add demo dependencies as real dependencies for users that extend our docs/demos. | ||
- 53d22a85: Prevent `opened-changed` event to be sent twice | ||
- Updated dependencies [98f1bb7e] | ||
- @lion/core@0.13.7 | ||
- singleton-manager@1.2.1 | ||
## 0.22.8 | ||
@@ -4,0 +18,0 @@ |
@@ -6,3 +6,3 @@ [//]: # 'AUTO INSERT HEADER PREPUBLISH' | ||
```js script | ||
import { html } from 'lit-html'; | ||
import { html } from '@lion/core'; | ||
import { render, LitElement } from '@lion/core'; | ||
@@ -79,3 +79,3 @@ import { renderLitAsNode } from '@lion/helpers'; | ||
We also export a few preset configuration objects, which you can find [here](?path=/docs/overlays-system-configuration--placement-local#overlay-system---configuration). | ||
We also export a few [preset configuration objects](?path=/docs/overlays-system-configuration--placement-local#overlay-system---configuration). | ||
@@ -275,2 +275,8 @@ - withModalDialogConfig | ||
<button slot="invoker">Click me to open the overlay!</button> | ||
<div slot="content" class="demo-overlay"> | ||
Hello! You can close this notification here: | ||
<button @click=${e => e.target.dispatchEvent(new Event('close-overlay', { bubbles: true }))}> | ||
⨯ | ||
</button> | ||
</div> | ||
</demo-overlay-system> | ||
@@ -507,3 +513,3 @@ `; | ||
For example, you may have a modal dialog that open another modal dialog. | ||
For example, you may have a modal dialog that opens another modal dialog. | ||
The second dialog needs to block the first. | ||
@@ -610,3 +616,2 @@ When the second dialog is closed, the first one is available again. | ||
class ArrowExample extends ArrowMixin(OverlayMixin(LitElement)) { | ||
// Alternatively, set `this.config = { popperConfig: { placement: 'bottom' } }` on connectedCallback | ||
_defineOverlayConfig() { | ||
@@ -622,15 +627,6 @@ return { | ||
constructor() { | ||
super(); | ||
this.__toggle = this.__toggle.bind(this); | ||
} | ||
__toggle() { | ||
this.opened = !this.opened; | ||
} | ||
_setupOpenCloseListeners() { | ||
super._setupOpenCloseListeners(); | ||
if (this._overlayInvokerNode) { | ||
this._overlayInvokerNode.addEventListener('click', this.__toggle); | ||
this._overlayInvokerNode.addEventListener('click', this.toggle); | ||
} | ||
@@ -642,3 +638,3 @@ } | ||
if (this._overlayInvokerNode) { | ||
this._overlayInvokerNode.removeEventListener('click', this.__toggle); | ||
this._overlayInvokerNode.removeEventListener('click', this.toggle); | ||
} | ||
@@ -645,0 +641,0 @@ } |
@@ -18,3 +18,3 @@ [//]: # 'AUTO INSERT HEADER PREPUBLISH' | ||
document flow. | ||
Overlays come in many forms (dialog, popover, dropown, tooltip etc.) | ||
Overlays come in many forms (dialog, popover, dropdown, tooltip etc.) | ||
For a more exhaustive list, see 'Types of overlays' below. | ||
@@ -146,3 +146,3 @@ Our system tries to focus on mapping all these forms to officially supported aria widgets. | ||
Also, the W3C document often refers to _popup_. This term is mentioned in the context of _combobox_, | ||
_listbox_, _grid_, _tree_, _dialog_ and _tooltip_. Therefore, one could say it could be a term | ||
_listbox_, _grid_, _tree_, _dialog_ and _tooltip_. It can be considered as a synonym of _overlay_. | ||
@@ -149,0 +149,0 @@ _aria-haspopup_ attribute needs to be mentioned: it can have values ‘menu’, ‘listbox’, ‘grid’, |
@@ -6,3 +6,3 @@ [//]: # 'AUTO INSERT HEADER PREPUBLISH' | ||
```js script | ||
import { html } from 'lit-html'; | ||
import { html } from '@lion/core'; | ||
import '../docs/demo-overlay-system.js'; | ||
@@ -345,3 +345,3 @@ import '../docs/applyDemoOverlayStyles.js'; | ||
> Popper strictly is scoped on positioning. **It does not change the dimensions of the content node nor the invoker node**. | ||
> This also means that if you use the arrow feature, you are in charge of styling it properly, use the x-placement attribute for this. | ||
> This also means that if you use the arrow feature, you are in charge of styling it properly, use the data-popper-placement attribute for this. | ||
> An example implementation can be found in [lion-tooltip](?path=/docs/overlays-tooltip--main#tooltip), where an arrow is set by default. | ||
@@ -361,27 +361,31 @@ | ||
positionFixed: true, | ||
modifiers: { | ||
/* Prevents detachment of content node from invoker node */ | ||
keepTogether: { | ||
enabled: true, | ||
}, | ||
modifiers: [ | ||
/* When enabled, adds shifting/sliding behavior on secondary axis */ | ||
preventOverflow: { | ||
{ | ||
name: 'preventOverflow', | ||
enabled: false, | ||
boundariesElement: 'viewport', | ||
/* When enabled, this is the <boundariesElement>-margin for the secondary axis */ | ||
padding: 32, | ||
options: { | ||
boundariesElement: 'viewport', | ||
/* When enabled, this is the <boundariesElement>-margin for the secondary axis */ | ||
padding: 32, | ||
}, | ||
}, | ||
/* Use to adjust flipping behavior or constrain directions */ | ||
flip: { | ||
boundariesElement: 'viewport', | ||
/* <boundariesElement>-margin for flipping on primary axis */ | ||
padding: 16, | ||
{ | ||
name: 'flip', | ||
options: { | ||
boundariesElement: 'viewport', | ||
/* <boundariesElement>-margin for flipping on primary axis */ | ||
padding: 16, | ||
}, | ||
}, | ||
/* When enabled, adds an offset to either primary or secondary axis */ | ||
offset: { | ||
enabled: true, | ||
/* margin between content node and invoker node */ | ||
offset: `0, 16px`, | ||
{ | ||
name: 'offset', | ||
options: { | ||
/* margin between content node and invoker node */ | ||
offset: [0, 16], | ||
}, | ||
}, | ||
}, | ||
], | ||
}, | ||
@@ -404,2 +408,2 @@ }} | ||
> Note: popperConfig reflects [Popper.js API](https://popper.js.org/popper-documentation.html) | ||
> Note: popperConfig reflects [Popper API](https://popper.js.org/docs/v2/) |
@@ -8,7 +8,2 @@ import { html, LitElement } from '@lion/core'; | ||
class DemoOverlaySystem extends OverlayMixin(LitElement) { | ||
constructor() { | ||
super(); | ||
this.__toggle = this.__toggle.bind(this); | ||
} | ||
// eslint-disable-next-line class-methods-use-this | ||
@@ -21,6 +16,2 @@ _defineOverlayConfig() { | ||
__toggle() { | ||
this.opened = !this.opened; | ||
} | ||
_setupOpenCloseListeners() { | ||
@@ -30,3 +21,3 @@ super._setupOpenCloseListeners(); | ||
if (this._overlayInvokerNode) { | ||
this._overlayInvokerNode.addEventListener('click', this.__toggle); | ||
this._overlayInvokerNode.addEventListener('click', this.toggle); | ||
} | ||
@@ -39,3 +30,3 @@ } | ||
if (this._overlayInvokerNode) { | ||
this._overlayInvokerNode.removeEventListener('click', this.__toggle); | ||
this._overlayInvokerNode.removeEventListener('click', this.toggle); | ||
} | ||
@@ -42,0 +33,0 @@ } |
import { directive } from '@lion/core'; | ||
/** | ||
* @typedef {import('lit-html').PropertyPart} PropertyPart | ||
* @typedef {import('@lion/core').PropertyPart} PropertyPart | ||
*/ | ||
@@ -6,0 +6,0 @@ |
{ | ||
"name": "@lion/overlays", | ||
"version": "0.22.8", | ||
"version": "0.23.0", | ||
"description": "Overlays System using lit-html for rendering", | ||
@@ -38,5 +38,5 @@ "license": "MIT", | ||
"dependencies": { | ||
"@lion/core": "0.13.6", | ||
"popper.js": "^1.15.0", | ||
"singleton-manager": "1.2.0" | ||
"@lion/core": "0.13.7", | ||
"@popperjs/core": "^2.5.4", | ||
"singleton-manager": "1.2.1" | ||
}, | ||
@@ -43,0 +43,0 @@ "keywords": [ |
/** | ||
* @typedef {import('../types/OverlayConfig').OverlayConfig} OverlayConfig | ||
* @typedef {import('../types/ArrowMixinTypes').ArrowMixin} ArrowMixin | ||
* @typedef {import('popper.js').PopperOptions} PopperOptions | ||
* @typedef {import('@popperjs/core/lib/popper').Options} PopperOptions | ||
* @typedef {import('@popperjs/core/lib/enums').Placement} Placement | ||
*/ | ||
@@ -14,2 +15,8 @@ /** | ||
export type OverlayConfig = import("../types/OverlayConfig.js").OverlayConfig; | ||
export type PopperOptions = import("popper.js").default.PopperOptions; | ||
export type PopperOptions = { | ||
placement: import("@popperjs/core/lib/enums").Placement; | ||
modifiers: Partial<import("@popperjs/core/lib/types").Modifier<any, any>>[]; | ||
strategy: import("@popperjs/core/lib/types").PositioningStrategy; /** @type {Placement} */ | ||
onFirstUpdate?: ((arg0: Partial<import("@popperjs/core/lib/types").State>) => void) | undefined; | ||
}; | ||
export type Placement = "auto" | "left" | "right" | "bottom" | "top" | "top-start" | "top-end" | "bottom-start" | "bottom-end" | "right-start" | "right-end" | "left-start" | "left-end" | "auto-start" | "auto-end"; |
@@ -7,3 +7,4 @@ import { css, html, dedupeMixin } from '@lion/core'; | ||
* @typedef {import('../types/ArrowMixinTypes').ArrowMixin} ArrowMixin | ||
* @typedef {import('popper.js').PopperOptions} PopperOptions | ||
* @typedef {import('@popperjs/core/lib/popper').Options} PopperOptions | ||
* @typedef {import('@popperjs/core/lib/enums').Placement} Placement | ||
*/ | ||
@@ -31,12 +32,12 @@ | ||
return [ | ||
superCtor.styles ? superCtor.styles : [], | ||
superCtor.styles || [], | ||
css` | ||
:host { | ||
--tooltip-arrow-width: 12px; | ||
--tooltip-arrow-height: 8px; | ||
.arrow svg { | ||
display: block; | ||
} | ||
.arrow { | ||
display: none; | ||
position: absolute; | ||
--tooltip-arrow-width: 12px; | ||
--tooltip-arrow-height: 8px; | ||
width: var(--tooltip-arrow-width); | ||
@@ -46,20 +47,19 @@ height: var(--tooltip-arrow-height); | ||
:host([has-arrow]) .arrow { | ||
.arrow__graphic { | ||
display: block; | ||
} | ||
.arrow svg { | ||
display: block; | ||
[data-popper-placement^='top'] .arrow { | ||
bottom: calc(-1 * var(--tooltip-arrow-height)); | ||
} | ||
[x-placement^='top'] .arrow { | ||
bottom: calc(-1 * var(--tooltip-arrow-height)); | ||
[data-popper-placement^='bottom'] .arrow { | ||
top: calc(-1 * var(--tooltip-arrow-height)); | ||
} | ||
[x-placement^='bottom'] .arrow { | ||
top: calc(-1 * var(--tooltip-arrow-height)); | ||
[data-popper-placement^='bottom'] .arrow__graphic { | ||
transform: rotate(180deg); | ||
} | ||
[x-placement^='left'] .arrow { | ||
[data-popper-placement^='left'] .arrow { | ||
right: calc( | ||
@@ -69,6 +69,9 @@ -1 * (var(--tooltip-arrow-height) + | ||
); | ||
} | ||
[data-popper-placement^='left'] .arrow__graphic { | ||
transform: rotate(270deg); | ||
} | ||
[x-placement^='right'] .arrow { | ||
[data-popper-placement^='right'] .arrow { | ||
left: calc( | ||
@@ -78,4 +81,11 @@ -1 * (var(--tooltip-arrow-height) + | ||
); | ||
} | ||
[data-popper-placement^='right'] .arrow__graphic { | ||
transform: rotate(90deg); | ||
} | ||
:host(:not([has-arrow])) .arrow { | ||
display: none; | ||
} | ||
`, | ||
@@ -102,3 +112,3 @@ ]; | ||
_arrowNodeTemplate() { | ||
return html`<div class="arrow" x-arrow>${this._arrowTemplate()}</div>`; | ||
return html` <div class="arrow" data-popper-arrow>${this._arrowTemplate()}</div> `; | ||
} | ||
@@ -109,3 +119,3 @@ | ||
return html` | ||
<svg viewBox="0 0 12 8"> | ||
<svg viewBox="0 0 12 8" class="arrow__graphic"> | ||
<path d="M 0,0 h 12 L 6,8 z"></path> | ||
@@ -131,3 +141,5 @@ </svg> | ||
popperConfig: { | ||
...this._getPopperArrowConfig(superConfig.popperConfig), | ||
...this._getPopperArrowConfig( | ||
/** @type {Partial<PopperOptions>} */ (superConfig.popperConfig), | ||
), | ||
}, | ||
@@ -138,30 +150,36 @@ }; | ||
/** | ||
* @param {PopperOptions} popperConfigToExtendFrom | ||
* @returns {PopperOptions} | ||
* @param {Partial<PopperOptions>} popperConfigToExtendFrom | ||
* @returns {Partial<PopperOptions>} | ||
*/ | ||
_getPopperArrowConfig(popperConfigToExtendFrom = {}) { | ||
return { | ||
placement: 'top', | ||
modifiers: { | ||
...popperConfigToExtendFrom.modifiers, | ||
keepTogether: { | ||
...popperConfigToExtendFrom.modifiers?.keepTogether, | ||
_getPopperArrowConfig(popperConfigToExtendFrom) { | ||
/** @type {Partial<PopperOptions> & { afterWrite: (arg0: Partial<import('@popperjs/core/lib/popper').State>) => void }} */ | ||
const popperCfg = { | ||
...(popperConfigToExtendFrom || {}), | ||
placement: /** @type {Placement} */ ('top'), | ||
modifiers: [ | ||
{ | ||
name: 'arrow', | ||
enabled: true, | ||
options: { | ||
padding: 8, // 8px from the edges of the popper | ||
}, | ||
}, | ||
arrow: { | ||
...popperConfigToExtendFrom.modifiers?.arrow, | ||
{ | ||
name: 'offset', | ||
enabled: true, | ||
options: { offset: [0, 8] }, | ||
}, | ||
}, | ||
/** @param {import("popper.js").default.Data} data */ | ||
onCreate: data => { | ||
...((popperConfigToExtendFrom && popperConfigToExtendFrom.modifiers) || []), | ||
], | ||
/** @param {Partial<import('@popperjs/core/lib/popper').State>} data */ | ||
onFirstUpdate: data => { | ||
this.__syncFromPopperState(data); | ||
}, | ||
/** @param {import("popper.js").default.Data} data */ | ||
onUpdate: data => { | ||
/** @param {Partial<import('@popperjs/core/lib/popper').State>} data */ | ||
afterWrite: data => { | ||
this.__syncFromPopperState(data); | ||
}, | ||
}; | ||
return popperCfg; | ||
} | ||
@@ -176,7 +194,7 @@ | ||
get _arrowNode() { | ||
return /** @type {ShadowRoot} */ (this.shadowRoot).querySelector('[x-arrow]'); | ||
return /** @type {ShadowRoot} */ (this.shadowRoot).querySelector('[data-popper-arrow]'); | ||
} | ||
/** | ||
* @param {import("popper.js").default.Data} data | ||
* @param {Partial<import('@popperjs/core/lib/popper').State>} data | ||
*/ | ||
@@ -183,0 +201,0 @@ __syncFromPopperState(data) { |
@@ -12,9 +12,10 @@ /** | ||
placement: 'bottom-start', | ||
modifiers: { | ||
offset: { | ||
modifiers: [ | ||
{ | ||
name: 'offset', | ||
enabled: false, | ||
}, | ||
}, | ||
], | ||
}, | ||
handlesAccessibility: true, | ||
}); |
@@ -201,3 +201,3 @@ /** | ||
*/ | ||
get popperConfig(): import("popper.js").default.PopperOptions; | ||
get popperConfig(): import("@popperjs/core/lib/types").Options; | ||
/** | ||
@@ -239,66 +239,4 @@ * Viewport configuration. Will be used when placementMode is 'global' | ||
__prevConfig: import("../types/OverlayConfig.js").OverlayConfig | undefined; | ||
config: { | ||
popperConfig: { | ||
modifiers: { | ||
[x: string]: (import("popper.js").default.BaseModifier & Record<string, any>) | undefined; | ||
shift?: import("popper.js").default.BaseModifier | undefined; | ||
offset?: (import("popper.js").default.BaseModifier & { | ||
offset?: string | number | undefined; | ||
}) | undefined; | ||
preventOverflow?: (import("popper.js").default.BaseModifier & { | ||
priority?: import("popper.js").default.Position[] | undefined; | ||
padding?: number | import("popper.js").default.Padding | undefined; | ||
boundariesElement?: "window" | Element | "scrollParent" | "viewport" | undefined; | ||
escapeWithReference?: boolean | undefined; | ||
}) | undefined; | ||
keepTogether?: import("popper.js").default.BaseModifier | undefined; | ||
arrow?: (import("popper.js").default.BaseModifier & { | ||
element?: string | Element | undefined; | ||
}) | undefined; | ||
flip?: (import("popper.js").default.BaseModifier & { | ||
behavior?: import("popper.js").default.Position[] | "flip" | "clockwise" | "counterclockwise" | undefined; | ||
padding?: number | import("popper.js").default.Padding | undefined; | ||
boundariesElement?: "window" | Element | "scrollParent" | "viewport" | undefined; | ||
flipVariations?: boolean | undefined; | ||
flipVariationsByContent?: boolean | undefined; | ||
}) | undefined; | ||
inner?: import("popper.js").default.BaseModifier | undefined; | ||
hide?: import("popper.js").default.BaseModifier | undefined; | ||
applyStyle?: (import("popper.js").default.BaseModifier & { | ||
onLoad?: Function | undefined; | ||
gpuAcceleration?: boolean | undefined; | ||
}) | undefined; | ||
computeStyle?: (import("popper.js").default.BaseModifier & { | ||
gpuAcceleration?: boolean | undefined; | ||
x?: "bottom" | "top" | undefined; | ||
y?: "left" | "right" | undefined; | ||
}) | undefined; | ||
}; | ||
placement?: "auto" | "left" | "right" | "bottom" | "top" | "auto-start" | "auto-end" | "top-start" | "top-end" | "right-start" | "right-end" | "bottom-end" | "bottom-start" | "left-end" | "left-start" | undefined; | ||
positionFixed?: boolean | undefined; | ||
eventsEnabled?: boolean | undefined; | ||
removeOnDestroy?: boolean | undefined; | ||
onCreate?: ((data: import("popper.js").default.Data) => void) | undefined; | ||
onUpdate?: ((data: import("popper.js").default.Data) => void) | undefined; | ||
}; | ||
placementMode?: "global" | "local" | undefined; | ||
invokerNode?: HTMLElement | undefined; | ||
referenceNode?: HTMLElement | undefined; | ||
contentNode?: HTMLElement | undefined; | ||
contentWrapperNode?: HTMLElement | undefined; | ||
backdropNode?: HTMLElement | undefined; | ||
elementToFocusAfterHide?: HTMLElement | undefined; | ||
hasBackdrop?: boolean | undefined; | ||
isBlocking?: boolean | undefined; | ||
preventsScroll?: boolean | undefined; | ||
trapsKeyboardFocus?: boolean | undefined; | ||
hidesOnEsc?: boolean | undefined; | ||
hidesOnOutsideClick?: boolean | undefined; | ||
hidesOnOutsideEsc?: boolean | undefined; | ||
inheritsReferenceWidth?: "max" | "none" | "min" | "full" | undefined; | ||
handlesAccessibility?: boolean | undefined; | ||
isTooltip?: boolean | undefined; | ||
invokerRelation?: "label" | "description" | undefined; | ||
viewportConfig?: import("../types/OverlayConfig.js").ViewportConfig | undefined; | ||
} | undefined; | ||
/** @type {OverlayConfig} */ | ||
config: import("../types/OverlayConfig.js").OverlayConfig | undefined; | ||
__elementToFocusAfterHide: HTMLElement | undefined; | ||
@@ -491,3 +429,3 @@ /** | ||
__createPopperInstance(): Promise<void>; | ||
_popper: import("popper.js").default | undefined; | ||
_popper: any; | ||
} | ||
@@ -499,8 +437,14 @@ export namespace OverlayController { | ||
export type ViewportConfig = import("../types/OverlayConfig.js").ViewportConfig; | ||
export type Popper = import("popper.js").default; | ||
export type PopperOptions = import("popper.js").default.PopperOptions; | ||
export type Popper = any; | ||
export type PopperOptions = { | ||
placement: import("@popperjs/core/lib/enums").Placement; | ||
modifiers: Partial<import("@popperjs/core/lib/types").Modifier<any, any>>[]; | ||
strategy: import("@popperjs/core/lib/types").PositioningStrategy; | ||
onFirstUpdate?: ((arg0: Partial<import("@popperjs/core/lib/types").State>) => void) | undefined; | ||
}; | ||
export type Placement = "auto" | "left" | "right" | "bottom" | "top" | "top-start" | "top-end" | "bottom-start" | "bottom-end" | "right-start" | "right-end" | "left-start" | "left-end" | "auto-start" | "auto-end"; | ||
export type PopperModule = { | ||
default: Popper; | ||
createPopper: any; | ||
}; | ||
export type OverlayPhase = "add" | "hide" | "show" | "remove" | "before-show" | "setup" | "teardown" | "init"; | ||
import { EventTargetShim } from "@lion/core"; |
@@ -10,5 +10,6 @@ import '@lion/core/src/differentKeyEventNamesShimIE.js'; | ||
* @typedef {import('../types/OverlayConfig').ViewportConfig} ViewportConfig | ||
* @typedef {import('popper.js').default} Popper | ||
* @typedef {import('popper.js').PopperOptions} PopperOptions | ||
* @typedef {{ default: Popper }} PopperModule | ||
* @typedef {import('@popperjs/core/lib/popper').createPopper} Popper | ||
* @typedef {import('@popperjs/core/lib/popper').Options} PopperOptions | ||
* @typedef {import('@popperjs/core/lib/enums').Placement} Placement | ||
* @typedef {{ createPopper: Popper }} PopperModule | ||
* @typedef {'setup'|'init'|'teardown'|'before-show'|'show'|'hide'|'add'|'remove'} OverlayPhase | ||
@@ -21,4 +22,4 @@ */ | ||
async function preloadPopper() { | ||
// @ts-ignore | ||
return /** @type {Promise<PopperModule>} */ (import('popper.js/dist/esm/popper.min.js')); | ||
// @ts-ignore import complains about untyped module, but we typecast it ourselves | ||
return /** @type {Promise<PopperModule>} */ (import('@popperjs/core/dist/esm/popper.js')); | ||
} | ||
@@ -123,24 +124,31 @@ | ||
placement: 'top', | ||
positionFixed: false, | ||
modifiers: { | ||
keepTogether: { | ||
enabled: false, | ||
}, | ||
preventOverflow: { | ||
strategy: 'absolute', | ||
modifiers: [ | ||
{ | ||
name: 'preventOverflow', | ||
enabled: true, | ||
boundariesElement: 'viewport', | ||
padding: 8, // viewport-margin for shifting/sliding | ||
options: { | ||
boundariesElement: 'viewport', | ||
padding: 8, // viewport-margin for shifting/sliding | ||
}, | ||
}, | ||
flip: { | ||
boundariesElement: 'viewport', | ||
padding: 16, // viewport-margin for flipping | ||
{ | ||
name: 'flip', | ||
options: { | ||
boundariesElement: 'viewport', | ||
padding: 16, // viewport-margin for flipping | ||
}, | ||
}, | ||
offset: { | ||
{ | ||
name: 'offset', | ||
enabled: true, | ||
offset: `0, 8px`, // horizontal and vertical margin (distance between popper and referenceElement) | ||
options: { | ||
offset: [0, 8], // horizontal and vertical margin (distance between popper and referenceElement) | ||
}, | ||
}, | ||
arrow: { | ||
{ | ||
name: 'arrow', | ||
enabled: false, | ||
}, | ||
}, | ||
], | ||
}, | ||
@@ -431,2 +439,3 @@ viewportConfig: { | ||
/** @type {OverlayConfig} */ | ||
this.config = { | ||
@@ -440,13 +449,13 @@ ...this._defaultConfig, // our basic ingredients | ||
...(cfgToAdd.popperConfig || {}), | ||
modifiers: { | ||
modifiers: [ | ||
...((this._defaultConfig.popperConfig && this._defaultConfig.popperConfig.modifiers) || | ||
{}), | ||
[]), | ||
...((this.__sharedConfig.popperConfig && this.__sharedConfig.popperConfig.modifiers) || | ||
{}), | ||
...((cfgToAdd.popperConfig && cfgToAdd.popperConfig.modifiers) || {}), | ||
}, | ||
[]), | ||
...((cfgToAdd.popperConfig && cfgToAdd.popperConfig.modifiers) || []), | ||
], | ||
}, | ||
}; | ||
this.__validateConfiguration(this.config); | ||
this.__validateConfiguration(/** @type {OverlayConfig} */ (this.config)); | ||
// TODO: remove this, so we only have the getters (no setters) | ||
@@ -722,3 +731,3 @@ // Object.assign(this, this.config); | ||
await this.__createPopperInstance(); | ||
/** @type {Popper} */ (this._popper).update(); | ||
/** @type {Popper} */ (this._popper).forceUpdate(); | ||
} | ||
@@ -854,3 +863,3 @@ } | ||
} | ||
resolve(); | ||
resolve(undefined); | ||
}; | ||
@@ -1227,8 +1236,9 @@ }); | ||
} | ||
// @ts-expect-error | ||
const { default: Popper } = await OverlayController.popperModule; | ||
/** @type {Popper} */ | ||
this._popper = new Popper(this._referenceNode, this.contentWrapperNode, { | ||
...this.config?.popperConfig, | ||
}); | ||
if (OverlayController.popperModule !== undefined) { | ||
const { createPopper } = await OverlayController.popperModule; | ||
this._popper = createPopper(this._referenceNode, this.contentWrapperNode, { | ||
...this.config?.popperConfig, | ||
}); | ||
} | ||
} | ||
@@ -1235,0 +1245,0 @@ } |
@@ -65,3 +65,3 @@ import { dedupeMixin } from '@lion/core'; | ||
super.requestUpdateInternal(name, oldValue); | ||
if (name === 'opened') { | ||
if (name === 'opened' && this.opened !== oldValue) { | ||
this.dispatchEvent(new Event('opened-changed')); | ||
@@ -80,2 +80,4 @@ } | ||
_defineOverlay({ contentNode, invokerNode, referenceNode, backdropNode, contentWrapperNode }) { | ||
const overlayConfig = this._defineOverlayConfig() || {}; | ||
return new OverlayController({ | ||
@@ -87,13 +89,11 @@ contentNode, | ||
contentWrapperNode, | ||
...this._defineOverlayConfig(), // wc provided in the class as defaults | ||
...overlayConfig, // wc provided in the class as defaults | ||
...this.config, // user provided (e.g. in template) | ||
popperConfig: { | ||
...(this._defineOverlayConfig().popperConfig || {}), | ||
...(overlayConfig.popperConfig || {}), | ||
...(this.config.popperConfig || {}), | ||
modifiers: { | ||
...((this._defineOverlayConfig().popperConfig && | ||
this._defineOverlayConfig()?.popperConfig?.modifiers) || | ||
{}), | ||
...((this.config.popperConfig && this.config.popperConfig.modifiers) || {}), | ||
}, | ||
modifiers: [ | ||
...(overlayConfig.popperConfig?.modifiers || []), | ||
...(this.config.popperConfig?.modifiers || []), | ||
], | ||
}, | ||
@@ -117,3 +117,3 @@ }); | ||
/** | ||
* @param {import('lit-element').PropertyValues } changedProperties | ||
* @param {import('@lion/core').PropertyValues } changedProperties | ||
*/ | ||
@@ -120,0 +120,0 @@ updated(changedProperties) { |
import { expect, fixture, fixtureSync, html } from '@open-wc/testing'; | ||
// @ts-ignore | ||
import Popper from 'popper.js/dist/esm/popper.min.js'; | ||
import { OverlayController } from '../src/OverlayController.js'; | ||
@@ -30,7 +28,5 @@ import { normalizeTransformStyle } from './utils-tests/local-positioning-helpers.js'; | ||
await ctrl.show(); | ||
expect(/** @type {Popper} */ (ctrl._popper)).to.be.an.instanceof(Popper); | ||
expect(/** @type {Popper} */ (ctrl._popper).modifiers).to.exist; | ||
expect(ctrl._popper.state.modifiersData).to.exist; | ||
await ctrl.hide(); | ||
expect(/** @type {Popper} */ (ctrl._popper)).to.be.an.instanceof(Popper); | ||
expect(/** @type {Popper} */ (ctrl._popper).modifiers).to.exist; | ||
expect(ctrl._popper.state.modifiersData).to.exist; | ||
}); | ||
@@ -57,4 +53,4 @@ | ||
expect(normalizeTransformStyle(ctrl.content.style.transform)).to.equal( | ||
'translate3d(-30px, -38px, 0px)', | ||
'translate3d should be -30px [to center = (80 - 20)/2*-1] -38px [to place above = 30 + 8 default padding]', | ||
'translate(-30px, -18px)', | ||
'translate should be -30px [to center = (80 - 20)/2*-1], -18px [to place above = 10 invoker height + 8 default padding]', | ||
); | ||
@@ -79,3 +75,3 @@ }); | ||
await ctrl.show(); | ||
expect(ctrl.content.getAttribute('x-placement')).to.equal('top'); | ||
expect(ctrl.content.getAttribute('data-popper-placement')).to.equal('top'); | ||
}); | ||
@@ -103,3 +99,3 @@ | ||
await ctrl.show(); | ||
expect(ctrl.content.getAttribute('x-placement')).to.equal('left-start'); | ||
expect(ctrl.content.getAttribute('data-popper-placement')).to.equal('left-start'); | ||
}); | ||
@@ -119,11 +115,11 @@ | ||
popperConfig: { | ||
placement: 'top-start', | ||
placement: 'left', | ||
}, | ||
}); | ||
await fixture(html` | ||
<div style="position: absolute; top: 0;">${ctrl.invokerNode}${ctrl.content}</div> | ||
<div style="position: absolute; top: 50px;">${ctrl.invokerNode}${ctrl.content}</div> | ||
`); | ||
await ctrl.show(); | ||
expect(ctrl.content.getAttribute('x-placement')).to.equal('bottom-start'); | ||
expect(ctrl.content.getAttribute('data-popper-placement')).to.equal('right'); | ||
}); | ||
@@ -141,11 +137,9 @@ | ||
popperConfig: { | ||
modifiers: { | ||
keepTogether: { | ||
modifiers: [ | ||
{ | ||
name: 'keepTogether', | ||
enabled: false, | ||
}, | ||
offset: { | ||
enabled: true, | ||
offset: `0, 16px`, | ||
}, | ||
}, | ||
{ name: 'offset', enabled: true, options: { offset: [0, 16] } }, | ||
], | ||
}, | ||
@@ -160,11 +154,3 @@ }); | ||
await ctrl.show(); | ||
const keepTogether = /** @type {Popper} */ (ctrl._popper).modifiers.find( | ||
(/** @type {{ name: string }} */ item) => item.name === 'keepTogether', | ||
); | ||
const offset = /** @type {Popper} */ (ctrl._popper).modifiers.find( | ||
(/** @type {{ name: string }} */ item) => item.name === 'offset', | ||
); | ||
expect(keepTogether.enabled).to.be.false; | ||
expect(offset.enabled).to.be.true; | ||
expect(offset.offset).to.equal('0, 16px'); | ||
expect(ctrl._popper.state.modifiersData.offset.auto).to.eql({ x: 0, y: 16 }); | ||
}); | ||
@@ -192,3 +178,3 @@ | ||
expect(normalizeTransformStyle(ctrl.content.style.transform)).to.equal( | ||
'translate3d(10px, -28px, 0px)', | ||
'translate(10px, -28px)', | ||
'Popper positioning values', | ||
@@ -200,3 +186,3 @@ ); | ||
expect(normalizeTransformStyle(ctrl.content.style.transform)).to.equal( | ||
'translate3d(10px, -28px, 0px)', | ||
'translate(10px, -28px)', | ||
'Popper positioning values should be identical after hiding and showing', | ||
@@ -218,8 +204,11 @@ ); | ||
placement: 'top', | ||
modifiers: { | ||
offset: { | ||
modifiers: [ | ||
{ | ||
name: 'offset', | ||
enabled: true, | ||
offset: '0, 10px', | ||
options: { | ||
offset: [0, 10], | ||
}, | ||
}, | ||
}, | ||
], | ||
}, | ||
@@ -242,14 +231,15 @@ }); | ||
popperConfig: { | ||
modifiers: { | ||
offset: { | ||
modifiers: [ | ||
{ | ||
name: 'offset', | ||
enabled: true, | ||
offset: '0, 20px', | ||
options: { | ||
offset: [0, 20], | ||
}, | ||
}, | ||
}, | ||
], | ||
}, | ||
}); | ||
await ctrl.show(); | ||
expect(/** @type {Popper} */ (ctrl._popper).options.modifiers.offset.offset).to.equal( | ||
'0, 20px', | ||
); | ||
expect(ctrl._popper.options.modifiers.offset.offset).to.equal('0, 20px'); | ||
expect(normalizeTransformStyle(ctrl.content.style.transform)).to.equal( | ||
@@ -275,8 +265,11 @@ 'translate3d(10px, -40px, 0px)', | ||
placement: 'top', | ||
modifiers: { | ||
offset: { | ||
modifiers: [ | ||
{ | ||
name: 'offset', | ||
enabled: true, | ||
offset: '0, 10px', | ||
options: { | ||
offset: [0, 10], | ||
}, | ||
}, | ||
}, | ||
], | ||
}, | ||
@@ -298,8 +291,3 @@ }); | ||
popperConfig: { | ||
modifiers: { | ||
offset: { | ||
enabled: true, | ||
offset: '0, 20px', | ||
}, | ||
}, | ||
modifiers: [{ name: 'offset', enabled: true, options: { offset: [0, 20] } }], | ||
}, | ||
@@ -306,0 +294,0 @@ }); |
import { Constructor } from '@open-wc/dedupe-mixin'; | ||
import { LitElement, TemplateResult } from '@lion/core'; | ||
import { CSSResultArray } from 'lit-element'; | ||
import { CSSResultArray } from '@lion/core'; | ||
import Data from 'popper.js'; | ||
import { Options as PopperOptions } from '@popperjs/core/lib/popper'; | ||
import { OverlayConfig } from '../types/OverlayConfig'; | ||
@@ -24,2 +25,3 @@ | ||
_defineOverlayConfig(): OverlayConfig; | ||
_getPopperArrowConfig(popperConfigToExtendFrom: Partial<PopperOptions>): Partial<PopperOptions>; | ||
__setupRepositionCompletePromise(): void; | ||
@@ -26,0 +28,0 @@ get _arrowNode(): Element | null; |
@@ -1,2 +0,2 @@ | ||
import { PopperOptions } from 'popper.js'; | ||
import { Options } from '@popperjs/core'; | ||
@@ -50,3 +50,3 @@ export interface OverlayConfig { | ||
/** Popper configuration. Will be used when placementMode is 'local' */ | ||
popperConfig?: PopperOptions; | ||
popperConfig?: Partial<Options>; | ||
/** Viewport configuration. Will be used when placementMode is 'global' */ | ||
@@ -53,0 +53,0 @@ viewportConfig?: ViewportConfig; |
320092
6338
+ Added@popperjs/core@^2.5.4
+ Added@lion/core@0.13.7(transitive)
+ Added@popperjs/core@2.11.8(transitive)
+ Addedsingleton-manager@1.2.1(transitive)
- Removedpopper.js@^1.15.0
- Removed@lion/core@0.13.6(transitive)
- Removedpopper.js@1.16.1(transitive)
- Removedsingleton-manager@1.2.0(transitive)
Updated@lion/core@0.13.7
Updatedsingleton-manager@1.2.1