feat(overlays): improve API for overriding controller config in mixin
This commit is contained in:
parent
6b2b91f1b3
commit
45f557183d
16 changed files with 173 additions and 87 deletions
10
README.md
10
README.md
|
|
@ -40,7 +40,7 @@ The accessibility column indicates whether the functionality is accessible in it
|
||||||
| [icon](./packages/icon) | [](https://www.npmjs.com/package/@lion/icon) | Display our svg icons | [#173][i173], [#172][i172] |
|
| [icon](./packages/icon) | [](https://www.npmjs.com/package/@lion/icon) | Display our svg icons | [#173][i173], [#172][i172] |
|
||||||
| [steps](./packages/steps) | [](https://www.npmjs.com/package/@lion/steps) | Multi Step System | n/a |
|
| [steps](./packages/steps) | [](https://www.npmjs.com/package/@lion/steps) | Multi Step System | n/a |
|
||||||
| [tabs](./packages/tabs) | [](https://www.npmjs.com/package/@lion/tabs) | Move between a small number of equally important views | n/a |
|
| [tabs](./packages/tabs) | [](https://www.npmjs.com/package/@lion/tabs) | Move between a small number of equally important views | n/a |
|
||||||
| **-- Forms --** | | |
|
| **-- Forms --** | | | |
|
||||||
| [form](./packages/form) | [](https://www.npmjs.com/package/@lion/form) | Wrapper for multiple form elements | ✔️ |
|
| [form](./packages/form) | [](https://www.npmjs.com/package/@lion/form) | Wrapper for multiple form elements | ✔️ |
|
||||||
| [field](./packages/field) | [](https://www.npmjs.com/package/@lion/field) | Base Class for all inputs | [#190][i190] |
|
| [field](./packages/field) | [](https://www.npmjs.com/package/@lion/field) | Base Class for all inputs | [#190][i190] |
|
||||||
| [fieldset](./packages/fieldset) | [](https://www.npmjs.com/package/@lion/fieldset) | Group for form inputs | ✔️ |
|
| [fieldset](./packages/fieldset) | [](https://www.npmjs.com/package/@lion/fieldset) | Group for form inputs | ✔️ |
|
||||||
|
|
@ -48,7 +48,7 @@ The accessibility column indicates whether the functionality is accessible in it
|
||||||
| [checkbox](./packages/checkbox) | [](https://www.npmjs.com/package/@lion/checkbox) | Checkbox form element | ✔️ |
|
| [checkbox](./packages/checkbox) | [](https://www.npmjs.com/package/@lion/checkbox) | Checkbox form element | ✔️ |
|
||||||
| [checkbox-group](./packages/checkbox-group) | [](https://www.npmjs.com/package/@lion/checkbox-group) | Group of checkboxes | ✔️ |
|
| [checkbox-group](./packages/checkbox-group) | [](https://www.npmjs.com/package/@lion/checkbox-group) | Group of checkboxes | ✔️ |
|
||||||
| [input](./packages/input) | [](https://www.npmjs.com/package/@lion/input) | Input element for strings | ✔️ |
|
| [input](./packages/input) | [](https://www.npmjs.com/package/@lion/input) | Input element for strings | ✔️ |
|
||||||
| [input-amount](./packages/input-amount) | [](https://www.npmjs.com/package/@lion/input-amount) | Input element for amounts | [#166][i166] | ✔️ |
|
| [input-amount](./packages/input-amount) | [](https://www.npmjs.com/package/@lion/input-amount) | Input element for amounts | [#166][i166] |
|
||||||
| [input-date](./packages/input-date) | [](https://www.npmjs.com/package/@lion/input-date) | Input element for dates | ✔️ |
|
| [input-date](./packages/input-date) | [](https://www.npmjs.com/package/@lion/input-date) | Input element for dates | ✔️ |
|
||||||
| [input-datepicker](./packages/input-datepicker) | [](https://www.npmjs.com/package/@lion/input-datepicker) | Input element for dates with a datepicker | ✔️ |
|
| [input-datepicker](./packages/input-datepicker) | [](https://www.npmjs.com/package/@lion/input-datepicker) | Input element for dates with a datepicker | ✔️ |
|
||||||
| [input-email](./packages/input-email) | [](https://www.npmjs.com/package/@lion/input-email) | Input element for e-mails | [#169][i169] |
|
| [input-email](./packages/input-email) | [](https://www.npmjs.com/package/@lion/input-email) | Input element for e-mails | [#169][i169] |
|
||||||
|
|
@ -58,9 +58,9 @@ The accessibility column indicates whether the functionality is accessible in it
|
||||||
| [select](./packages/select) | [](https://www.npmjs.com/package/@lion/select) | Simple native dropdown element | ✔️ |
|
| [select](./packages/select) | [](https://www.npmjs.com/package/@lion/select) | Simple native dropdown element | ✔️ |
|
||||||
| [textarea](./packages/textarea) | [](https://www.npmjs.com/package/@lion/textarea) | Multiline text input | [#165][i165] |
|
| [textarea](./packages/textarea) | [](https://www.npmjs.com/package/@lion/textarea) | Multiline text input | [#165][i165] |
|
||||||
| **-- Overlays --** | | | |
|
| **-- Overlays --** | | | |
|
||||||
| [overlays](./packages/overlays) | [](https://www.npmjs.com/package/@lion/overlays) | Overlays System using lit-html for rendering | ✔️ |
|
| [overlays](./packages/overlays) | [](https://www.npmjs.com/package/@lion/overlays) | Overlay System | ✔️ |
|
||||||
| [popup](./packages/popup) | [](https://www.npmjs.com/package/@lion/popup) | Popup element | [#175][i175], [#174][i174] |
|
| [dialog](./packages/dialog) | [](https://www.npmjs.com/package/@lion/dialog) | Dialog element | ✔️ |
|
||||||
| [tooltip](./packages/tooltip) | [](https://www.npmjs.com/package/@lion/tooltip) | Popup element | [#178][i178], [#177][i177], [#176][i176], [#175][i175], [#174][i174] |
|
| [tooltip](./packages/tooltip) | [](https://www.npmjs.com/package/@lion/tooltip) | Tooltip element | [#178][i178], [#177][i177], [#176][i176], [#175][i175], [#174][i174] |
|
||||||
|
|
||||||
## How to use
|
## How to use
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -108,10 +108,16 @@ describe('<lion-calendar>', () => {
|
||||||
`),
|
`),
|
||||||
);
|
);
|
||||||
expect(
|
expect(
|
||||||
elObj.checkForAllDayObjs(o => o.buttonEl.getAttribute('tabindex') === '0', n => n === 5),
|
elObj.checkForAllDayObjs(
|
||||||
|
o => o.buttonEl.getAttribute('tabindex') === '0',
|
||||||
|
n => n === 5,
|
||||||
|
),
|
||||||
).to.be.true;
|
).to.be.true;
|
||||||
expect(
|
expect(
|
||||||
elObj.checkForAllDayObjs(o => o.buttonEl.getAttribute('tabindex') === '-1', n => n !== 5),
|
elObj.checkForAllDayObjs(
|
||||||
|
o => o.buttonEl.getAttribute('tabindex') === '-1',
|
||||||
|
n => n !== 5,
|
||||||
|
),
|
||||||
).to.be.true;
|
).to.be.true;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ html`
|
||||||
}}>
|
}}>
|
||||||
This is a dialog
|
This is a dialog
|
||||||
<button
|
<button
|
||||||
@click=${e => e.target.dispatchEvent(new Event('close', { bubbles: true }))}
|
@click=${e => e.target.dispatchEvent(new Event('dialog-close', { bubbles: true }))}
|
||||||
>x</button>
|
>x</button>
|
||||||
<div>
|
<div>
|
||||||
<button slot="invoker">
|
<button slot="invoker">
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,17 @@
|
||||||
import { OverlayController, withModalDialogConfig, OverlayMixin } from '@lion/overlays';
|
import { withModalDialogConfig, OverlayMixin } from '@lion/overlays';
|
||||||
import { LitElement, html } from '@lion/core';
|
import { LitElement, html } from '@lion/core';
|
||||||
|
|
||||||
export class LionDialog extends OverlayMixin(LitElement) {
|
export class LionDialog extends OverlayMixin(LitElement) {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.closeEventName = 'dialog-close';
|
||||||
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line class-methods-use-this
|
// eslint-disable-next-line class-methods-use-this
|
||||||
_defineOverlay({ contentNode, invokerNode }) {
|
_defineOverlayConfig() {
|
||||||
return new OverlayController({
|
return {
|
||||||
...withModalDialogConfig(),
|
...withModalDialogConfig(),
|
||||||
elementToFocusAfterHide: invokerNode,
|
};
|
||||||
contentNode,
|
|
||||||
invokerNode,
|
|
||||||
...this.config, // lit-property set by user for overrides
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_setupOpenCloseListeners() {
|
_setupOpenCloseListeners() {
|
||||||
|
|
@ -21,12 +22,10 @@ export class LionDialog extends OverlayMixin(LitElement) {
|
||||||
this.opened = !this.opened;
|
this.opened = !this.opened;
|
||||||
};
|
};
|
||||||
this._overlayCtrl.invokerNode.addEventListener('click', this.__toggle);
|
this._overlayCtrl.invokerNode.addEventListener('click', this.__toggle);
|
||||||
this._overlayCtrl.contentNode.addEventListener('close', this.__close);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_teardownOpenCloseListeners() {
|
_teardownOpenCloseListeners() {
|
||||||
this._overlayCtrl.invokerNode.removeEventListener('click', this.__toggle);
|
this._overlayCtrl.invokerNode.removeEventListener('click', this.__toggle);
|
||||||
this._overlayCtrl.contentNode.removeEventListener('close', this.__close);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,7 @@ storiesOf('Overlays Specific WC | Dialog', module)
|
||||||
Hello! You can close this notification here:
|
Hello! You can close this notification here:
|
||||||
<lion-button
|
<lion-button
|
||||||
class="close-button"
|
class="close-button"
|
||||||
@click=${e => e.target.dispatchEvent(new Event('close', { bubbles: true }))}
|
@click=${e => e.target.dispatchEvent(new Event('dialog-close', { bubbles: true }))}
|
||||||
>⨯</lion-button
|
>⨯</lion-button
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -98,7 +98,7 @@ storiesOf('Overlays Specific WC | Dialog', module)
|
||||||
Hello! You can close this notification here:
|
Hello! You can close this notification here:
|
||||||
<lion-button
|
<lion-button
|
||||||
class="close-button"
|
class="close-button"
|
||||||
@click=${e => e.target.dispatchEvent(new Event('close', { bubbles: true }))}
|
@click=${e => e.target.dispatchEvent(new Event('dialog-close', { bubbles: true }))}
|
||||||
>⨯</lion-button
|
>⨯</lion-button
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -123,7 +123,7 @@ storiesOf('Overlays Specific WC | Dialog', module)
|
||||||
Hello! You can close this notification here:
|
Hello! You can close this notification here:
|
||||||
<lion-button
|
<lion-button
|
||||||
class="close-button"
|
class="close-button"
|
||||||
@click=${e => e.target.dispatchEvent(new Event('close', { bubbles: true }))}
|
@click=${e => e.target.dispatchEvent(new Event('dialog-close', { bubbles: true }))}
|
||||||
>⨯</lion-button
|
>⨯</lion-button
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,9 @@ describe('lion-dialog', () => {
|
||||||
<lion-dialog>
|
<lion-dialog>
|
||||||
<div slot="content" class="dialog">
|
<div slot="content" class="dialog">
|
||||||
Hey there
|
Hey there
|
||||||
<button @click=${e => e.target.dispatchEvent(new Event('close', { bubbles: true }))}>
|
<button
|
||||||
|
@click=${e => e.target.dispatchEvent(new Event('dialog-close', { bubbles: true }))}
|
||||||
|
>
|
||||||
x
|
x
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -177,16 +177,28 @@ describe('<lion-fieldset>', () => {
|
||||||
expect(el.modelValue).to.deep.equal({
|
expect(el.modelValue).to.deep.equal({
|
||||||
lastName: 'Bar',
|
lastName: 'Bar',
|
||||||
newfieldset: {
|
newfieldset: {
|
||||||
'hobbies[]': [{ checked: true, value: 'chess' }, { checked: false, value: 'football' }],
|
'hobbies[]': [
|
||||||
'gender[]': [{ checked: false, value: 'male' }, { checked: false, value: 'female' }],
|
{ checked: true, value: 'chess' },
|
||||||
|
{ checked: false, value: 'football' },
|
||||||
|
],
|
||||||
|
'gender[]': [
|
||||||
|
{ checked: false, value: 'male' },
|
||||||
|
{ checked: false, value: 'female' },
|
||||||
|
],
|
||||||
color: { checked: false, value: 'blue' },
|
color: { checked: false, value: 'blue' },
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
el.modelValue = {
|
el.modelValue = {
|
||||||
lastName: 2,
|
lastName: 2,
|
||||||
newfieldset: {
|
newfieldset: {
|
||||||
'hobbies[]': [{ checked: true, value: 'chess' }, { checked: false, value: 'baseball' }],
|
'hobbies[]': [
|
||||||
'gender[]': [{ checked: false, value: 'male' }, { checked: false, value: 'female' }],
|
{ checked: true, value: 'chess' },
|
||||||
|
{ checked: false, value: 'baseball' },
|
||||||
|
],
|
||||||
|
'gender[]': [
|
||||||
|
{ checked: false, value: 'male' },
|
||||||
|
{ checked: false, value: 'female' },
|
||||||
|
],
|
||||||
color: { checked: false, value: 'blue' },
|
color: { checked: false, value: 'blue' },
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
@ -546,7 +558,10 @@ describe('<lion-fieldset>', () => {
|
||||||
expect(fieldset.formElements['hobbies[]'][0].serializedValue).to.equal('Bar-serialized');
|
expect(fieldset.formElements['hobbies[]'][0].serializedValue).to.equal('Bar-serialized');
|
||||||
expect(fieldset.serializeGroup()).to.deep.equal({
|
expect(fieldset.serializeGroup()).to.deep.equal({
|
||||||
'hobbies[]': ['Bar-serialized', { checked: false, value: 'rugby' }],
|
'hobbies[]': ['Bar-serialized', { checked: false, value: 'rugby' }],
|
||||||
'gender[]': [{ checked: false, value: 'male' }, { checked: false, value: 'female' }],
|
'gender[]': [
|
||||||
|
{ checked: false, value: 'male' },
|
||||||
|
{ checked: false, value: 'female' },
|
||||||
|
],
|
||||||
color: { checked: false, value: 'blue' },
|
color: { checked: false, value: 'blue' },
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -562,15 +577,27 @@ describe('<lion-fieldset>', () => {
|
||||||
fieldset.formElements.color.modelValue = { checked: false, value: 'blue' };
|
fieldset.formElements.color.modelValue = { checked: false, value: 'blue' };
|
||||||
|
|
||||||
expect(fieldset.serializeGroup()).to.deep.equal({
|
expect(fieldset.serializeGroup()).to.deep.equal({
|
||||||
'hobbies[]': [{ checked: true, value: 'football' }, { checked: false, value: 'rugby' }],
|
'hobbies[]': [
|
||||||
'gender[]': [{ checked: true, value: 'male' }, { checked: false, value: 'female' }],
|
{ checked: true, value: 'football' },
|
||||||
|
{ checked: false, value: 'rugby' },
|
||||||
|
],
|
||||||
|
'gender[]': [
|
||||||
|
{ checked: true, value: 'male' },
|
||||||
|
{ checked: false, value: 'female' },
|
||||||
|
],
|
||||||
color: { checked: false, value: 'blue' },
|
color: { checked: false, value: 'blue' },
|
||||||
});
|
});
|
||||||
fieldset.formElements.color.disabled = true;
|
fieldset.formElements.color.disabled = true;
|
||||||
|
|
||||||
expect(fieldset.serializeGroup()).to.deep.equal({
|
expect(fieldset.serializeGroup()).to.deep.equal({
|
||||||
'hobbies[]': [{ checked: true, value: 'football' }, { checked: false, value: 'rugby' }],
|
'hobbies[]': [
|
||||||
'gender[]': [{ checked: true, value: 'male' }, { checked: false, value: 'female' }],
|
{ checked: true, value: 'football' },
|
||||||
|
{ checked: false, value: 'rugby' },
|
||||||
|
],
|
||||||
|
'gender[]': [
|
||||||
|
{ checked: true, value: 'male' },
|
||||||
|
{ checked: false, value: 'female' },
|
||||||
|
],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -594,8 +621,14 @@ describe('<lion-fieldset>', () => {
|
||||||
expect(fieldset.serializeGroup()).to.deep.equal({
|
expect(fieldset.serializeGroup()).to.deep.equal({
|
||||||
comment: 'Foo',
|
comment: 'Foo',
|
||||||
newfieldset: {
|
newfieldset: {
|
||||||
'hobbies[]': [{ checked: false, value: 'chess' }, { checked: false, value: 'rugby' }],
|
'hobbies[]': [
|
||||||
'gender[]': [{ checked: false, value: 'male' }, { checked: false, value: 'female' }],
|
{ checked: false, value: 'chess' },
|
||||||
|
{ checked: false, value: 'rugby' },
|
||||||
|
],
|
||||||
|
'gender[]': [
|
||||||
|
{ checked: false, value: 'male' },
|
||||||
|
{ checked: false, value: 'female' },
|
||||||
|
],
|
||||||
color: { checked: false, value: 'blue' },
|
color: { checked: false, value: 'blue' },
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
@ -622,8 +655,14 @@ describe('<lion-fieldset>', () => {
|
||||||
expect(fieldset.serializeGroup()).to.deep.equal({
|
expect(fieldset.serializeGroup()).to.deep.equal({
|
||||||
comment: 'Foo',
|
comment: 'Foo',
|
||||||
newfieldset: {
|
newfieldset: {
|
||||||
'hobbies[]': [{ checked: false, value: 'chess' }, { checked: false, value: 'rugby' }],
|
'hobbies[]': [
|
||||||
'gender[]': [{ checked: false, value: 'male' }, { checked: false, value: 'female' }],
|
{ checked: false, value: 'chess' },
|
||||||
|
{ checked: false, value: 'rugby' },
|
||||||
|
],
|
||||||
|
'gender[]': [
|
||||||
|
{ checked: false, value: 'male' },
|
||||||
|
{ checked: false, value: 'female' },
|
||||||
|
],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -631,8 +670,14 @@ describe('<lion-fieldset>', () => {
|
||||||
expect(fieldset.serializeGroup()).to.deep.equal({
|
expect(fieldset.serializeGroup()).to.deep.equal({
|
||||||
comment: 'Foo',
|
comment: 'Foo',
|
||||||
newfieldset: {
|
newfieldset: {
|
||||||
'hobbies[]': [{ checked: false, value: 'chess' }, { checked: false, value: 'rugby' }],
|
'hobbies[]': [
|
||||||
'gender[]': [{ checked: false, value: 'male' }, { checked: false, value: 'female' }],
|
{ checked: false, value: 'chess' },
|
||||||
|
{ checked: false, value: 'rugby' },
|
||||||
|
],
|
||||||
|
'gender[]': [
|
||||||
|
{ checked: false, value: 'male' },
|
||||||
|
{ checked: false, value: 'female' },
|
||||||
|
],
|
||||||
color: { checked: false, value: 'blue' },
|
color: { checked: false, value: 'blue' },
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
@ -647,8 +692,14 @@ describe('<lion-fieldset>', () => {
|
||||||
fieldset.formElements['gender[]'][1].modelValue = { checked: false, value: 'female' };
|
fieldset.formElements['gender[]'][1].modelValue = { checked: false, value: 'female' };
|
||||||
fieldset.formElements.color.modelValue = { checked: false, value: 'blue' };
|
fieldset.formElements.color.modelValue = { checked: false, value: 'blue' };
|
||||||
expect(fieldset.serializeGroup()).to.deep.equal({
|
expect(fieldset.serializeGroup()).to.deep.equal({
|
||||||
'hobbies[]': [{ checked: false, value: 'chess' }, { checked: false, value: 'rugby' }],
|
'hobbies[]': [
|
||||||
'gender[]': [{ checked: false, value: 'male' }, { checked: false, value: 'female' }],
|
{ checked: false, value: 'chess' },
|
||||||
|
{ checked: false, value: 'rugby' },
|
||||||
|
],
|
||||||
|
'gender[]': [
|
||||||
|
{ checked: false, value: 'male' },
|
||||||
|
{ checked: false, value: 'female' },
|
||||||
|
],
|
||||||
color: { checked: false, value: 'blue' },
|
color: { checked: false, value: 'blue' },
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { html, ifDefined, render } from '@lion/core';
|
import { html, ifDefined, render } from '@lion/core';
|
||||||
import { LionInputDate } from '@lion/input-date';
|
import { LionInputDate } from '@lion/input-date';
|
||||||
import { OverlayController, withModalDialogConfig, OverlayMixin } from '@lion/overlays';
|
import { withModalDialogConfig, OverlayMixin } from '@lion/overlays';
|
||||||
|
|
||||||
import '@lion/calendar/lion-calendar.js';
|
import '@lion/calendar/lion-calendar.js';
|
||||||
import './lion-calendar-overlay-frame.js';
|
import './lion-calendar-overlay-frame.js';
|
||||||
|
|
@ -255,17 +255,14 @@ export class LionInputDatepicker extends OverlayMixin(LionInputDate) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @override Configures OverlayMixin
|
* @override Configures OverlayMixin
|
||||||
* @desc returns an instance of a (dynamic) overlay controller
|
* @desc overrides default configuration options for this component
|
||||||
* @returns {OverlayController}
|
* @returns {Object}
|
||||||
*/
|
*/
|
||||||
// eslint-disable-next-line class-methods-use-this
|
// eslint-disable-next-line class-methods-use-this
|
||||||
_defineOverlay({ contentNode, invokerNode }) {
|
_defineOverlayConfig() {
|
||||||
const ctrl = new OverlayController({
|
return {
|
||||||
...withModalDialogConfig(),
|
...withModalDialogConfig(),
|
||||||
contentNode,
|
};
|
||||||
invokerNode,
|
|
||||||
});
|
|
||||||
return ctrl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async __openCalendarOverlay() {
|
async __openCalendarOverlay() {
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ const template = html`
|
||||||
<button slot="invoker">Click me!</button>
|
<button slot="invoker">Click me!</button>
|
||||||
<div slot="content">
|
<div slot="content">
|
||||||
<div>Hello, World!</div>
|
<div>Hello, World!</div>
|
||||||
<button @click=${e => e.target.dispatchEvent(new Event('close', { bubbles: true }))}>
|
<button @click=${e => e.target.dispatchEvent(new Event('dialog-close', { bubbles: true }))}>
|
||||||
Close
|
Close
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -152,7 +152,7 @@ export class OverlayController {
|
||||||
// TODO: Instead, prefetch it or use a preloader-manager to load it during idle time
|
// TODO: Instead, prefetch it or use a preloader-manager to load it during idle time
|
||||||
this.constructor.popperModule = preloadPopper();
|
this.constructor.popperModule = preloadPopper();
|
||||||
}
|
}
|
||||||
this.__mergePopperConfigs(this.config.popperConfig || {});
|
this.__mergePopperConfigs(cfgToAdd.popperConfig || {});
|
||||||
}
|
}
|
||||||
this._handleFeatures({ phase: 'init' });
|
this._handleFeatures({ phase: 'init' });
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import { render, dedupeMixin } from '@lion/core';
|
import { render, dedupeMixin } from '@lion/core';
|
||||||
|
import { OverlayController } from './OverlayController.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {Function()}
|
* @type {Function()}
|
||||||
|
|
@ -18,12 +19,16 @@ export const OverlayMixin = dedupeMixin(
|
||||||
config: {
|
config: {
|
||||||
type: Object,
|
type: Object,
|
||||||
},
|
},
|
||||||
|
closeEventName: {
|
||||||
|
type: String,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this.config = {};
|
this.config = {};
|
||||||
|
this.closeEventName = 'overlay-close';
|
||||||
}
|
}
|
||||||
|
|
||||||
get opened() {
|
get opened() {
|
||||||
|
|
@ -59,10 +64,29 @@ export const OverlayMixin = dedupeMixin(
|
||||||
/**
|
/**
|
||||||
* @overridable method `_defineOverlay`
|
* @overridable method `_defineOverlay`
|
||||||
* @desc returns an instance of a (dynamic) overlay controller
|
* @desc returns an instance of a (dynamic) overlay controller
|
||||||
|
* In case overriding _defineOverlayConfig is not enough
|
||||||
* @returns {OverlayController}
|
* @returns {OverlayController}
|
||||||
*/
|
*/
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
_defineOverlay({ contentNode, invokerNode }) {}
|
_defineOverlay({ contentNode, invokerNode }) {
|
||||||
|
return new OverlayController({
|
||||||
|
contentNode,
|
||||||
|
invokerNode,
|
||||||
|
...this._defineOverlayConfig(),
|
||||||
|
...this.config,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @overridable method `_defineOverlay`
|
||||||
|
* @desc returns an object with default configuration options for your overlay component.
|
||||||
|
* This is generally speaking easier to override than _defineOverlay method entirely.
|
||||||
|
* @returns {OverlayController}
|
||||||
|
*/
|
||||||
|
// eslint-disable-next-line
|
||||||
|
_defineOverlayConfig() {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @overridable
|
* @overridable
|
||||||
|
|
@ -84,6 +108,14 @@ export const OverlayMixin = dedupeMixin(
|
||||||
super.connectedCallback();
|
super.connectedCallback();
|
||||||
}
|
}
|
||||||
this._createOverlay();
|
this._createOverlay();
|
||||||
|
|
||||||
|
// Default close event catcher on the contentNode which is useful if people want to close
|
||||||
|
// their overlay but the content is not in the global root node (nowhere near the overlay component)
|
||||||
|
this.__close = () => {
|
||||||
|
this.opened = false;
|
||||||
|
};
|
||||||
|
this._overlayCtrl.contentNode.addEventListener(this.closeEventName, this.__close);
|
||||||
|
|
||||||
this._setupOpenCloseListeners();
|
this._setupOpenCloseListeners();
|
||||||
this.__syncOpened();
|
this.__syncOpened();
|
||||||
this.__syncPopper();
|
this.__syncPopper();
|
||||||
|
|
@ -91,10 +123,8 @@ export const OverlayMixin = dedupeMixin(
|
||||||
|
|
||||||
firstUpdated(c) {
|
firstUpdated(c) {
|
||||||
super.firstUpdated(c);
|
super.firstUpdated(c);
|
||||||
if (this._overlayCtrl.config.placementMode === 'local') {
|
|
||||||
this._createOutletForLocalOverlay();
|
this._createOutletForLocalOverlay();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
updated(c) {
|
updated(c) {
|
||||||
super.updated(c);
|
super.updated(c);
|
||||||
|
|
@ -107,6 +137,7 @@ export const OverlayMixin = dedupeMixin(
|
||||||
if (super.disconnectedCallback) {
|
if (super.disconnectedCallback) {
|
||||||
super.disconnectedCallback();
|
super.disconnectedCallback();
|
||||||
}
|
}
|
||||||
|
this._overlayCtrl.contentNode.removeEventListener(this.closeEventName, this.__close);
|
||||||
this._teardownOpenCloseListeners();
|
this._teardownOpenCloseListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -114,7 +145,8 @@ export const OverlayMixin = dedupeMixin(
|
||||||
return Array.from(this.children).find(child => child.slot === 'invoker');
|
return Array.from(this.children).find(child => child.slot === 'invoker');
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: This should be refactored to Array.from(this.children).find(child => child.slot === 'content')
|
// FIXME: This should be refactored to
|
||||||
|
// Array.from(this.children).find(child => child.slot === 'content')
|
||||||
// When this issue is fixed https://github.com/ing-bank/lion/issues/382
|
// When this issue is fixed https://github.com/ing-bank/lion/issues/382
|
||||||
get _overlayContentNode() {
|
get _overlayContentNode() {
|
||||||
const contentNode = this.querySelector('[slot=content]');
|
const contentNode = this.querySelector('[slot=content]');
|
||||||
|
|
@ -184,7 +216,7 @@ export const OverlayMixin = dedupeMixin(
|
||||||
|
|
||||||
__syncPopper() {
|
__syncPopper() {
|
||||||
if (this._overlayCtrl) {
|
if (this._overlayCtrl) {
|
||||||
// TODO: Use updateConfig directly.. but first check if this sync is even still needed! Maybe we can remove it.
|
// TODO: Use updateConfig directly.. But maybe we can remove this entirely.
|
||||||
this._overlayCtrl.updatePopperConfig(this.config.popperConfig);
|
this._overlayCtrl.updatePopperConfig(this.config.popperConfig);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@ import {
|
||||||
withDropdownConfig,
|
withDropdownConfig,
|
||||||
withModalDialogConfig,
|
withModalDialogConfig,
|
||||||
OverlayMixin,
|
OverlayMixin,
|
||||||
OverlayController,
|
|
||||||
} from '../index.js';
|
} from '../index.js';
|
||||||
|
|
||||||
function renderOffline(litHtmlTemplate) {
|
function renderOffline(litHtmlTemplate) {
|
||||||
|
|
@ -96,14 +95,16 @@ const overlayDemoStyle = css`
|
||||||
customElements.define(
|
customElements.define(
|
||||||
'lion-demo-overlay',
|
'lion-demo-overlay',
|
||||||
class extends OverlayMixin(LitElement) {
|
class extends OverlayMixin(LitElement) {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.closeEventName = 'demo-overlay-close';
|
||||||
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line class-methods-use-this
|
// eslint-disable-next-line class-methods-use-this
|
||||||
_defineOverlay({ contentNode, invokerNode }) {
|
_defineOverlayConfig() {
|
||||||
return new OverlayController({
|
return {
|
||||||
placementMode: 'global', // have to set a default
|
placementMode: 'global', // have to set a default
|
||||||
contentNode,
|
};
|
||||||
invokerNode,
|
|
||||||
...this.config,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_setupOpenCloseListeners() {
|
_setupOpenCloseListeners() {
|
||||||
|
|
@ -114,12 +115,10 @@ customElements.define(
|
||||||
this.opened = !this.opened;
|
this.opened = !this.opened;
|
||||||
};
|
};
|
||||||
this._overlayCtrl.invokerNode.addEventListener('click', this.__toggle);
|
this._overlayCtrl.invokerNode.addEventListener('click', this.__toggle);
|
||||||
this._overlayCtrl.contentNode.addEventListener('close', this.__close);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_teardownOpenCloseListeners() {
|
_teardownOpenCloseListeners() {
|
||||||
this._overlayCtrl.invokerNode.removeEventListener('click', this.__toggle);
|
this._overlayCtrl.invokerNode.removeEventListener('click', this.__toggle);
|
||||||
this._overlayCtrl.contentNode.removeEventListener('close', this.__close);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|
@ -161,7 +160,8 @@ storiesOf('Overlay System | Overlay as a WC', module)
|
||||||
Hello! You can close this notification here:
|
Hello! You can close this notification here:
|
||||||
<lion-button
|
<lion-button
|
||||||
class="close-button"
|
class="close-button"
|
||||||
@click=${e => e.target.dispatchEvent(new Event('close', { bubbles: true }))}
|
@click=${e =>
|
||||||
|
e.target.dispatchEvent(new Event('demo-overlay-close', { bubbles: true }))}
|
||||||
>⨯</lion-button
|
>⨯</lion-button
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -179,7 +179,8 @@ storiesOf('Overlay System | Overlay as a WC', module)
|
||||||
Hello! You can close this notification here:
|
Hello! You can close this notification here:
|
||||||
<lion-button
|
<lion-button
|
||||||
class="close-button"
|
class="close-button"
|
||||||
@click=${e => e.target.dispatchEvent(new Event('close', { bubbles: true }))}
|
@click=${e =>
|
||||||
|
e.target.dispatchEvent(new Event('demo-overlay-close', { bubbles: true }))}
|
||||||
>⨯</lion-button
|
>⨯</lion-button
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -211,7 +212,8 @@ storiesOf('Overlay System | Overlay as a WC', module)
|
||||||
Hello! You can close this notification here:
|
Hello! You can close this notification here:
|
||||||
<lion-button
|
<lion-button
|
||||||
class="close-button"
|
class="close-button"
|
||||||
@click=${e => e.target.dispatchEvent(new Event('close', { bubbles: true }))}
|
@click=${e =>
|
||||||
|
e.target.dispatchEvent(new Event('demo-overlay-close', { bubbles: true }))}
|
||||||
>⨯</lion-button
|
>⨯</lion-button
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -275,7 +277,8 @@ storiesOf('Overlay System | Overlay as a WC', module)
|
||||||
Hello! You can close this notification here:
|
Hello! You can close this notification here:
|
||||||
<lion-button
|
<lion-button
|
||||||
class="close-button"
|
class="close-button"
|
||||||
@click=${e => e.target.dispatchEvent(new Event('close', { bubbles: true }))}
|
@click=${e =>
|
||||||
|
e.target.dispatchEvent(new Event('demo-overlay-close', { bubbles: true }))}
|
||||||
>⨯</lion-button
|
>⨯</lion-button
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -410,7 +413,7 @@ storiesOf('Overlay System | Overlay as a WC', module)
|
||||||
Hello! You can close this notification here:
|
Hello! You can close this notification here:
|
||||||
<lion-button
|
<lion-button
|
||||||
class="close-button"
|
class="close-button"
|
||||||
@click=${e => e.target.dispatchEvent(new Event('close', { bubbles: true }))}
|
@click=${e => e.target.dispatchEvent(new Event('demo-overlay-close', { bubbles: true }))}
|
||||||
>⨯</lion-button
|
>⨯</lion-button
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { html, css, LitElement, SlotMixin } from '@lion/core';
|
import { html, css, LitElement, SlotMixin } from '@lion/core';
|
||||||
import { OverlayController, withDropdownConfig, OverlayMixin } from '@lion/overlays';
|
import { withDropdownConfig, OverlayMixin } from '@lion/overlays';
|
||||||
import { FormControlMixin, InteractionStateMixin, FormRegistrarMixin } from '@lion/field';
|
import { FormControlMixin, InteractionStateMixin, FormRegistrarMixin } from '@lion/field';
|
||||||
import { ValidateMixin } from '@lion/validate';
|
import { ValidateMixin } from '@lion/validate';
|
||||||
import './differentKeyNamesShimIE.js';
|
import './differentKeyNamesShimIE.js';
|
||||||
|
|
@ -601,12 +601,10 @@ export class LionSelectRich extends OverlayMixin(
|
||||||
}
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line class-methods-use-this
|
// eslint-disable-next-line class-methods-use-this
|
||||||
_defineOverlay({ invokerNode, contentNode } = {}) {
|
_defineOverlayConfig() {
|
||||||
return new OverlayController({
|
return {
|
||||||
...withDropdownConfig(),
|
...withDropdownConfig(),
|
||||||
contentNode,
|
};
|
||||||
invokerNode,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
__setupOverlay() {
|
__setupOverlay() {
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ e invoker element is focused.
|
||||||
### Installation
|
### Installation
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
npm i --save @lion/popup
|
npm i --save @lion/tooltip
|
||||||
```
|
```
|
||||||
|
|
||||||
```js
|
```js
|
||||||
|
|
@ -28,7 +28,7 @@ import '@lion/tooltip/lion-tooltip.js';
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<lion-tooltip>
|
<lion-tooltip>
|
||||||
<div slot="content" class="tooltip">This is a popup<div>
|
<div slot="content" class="tooltip">This is a tooltip<div>
|
||||||
<a slot="invoker" href="https://www.google.com/">
|
<a slot="invoker" href="https://www.google.com/">
|
||||||
Popup on link
|
Popup on link
|
||||||
</a>
|
</a>
|
||||||
|
|
|
||||||
|
|
@ -33,8 +33,7 @@
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@lion/core": "^0.3.0",
|
"@lion/core": "^0.3.0",
|
||||||
"@lion/overlays": "^0.6.4",
|
"@lion/overlays": "^0.6.4"
|
||||||
"@lion/popup": "^0.3.20"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@lion/button": "^0.3.43",
|
"@lion/button": "^0.3.43",
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,20 @@
|
||||||
import { OverlayMixin, OverlayController } from '@lion/overlays';
|
import { OverlayMixin } from '@lion/overlays';
|
||||||
import { LitElement, html } from '@lion/core';
|
import { LitElement, html } from '@lion/core';
|
||||||
|
|
||||||
export class LionTooltip extends OverlayMixin(LitElement) {
|
export class LionTooltip extends OverlayMixin(LitElement) {
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
|
this.closeEventName = 'tooltip-close';
|
||||||
this.mouseActive = false;
|
this.mouseActive = false;
|
||||||
this.keyActive = false;
|
this.keyActive = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
_defineOverlay({ contentNode, invokerNode }) {
|
// eslint-disable-next-line class-methods-use-this
|
||||||
return new OverlayController({
|
_defineOverlayConfig() {
|
||||||
|
return {
|
||||||
placementMode: 'local', // have to set a default
|
placementMode: 'local', // have to set a default
|
||||||
elementToFocusAfterHide: null,
|
elementToFocusAfterHide: null,
|
||||||
contentNode,
|
};
|
||||||
invokerNode,
|
|
||||||
...this.config,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_setupOpenCloseListeners() {
|
_setupOpenCloseListeners() {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue