fix(steps): fire enter event for initial step

This commit is contained in:
Thomas Allmer 2019-11-01 17:00:55 +01:00 committed by Thomas Allmer
parent ad5b7d0bcf
commit a05b52e938
4 changed files with 40 additions and 46 deletions

View file

@ -100,30 +100,12 @@ export class LionStep extends LionLitElement {
firstUpdated() { firstUpdated() {
super.firstUpdated(); super.firstUpdated();
this.controller = this.parentNode; this.controller = this.parentNode;
if (this.initialStep === true) {
this.enter(true);
}
} }
getControllerIndex() { enter() {
const { steps } = this.controller;
for (let i = 0; i < steps.length; i += 1) {
if (steps[i] === this) {
return i;
}
}
return 0;
}
enter(updateController) {
this.status = 'entered'; this.status = 'entered';
if (updateController === true) {
this.controller.current = this.getControllerIndex();
// controller will trigger enter() again which will dispatch the enter event
} else {
this.dispatchEvent(new CustomEvent('enter', { bubbles: true, composed: true })); this.dispatchEvent(new CustomEvent('enter', { bubbles: true, composed: true }));
} }
}
leave() { leave() {
this.status = 'left'; this.status = 'left';

View file

@ -64,6 +64,17 @@ export class LionSteps extends ObserverMixin(LionLitElement) {
firstUpdated() { firstUpdated() {
super.firstUpdated(); super.firstUpdated();
this._max = this.steps.length - 1; this._max = this.steps.length - 1;
let hasInitial = false;
this.steps.forEach((step, i) => {
if (step.initialStep && i !== 0) {
this.current = i;
hasInitial = true;
}
});
if (!hasInitial) {
this.steps[0].enter();
}
} }
next() { next() {

View file

@ -1,4 +1,4 @@
import { expect, fixture, fixtureSync, html, oneEvent } from '@open-wc/testing'; import { expect, fixture, html, oneEvent } from '@open-wc/testing';
import '../lion-step.js'; import '../lion-step.js';
@ -35,30 +35,6 @@ describe('lion-step', () => {
expect(el.children[0].passesCondition()).to.equal(false); expect(el.children[0].passesCondition()).to.equal(false);
}); });
it('allows to define it as the initial-step', async () => {
const el = fixtureSync(html`
<fake-lion-steps>
<lion-step initial-step>Step 1</lion-step>
</fake-lion-steps>
`);
el.steps = [el.children[0]];
await el.updateComplete;
expect(el.current).to.equal(0);
expect(el.children[0].status).to.equal('entered');
const el2 = fixtureSync(html`
<fake-lion-steps>
<lion-step>Step 1</lion-step>
<lion-step initial-step>Step 2</lion-step>
</fake-lion-steps>
`);
el2.steps = [el2.children[0], el2.children[1]];
await el2.updateComplete;
expect(el2.current).to.equal(1);
expect(el2.children[0].status).to.equal('untouched');
expect(el2.children[1].status).to.equal('entered');
});
it('has "untouched" status by default', async () => { it('has "untouched" status by default', async () => {
const el = await fixture(html` const el = await fixture(html`
<fake-lion-steps> <fake-lion-steps>

View file

@ -1,5 +1,5 @@
import sinon from 'sinon'; import sinon from 'sinon';
import { expect, fixture, html, oneEvent } from '@open-wc/testing'; import { expect, fixture, html, oneEvent, nextFrame } from '@open-wc/testing';
import '../lion-steps.js'; import '../lion-steps.js';
import '../lion-step.js'; import '../lion-step.js';
@ -130,6 +130,7 @@ describe('lion-steps', () => {
<lion-step>Step 4</lion-step> <lion-step>Step 4</lion-step>
</lion-steps> </lion-steps>
`); `);
await nextFrame();
el.current = 2; el.current = 2;
await checkWorkflow(el, { await checkWorkflow(el, {
@ -191,6 +192,30 @@ describe('lion-steps', () => {
expect(currentInEnterEvent).to.equal(1); expect(currentInEnterEvent).to.equal(1);
}); });
it('will fire initial @enter event on first step with or with [initial-step] attribute', async () => {
const firstEnterSpy = sinon.spy();
await fixture(html`
<lion-steps>
<lion-step @enter=${firstEnterSpy}>
<div>test1</div>
</lion-step>
</lion-steps>
`);
await nextFrame();
expect(firstEnterSpy).to.have.been.calledOnce;
const firstEnterSpyWithInitial = sinon.spy();
await fixture(html`
<lion-steps>
<lion-step initial-step @enter=${firstEnterSpyWithInitial}>
<div>test1</div>
</lion-step>
</lion-steps>
`);
await nextFrame();
expect(firstEnterSpyWithInitial).to.have.been.calledOnce;
});
it('will fire initial @enter event only once if [initial-step] is not on first step', async () => { it('will fire initial @enter event only once if [initial-step] is not on first step', async () => {
const firstEnterSpy = sinon.spy(); const firstEnterSpy = sinon.spy();
const secondEnterSpy = sinon.spy(); const secondEnterSpy = sinon.spy();