feat(core): add ScopedStylesMixin
This commit is contained in:
parent
cc281b505a
commit
57d2c62b78
10 changed files with 206 additions and 63 deletions
6
.changeset/itchy-plums-sip.md
Normal file
6
.changeset/itchy-plums-sip.md
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
---
|
||||||
|
'@lion/core': patch
|
||||||
|
'@lion/input-range': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Abstract input-range's scoped styles feature to a mixin for reuse. With this mixin, you can scope styles on a LightDOM component.
|
||||||
|
|
@ -18,7 +18,8 @@ import { LitElement, html, render } from 'lit-element';
|
||||||
- [function to deduplicate mixins (dedupeMixin)](#deduping-of-mixins)
|
- [function to deduplicate mixins (dedupeMixin)](#deduping-of-mixins)
|
||||||
- Mixin to handle disabled (DisabledMixin)
|
- Mixin to handle disabled (DisabledMixin)
|
||||||
- Mixin to handle disabled AND tabIndex (DisabledWithTabIndexMixin)
|
- Mixin to handle disabled AND tabIndex (DisabledWithTabIndexMixin)
|
||||||
- Mixin to manage auto generated needed slot elements in light dom (SlotMixin)
|
- Mixin to manage auto-generated needed slot elements in light dom (SlotMixin)
|
||||||
|
- Mixin to create scoped styles in LightDOM-using components (ScopedStylesMixin)
|
||||||
|
|
||||||
> These features are not well documented - care to help out?
|
> These features are not well documented - care to help out?
|
||||||
|
|
||||||
|
|
@ -49,7 +50,7 @@ In other words, this may happen to the protoype chain `... -> M2 -> BaseMixin ->
|
||||||
|
|
||||||
An example of this may be a `LocalizeMixin` used across different components and mixins. Some mixins may need it and many components need it too and can not rely on other mixins to have it by default, so must inherit from it independently.
|
An example of this may be a `LocalizeMixin` used across different components and mixins. Some mixins may need it and many components need it too and can not rely on other mixins to have it by default, so must inherit from it independently.
|
||||||
|
|
||||||
The more generic the mixin is, the higher the chance of being appliend more than once. As a mixin author you can't control how it is used, and can't always predict it. So as a safety measure it is always recommended to create deduping mixins.
|
The more generic the mixin is, the higher the chance of being applied more than once. As a mixin author you can't control how it is used, and can't always predict it. So as a safety measure it is always recommended to create deduping mixins.
|
||||||
|
|
||||||
### Usage of dedupeMixin()
|
### Usage of dedupeMixin()
|
||||||
|
|
||||||
|
|
|
||||||
1
packages/core/index.d.ts
vendored
1
packages/core/index.d.ts
vendored
|
|
@ -80,6 +80,7 @@ export { dedupeMixin } from '@open-wc/dedupe-mixin';
|
||||||
export { DelegateMixin } from './src/DelegateMixin.js';
|
export { DelegateMixin } from './src/DelegateMixin.js';
|
||||||
export { DisabledMixin } from './src/DisabledMixin.js';
|
export { DisabledMixin } from './src/DisabledMixin.js';
|
||||||
export { DisabledWithTabIndexMixin } from './src/DisabledWithTabIndexMixin.js';
|
export { DisabledWithTabIndexMixin } from './src/DisabledWithTabIndexMixin.js';
|
||||||
|
export { ScopedStylesMixin } from './src/ScopedStylesMixin.js';
|
||||||
export { SlotMixin } from './src/SlotMixin.js';
|
export { SlotMixin } from './src/SlotMixin.js';
|
||||||
export { UpdateStylesMixin } from './src/UpdateStylesMixin.js';
|
export { UpdateStylesMixin } from './src/UpdateStylesMixin.js';
|
||||||
export { browserDetection } from './src/browserDetection.js';
|
export { browserDetection } from './src/browserDetection.js';
|
||||||
|
|
|
||||||
|
|
@ -71,6 +71,7 @@ export { dedupeMixin } from '@open-wc/dedupe-mixin';
|
||||||
export { DelegateMixin } from './src/DelegateMixin.js';
|
export { DelegateMixin } from './src/DelegateMixin.js';
|
||||||
export { DisabledMixin } from './src/DisabledMixin.js';
|
export { DisabledMixin } from './src/DisabledMixin.js';
|
||||||
export { DisabledWithTabIndexMixin } from './src/DisabledWithTabIndexMixin.js';
|
export { DisabledWithTabIndexMixin } from './src/DisabledWithTabIndexMixin.js';
|
||||||
|
export { ScopedStylesMixin } from './src/ScopedStylesMixin.js';
|
||||||
export { SlotMixin } from './src/SlotMixin.js';
|
export { SlotMixin } from './src/SlotMixin.js';
|
||||||
export { UpdateStylesMixin } from './src/UpdateStylesMixin.js';
|
export { UpdateStylesMixin } from './src/UpdateStylesMixin.js';
|
||||||
export { browserDetection } from './src/browserDetection.js';
|
export { browserDetection } from './src/browserDetection.js';
|
||||||
|
|
|
||||||
55
packages/core/src/ScopedStylesMixin.js
Normal file
55
packages/core/src/ScopedStylesMixin.js
Normal file
|
|
@ -0,0 +1,55 @@
|
||||||
|
import { dedupeMixin } from '@open-wc/dedupe-mixin';
|
||||||
|
import { unsafeCSS, css } from 'lit';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {import('../types/ScopedStylesMixinTypes').ScopedStylesMixin} ScopedStylesMixin
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {ScopedStylesMixin}
|
||||||
|
* @param {import('@open-wc/dedupe-mixin').Constructor<import('lit').LitElement>} superclass
|
||||||
|
*/
|
||||||
|
const ScopedStylesMixinImplementation = superclass =>
|
||||||
|
// eslint-disable-next-line no-shadow
|
||||||
|
// @ts-ignore https://github.com/microsoft/TypeScript/issues/36821#issuecomment-588375051
|
||||||
|
class ScopedStylesHost extends superclass {
|
||||||
|
/**
|
||||||
|
* @param {import('lit').CSSResult} scope
|
||||||
|
* @return {import('lit').CSSResultGroup}
|
||||||
|
*/
|
||||||
|
// eslint-disable-next-line no-unused-vars
|
||||||
|
static scopedStyles(scope) {
|
||||||
|
return css``;
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
// Perhaps use constructable stylesheets instead once Safari supports replace(Sync) methods
|
||||||
|
this.__styleTag = document.createElement('style');
|
||||||
|
this.scopedClass = `${this.localName}-${Math.floor(Math.random() * 10000)}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
connectedCallback() {
|
||||||
|
super.connectedCallback();
|
||||||
|
this.classList.add(this.scopedClass);
|
||||||
|
this.__setupStyleTag();
|
||||||
|
}
|
||||||
|
|
||||||
|
disconnectedCallback() {
|
||||||
|
super.disconnectedCallback();
|
||||||
|
this.__teardownStyleTag();
|
||||||
|
}
|
||||||
|
|
||||||
|
__setupStyleTag() {
|
||||||
|
this.__styleTag.textContent = /** @type {typeof ScopedStylesHost} */ (this.constructor)
|
||||||
|
.scopedStyles(unsafeCSS(this.scopedClass))
|
||||||
|
.toString();
|
||||||
|
this.insertBefore(this.__styleTag, this.childNodes[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
__teardownStyleTag() {
|
||||||
|
this.removeChild(this.__styleTag);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const ScopedStylesMixin = dedupeMixin(ScopedStylesMixinImplementation);
|
||||||
64
packages/core/test/ScopedStylesMixin.test.js
Normal file
64
packages/core/test/ScopedStylesMixin.test.js
Normal file
|
|
@ -0,0 +1,64 @@
|
||||||
|
import { expect, fixture } from '@open-wc/testing';
|
||||||
|
// import { html as _html } from 'lit/static-html.js';
|
||||||
|
import { LitElement, css, html } from '../index.js';
|
||||||
|
import { ScopedStylesMixin } from '../src/ScopedStylesMixin.js';
|
||||||
|
|
||||||
|
describe('ScopedStylesMixin', () => {
|
||||||
|
class Scoped extends ScopedStylesMixin(LitElement) {
|
||||||
|
/**
|
||||||
|
* @param {import('lit').CSSResult} scope
|
||||||
|
* @returns {import('lit').CSSResultGroup}
|
||||||
|
*/
|
||||||
|
static scopedStyles(scope) {
|
||||||
|
return css`
|
||||||
|
.${scope} .test {
|
||||||
|
color: #fff000;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return html` <p class="test">Some Text</p> `;
|
||||||
|
}
|
||||||
|
|
||||||
|
createRenderRoot() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
before(() => {
|
||||||
|
customElements.define('scoped-el', Scoped);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('contains the scoped css class for the slotted input style', async () => {
|
||||||
|
const el = /** @type {Scoped} */ (await fixture(html`<scoped-el></scoped-el>`));
|
||||||
|
expect(el.classList.contains(el.scopedClass)).to.equal(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('adds a style tag as the first child which contains a class selector to the element', async () => {
|
||||||
|
const el = /** @type {Scoped} */ (await fixture(html` <scoped-el></scoped-el> `));
|
||||||
|
expect(el.children[0].tagName).to.equal('STYLE');
|
||||||
|
expect(el.children[0].innerHTML).to.contain(el.scopedClass);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('the scoped styles are applied correctly to the DOM elements', async () => {
|
||||||
|
const el = /** @type {Scoped} */ (await fixture(html`<scoped-el></scoped-el>`));
|
||||||
|
const testText = /** @type {HTMLElement} */ (el.querySelector('.test'));
|
||||||
|
const cl = Array.from(el.classList);
|
||||||
|
expect(cl.find(item => item.startsWith('scoped-el-'))).to.not.be.undefined;
|
||||||
|
expect(getComputedStyle(testText).getPropertyValue('color')).to.equal('rgb(255, 240, 0)');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does cleanup of the style tag when moving or deleting the el', async () => {
|
||||||
|
const wrapper = await fixture(`
|
||||||
|
<div></div>
|
||||||
|
`);
|
||||||
|
const wrapper2 = await fixture(`
|
||||||
|
<div></div>
|
||||||
|
`);
|
||||||
|
const el = document.createElement('scoped-el');
|
||||||
|
wrapper.appendChild(el);
|
||||||
|
wrapper2.appendChild(el);
|
||||||
|
expect(el.children[1]).to.be.undefined;
|
||||||
|
});
|
||||||
|
});
|
||||||
20
packages/core/types/ScopedStylesMixinTypes.d.ts
vendored
Normal file
20
packages/core/types/ScopedStylesMixinTypes.d.ts
vendored
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
import { Constructor } from '@open-wc/dedupe-mixin';
|
||||||
|
import { CSSResultGroup, CSSResult, LitElement } from 'lit';
|
||||||
|
|
||||||
|
export declare class ScopedStylesHost {
|
||||||
|
static scopedStyles(scope: CSSResult): CSSResultGroup;
|
||||||
|
|
||||||
|
__styleTag: HTMLStyleElement;
|
||||||
|
|
||||||
|
scopedClass: string;
|
||||||
|
|
||||||
|
private __setupStyleTag(): void;
|
||||||
|
|
||||||
|
private __teardownStyleTag(): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export declare function ScopedStylesMixinImplementation<T extends Constructor<LitElement>>(
|
||||||
|
superclass: T,
|
||||||
|
): T & Constructor<ScopedStylesHost> & Pick<typeof ScopedStylesHost, keyof typeof ScopedStylesHost>;
|
||||||
|
|
||||||
|
export type ScopedStylesMixin = typeof ScopedStylesMixinImplementation;
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/* eslint-disable import/no-extraneous-dependencies */
|
/* eslint-disable import/no-extraneous-dependencies */
|
||||||
import { css, html, unsafeCSS } from '@lion/core';
|
import { css, html, ScopedStylesMixin } from '@lion/core';
|
||||||
import { LionInput } from '@lion/input';
|
import { LionInput } from '@lion/input';
|
||||||
import { formatNumber } from '@lion/localize';
|
import { formatNumber } from '@lion/localize';
|
||||||
|
|
||||||
|
|
@ -12,7 +12,7 @@ import { formatNumber } from '@lion/localize';
|
||||||
*
|
*
|
||||||
* @customElement `lion-input-range`
|
* @customElement `lion-input-range`
|
||||||
*/
|
*/
|
||||||
export class LionInputRange extends LionInput {
|
export class LionInputRange extends ScopedStylesMixin(LionInput) {
|
||||||
/** @type {any} */
|
/** @type {any} */
|
||||||
static get properties() {
|
static get properties() {
|
||||||
return {
|
return {
|
||||||
|
|
@ -42,7 +42,7 @@ export class LionInputRange extends LionInput {
|
||||||
/**
|
/**
|
||||||
* @param {CSSResult} scope
|
* @param {CSSResult} scope
|
||||||
*/
|
*/
|
||||||
static rangeStyles(scope) {
|
static scopedStyles(scope) {
|
||||||
return css`
|
return css`
|
||||||
/* Custom input range styling comes here, be aware that this won't work for polyfilled browsers */
|
/* Custom input range styling comes here, be aware that this won't work for polyfilled browsers */
|
||||||
.${scope} .form-control {
|
.${scope} .form-control {
|
||||||
|
|
@ -69,22 +69,6 @@ export class LionInputRange extends LionInput {
|
||||||
* @param {string} modelValue
|
* @param {string} modelValue
|
||||||
*/
|
*/
|
||||||
this.parser = modelValue => parseFloat(modelValue);
|
this.parser = modelValue => parseFloat(modelValue);
|
||||||
this.scopedClass = `${this.localName}-${Math.floor(Math.random() * 10000)}`;
|
|
||||||
/** @private */
|
|
||||||
this.__styleTag = document.createElement('style');
|
|
||||||
}
|
|
||||||
|
|
||||||
connectedCallback() {
|
|
||||||
super.connectedCallback();
|
|
||||||
/* eslint-disable-next-line wc/no-self-class */
|
|
||||||
this.classList.add(this.scopedClass);
|
|
||||||
|
|
||||||
this.__setupStyleTag();
|
|
||||||
}
|
|
||||||
|
|
||||||
disconnectedCallback() {
|
|
||||||
super.disconnectedCallback();
|
|
||||||
this.__teardownStyleTag();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @param {import('@lion/core').PropertyValues } changedProperties */
|
/** @param {import('@lion/core').PropertyValues } changedProperties */
|
||||||
|
|
@ -151,17 +135,4 @@ export class LionInputRange extends LionInput {
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @private */
|
|
||||||
__setupStyleTag() {
|
|
||||||
this.__styleTag.textContent = /** @type {typeof LionInputRange} */ (this.constructor)
|
|
||||||
.rangeStyles(unsafeCSS(this.scopedClass))
|
|
||||||
.toString();
|
|
||||||
this.insertBefore(this.__styleTag, this.childNodes[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @private */
|
|
||||||
__teardownStyleTag() {
|
|
||||||
this.removeChild(this.__styleTag);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,35 +14,6 @@ describe('<lion-input-range>', () => {
|
||||||
expect(el._inputNode.type).to.equal('range');
|
expect(el._inputNode.type).to.equal('range');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('contain the scoped css class for the slotted input style', async () => {
|
|
||||||
const el = await fixture(`
|
|
||||||
<lion-input-range></lion-input-range>
|
|
||||||
`);
|
|
||||||
expect(el.classList.contains(el.scopedClass)).to.equal(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('adds a style tag as the first child which contains a class selector to the element', async () => {
|
|
||||||
const el = await fixture(`
|
|
||||||
<lion-input-range></lion-input-range>
|
|
||||||
`);
|
|
||||||
expect(el.children[0].tagName).to.equal('STYLE');
|
|
||||||
expect(el.children[0].innerHTML).to.contain(el.scopedClass);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('does cleanup of the style tag when moving or deleting the el', async () => {
|
|
||||||
const wrapper = await fixture(`
|
|
||||||
<div></div>
|
|
||||||
`);
|
|
||||||
const wrapper2 = await fixture(`
|
|
||||||
<div></div>
|
|
||||||
`);
|
|
||||||
const el = document.createElement('lion-input-range');
|
|
||||||
wrapper.appendChild(el);
|
|
||||||
wrapper2.appendChild(el);
|
|
||||||
|
|
||||||
expect(el.children[1].tagName).to.not.equal('STYLE');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('displays the modelValue and unit', async () => {
|
it('displays the modelValue and unit', async () => {
|
||||||
const el = await fixture(html`
|
const el = await fixture(html`
|
||||||
<lion-input-range .modelValue=${75} unit="${`%`}"></lion-input-range>
|
<lion-input-range .modelValue=${75} unit="${`%`}"></lion-input-range>
|
||||||
|
|
|
||||||
53
yarn.lock
53
yarn.lock
|
|
@ -1322,6 +1322,16 @@
|
||||||
dependencies:
|
dependencies:
|
||||||
"@lion/core" "0.18.2"
|
"@lion/core" "0.18.2"
|
||||||
|
|
||||||
|
"@lion/combobox@^0.8.6":
|
||||||
|
version "0.8.7"
|
||||||
|
resolved "https://registry.yarnpkg.com/@lion/combobox/-/combobox-0.8.7.tgz#74414fddb317f8abb27409ce0cf1a6708ecd6d9d"
|
||||||
|
integrity sha512-1SfaqOW1zihuX3oXlLnawwC9m9MajZoKZ5Ow4KYCKKiBkAVGifDAHTDXz/ls3hyWICFn7/oYtqRpa7qbwZ0CXQ==
|
||||||
|
dependencies:
|
||||||
|
"@lion/core" "0.20.0"
|
||||||
|
"@lion/form-core" "0.15.5"
|
||||||
|
"@lion/listbox" "0.11.0"
|
||||||
|
"@lion/overlays" "0.30.0"
|
||||||
|
|
||||||
"@lion/core@0.16.0":
|
"@lion/core@0.16.0":
|
||||||
version "0.16.0"
|
version "0.16.0"
|
||||||
resolved "https://registry.yarnpkg.com/@lion/core/-/core-0.16.0.tgz#c4c8ac81b8d5bece6d40d561a392382c7ae73533"
|
resolved "https://registry.yarnpkg.com/@lion/core/-/core-0.16.0.tgz#c4c8ac81b8d5bece6d40d561a392382c7ae73533"
|
||||||
|
|
@ -1350,6 +1360,15 @@
|
||||||
"@open-wc/scoped-elements" "^2.0.1"
|
"@open-wc/scoped-elements" "^2.0.1"
|
||||||
lit "^2.0.2"
|
lit "^2.0.2"
|
||||||
|
|
||||||
|
"@lion/core@0.20.0":
|
||||||
|
version "0.20.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@lion/core/-/core-0.20.0.tgz#3982dc7a6ec5e742680b7453a684840358799759"
|
||||||
|
integrity sha512-CyJNGNMWkPI/kf9lhMnkZInrLLvmPQxt6qO7B60S2k7UNANd2R53zNgqTtllYp16Ej+4Mol9JoW2Ik6+1vq9ig==
|
||||||
|
dependencies:
|
||||||
|
"@open-wc/dedupe-mixin" "^1.3.0"
|
||||||
|
"@open-wc/scoped-elements" "^2.0.1"
|
||||||
|
lit "^2.0.2"
|
||||||
|
|
||||||
"@lion/form-core@0.15.4":
|
"@lion/form-core@0.15.4":
|
||||||
version "0.15.4"
|
version "0.15.4"
|
||||||
resolved "https://registry.yarnpkg.com/@lion/form-core/-/form-core-0.15.4.tgz#e5fdc49199b9a491becf70370ab6de1407bc7a66"
|
resolved "https://registry.yarnpkg.com/@lion/form-core/-/form-core-0.15.4.tgz#e5fdc49199b9a491becf70370ab6de1407bc7a66"
|
||||||
|
|
@ -1358,6 +1377,22 @@
|
||||||
"@lion/core" "0.19.0"
|
"@lion/core" "0.19.0"
|
||||||
"@lion/localize" "0.21.3"
|
"@lion/localize" "0.21.3"
|
||||||
|
|
||||||
|
"@lion/form-core@0.15.5":
|
||||||
|
version "0.15.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/@lion/form-core/-/form-core-0.15.5.tgz#af40dab6c7ca32187322b84a6319a277fcbd4617"
|
||||||
|
integrity sha512-SM27hqupHZ2eq4enaaX/dbIH6fTJYrISA378zZjCBPcYSDq39EXMgnzgGXWfZzi1DPEffbl2g6VKR+UGc8xRZg==
|
||||||
|
dependencies:
|
||||||
|
"@lion/core" "0.20.0"
|
||||||
|
"@lion/localize" "0.22.0"
|
||||||
|
|
||||||
|
"@lion/listbox@0.11.0":
|
||||||
|
version "0.11.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@lion/listbox/-/listbox-0.11.0.tgz#f730714803f14a6d001a5e0c2cdff17146eccac7"
|
||||||
|
integrity sha512-nLwNZuARVcdT5+TNqph56+g1CnXMcRMjM0vzvSNgezGTZJ3b6onumgQwEXLGhxIbB16qFbfpaPZP7SaALfFsBA==
|
||||||
|
dependencies:
|
||||||
|
"@lion/core" "0.20.0"
|
||||||
|
"@lion/form-core" "0.15.5"
|
||||||
|
|
||||||
"@lion/listbox@^0.10.7":
|
"@lion/listbox@^0.10.7":
|
||||||
version "0.10.7"
|
version "0.10.7"
|
||||||
resolved "https://registry.yarnpkg.com/@lion/listbox/-/listbox-0.10.7.tgz#9af689615ea0964e4a5613c3e5b2df9b33fc2d54"
|
resolved "https://registry.yarnpkg.com/@lion/listbox/-/listbox-0.10.7.tgz#9af689615ea0964e4a5613c3e5b2df9b33fc2d54"
|
||||||
|
|
@ -1375,6 +1410,24 @@
|
||||||
"@lion/core" "0.19.0"
|
"@lion/core" "0.19.0"
|
||||||
singleton-manager "1.4.2"
|
singleton-manager "1.4.2"
|
||||||
|
|
||||||
|
"@lion/localize@0.22.0":
|
||||||
|
version "0.22.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@lion/localize/-/localize-0.22.0.tgz#88e0755b53c699231af0df0b4302de2197484bc0"
|
||||||
|
integrity sha512-75q3Xp/5A2v39mWHTaCZXc3L6nO3DD2vU5w/WPFusW6mzMJw3nzB4ot665UrjbY/HJwQV7Trjh9c/O79oh5x8Q==
|
||||||
|
dependencies:
|
||||||
|
"@bundled-es-modules/message-format" "6.0.4"
|
||||||
|
"@lion/core" "0.20.0"
|
||||||
|
singleton-manager "1.4.3"
|
||||||
|
|
||||||
|
"@lion/overlays@0.30.0":
|
||||||
|
version "0.30.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@lion/overlays/-/overlays-0.30.0.tgz#cd30c6ee8beda2ef977eb9b049cbac3549040c50"
|
||||||
|
integrity sha512-3P/VMCkzp6c0E8Nl6Mtvtqg/7J93JM3MEPi14WE9PWYQZcrtvcWSfLXCoI3Va1HoFfRuaAcN0DN0AO6Z71iFeg==
|
||||||
|
dependencies:
|
||||||
|
"@lion/core" "0.20.0"
|
||||||
|
"@popperjs/core" "^2.5.4"
|
||||||
|
singleton-manager "1.4.3"
|
||||||
|
|
||||||
"@lion/overlays@^0.26.1":
|
"@lion/overlays@^0.26.1":
|
||||||
version "0.26.1"
|
version "0.26.1"
|
||||||
resolved "https://registry.yarnpkg.com/@lion/overlays/-/overlays-0.26.1.tgz#d1bfa4f5f97108982afa7b409ba4300f8b2d2ba5"
|
resolved "https://registry.yarnpkg.com/@lion/overlays/-/overlays-0.26.1.tgz#d1bfa4f5f97108982afa7b409ba4300f8b2d2ba5"
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue