chore(overlays): change to API popperConfig to make clear it's Popper.js

This commit is contained in:
Joren Broekema 2019-06-27 15:53:16 +02:00
parent 1e9ec400dd
commit e775554a07
10 changed files with 66 additions and 52 deletions

View file

@ -91,7 +91,7 @@ other overlays, so needed for internals.
- sets focus to overlay content(?)
- For `isTooltip`:
- sets role="tooltip" and aria-labelledby/aria-describedby on the content
- {Object} placementConfig
- {Object} popperConfig
- {String} placement - vertical/horizontal position to be supplied to `managePosition`. See https://github.com/ing-bank/lion/pull/61 for current api. Consists of a primary part (where the overlay is located relative from invoker) and secondary alignnment part (how the overlay 'snaps' to the perpendicular boundary of the invoker), separated via '-'.
- primary : 'bottom' | 'top' | 'left' | 'right' | 'over' (this means the overlay will be positioned on top of the invoker. Think for instance of a select dropdown that opens a selected option on top of the invoker (default behavior of `<select>` on iOS))
- secondary : 'start' | 'end' | 'fill' (occupies width of invoker) | 'middle' (implicit option that will be choosen by default when none of the previous are specified)

View file

@ -9,7 +9,7 @@ export class LocalOverlayController {
constructor(params = {}) {
// TODO: Instead of in constructor, prefetch it or use a preloader-manager to load it during idle time
this.constructor.popperModule = __preloadPopper();
this.__mergePlacementConfigs(params.placementConfig || {});
this.__mergePopperConfigs(params.popperConfig || {});
this.hidesOnEsc = params.hidesOnEsc;
this.hidesOnOutsideClick = params.hidesOnOutsideClick;
@ -125,8 +125,8 @@ export class LocalOverlayController {
// Popper does not export a nice method to update an existing instance with a new config. Therefore we recreate the instance.
// TODO: Send a merge request to Popper to abstract their logic in the constructor to an exposed method which takes in the user config.
async updatePlacementConfig(config = {}) {
this.__mergePlacementConfigs(config);
async updatePopperConfig(config = {}) {
this.__mergePopperConfigs(config);
await this.__createPopperInstance();
}
@ -233,12 +233,10 @@ export class LocalOverlayController {
* Merges the default config with the current config, and finally with the user supplied config
* @param {Object} config user supplied configuration
*/
__mergePlacementConfigs(config = {}) {
this.placementConfig = {
__mergePopperConfigs(config = {}) {
const defaultConfig = {
placement: 'top',
positionFixed: false,
...(this.placementConfig || {}),
...(config || {}),
modifiers: {
keepTogether: {
enabled: false,
@ -259,7 +257,17 @@ export class LocalOverlayController {
arrow: {
enabled: false,
},
...((this.placementConfig && this.placementConfig.modifiers) || {}),
},
};
// Deep merging default config, previously configured user config, new user config
this.popperConfig = {
...defaultConfig,
...(this.popperConfig || {}),
...(config || {}),
modifiers: {
...defaultConfig.modifiers,
...((this.popperConfig && this.popperConfig.modifiers) || {}),
...((config && config.modifiers) || {}),
},
};
@ -273,7 +281,7 @@ export class LocalOverlayController {
const mod = await this.constructor.popperModule;
const Popper = mod.default;
this._popper = new Popper(this.invokerNode, this.contentNode, {
...this.placementConfig,
...this.popperConfig,
});
}
}

View file

@ -20,7 +20,7 @@ const togglePlacement = popupController => {
'left-end',
];
placement = placements[(placements.indexOf(placement) + 1) % placements.length];
popupController.updatePlacementConfig({ placement });
popupController.updatePopperConfig({ placement });
};
const popupPlacementDemoStyle = css`
@ -70,11 +70,11 @@ storiesOf('Local Overlay System|Local Overlay Placement', module)
</div>
`;
})
.add('Override the placement config', () => {
.add('Override the popper config', () => {
const popupController = overlays.add(
new LocalOverlayController({
hidesOnEsc: true,
placementConfig: {
popperConfig: {
placement: 'bottom-start',
positionFixed: true,
modifiers: {

View file

@ -54,7 +54,9 @@ storiesOf('Local Overlay System|Local Overlay', module)
new LocalOverlayController({
hidesOnEsc: true,
hidesOnOutsideClick: true,
placement: 'top right',
popperConfig: {
placement: 'top-end',
},
contentTemplate: () =>
html`
<div class="demo-popup">United Kingdom</div>
@ -79,7 +81,9 @@ storiesOf('Local Overlay System|Local Overlay', module)
new LocalOverlayController({
hidesOnEsc: true,
hidesOnOutsideClick: true,
placement: 'bottom',
popperConfig: {
placement: 'bottom',
},
contentTemplate: () => html`
<div class="demo-popup">
Supplying placement with a single parameter will assume 'center' for the other.
@ -105,7 +109,9 @@ storiesOf('Local Overlay System|Local Overlay', module)
new LocalOverlayController({
hidesOnEsc: true,
hidesOnOutsideClick: true,
placement: 'bottom',
popperConfig: {
placement: 'bottom',
},
contentTemplate: () =>
html`
<div class="demo-popup">United Kingdom</div>

View file

@ -269,7 +269,7 @@ describe('LocalOverlayController', () => {
html`
<p>Content</p>
`,
placementConfig: {
popperConfig: {
placement: 'left-start',
},
});
@ -295,7 +295,7 @@ describe('LocalOverlayController', () => {
Invoker
</button>
`,
placementConfig: {
popperConfig: {
placement: 'top-start',
},
});
@ -312,7 +312,7 @@ describe('LocalOverlayController', () => {
it('allows the user to override default Popper modifiers', async () => {
const controller = new LocalOverlayController({
placementConfig: {
popperConfig: {
modifiers: {
keepTogether: {
enabled: false,
@ -345,7 +345,7 @@ describe('LocalOverlayController', () => {
expect(offset.offset).to.equal('0, 16px');
});
it('updates placementConfig even when overlay is closed', async () => {
it('updates popperConfig even when overlay is closed', async () => {
const controller = new LocalOverlayController({
contentTemplate: () =>
html`
@ -356,7 +356,7 @@ describe('LocalOverlayController', () => {
Invoker
</button>
`,
placementConfig: {
popperConfig: {
placement: 'top',
},
});
@ -370,7 +370,7 @@ describe('LocalOverlayController', () => {
expect(contentChild.getAttribute('x-placement')).to.equal('top');
controller.hide();
await controller.updatePlacementConfig({ placement: 'bottom' });
await controller.updatePopperConfig({ placement: 'bottom' });
await controller.show();
expect(controller._popper.options.placement).to.equal('bottom');
});
@ -386,7 +386,7 @@ describe('LocalOverlayController', () => {
Invoker
</button>
`,
placementConfig: {
popperConfig: {
placement: 'top',
},
});
@ -417,7 +417,7 @@ describe('LocalOverlayController', () => {
Invoker
</button>
`,
placementConfig: {
popperConfig: {
placement: 'top',
},
});
@ -432,7 +432,7 @@ describe('LocalOverlayController', () => {
expect(contentChild.style.transform).to.equal('translate3d(14px, -58px, 0px)');
controller.hide();
await controller.updatePlacementConfig({
await controller.updatePopperConfig({
modifiers: {
offset: {
enabled: true,

View file

@ -4,24 +4,24 @@ import { overlays, LocalOverlayController } from '@lion/overlays';
export class LionPopup extends UpdatingElement {
static get properties() {
return {
placementConfig: {
popperConfig: {
type: Object,
},
};
}
get placementConfig() {
return this._placementConfig;
get popperConfig() {
return this._popperConfig;
}
set placementConfig(config) {
this._placementConfig = {
...this._placementConfig,
set popperConfig(config) {
this._popperConfig = {
...this._popperConfig,
...config,
};
if (this._controller && this._controller._popper) {
this._controller.updatePlacementConfig(this._placementConfig);
this._controller.updatePopperConfig(this._popperConfig);
}
}
@ -34,7 +34,7 @@ export class LionPopup extends UpdatingElement {
new LocalOverlayController({
hidesOnEsc: true,
hidesOnOutsideClick: true,
placementConfig: this.placementConfig,
popperConfig: this.popperConfig,
contentNode: this.contentNode,
invokerNode: this.invokerNode,
}),

View file

@ -58,7 +58,7 @@ storiesOf('Local Overlay System|Popup', module)
${popupDemoStyle}
</style>
<div class="demo-box">
<lion-popup .placementConfig="${{ placement: 'top' }}">
<lion-popup .popperConfig="${{ placement: 'top' }}">
<div slot="content" class="popup">Hello there!</div>
<lion-button slot="invoker">Popup</lion-button>
</lion-popup>
@ -72,19 +72,19 @@ storiesOf('Local Overlay System|Popup', module)
${popupDemoStyle}
</style>
<div class="demo-box_placements">
<lion-popup .placementConfig="${{ placement: 'top' }}">
<lion-popup .popperConfig="${{ placement: 'top' }}">
<div slot="content" class="popup">Its top placement</div>
<lion-button slot="invoker">Top</lion-button>
</lion-popup>
<lion-popup .placementConfig="${{ placement: 'right' }}">
<lion-popup .popperConfig="${{ placement: 'right' }}">
<div slot="content" class="popup">Its right placement</div>
<lion-button slot="invoker">Right</lion-button>
</lion-popup>
<lion-popup .placementConfig="${{ placement: 'bottom' }}">
<lion-popup .popperConfig="${{ placement: 'bottom' }}">
<div slot="content" class="popup">Its bottom placement</div>
<lion-button slot="invoker">Bottom</lion-button>
</lion-popup>
<lion-popup .placementConfig="${{ placement: 'left' }}">
<lion-popup .popperConfig="${{ placement: 'left' }}">
<div slot="content" class="popup">Its left placement</div>
<lion-button slot="invoker">Left</lion-button>
</lion-popup>
@ -92,15 +92,15 @@ storiesOf('Local Overlay System|Popup', module)
`,
)
.add(
'Override placement configuration',
'Override popper configuration',
() => html`
<style>
${popupDemoStyle}
</style>
<p>Use the Storybook Knobs to dynamically change the placement configuration!</p>
<p>Use the Storybook Knobs to dynamically change the popper configuration!</p>
<div class="demo-box">
<lion-popup
.placementConfig="${object('Placement Configuration', {
.popperConfig="${object('Popper Configuration', {
placement: 'bottom-start',
positionFixed: true,
modifiers: {

View file

@ -46,7 +46,7 @@ describe('lion-popup', () => {
expect(el.querySelector('strong')).to.not.be.undefined;
});
it('should respond to dynamically changing the placementConfig', async () => {
it('should respond to dynamically changing the popperConfig', async () => {
const el = await fixture(html`
<lion-popup>
<div slot="content" class="popup">Hey there</div>
@ -56,7 +56,7 @@ describe('lion-popup', () => {
await el._controller.show();
expect(el._controller._popper.options.placement).to.equal('top');
el.placementConfig = { placement: 'left' };
el.popperConfig = { placement: 'left' };
await el._controller.show();
expect(el._controller._popper.options.placement).to.equal('left');
});

View file

@ -11,7 +11,7 @@ export class LionTooltip extends LionPopup {
new LocalOverlayController({
hidesOnEsc: true,
hidesOnOutsideClick: true,
placementConfig: this.placementConfig,
popperConfig: this.popperConfig,
contentNode: this.contentNode,
invokerNode: this.invokerNode,
}),

View file

@ -58,7 +58,7 @@ storiesOf('Local Overlay System|Tooltip', module)
${tooltipDemoStyle}
</style>
<div class="demo-box">
<lion-tooltip .placementConfig=${{ placement: 'right' }}>
<lion-tooltip .popperConfig=${{ placement: 'right' }}>
<div slot="content" class="tooltip">Hello there!</div>
<lion-button slot="invoker">Tooltip</lion-button>
</lion-tooltip>
@ -72,19 +72,19 @@ storiesOf('Local Overlay System|Tooltip', module)
${tooltipDemoStyle}
</style>
<div class="demo-box_placements">
<lion-tooltip .placementConfig=${{ placement: 'top' }}>
<lion-tooltip .popperConfig=${{ placement: 'top' }}>
<div slot="content" class="tooltip">Its top placement</div>
<lion-button slot="invoker">Top</lion-button>
</lion-tooltip>
<lion-tooltip .placementConfig=${{ placement: 'right' }}>
<lion-tooltip .popperConfig=${{ placement: 'right' }}>
<div slot="content" class="tooltip">Its right placement</div>
<lion-button slot="invoker">Right</lion-button>
</lion-tooltip>
<lion-tooltip .placementConfig=${{ placement: 'bottom' }}>
<lion-tooltip .popperConfig=${{ placement: 'bottom' }}>
<div slot="content" class="tooltip">Its bottom placement</div>
<lion-button slot="invoker">Bottom</lion-button>
</lion-tooltip>
<lion-tooltip .placementConfig=${{ placement: 'left' }}>
<lion-tooltip .popperConfig=${{ placement: 'left' }}>
<div slot="content" class="tooltip">Its left placement</div>
<lion-button slot="invoker">Left</lion-button>
</lion-tooltip>
@ -92,15 +92,15 @@ storiesOf('Local Overlay System|Tooltip', module)
`,
)
.add(
'Override placement configuration',
'Override popper configuration',
() => html`
<style>
${tooltipDemoStyle}
</style>
<p>Use the Storybook Knobs to dynamically change the placement configuration!</p>
<p>Use the Storybook Knobs to dynamically change the popper configuration!</p>
<div class="demo-box_placements">
<lion-tooltip
.placementConfig="${object('Placement Configuration', {
.popperConfig="${object('Popper Configuration', {
placement: 'bottom-start',
positionFixed: true,
modifiers: {