fix(helpers): fix missing types
This commit is contained in:
parent
a3ac76f174
commit
9da2aa2030
7 changed files with 106 additions and 53 deletions
5
.changeset/fifty-jars-sing.md
Normal file
5
.changeset/fifty-jars-sing.md
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
'@lion/helpers': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Fix types for helpers
|
||||||
|
|
@ -1,5 +1,11 @@
|
||||||
import { render } from '@lion/core';
|
import { render } from '@lion/core';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper to render a lit TemplateResult as an offline-created DOM node
|
||||||
|
* Make sure that the top-most element in the template has no siblings,
|
||||||
|
* as they won't be taken into account. We only return firstElementChild.
|
||||||
|
* @param {import('lit-html').TemplateResult} litHtmlTemplate
|
||||||
|
*/
|
||||||
export const renderLitAsNode = litHtmlTemplate => {
|
export const renderLitAsNode = litHtmlTemplate => {
|
||||||
const offlineRenderContainer = document.createElement('div');
|
const offlineRenderContainer = document.createElement('div');
|
||||||
render(litHtmlTemplate, offlineRenderContainer);
|
render(litHtmlTemplate, offlineRenderContainer);
|
||||||
|
|
|
||||||
|
|
@ -122,11 +122,14 @@ export class SbActionLogger extends LitElement {
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this.title = 'Action Logger';
|
this.title = 'Action Logger';
|
||||||
|
this.simple = false;
|
||||||
this.__logCounter = 0;
|
this.__logCounter = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
get loggerEl() {
|
get loggerEl() {
|
||||||
return this.shadowRoot.querySelector('.logger');
|
return /** @type {HTMLElement} */ (
|
||||||
|
/** @type {ShadowRoot} */ (this.shadowRoot).querySelector('.logger')
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -134,7 +137,7 @@ export class SbActionLogger extends LitElement {
|
||||||
* Only supports simple values, will be interpreted to a String
|
* Only supports simple values, will be interpreted to a String
|
||||||
* E.g. an Object will become '[object Object]'
|
* E.g. an Object will become '[object Object]'
|
||||||
*
|
*
|
||||||
* @param {} content Content to be logged to the action logger
|
* @param {string} content Content to be logged to the action logger
|
||||||
*/
|
*/
|
||||||
log(content) {
|
log(content) {
|
||||||
this.__animateCue();
|
this.__animateCue();
|
||||||
|
|
@ -147,7 +150,10 @@ export class SbActionLogger extends LitElement {
|
||||||
this.__handleConsecutiveDuplicateLog();
|
this.__handleConsecutiveDuplicateLog();
|
||||||
} else {
|
} else {
|
||||||
this.__appendLog(content);
|
this.__appendLog(content);
|
||||||
this.loggerEl.scrollTo({ top: this.loggerEl.scrollHeight, behavior: 'smooth' });
|
this.loggerEl.scrollTo({
|
||||||
|
top: this.loggerEl.scrollHeight,
|
||||||
|
behavior: 'smooth',
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
this.__logCounter += 1; // increment total log counter
|
this.__logCounter += 1; // increment total log counter
|
||||||
|
|
@ -156,6 +162,7 @@ export class SbActionLogger extends LitElement {
|
||||||
/**
|
/**
|
||||||
* Protected getter that returns the template of a single log
|
* Protected getter that returns the template of a single log
|
||||||
*
|
*
|
||||||
|
* @param {string} content
|
||||||
* @return {TemplateResult} TemplateResult that uses the content passed to create a log
|
* @return {TemplateResult} TemplateResult that uses the content passed to create a log
|
||||||
*/
|
*/
|
||||||
// eslint-disable-next-line class-methods-use-this
|
// eslint-disable-next-line class-methods-use-this
|
||||||
|
|
@ -183,16 +190,24 @@ export class SbActionLogger extends LitElement {
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} content
|
||||||
|
*/
|
||||||
__appendLog(content) {
|
__appendLog(content) {
|
||||||
const offlineRenderContainer = document.createElement('div');
|
const offlineRenderContainer = document.createElement('div');
|
||||||
render(this._logTemplate(content), offlineRenderContainer);
|
render(this._logTemplate(content), offlineRenderContainer);
|
||||||
this.loggerEl.appendChild(offlineRenderContainer.firstElementChild);
|
if (offlineRenderContainer.firstElementChild) {
|
||||||
|
this.loggerEl.appendChild(offlineRenderContainer.firstElementChild);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} content
|
||||||
|
*/
|
||||||
__isConsecutiveDuplicateLog(content) {
|
__isConsecutiveDuplicateLog(content) {
|
||||||
if (
|
if (
|
||||||
this.loggerEl.lastElementChild &&
|
this.loggerEl.lastElementChild &&
|
||||||
this.loggerEl.lastElementChild.querySelector('code').textContent.trim() === content
|
this.loggerEl.lastElementChild.querySelector('code')?.textContent?.trim() === content
|
||||||
) {
|
) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -200,41 +215,51 @@ export class SbActionLogger extends LitElement {
|
||||||
}
|
}
|
||||||
|
|
||||||
__handleConsecutiveDuplicateLog() {
|
__handleConsecutiveDuplicateLog() {
|
||||||
if (!this.loggerEl.lastElementChild.querySelector('.logger__log-count')) {
|
if (!this.loggerEl.lastElementChild?.querySelector('.logger__log-count')) {
|
||||||
this.__prependLogCounterElement();
|
this.__prependLogCounterElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Increment log counter for these duplicate logs
|
// Increment log counter for these duplicate logs
|
||||||
const logCounter = this.loggerEl.lastElementChild.querySelector('.logger__log-count');
|
|
||||||
let incrementedLogCount = logCounter.textContent;
|
const logCounter = this.loggerEl.lastElementChild?.querySelector('.logger__log-count');
|
||||||
incrementedLogCount = parseInt(incrementedLogCount, 10) + 1;
|
if (logCounter instanceof HTMLElement) {
|
||||||
logCounter.innerText = incrementedLogCount;
|
const logCount = logCounter.textContent;
|
||||||
|
if (logCount != null) {
|
||||||
|
const incrementedLogCount = parseInt(logCount, 10) + 1;
|
||||||
|
logCounter.innerText = incrementedLogCount.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
__prependLogCounterElement() {
|
__prependLogCounterElement() {
|
||||||
const countEl = document.createElement('div');
|
const countEl = document.createElement('div');
|
||||||
countEl.classList.add('logger__log-count');
|
countEl.classList.add('logger__log-count');
|
||||||
countEl.innerText = 1;
|
countEl.innerText = (1).toString();
|
||||||
this.loggerEl.lastElementChild.insertBefore(
|
|
||||||
countEl,
|
const loggerLastElementChild = this.loggerEl.lastElementChild;
|
||||||
this.loggerEl.lastElementChild.firstElementChild,
|
if (loggerLastElementChild) {
|
||||||
);
|
loggerLastElementChild.insertBefore(countEl, loggerLastElementChild.firstElementChild);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
__animateCue() {
|
__animateCue() {
|
||||||
const cueEl = this.shadowRoot.querySelector('.header__log-cue-overlay');
|
const cueEl = this.shadowRoot?.querySelector('.header__log-cue-overlay');
|
||||||
cueEl.classList.remove('header__log-cue-overlay--slide');
|
if (cueEl) {
|
||||||
// This triggers browser to stop batching changes because it has to evaluate something.
|
cueEl.classList.remove('header__log-cue-overlay--slide');
|
||||||
// eslint-disable-next-line no-void
|
// This triggers browser to stop batching changes because it has to evaluate something.
|
||||||
void this.offsetWidth;
|
// eslint-disable-next-line no-void
|
||||||
// So that when we arrive here, the browser sees this adding as an actual 'change'
|
void this.offsetWidth;
|
||||||
// and this means the animation gets refired.
|
// So that when we arrive here, the browser sees this adding as an actual 'change'
|
||||||
cueEl.classList.add('header__log-cue-overlay--slide');
|
// and this means the animation gets refired.
|
||||||
|
cueEl.classList.add('header__log-cue-overlay--slide');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
__clearLogs() {
|
__clearLogs() {
|
||||||
const loggerEl = this.shadowRoot.querySelector('.logger');
|
const loggerEl = this.shadowRoot?.querySelector('.logger');
|
||||||
loggerEl.innerHTML = '';
|
if (loggerEl) {
|
||||||
this.__logCounter = 0;
|
loggerEl.innerHTML = '';
|
||||||
|
this.__logCounter = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,25 @@
|
||||||
import { expect, fixture, html } from '@open-wc/testing';
|
import { expect, fixture as _fixture, html } from '@open-wc/testing';
|
||||||
import '../../sb-action-logger.js';
|
import '../../sb-action-logger.js';
|
||||||
|
|
||||||
// Note: skips are left out of first iteration
|
/**
|
||||||
|
* @typedef {import('../src/SbActionLogger').SbActionLogger} SbActionLogger
|
||||||
|
* @typedef {import('lit-html').TemplateResult} TemplateResult
|
||||||
|
*/
|
||||||
|
const fixture = /** @type {(arg: TemplateResult|string) => Promise<SbActionLogger>} */ (_fixture);
|
||||||
|
|
||||||
describe('sb-action-logger', () => {
|
describe('sb-action-logger', () => {
|
||||||
it('has a default title "Action Logger"', async () => {
|
it('has a default title "Action Logger"', async () => {
|
||||||
const el = await fixture(html`<sb-action-logger></sb-action-logger>`);
|
const el = await fixture(html`<sb-action-logger></sb-action-logger>`);
|
||||||
|
const titleEl = /** @type {HTMLElement} */ (el.shadowRoot?.querySelector('.header__title'));
|
||||||
|
|
||||||
expect(el.shadowRoot.querySelector('.header__title').innerText).to.equal('Action Logger');
|
expect(titleEl.innerText).to.equal('Action Logger');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('has a title property / attribute that can be overridden', async () => {
|
it('has a title property / attribute that can be overridden', async () => {
|
||||||
const el = await fixture(html`
|
const el = await fixture(html`
|
||||||
<sb-action-logger title="Logging your favorite fruit"></sb-action-logger>
|
<sb-action-logger title="Logging your favorite fruit"></sb-action-logger>
|
||||||
`);
|
`);
|
||||||
|
const titleEl = /** @type {HTMLElement} */ (el.shadowRoot?.querySelector('.header__title'));
|
||||||
const titleEl = el.shadowRoot.querySelector('.header__title');
|
|
||||||
|
|
||||||
expect(titleEl.innerText).to.equal('Logging your favorite fruit');
|
expect(titleEl.innerText).to.equal('Logging your favorite fruit');
|
||||||
});
|
});
|
||||||
|
|
@ -26,10 +30,10 @@ describe('sb-action-logger', () => {
|
||||||
|
|
||||||
el.log('Hello, World!');
|
el.log('Hello, World!');
|
||||||
|
|
||||||
const loggerEl = el.shadowRoot.querySelector('.logger');
|
const loggerEl = /** @type {HTMLElement} */ (el.shadowRoot?.querySelector('.logger'));
|
||||||
|
const loggerFirstEntryEl = /** @type {HTMLElement} */ (loggerEl.firstElementChild);
|
||||||
expect(loggerEl.children.length).to.equal(1);
|
expect(loggerEl.children.length).to.equal(1);
|
||||||
expect(loggerEl.firstElementChild.innerText).to.equal('Hello, World!');
|
expect(loggerFirstEntryEl.innerText).to.equal('Hello, World!');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('appends new logs to the logger', async () => {
|
it('appends new logs to the logger', async () => {
|
||||||
|
|
@ -41,7 +45,7 @@ describe('sb-action-logger', () => {
|
||||||
el.log('Hello, World!');
|
el.log('Hello, World!');
|
||||||
el.log('Hello, Planet!');
|
el.log('Hello, Planet!');
|
||||||
|
|
||||||
const loggerEl = el.shadowRoot.querySelector('.logger');
|
const loggerEl = /** @type {HTMLElement} */ (el.shadowRoot?.querySelector('.logger'));
|
||||||
|
|
||||||
expect(loggerEl.children.length).to.equal(5);
|
expect(loggerEl.children.length).to.equal(5);
|
||||||
});
|
});
|
||||||
|
|
@ -49,7 +53,9 @@ describe('sb-action-logger', () => {
|
||||||
it('shows a visual cue whenever something is logged to the logger', async () => {
|
it('shows a visual cue whenever something is logged to the logger', async () => {
|
||||||
const el = await fixture(html`<sb-action-logger></sb-action-logger>`);
|
const el = await fixture(html`<sb-action-logger></sb-action-logger>`);
|
||||||
|
|
||||||
const cueEl = el.shadowRoot.querySelector('.header__log-cue-overlay');
|
const cueEl = /** @type {HTMLElement} */ (el.shadowRoot?.querySelector(
|
||||||
|
'.header__log-cue-overlay',
|
||||||
|
));
|
||||||
expect(cueEl.classList.contains('header__log-cue-overlay--slide')).to.be.false;
|
expect(cueEl.classList.contains('header__log-cue-overlay--slide')).to.be.false;
|
||||||
|
|
||||||
el.log('Hello, World!');
|
el.log('Hello, World!');
|
||||||
|
|
@ -59,7 +65,9 @@ describe('sb-action-logger', () => {
|
||||||
it('has a visual counter that counts the amount of total logs', async () => {
|
it('has a visual counter that counts the amount of total logs', async () => {
|
||||||
const el = await fixture(html`<sb-action-logger></sb-action-logger>`);
|
const el = await fixture(html`<sb-action-logger></sb-action-logger>`);
|
||||||
|
|
||||||
const cueEl = el.shadowRoot.querySelector('.header__log-cue-overlay');
|
const cueEl = /** @type {HTMLElement} */ (el.shadowRoot?.querySelector(
|
||||||
|
'.header__log-cue-overlay',
|
||||||
|
));
|
||||||
|
|
||||||
expect(cueEl.classList.contains('.header__log-cue-overlay--slide')).to.be.false;
|
expect(cueEl.classList.contains('.header__log-cue-overlay--slide')).to.be.false;
|
||||||
|
|
||||||
|
|
@ -73,10 +81,10 @@ describe('sb-action-logger', () => {
|
||||||
el.log('Hello, World!');
|
el.log('Hello, World!');
|
||||||
el.log('Hello, Planet!');
|
el.log('Hello, Planet!');
|
||||||
|
|
||||||
const clearBtn = el.shadowRoot.querySelector('.header__clear');
|
const clearBtn = /** @type {HTMLElement} */ (el.shadowRoot?.querySelector('.header__clear'));
|
||||||
clearBtn.click();
|
clearBtn.click();
|
||||||
|
|
||||||
expect(el.shadowRoot.querySelector('.logger').children.length).to.equal(0);
|
expect(el.shadowRoot?.querySelector('.logger')?.children.length).to.equal(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('duplicate consecutive logs are kept as one, adds a visual counter', async () => {
|
it('duplicate consecutive logs are kept as one, adds a visual counter', async () => {
|
||||||
|
|
@ -90,33 +98,39 @@ describe('sb-action-logger', () => {
|
||||||
el.log('Hello, Planet!');
|
el.log('Hello, Planet!');
|
||||||
el.log('Hello, Planet!'); // 2 consecutive dupes
|
el.log('Hello, Planet!'); // 2 consecutive dupes
|
||||||
|
|
||||||
const loggerEl = el.shadowRoot.querySelector('.logger');
|
const loggerEl = /** @type {HTMLElement} */ (el.shadowRoot?.querySelector('.logger'));
|
||||||
|
|
||||||
const firstLog = loggerEl.firstElementChild;
|
const firstLogCount = /** @type {HTMLElement} */ (loggerEl.firstElementChild?.querySelector(
|
||||||
const lastLog = loggerEl.lastElementChild;
|
'.logger__log-count',
|
||||||
|
));
|
||||||
|
const lastLogCount = /** @type {HTMLElement} */ (loggerEl.lastElementChild?.querySelector(
|
||||||
|
'.logger__log-count',
|
||||||
|
));
|
||||||
|
|
||||||
expect(loggerEl.children.length).to.equal(4);
|
expect(loggerEl.children.length).to.equal(4);
|
||||||
expect(firstLog.querySelector('.logger__log-count').innerText).to.equal('3');
|
expect(firstLogCount.innerText).to.equal('3');
|
||||||
expect(lastLog.querySelector('.logger__log-count').innerText).to.equal('2');
|
expect(lastLogCount.innerText).to.equal('2');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can be set to simple mode for only showing a single log statement', async () => {
|
it('can be set to simple mode for only showing a single log statement', async () => {
|
||||||
const el = await fixture(html`<sb-action-logger simple></sb-action-logger>`);
|
const el = await fixture(html`<sb-action-logger simple></sb-action-logger>`);
|
||||||
el.log('Hello, World!');
|
el.log('Hello, World!');
|
||||||
const loggerEl = el.shadowRoot.querySelector('.logger');
|
const loggerEl = /** @type {HTMLElement} */ (el.shadowRoot?.querySelector('.logger'));
|
||||||
|
const loggerCountEl = loggerEl.firstElementChild?.querySelector('.logger__log-count');
|
||||||
|
const codeEl = /** @type {HTMLElement} */ (loggerEl.firstElementChild?.querySelector('code'));
|
||||||
|
|
||||||
expect(loggerEl.children.length).to.equal(1);
|
expect(loggerEl.children.length).to.equal(1);
|
||||||
expect(loggerEl.firstElementChild.querySelector('code').innerText).to.equal('Hello, World!');
|
expect(codeEl.innerText).to.equal('Hello, World!');
|
||||||
|
|
||||||
el.log('Hello, Earth!');
|
el.log('Hello, Earth!');
|
||||||
expect(loggerEl.children.length).to.equal(1);
|
expect(loggerEl.children.length).to.equal(1);
|
||||||
expect(loggerEl.firstElementChild.querySelector('code').innerText).to.equal('Hello, Earth!');
|
expect(codeEl.innerText).to.equal('Hello, Earth!');
|
||||||
|
|
||||||
el.log('Hello, Planet!');
|
el.log('Hello, Planet!');
|
||||||
el.log('Hello, Planet!');
|
el.log('Hello, Planet!');
|
||||||
expect(loggerEl.children.length).to.equal(1);
|
expect(loggerEl.children.length).to.equal(1);
|
||||||
expect(loggerEl.firstElementChild.querySelector('code').innerText).to.equal('Hello, Planet!');
|
expect(codeEl.innerText).to.equal('Hello, Planet!');
|
||||||
expect(loggerEl.firstElementChild.querySelector('.logger__log-count')).to.be.null;
|
expect(loggerCountEl).to.be.null;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,9 @@ export class SbLocaleSwitcher extends LitElement {
|
||||||
this.showLocales = ['en-GB', 'en-US', 'en-AU', 'nl-NL', 'nl-BE'];
|
this.showLocales = ['en-GB', 'en-US', 'en-AU', 'nl-NL', 'nl-BE'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} locale
|
||||||
|
*/
|
||||||
// eslint-disable-next-line class-methods-use-this
|
// eslint-disable-next-line class-methods-use-this
|
||||||
callback(locale) {
|
callback(locale) {
|
||||||
document.documentElement.lang = locale;
|
document.documentElement.lang = locale;
|
||||||
|
|
|
||||||
|
|
@ -12,10 +12,10 @@
|
||||||
* ]),
|
* ]),
|
||||||
* });
|
* });
|
||||||
*
|
*
|
||||||
* @param {array} orderPerDepth array of arrays giving the order of each level
|
* @param {Array.<[]>} orderPerDepth array of arrays giving the order of each level
|
||||||
*/
|
*/
|
||||||
export function sortEachDepth(orderPerDepth) {
|
export function sortEachDepth(orderPerDepth) {
|
||||||
return (a, b) => {
|
return (/** @type {Array.<?>} */ a, /** @type {Array.<?>} */ b) => {
|
||||||
// If the two stories have the same story kind, then use the default
|
// If the two stories have the same story kind, then use the default
|
||||||
// ordering, which is the order they are defined in the story file.
|
// ordering, which is the order they are defined in the story file.
|
||||||
if (a[1].kind === b[1].kind) {
|
if (a[1].kind === b[1].kind) {
|
||||||
|
|
@ -28,6 +28,7 @@ export function sortEachDepth(orderPerDepth) {
|
||||||
let nameB;
|
let nameB;
|
||||||
let indexA;
|
let indexA;
|
||||||
let indexB;
|
let indexB;
|
||||||
|
/** @type {Array.<?>} */
|
||||||
let ordering = orderPerDepth[0] || [];
|
let ordering = orderPerDepth[0] || [];
|
||||||
if (ordering.indexOf('...') !== -1 && ordering.indexOf('...abc') !== -1) {
|
if (ordering.indexOf('...') !== -1 && ordering.indexOf('...abc') !== -1) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
|
|
|
||||||
|
|
@ -27,10 +27,9 @@
|
||||||
"packages/remark-extend/**/*.js",
|
"packages/remark-extend/**/*.js",
|
||||||
"packages/select-rich/test/**/*.js", // TODO: Needs to get typed!
|
"packages/select-rich/test/**/*.js", // TODO: Needs to get typed!
|
||||||
"packages/overlays/test/utils-tests/**/*.js", // TODO: Needs to get typed!
|
"packages/overlays/test/utils-tests/**/*.js", // TODO: Needs to get typed!
|
||||||
"packages/helpers/**/*.js", // FIXME: Needs to get typed!
|
|
||||||
"packages/form-integrations/test/**/*.js", // TODO: Needs to get typed!
|
"packages/form-integrations/test/**/*.js", // TODO: Needs to get typed!
|
||||||
"packages/combobox/test/**/*.js", // TODO: Needs to get typed!
|
"packages/combobox/test/**/*.js", // TODO: Needs to get typed!
|
||||||
"packages/ajax/**/*.js", // FIXME: Needs to get typed!
|
"packages/ajax/**/*.js", // Deprecated because we will move to redaxios soon.
|
||||||
// ignore test/demos for singleton manager until overlays are typed as it's used in there
|
// ignore test/demos for singleton manager until overlays are typed as it's used in there
|
||||||
"packages/singleton-manager/demo/",
|
"packages/singleton-manager/demo/",
|
||||||
"packages/singleton-manager/test/"
|
"packages/singleton-manager/test/"
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue