diff --git a/karma.conf.js b/karma.conf.js index 61bff4482..00921513f 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -12,7 +12,7 @@ module.exports = config => { // npm run test -- --grep test/foo/bar.test.js // npm run test -- --grep test/bar/* { - pattern: config.grep ? config.grep : 'packages/*/test/**/*.test.js', + pattern: config.grep ? config.grep : 'packages/**/*/test/**/*.test.js', type: 'module', }, ], diff --git a/packages/helpers/sb-action-logger/src/SbActionLogger.js b/packages/helpers/sb-action-logger/src/SbActionLogger.js index 80595a9d7..e9404d834 100644 --- a/packages/helpers/sb-action-logger/src/SbActionLogger.js +++ b/packages/helpers/sb-action-logger/src/SbActionLogger.js @@ -21,6 +21,8 @@ export class SbActionLogger extends LitElement { box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2); display: block; + font-family: 'Nunito Sans', -apple-system, '.SFNSText-Regular', 'San Francisco', + BlinkMacSystemFont, 'Segoe UI', 'Helvetica Neue', Helvetica, Arial, sans-serif; } .header__info { @@ -88,6 +90,7 @@ export class SbActionLogger extends LitElement { .logger__log { padding: 16px; + display: flex; } .logger__log:not(:last-child) { @@ -102,6 +105,16 @@ export class SbActionLogger extends LitElement { white-space: -o-pre-wrap; /* Opera 7 */ word-wrap: break-word; /* Internet Explorer 5.5+ */ } + + .logger__log-count { + line-height: 8px; + font-size: 12px; + padding: 4px; + border-radius: 4px; + margin-right: 8px; + color: white; + background-color: #777; + } `; } @@ -111,6 +124,10 @@ export class SbActionLogger extends LitElement { this.__logCounter = 0; } + get loggerEl() { + return this.shadowRoot.querySelector('.logger'); + } + /** * Renders the passed content as a node, and appends it to the logger * Only supports simple values, will be interpreted to a String @@ -119,14 +136,15 @@ export class SbActionLogger extends LitElement { * @param {} content Content to be logged to the action logger */ log(content) { - const loggerEl = this.shadowRoot.querySelector('.logger'); - const offlineRenderContainer = document.createElement('div'); - render(this._logTemplate(content), offlineRenderContainer); - // TODO: Feature, combine duplicate consecutive logs as 1 dom element and add a counter for dupes - loggerEl.appendChild(offlineRenderContainer.firstElementChild); - this.__logCounter += 1; + if (this.__isConsecutiveDuplicateLog(content)) { + this.__handleConsecutiveDuplicateLog(); + } else { + this.__appendLog(content); + this.loggerEl.scrollTo({ top: this.loggerEl.scrollHeight, behavior: 'smooth' }); + } + + this.__logCounter += 1; // increment total log counter this.__animateCue(); - loggerEl.scrollTo({ top: loggerEl.scrollHeight, behavior: 'smooth' }); } /** @@ -143,6 +161,60 @@ export class SbActionLogger extends LitElement { `; } + render() { + return html` +
+
+

${this.title}

+
${this.__logCounter}
+ +
+
+
+
+
+
+ `; + } + + __appendLog(content) { + const offlineRenderContainer = document.createElement('div'); + render(this._logTemplate(content), offlineRenderContainer); + this.loggerEl.appendChild(offlineRenderContainer.firstElementChild); + } + + __isConsecutiveDuplicateLog(content) { + if ( + this.loggerEl.lastElementChild && + this.loggerEl.lastElementChild.querySelector('code').textContent.trim() === content + ) { + return true; + } + return false; + } + + __handleConsecutiveDuplicateLog() { + if (!this.loggerEl.lastElementChild.querySelector('.logger__log-count')) { + this.__prependLogCounterElement(); + } + + // Increment log counter for these duplicate logs + const logCounter = this.loggerEl.lastElementChild.querySelector('.logger__log-count'); + let incrementedLogCount = logCounter.textContent; + incrementedLogCount = parseInt(incrementedLogCount, 10) + 1; + logCounter.innerText = incrementedLogCount; + } + + __prependLogCounterElement() { + const countEl = document.createElement('div'); + countEl.classList.add('logger__log-count'); + countEl.innerText = 1; + this.loggerEl.lastElementChild.insertBefore( + countEl, + this.loggerEl.lastElementChild.firstElementChild, + ); + } + __animateCue() { const cueEl = this.shadowRoot.querySelector('.header__log-cue-overlay'); cueEl.classList.remove('header__log-cue-overlay--slide'); @@ -159,20 +231,4 @@ export class SbActionLogger extends LitElement { loggerEl.innerHTML = ''; this.__logCounter = 0; } - - render() { - return html` -
-
-

${this.title}

-
${this.__logCounter}
- -
-
-
-
-
-
- `; - } } diff --git a/packages/helpers/sb-action-logger/stories/index.stories.mdx b/packages/helpers/sb-action-logger/stories/index.stories.mdx index 9f59c9a40..071d09a28 100644 --- a/packages/helpers/sb-action-logger/stories/index.stories.mdx +++ b/packages/helpers/sb-action-logger/stories/index.stories.mdx @@ -24,18 +24,18 @@ A visual element to show action logs in Storybook demos `sb-action-logger` {() => { const uid = Math.random().toString(36).substr(2, 10); return html` -
To log: Hello, World!
+
Or to log: What's up, Planet!
+ `; }} diff --git a/packages/helpers/sb-action-logger/test/sb-action-logger.test.js b/packages/helpers/sb-action-logger/test/sb-action-logger.test.js index 80a7a45e8..6aa0a2d8b 100644 --- a/packages/helpers/sb-action-logger/test/sb-action-logger.test.js +++ b/packages/helpers/sb-action-logger/test/sb-action-logger.test.js @@ -91,22 +91,31 @@ describe('sb-action-logger', () => { expect(el.shadowRoot.querySelector('.logger').children.length).to.equal(0); }); - it('duplicate consecutive logs are kept as one', async () => { + it('duplicate consecutive logs are kept as one, adds a visual counter', async () => { const el = await fixture(html` `); - expect(el).to.be.true; + + el.log('Hello, World!'); + el.log('Hello, World!'); + el.log('Hello, World!'); // 3 consecutive dupes + el.log('Hello, Earth!'); + el.log('Hello, World!'); + el.log('Hello, Planet!'); + el.log('Hello, Planet!'); // 2 consecutive dupes + + const loggerEl = el.shadowRoot.querySelector('.logger'); + + const firstLog = loggerEl.firstElementChild; + const lastLog = loggerEl.lastElementChild; + + expect(loggerEl.children.length).to.equal(4); + expect(firstLog.querySelector('.logger__log-count').innerText).to.equal('3'); + expect(lastLog.querySelector('.logger__log-count').innerText).to.equal('2'); }); }); describe('Potential Additional Features', () => { - it.skip('duplicate consecutive adds a visual counter to count per duplicate', async () => { - const el = await fixture(html` - - `); - expect(el).to.be.true; - }); - // This is handy if you don't want to keep track of updates it.skip('can be set to mode=simple for only showing a single log statement', async () => { const el = await fixture(html`