diff --git a/app/components/stepper.hbs b/app/components/stepper.hbs new file mode 100644 index 00000000..a3c0fc00 --- /dev/null +++ b/app/components/stepper.hbs @@ -0,0 +1,26 @@ +{{#if this.arePropsValid}} +
+
+
+ {{#each this.numberOfSteps as |_ index|}} +
+ {{#if (eq index this.parsedCompletedSteps)}} + + + + + {{else if + (lt index this.parsedCompletedSteps) + }} + + + + + {{/if}} +
+ {{/each}} +
+
+{{/if}} \ No newline at end of file diff --git a/app/components/stepper.js b/app/components/stepper.js new file mode 100644 index 00000000..ec053621 --- /dev/null +++ b/app/components/stepper.js @@ -0,0 +1,17 @@ +import Component from '@glimmer/component'; + +export default class StepperComponent extends Component { + get arePropsValid() { + const { totalSteps, completedSteps } = this.args; + return !isNaN(totalSteps) && !isNaN(completedSteps) && totalSteps > 0; + } + + get numberOfSteps() { + const times = Number.parseInt(this.args.totalSteps, 10); + return new Array(times); + } + + get parsedCompletedSteps() { + return parseInt(this.args.completedSteps, 10); + } +} diff --git a/app/helpers/getStepperStepDataTestSelector.js b/app/helpers/getStepperStepDataTestSelector.js new file mode 100644 index 00000000..6e90a345 --- /dev/null +++ b/app/helpers/getStepperStepDataTestSelector.js @@ -0,0 +1,13 @@ +import { helper } from '@ember/component/helper'; + +function getStepperStepDataTestSelector([index], { completedSteps }) { + if (index < completedSteps) { + return 'completed'; + } else if (index === completedSteps) { + return 'active'; + } else { + return 'idle'; + } +} + +export default helper(getStepperStepDataTestSelector); diff --git a/app/styles/stepper.css b/app/styles/stepper.css new file mode 100644 index 00000000..d056674e --- /dev/null +++ b/app/styles/stepper.css @@ -0,0 +1,36 @@ +.stepper { + text-align: center; +} + +.stepper-progress--container { + display: flex; + justify-content: space-between; + position: relative; +} + +.progress { + background-color: var(--line-border-fill); + position: absolute; + top: 50%; + left: 0; + transform: translateY(-50%); + height: 4px; + width: 100%; + z-index: 1; + transition: 0.4s ease; +} + +.stepper__step { + background-color: #fff; + color: #999; + border-radius: 50%; + height: 20px; + width: 20px; + display: flex; + align-items: center; + justify-content: center; + border: 1px solid var(--line-border-empty); + border-color: var(--line-border-fill); + transition: 0.4s ease; + z-index: 2; +} diff --git a/app/styles/variables.css b/app/styles/variables.css index c33efa34..4cba2a10 100644 --- a/app/styles/variables.css +++ b/app/styles/variables.css @@ -173,6 +173,9 @@ --placeholder-text-color: grey; + --line-border-fill: #1d1283; + --line-border-empty: #e0e0e0; + --profile-field-input-bg-clr: #f9fafb; --profile-field-input-border-clr: #d1d5db; --profile-input-outline-clr: #1c64f2; diff --git a/tests/integration/components/stepper-test.js b/tests/integration/components/stepper-test.js new file mode 100644 index 00000000..539226a4 --- /dev/null +++ b/tests/integration/components/stepper-test.js @@ -0,0 +1,58 @@ +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'ember-qunit'; +import { render } from '@ember/test-helpers'; +import { hbs } from 'ember-cli-htmlbars'; + +module('Integration | Component | stepper', (hooks) => { + setupRenderingTest(hooks); + + test('it not renders the stepper component when no props passed', async function (assert) { + await render(hbs``); + + assert.dom('[data-test-stepper]').doesNotExist(); + }); + + test('it renders the stepper component without completed steps', async function (assert) { + this.setProperties({ + totalSteps: 5, + completedSteps: 0, + }); + + await render( + hbs`` + ); + + assert.dom('[data-test-stepper]').exists(); + assert + .dom('[data-test-stepper-step="active"]') + .exists({ count: 1 }, 'Active Step present on step-1 in the stepper'); + assert + .dom('[data-test-stepper-step="completed"]') + .exists({ count: 0 }, 'No Cleared Steps present in the stepper'); + }); + + test('it renders the stepper component with completed steps', async function (assert) { + this.setProperties({ + totalSteps: 5, + completedSteps: 2, + }); + + await render( + hbs`` + ); + + assert.dom('[data-test-stepper]').exists(); + assert + .dom('[data-test-stepper-step="active"]') + .exists({ count: 1 }, 'Active Step present on step-3 in the stepper'); + assert + .dom('[data-test-stepper-step="completed"]') + .exists({ count: 2 }, 'Two Cleared Steps present in the stepper'); + }); +});