diff --git a/CHANGELOG.md b/CHANGELOG.md
index 12ec37eef84..4f326bbdc78 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,21 @@ All notable changes for each version of this project will be documented in this
## 13.0.0
### New Features
+- Added `IgxStepper` component
+ - Highly customizable component that visualizes content as a process and shows its progress by dividing the content into chronological `igx-steps`.
+ - Exposed API to control features like step validation, styling, orientation, and easy-to-use keyboard navigation.
+ - Code example below:
+
+ ```html
+
+
+ ...
+
+
+ ```
+
+ - For more information, check out the [README](https://github.com/IgniteUI/igniteui-angular/blob/master/projects/igniteui-angular/src/lib/stepper/README.md), [specification](https://github.com/IgniteUI/igniteui-angular/wiki/Stepper-Specification) and [official documentation](https://www.infragistics.com/products/ignite-ui-angular/angular/components/stepper).
+
- `IgxCsvExporterService`, `IgxExcelExporterService`
- Exporter services are no longer required to be provided in the application since they are now injected on a root level.
- `IgxGridToolbarPinningComponent`, `IgxGridToolbarHidingComponent`
@@ -34,7 +49,9 @@ All notable changes for each version of this project will be documented in this
Use `IgxGridToolbarComponent`, `IgxGridToolbarHidingComponent`, `IgxGridToolbarPinningComponent` instead.
- `IgxColumnActionsComponent`
- **Breaking Change** - The following input has been removed
- - Input `columns`. Use `igxGrid` `columns` input instead.
+ - Input `columns`. Use `igxGrid` `columns` input instead.
+- `IgxCarousel`
+ - **Breaking Changes** -The carousel animation type `CarouselAnimationType` is renamed to `HorizontalAnimationType`.
## 12.2.3
diff --git a/README.md b/README.md
index ad12d325d9f..5bca238553b 100644
--- a/README.md
+++ b/README.md
@@ -65,6 +65,7 @@ Some of the Angular chart types included are: [Polar chart](https://www.infragis
|select|:white_check_mark:|[Readme](https://github.com/IgniteUI/igniteui-angular/blob/master/projects/igniteui-angular/src/lib/select/README.md)|[Docs](https://www.infragistics.com/products/ignite-ui-angular/angular/components/select)|||||
|slider|:white_check_mark:|[Readme](https://github.com/IgniteUI/igniteui-angular/blob/master/projects/igniteui-angular/src/lib/slider/README.md)|[Docs](https://www.infragistics.com/products/ignite-ui-angular/angular/components/slider/slider)|||||
|snackbar|:white_check_mark:|[Readme](https://github.com/IgniteUI/igniteui-angular/blob/master/projects/igniteui-angular/src/lib/snackbar/README.md)|[Docs](https://www.infragistics.com/products/ignite-ui-angular/angular/components/snackbar)|||||
+|stepper|:white_check_mark:|[Readme](https://github.com/IgniteUI/igniteui-angular/blob/master/projects/igniteui-angular/src/lib/stepper/README.md)|[Docs](https://www.infragistics.com/products/ignite-ui-angular/angular/components/stepper)|
|switch|:white_check_mark:|[Readme](https://github.com/IgniteUI/igniteui-angular/blob/master/projects/igniteui-angular/src/lib/switch/README.md)|[Docs](https://www.infragistics.com/products/ignite-ui-angular/angular/components/switch)|||||
|tabs|:white_check_mark:|[Readme](https://github.com/IgniteUI/igniteui-angular/blob/master/projects/igniteui-angular/src/lib/tabs/tabs/README.md)|[Docs](https://www.infragistics.com/products/ignite-ui-angular/angular/components/tabs)|||||
|time picker|:white_check_mark:|[Readme](https://github.com/IgniteUI/igniteui-angular/blob/master/projects/igniteui-angular/src/lib/time-picker/README.md)|[Docs](https://www.infragistics.com/products/ignite-ui-angular/angular/components/time-picker)|||||
diff --git a/projects/igniteui-angular/migrations/migration-collection.json b/projects/igniteui-angular/migrations/migration-collection.json
index b00301e1fdc..b4206ea4131 100644
--- a/projects/igniteui-angular/migrations/migration-collection.json
+++ b/projects/igniteui-angular/migrations/migration-collection.json
@@ -105,6 +105,11 @@
"version": "12.1.0",
"description": "Updates Ignite UI for Angular from v11.1.x to v12.1.0",
"factory": "./update-12_1_0"
+ },
+ "migration-22": {
+ "version": "13.0.0",
+ "description": "Updates Ignite UI for Angular from v12.2.x to v13.0.0",
+ "factory": "./update-13_0_0"
}
}
}
diff --git a/projects/igniteui-angular/migrations/update-13_0_0/changes/classes.json b/projects/igniteui-angular/migrations/update-13_0_0/changes/classes.json
new file mode 100644
index 00000000000..ec58fda9821
--- /dev/null
+++ b/projects/igniteui-angular/migrations/update-13_0_0/changes/classes.json
@@ -0,0 +1,8 @@
+{
+ "$schema": "../../common/schema/class.schema.json",
+ "changes": [{
+ "name": "CarouselAnimationType",
+ "replaceWith": "HorizontalAnimationType"
+ }
+ ]
+}
diff --git a/projects/igniteui-angular/migrations/update-13_0_0/index.spec.ts b/projects/igniteui-angular/migrations/update-13_0_0/index.spec.ts
new file mode 100644
index 00000000000..f6e3398bf8b
--- /dev/null
+++ b/projects/igniteui-angular/migrations/update-13_0_0/index.spec.ts
@@ -0,0 +1,70 @@
+import * as path from 'path';
+
+import { EmptyTree } from '@angular-devkit/schematics';
+import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing';
+
+const version = '13.0.0';
+
+describe(`Update to ${version}`, () => {
+ let appTree: UnitTestTree;
+ const schematicRunner = new SchematicTestRunner('ig-migrate', path.join(__dirname, '../migration-collection.json'));
+ const configJson = {
+ defaultProject: 'testProj',
+ projects: {
+ testProj: {
+ sourceRoot: '/testSrc'
+ }
+ },
+ schematics: {
+ '@schematics/angular:component': {
+ prefix: 'appPrefix'
+ }
+ }
+ };
+
+ const migrationName = 'migration-22';
+
+ beforeEach(() => {
+ appTree = new UnitTestTree(new EmptyTree());
+ appTree.create('/angular.json', JSON.stringify(configJson));
+ });
+
+ it('should rename CarouselAnimationType to HorizontalAnimationType', async () => {
+ appTree.create(
+ '/testSrc/appPrefix/component/test.component.ts',
+ `import { Component, ViewChild } from '@angular/core';
+ import { CarouselAnimationType } from 'igniteui-angular';
+
+ @Component({
+ selector: 'animationType',
+ templateUrl: './test.component.html',
+ styleUrls: ['./test.component.scss']
+ })
+ export class AnimationType {
+ public animationType: CarouselAnimationType = CarouselAnimationType.slide;
+ }
+ `);
+ const tree = await schematicRunner
+ .runSchematicAsync(migrationName, {}, appTree)
+ .toPromise();
+
+ const expectedContent = `import { Component, ViewChild } from '@angular/core';
+ import { HorizontalAnimationType } from 'igniteui-angular';
+
+ @Component({
+ selector: 'animationType',
+ templateUrl: './test.component.html',
+ styleUrls: ['./test.component.scss']
+ })
+ export class AnimationType {
+ public animationType: HorizontalAnimationType = HorizontalAnimationType.slide;
+ }
+ `;
+
+ expect(
+ tree.readContent(
+ '/testSrc/appPrefix/component/test.component.ts'
+ )
+ ).toEqual(expectedContent);
+ });
+});
diff --git a/projects/igniteui-angular/migrations/update-13_0_0/index.ts b/projects/igniteui-angular/migrations/update-13_0_0/index.ts
new file mode 100644
index 00000000000..ab7fddb6b1c
--- /dev/null
+++ b/projects/igniteui-angular/migrations/update-13_0_0/index.ts
@@ -0,0 +1,11 @@
+import { Rule, SchematicContext, Tree } from '@angular-devkit/schematics';
+import { UpdateChanges } from '../common/UpdateChanges';
+
+const version = '13.0.0';
+
+export default (): Rule => (host: Tree, context: SchematicContext) => {
+ context.logger.info(`Applying migration for Ignite UI for Angular to version ${version}`);
+
+ const update = new UpdateChanges(__dirname, host, context);
+ update.applyChanges();
+};
diff --git a/projects/igniteui-angular/src/lib/carousel/README.md b/projects/igniteui-angular/src/lib/carousel/README.md
index 54d009d4a73..b1433017bc2 100644
--- a/projects/igniteui-angular/src/lib/carousel/README.md
+++ b/projects/igniteui-angular/src/lib/carousel/README.md
@@ -17,7 +17,7 @@ A walkthrough of how to get started can be found [here](https://www.infragistics
| `gesturesSupport` | boolean | Controls should the gestures should be supported. Defaults to `true`. |
| `maximumIndicatorsCount` | number | The number of visible indicators. Defaults to `5`. |
| `indicatorsOrientation` | CarouselIndicatorsOrientation | Controls whether the indicators should be previewed on top or on bottom of carousel. Defaults to `bottom`. |
-| `animationType` | CarouselAnimationType | Controls what animation should be played when slides are changing. Defaults to `slide`. |
+| `animationType` | HorizontalAnimationType | Controls what animation should be played when slides are changing. Defaults to `slide`. |
| `total` | number | The number of slides the carousel currently has. |
| `current` | number | The index of the slide currently showing. |
| `isPlaying` | boolean | Returns whether the carousel is paused/playing. |
diff --git a/projects/igniteui-angular/src/lib/carousel/carousel-base.ts b/projects/igniteui-angular/src/lib/carousel/carousel-base.ts
index 87f27b56c83..3de3a208164 100644
--- a/projects/igniteui-angular/src/lib/carousel/carousel-base.ts
+++ b/projects/igniteui-angular/src/lib/carousel/carousel-base.ts
@@ -1,16 +1,17 @@
import { AnimationBuilder, AnimationPlayer, AnimationReferenceMetadata, useAnimation } from '@angular/animations';
+import { EventEmitter } from '@angular/core';
import { fadeIn } from '../animations/fade';
import { slideInLeft } from '../animations/slide';
import { mkenum } from '../core/utils';
export enum Direction { NONE, NEXT, PREV }
-export const CarouselAnimationType = mkenum({
+export const HorizontalAnimationType = mkenum({
none: 'none',
slide: 'slide',
fade: 'fade'
});
-export type CarouselAnimationType = (typeof CarouselAnimationType)[keyof typeof CarouselAnimationType];
+export type HorizontalAnimationType = (typeof HorizontalAnimationType)[keyof typeof HorizontalAnimationType];
export interface CarouselAnimationSettings {
enterAnimation: AnimationReferenceMetadata;
@@ -26,7 +27,12 @@ export interface IgxSlideComponentBase {
/** @hidden */
export abstract class IgxCarouselComponentBase {
/** @hidden */
- public animationType = CarouselAnimationType.slide;
+ public animationType: HorizontalAnimationType = HorizontalAnimationType.slide;
+
+ /** @hidden @internal */
+ public enterAnimationDone = new EventEmitter();
+ /** @hidden @internal */
+ public leaveAnimationDone = new EventEmitter();
/** @hidden */
protected currentItem: IgxSlideComponentBase;
@@ -37,7 +43,7 @@ export abstract class IgxCarouselComponentBase {
/** @hidden */
protected leaveAnimationPlayer?: AnimationPlayer;
/** @hidden */
- protected animationDuration = 320;
+ protected defaultAnimationDuration = 320;
/** @hidden */
protected animationPosition = 0;
/** @hidden */
@@ -48,7 +54,7 @@ export abstract class IgxCarouselComponentBase {
/** @hidden */
protected triggerAnimations() {
- if (this.animationType !== CarouselAnimationType.none) {
+ if (this.animationType !== HorizontalAnimationType.none) {
if (this.animationStarted(this.leaveAnimationPlayer) || this.animationStarted(this.enterAnimationPlayer)) {
requestAnimationFrame(() => {
this.resetAnimations();
@@ -74,10 +80,12 @@ export abstract class IgxCarouselComponentBase {
private resetAnimations() {
if (this.animationStarted(this.leaveAnimationPlayer)) {
this.leaveAnimationPlayer.reset();
+ this.leaveAnimationDone.emit();
}
if (this.animationStarted(this.enterAnimationPlayer)) {
this.enterAnimationPlayer.reset();
+ this.enterAnimationDone.emit();
}
}
@@ -86,11 +94,11 @@ export abstract class IgxCarouselComponentBase {
if (this.newDuration) {
duration = this.animationPosition ? this.animationPosition * this.newDuration : this.newDuration;
} else {
- duration = this.animationPosition ? this.animationPosition * this.animationDuration : this.animationDuration;
+ duration = this.animationPosition ? this.animationPosition * this.defaultAnimationDuration : this.defaultAnimationDuration;
}
switch (this.animationType) {
- case CarouselAnimationType.slide:
+ case HorizontalAnimationType.slide:
const trans = this.animationPosition ? this.animationPosition * 100 : 100;
return {
enterAnimation: useAnimation(slideInLeft,
@@ -116,7 +124,7 @@ export abstract class IgxCarouselComponentBase {
}
})
};
- case CarouselAnimationType.fade:
+ case HorizontalAnimationType.fade:
return {
enterAnimation: useAnimation(fadeIn,
{ params: { duration: `${duration}ms`, startOpacity: `${this.animationPosition}` } }),
@@ -146,6 +154,7 @@ export abstract class IgxCarouselComponentBase {
this.animationPosition = 0;
this.newDuration = 0;
this.previousItem.previous = false;
+ this.enterAnimationDone.emit();
});
this.previousItem.previous = true;
this.enterAnimationPlayer.play();
@@ -167,6 +176,7 @@ export abstract class IgxCarouselComponentBase {
}
this.animationPosition = 0;
this.newDuration = 0;
+ this.leaveAnimationDone.emit();
});
this.leaveAnimationPlayer.play();
}
diff --git a/projects/igniteui-angular/src/lib/carousel/carousel.component.spec.ts b/projects/igniteui-angular/src/lib/carousel/carousel.component.spec.ts
index 59cf590d689..eddc5445e45 100644
--- a/projects/igniteui-angular/src/lib/carousel/carousel.component.spec.ts
+++ b/projects/igniteui-angular/src/lib/carousel/carousel.component.spec.ts
@@ -11,7 +11,7 @@ import { UIInteractions, wait } from '../test-utils/ui-interactions.spec';
import { configureTestSuite } from '../test-utils/configure-suite';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { IgxSlideComponent } from './slide.component';
-import { CarouselAnimationType } from './carousel-base';
+import { HorizontalAnimationType } from './carousel-base';
describe('Carousel', () => {
configureTestSuite();
@@ -589,7 +589,7 @@ describe('Carousel', () => {
await wait();
expect(carousel.get(0).active).toBeTruthy();
expect(carousel.get(0).nativeElement.classList.contains(HelperTestFunctions.ACTIVE_SLIDE_CLASS)).toBeTruthy();
- expect(carousel.animationType).toBe(CarouselAnimationType.slide);
+ expect(carousel.animationType).toBe(HorizontalAnimationType.slide);
carousel.next();
fixture.detectChanges();
await wait(200);
@@ -616,12 +616,12 @@ describe('Carousel', () => {
it('Test fade animation', async () => {
await wait();
- carousel.animationType = CarouselAnimationType.fade;
+ carousel.animationType = HorizontalAnimationType.fade;
fixture.detectChanges();
expect(carousel.get(0).active).toBeTruthy();
expect(carousel.get(0).nativeElement.classList.contains(HelperTestFunctions.ACTIVE_SLIDE_CLASS)).toBeTruthy();
- expect(carousel.animationType).toBe(CarouselAnimationType.fade);
+ expect(carousel.animationType).toBe(HorizontalAnimationType.fade);
carousel.next();
fixture.detectChanges();
await wait(200);
diff --git a/projects/igniteui-angular/src/lib/carousel/carousel.component.ts b/projects/igniteui-angular/src/lib/carousel/carousel.component.ts
index 1f1912c7677..d55a083864e 100644
--- a/projects/igniteui-angular/src/lib/carousel/carousel.component.ts
+++ b/projects/igniteui-angular/src/lib/carousel/carousel.component.ts
@@ -30,7 +30,7 @@ import { IgxSlideComponent } from './slide.component';
import { ICarouselResourceStrings } from '../core/i18n/carousel-resources';
import { CurrentResourceStrings } from '../core/i18n/resources';
import { HammerGestureConfig, HAMMER_GESTURE_CONFIG } from '@angular/platform-browser';
-import { CarouselAnimationType, Direction, IgxCarouselComponentBase } from './carousel-base';
+import { HorizontalAnimationType, Direction, IgxCarouselComponentBase } from './carousel-base';
let NEXT_ID = 0;
@@ -227,7 +227,7 @@ export class IgxCarouselComponent extends IgxCarouselComponentBase implements On
*
* @memberOf IgxSlideComponent
*/
- @Input() public animationType = CarouselAnimationType.slide;
+ @Input() public animationType: HorizontalAnimationType = HorizontalAnimationType.slide;
/**
* The custom template, if any, that should be used when rendering carousel indicators
@@ -647,18 +647,18 @@ export class IgxCarouselComponent extends IgxCarouselComponentBase implements On
this.incomingSlide.direction = event.deltaX < 0 ? Direction.NEXT : Direction.PREV;
this.incomingSlide.previous = false;
- this.animationPosition = this.animationType === CarouselAnimationType.fade ?
+ this.animationPosition = this.animationType === HorizontalAnimationType.fade ?
deltaX / slideWidth : (slideWidth - deltaX) / slideWidth;
if (velocity > 1) {
- this.newDuration = this.animationDuration / velocity;
+ this.newDuration = this.defaultAnimationDuration / velocity;
}
this.incomingSlide.active = true;
} else {
this.currentItem.direction = event.deltaX > 0 ? Direction.NEXT : Direction.PREV;
this.previousItem = this.incomingSlide;
this.previousItem.previous = true;
- this.animationPosition = this.animationType === CarouselAnimationType.fade ?
+ this.animationPosition = this.animationType === HorizontalAnimationType.fade ?
Math.abs((slideWidth - deltaX) / slideWidth) : deltaX / slideWidth;
this.playAnimations();
}
@@ -912,7 +912,7 @@ export class IgxCarouselComponent extends IgxCarouselComponentBase implements On
}
this.incomingSlide.previous = true;
- if (this.animationType === CarouselAnimationType.fade) {
+ if (this.animationType === HorizontalAnimationType.fade) {
this.currentItem.nativeElement.style.opacity = `${Math.abs(offset) / slideWidth}`;
} else {
this.currentItem.nativeElement.style.transform = `translateX(${deltaX}px)`;
diff --git a/projects/igniteui-angular/src/lib/core/styles/components/stepper/_stepper-component.scss b/projects/igniteui-angular/src/lib/core/styles/components/stepper/_stepper-component.scss
new file mode 100644
index 00000000000..64b13c6a917
--- /dev/null
+++ b/projects/igniteui-angular/src/lib/core/styles/components/stepper/_stepper-component.scss
@@ -0,0 +1,101 @@
+////
+/// @group components
+/// @author Marin Popov
+/// @requires {mixin} bem-block
+/// @requires {mixin} bem-elem
+/// @requires {mixin} bem-mod
+////
+@include b(igx-stepper) {
+ $block: bem--selector-to-string(&);
+ @include register-component($block);
+
+ @extend %stepper-display !optional;
+
+ @include e(header) {
+ @extend %igx-stepper__header !optional;
+ }
+
+ @include e(body) {
+ @extend %igx-stepper__body !optional;
+ }
+
+ @include e(step) {
+ @extend %igx-stepper__step !optional;
+ }
+
+ @include e(step, $m: simple) {
+ @extend %igx-stepper__step--simple !optional;
+ }
+
+ @include e(step, $m: completed) {
+ @extend %igx-stepper__step--completed !optional;
+ }
+
+ @include e(step, $m: disabled) {
+ @extend %igx-stepper__step--disabled !optional;
+ }
+
+ @include e(step-header) {
+ @extend %igx-stepper__step-header !optional;
+ }
+
+ @include e(step-header, $m: current) {
+ @extend %igx-stepper__step-header--current !optional;
+ }
+
+ @include e(step-header, $m: invalid) {
+ @extend %igx-stepper__step-header--invalid !optional;
+ }
+
+ @include e(step-content) {
+ @extend %igx-stepper__step-content !optional;
+ }
+
+ @include e(step-content-wrapper) {
+ @extend %igx-stepper__step-content-wrapper !optional;
+ }
+
+ @include e(step-indicator) {
+ @extend %igx-stepper__step-indicator !optional;
+ }
+
+ @include e(step-title-wrapper) {
+ @extend %igx-stepper__step-title-wrapper !optional;
+ }
+
+ @include e(step-title) {
+ @extend %igx-stepper__step-title !optional;
+ }
+
+ @include e(step-subtitle) {
+ @extend %igx-stepper__step-subtitle !optional;
+ }
+
+ @include e(step, $m: top) {
+ @extend %igx-stepper__step--top !optional;
+ }
+
+ @include e(step, $m: bottom) {
+ @extend %igx-stepper__step--bottom !optional;
+ }
+
+ @include e(step, $m: start) {
+ @extend %igx-stepper__step--start !optional;
+ }
+
+ @include e(step, $m: end) {
+ @extend %igx-stepper__step--end !optional;
+ }
+
+ @include m(horizontal) {
+ @extend %igx-stepper--horizontal !optional;
+
+ @include e(body-content) {
+ @extend %igx-stepper__body-content !optional;
+ }
+
+ @include e(body-content, $m: active) {
+ @extend %igx-stepper__body-content--active !optional;
+ }
+ }
+}
diff --git a/projects/igniteui-angular/src/lib/core/styles/components/stepper/_stepper-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/stepper/_stepper-theme.scss
new file mode 100644
index 00000000000..c1e0875b874
--- /dev/null
+++ b/projects/igniteui-angular/src/lib/core/styles/components/stepper/_stepper-theme.scss
@@ -0,0 +1,986 @@
+@use 'sass:math';
+
+////
+/// @group themes
+/// @access public
+/// @author Marin Popov
+////
+
+/// @param {Map} $palette [null] - The palette used as basis for styling the component.
+/// @param {Map} $schema [$light-schema] - The schema used as basis for styling the component.
+///
+/// @param {Color} $step-background [null] - The background of the step header.
+/// @param {Color} $step-hover-background [null] - The background of the step header on hover.
+/// @param {Color} $step-focus-background [null] - The background of the step header on focus.
+/// @param {Color} $title-color [null] - The color of the step title.
+/// @param {Color} $title-hover-color [null] - The color of the step title on hover.
+/// @param {Color} $title-focus-color [null] - The color of the step title on focus.
+/// @param {Color} $subtitle-color [null] - The color of the step subtitle.
+/// @param {Color} $subtitle-hover-color [null] - The color of the step subtitle on hover.
+/// @param {Color} $subtitle-focus-color [null] - The color of the step subtitle on focus.
+/// @param {Color} $indicator-color [null] - The text color of the step indicator.
+/// @param {Color} $indicator-background [null] - The background color of the step indicator.
+/// @param {Color} $indicator-outline [null] - The outline color of the step indicator.
+///
+/// @param {Color} $invalid-step-background [null] - The background of the invalid step header.
+/// @param {Color} $invalid-step-hover-background [null] - The background of the invalid step header on hover.
+/// @param {Color} $invalid-step-focus-background [null] - The background of the invalid step header on focus.
+/// @param {Color} $invalid-title-color [null] - The color of the invalid step title.
+/// @param {Color} $invalid-title-hover-color [null] - The color of the invalid step title on hover.
+/// @param {Color} $invalid-title-focus-color [null] - The color of the invalid step title on focus.
+/// @param {Color} $invalid-subtitle-color [null] - The color of the invalid step subtitle.
+/// @param {Color} $invalid-subtitle-hover-color [null] - The color of the invalid step subtitle on hover.
+/// @param {Color} $invalid-subtitle-focus-color [null] - The color of the invalid step subtitle on focus.
+/// @param {Color} $invalid-indicator-color [null] - The color of the invalid step indicator.
+/// @param {Color} $invalid-indicator-background [null] - The background color of the invalid step indicator.
+/// @param {Color} $invalid-indicator-outline [null] - The outline color of the invalid step indicator.
+///
+/// @param {Color} $current-step-background [null] - The background of the current step header.
+/// @param {Color} $current-step-hover-background [null] - The background of the current step header on hover.
+/// @param {Color} $current-step-focus-background [null] - The background of the current step header on focus.
+/// @param {Color} $current-title-color [null] - The color of the current step title.
+/// @param {Color} $current-title-hover-color [null] - The color of the current step title on hover.
+/// @param {Color} $current-title-focus-color [null] - The color of the current step title on focus.
+/// @param {Color} $current-subtitle-color [null] - The color of the current step subtitle.
+/// @param {Color} $current-subtitle-hover-color [null] - The color of the current step subtitle on hover.
+/// @param {Color} $current-subtitle-focus-color [null] - The color of the current step subtitle on focus.
+/// @param {Color} $current-indicator-color [null] - The color of the current step indicator.
+/// @param {Color} $current-indicator-background [null] - The background color of the current step indicator.
+/// @param {Color} $current-indicator-outline [null] - The outline color of the current step indicator.
+///
+/// @param {Color} $complete-step-background [null] - The background of the complete step header.
+/// @param {Color} $complete-step-hover-background [null] - The background of the complete step header on hover.
+/// @param {Color} $complete-step-focus-background [null] - The background of the complete step header on focus.
+/// @param {Color} $complete-title-color [null] - The color of the complete step title.
+/// @param {Color} $complete-title-hover-color [null] - The color of the complete step title on hover.
+/// @param {Color} $complete-title-focus-color [null] - The color of the complete step title on focus.
+/// @param {Color} $complete-subtitle-color [null] - The color of the complete step subtitle.
+/// @param {Color} $complete-subtitle-hover-color [null] - The color of the complete step subtitle on hover.
+/// @param {Color} $complete-subtitle-focus-color [null] - The color of the complete step subtitle on focus.
+/// @param {Color} $complete-indicator-color [null] - The color of the completed step indicator.
+/// @param {Color} $complete-indicator-background [null] - The background color of the completed step indicator.
+/// @param {Color} $complete-indicator-outline [null] - The outline color of the completed step indicator.
+///
+/// @param {Color} $disabled-title-color [null] - The title color of the disabled step.
+/// @param {Color} $disabled-subtitle-color [null] - The subtitle color of the disabled step.
+/// @param {Color} $disabled-indicator-color [null] - The indicator color of the disabled step.
+/// @param {Color} $disabled-indicator-background [null] - The indicator background of the disabled step.
+/// @param {Color} $disabled-indicator-outline [null] - The indicator outline color of the disabled step.
+///
+/// @param {Color} $step-separator-color [null] - The separator border-color of between the steps.
+/// @param {Color} $complete-step-separator-color [null] - The separator border-color between the completed steps.
+///
+/// @param {Color} $step-separator-style [null] - The separator border-style of between the steps.
+/// @param {Color} $complete-step-separator-style [null] - The separator border-style between the completed steps.
+///
+/// @param {Color} $border-radius-indicator [null] - The border-radius of the step indicator.
+/// @param {Color} $border-radius-step-header [null] - The border-radius of the step header.
+///
+/// @requires $default-palette
+/// @requires $light-schema
+/// @requires apply-palette
+/// @requires extend
+///
+/// @example scss Set custom track and thumb on colors
+/// $my-stepper-theme: igx-stepper-theme();
+/// @include igx-stepper($my-stepper-theme);
+///
+/// @example scss Set custom steppet colors
+/// $my-stepper-theme: igx-stepper-theme($step-hover-background: red);
+/// // Pass the theme to the igx-stepper component mixin
+/// @include igx-stepper($my-stepper-theme);
+@function igx-stepper-theme(
+ $palette: null,
+ $schema: $light-schema,
+
+ $step-background: null,
+ $step-hover-background: null,
+ $step-focus-background: null,
+
+ $invalid-step-background: null,
+ $invalid-step-hover-background: null,
+ $invalid-step-focus-background: null,
+
+ $current-step-background: null,
+ $current-step-hover-background: null,
+ $current-step-focus-background: null,
+
+ $complete-step-background: null,
+ $complete-step-hover-background: null,
+ $complete-step-focus-background: null,
+
+ // Incomplete
+ $indicator-color: null,
+ $indicator-background: null,
+ $indicator-outline: null,
+
+ $title-color: null,
+ $title-hover-color: null,
+ $title-focus-color: null,
+
+ $subtitle-color: null,
+ $subtitle-hover-color: null,
+ $subtitle-focus-color: null,
+
+ // Invalid
+ $invalid-indicator-color: null,
+ $invalid-indicator-background: null,
+ $invalid-indicator-outline: null,
+
+ $invalid-title-color: null,
+ $invalid-title-hover-color: null,
+ $invalid-title-focus-color: null,
+
+ $invalid-subtitle-color: null,
+ $invalid-subtitle-hover-color: null,
+ $invalid-subtitle-focus-color: null,
+
+ // Current
+ $current-indicator-color: null,
+ $current-indicator-background: null,
+ $current-indicator-outline: null,
+
+ $current-title-color: null,
+ $current-title-hover-color: null,
+ $current-title-focus-color: null,
+
+ $current-subtitle-color: null,
+ $current-subtitle-hover-color: null,
+ $current-subtitle-focus-color: null,
+
+ // complete
+ $complete-indicator-color: null,
+ $complete-indicator-background: null,
+ $complete-indicator-outline: null,
+
+ $complete-title-color: null,
+ $complete-title-hover-color: null,
+ $complete-title-focus-color: null,
+
+ $complete-subtitle-color: null,
+ $complete-subtitle-hover-color: null,
+ $complete-subtitle-focus-color: null,
+
+ // Disabled
+ $disabled-indicator-color: null,
+ $disabled-indicator-background: null,
+ $disabled-indicator-outline: null,
+ $disabled-title-color: null,
+ $disabled-subtitle-color: null,
+
+ // Separator
+ $step-separator-color: null,
+ $complete-step-separator-color: null,
+
+ $step-separator-style: null,
+ $complete-step-separator-style: null,
+
+ // Border-radius
+ $border-radius-indicator: null,
+ $border-radius-step-header: null,
+) {
+ $name: 'igx-stepper';
+ $stepper-schema: ();
+
+ @if map-has-key($schema, $name) {
+ $stepper-schema: map-get($schema, $name);
+ } @else {
+ $stepper-schema: $schema;
+ }
+
+ $theme: apply-palette($stepper-schema, $palette);
+
+ $border-radius-indicator: round-borders(
+ if($border-radius-indicator, $border-radius-indicator, map-get($stepper-schema, 'border-radius-indicator')), 0, 100px
+ );
+
+ $border-radius-step-header: round-borders(
+ if($border-radius-step-header, $border-radius-step-header, map-get($stepper-schema, 'border-radius-step-header')), 0, 100px
+ );
+
+ @if not($indicator-background) and $step-background {
+ $indicator-background: text-contrast($step-background);
+ }
+
+ @if not($indicator-color) and $indicator-background {
+ $indicator-color: text-contrast($indicator-background);
+ }
+
+ @if not($complete-indicator-color) and $complete-indicator-background {
+ $complete-indicator-color: text-contrast($complete-indicator-background);
+ }
+
+ @if not($invalid-indicator-color) and $invalid-indicator-background {
+ $invalid-indicator-color: text-contrast($invalid-indicator-background);
+ }
+
+ @if not($current-indicator-color) and $current-indicator-background {
+ $current-indicator-color: text-contrast($current-indicator-background);
+ }
+
+ @if not($title-color) and $step-background {
+ $title-color: text-contrast($step-background);
+ }
+
+ @if not($subtitle-color) and $step-background {
+ $subtitle-color: text-contrast($step-background);
+ }
+
+ @if not($title-hover-color) and $step-hover-background {
+ $title-hover-color: text-contrast($step-hover-background);
+ }
+
+ @if not($subtitle-hover-color) and $step-hover-background {
+ $subtitle-hover-color: text-contrast($step-hover-background);
+ }
+
+ @if not($title-focus-color) and $step-focus-background {
+ $title-focus-color: text-contrast($step-focus-background);
+ }
+
+ @if not($subtitle-focus-color) and $step-focus-background {
+ $subtitle-focus-color: text-contrast($step-focus-background);
+ }
+
+ @return extend($theme, (
+ name: $name,
+ palette: $palette,
+
+ // Incomplete
+ step-background: $step-background,
+ step-hover-background: $step-hover-background,
+ step-focus-background: $step-focus-background,
+ indicator-color: $indicator-color,
+ indicator-background: $indicator-background,
+ indicator-outline: $indicator-outline,
+ title-color: $title-color,
+ title-hover-color: $title-hover-color,
+ title-focus-color: $title-focus-color,
+ subtitle-color: $subtitle-color,
+ subtitle-hover-color: $subtitle-hover-color,
+ subtitle-focus-color: $subtitle-focus-color,
+
+ // Invalid
+ invalid-step-background: $invalid-step-background,
+ invalid-step-hover-background: $invalid-step-hover-background,
+ invalid-step-focus-background: $invalid-step-focus-background,
+ invalid-indicator-color: $invalid-indicator-color,
+ invalid-indicator-background: $invalid-indicator-background,
+ invalid-indicator-outline: $invalid-indicator-outline,
+ invalid-title-color: $invalid-title-color,
+ invalid-title-hover-color: $invalid-title-hover-color,
+ invalid-title-focus-color: $invalid-title-focus-color,
+ invalid-subtitle-color: $invalid-subtitle-color,
+ invalid-subtitle-hover-color: $invalid-subtitle-hover-color,
+ invalid-subtitle-focus-color: $invalid-subtitle-focus-color,
+
+ // Current
+ current-step-background: $current-step-background,
+ current-step-hover-background: $current-step-hover-background,
+ current-step-focus-background: $current-step-focus-background,
+ current-indicator-color: $current-indicator-color,
+ current-indicator-background: $current-indicator-background,
+ current-indicator-outline: $current-indicator-outline,
+ current-title-color: $current-title-color,
+ current-title-hover-color: $current-title-hover-color,
+ current-title-focus-color: $current-title-focus-color,
+ current-subtitle-color: $current-subtitle-color,
+ current-subtitle-hover-color: $current-subtitle-hover-color,
+ current-subtitle-focus-color: $current-subtitle-focus-color,
+
+ // Complete
+ complete-step-background: $complete-step-background,
+ complete-step-hover-background: $complete-step-hover-background,
+ complete-step-focus-background: $complete-step-focus-background,
+ complete-indicator-color: $complete-indicator-color,
+ complete-indicator-background: $complete-indicator-background,
+ complete-indicator-outline: $complete-indicator-outline,
+ complete-title-color: $complete-title-color,
+ complete-title-hover-color: $complete-title-hover-color,
+ complete-title-focus-color: $complete-title-focus-color,
+ complete-subtitle-color: $complete-subtitle-color,
+ complete-subtitle-hover-color: $complete-subtitle-hover-color,
+ complete-subtitle-focus-color: $complete-subtitle-focus-color,
+
+ // Disabled
+ disabled-indicator-color: $disabled-indicator-color,
+ disabled-indicator-background: $disabled-indicator-background,
+ disabled-indicator-outline: $disabled-indicator-outline,
+ disabled-title-color: $disabled-title-color,
+ disabled-subtitle-color: $disabled-subtitle-color,
+
+ // Separator
+ step-separator-color: $step-separator-color,
+ complete-step-separator-color: $complete-step-separator-color,
+ step-separator-style: $step-separator-style,
+ complete-step-separator-style: $complete-step-separator-style,
+
+ // Border-radius
+ border-radius-indicator: $border-radius-indicator,
+ border-radius-step-header: $border-radius-step-header,
+ ));
+}
+
+/// @param {Map} $theme - The theme used to style the component.
+/// @requires {mixin} igx-css-vars
+/// @requires em
+/// @requires --var
+@mixin igx-stepper($theme) {
+ @include igx-css-vars($theme);
+
+ $variant: map-get($theme, variant);
+
+ $indicator-size: map-get((
+ material: rem(24px),
+ fluent: rem(24px),
+ bootstrap: rem(40px),
+ indigo-design: rem(24px)
+ ), $variant);
+
+ $step-header-padding: map-get((
+ material: rem(24px),
+ fluent: rem(8px),
+ bootstrap: rem(24px),
+ indigo-design: rem(16px)
+ ), $variant);
+
+ $step-header-padding-simple: map-get((
+ material: rem(8px),
+ fluent: rem(8px),
+ bootstrap: rem(16px),
+ indigo-design: rem(8px)
+ ), $variant);
+
+ $step-body-padding: rem(16px);
+ $title-gap: rem(8px);
+ $indicator-gap: rem(4px);
+ $indicator-padding: rem(2px);
+ $v-line-indent: calc(#{$step-header-padding} + (#{$indicator-size} / 2));
+ $separator-position: 50%;
+
+ $outline-width: map-get((
+ material: rem(1px),
+ fluent: rem(1px),
+ bootstrap: rem(1px),
+ indigo-design: rem(2px)
+ ), $variant);
+
+ $separator-size: map-get((
+ material: rem(1px),
+ fluent: rem(1px),
+ bootstrap: rem(8px),
+ indigo-design: rem(2px)
+ ), $variant);
+
+ $separator-title-top: calc(100% - ((#{$indicator-size} / 2) + #{$step-header-padding} + (#{$separator-size} / 2)));
+ $separator-title-bottom: calc((#{$indicator-size} / 2) + #{$step-header-padding} - (#{$separator-size} / 2));
+
+ $left: if-ltr(left, right);
+ $right: if-ltr(right, left);
+
+ %stepper-display,
+ %igx-stepper__header,
+ %igx-stepper__body,
+ %igx-stepper__step {
+ display: flex;
+ }
+
+ %stepper-display {
+ flex-direction: column;
+ width: 100%;
+ }
+
+ %igx-stepper__header {
+ white-space: nowrap;
+ flex-direction: column;
+ width: 100%;
+ }
+
+ %igx-stepper__body {
+ position: relative
+ }
+
+ %stepper-display,
+ %igx-stepper__body,
+ %igx-stepper__step-header,
+ %igx-stepper__step-title-wrapper {
+ overflow: hidden;
+ }
+
+ %igx-stepper__step-title {
+ color: --var($theme, 'title-color');
+ }
+
+ %igx-stepper__step-subtitle {
+ color: --var($theme, 'subtitle-color');
+ }
+
+ %igx-stepper__step {
+ position: relative;
+ flex-direction: column;
+ align-content: center;
+ justify-content: center;
+ min-width: rem(100px);
+
+ &:focus {
+ outline: none;
+
+ %igx-stepper__step-title {
+ color: --var($theme, 'title-focus-color');
+ }
+
+ %igx-stepper__step-subtitle {
+ color: --var($theme, 'subtitle-focus-color');
+ }
+
+ %igx-stepper__step-header {
+ background: --var($theme, 'step-focus-background');
+ color: --var($theme, 'title-focus-color');
+
+ @if $variant == 'bootstrap' {
+ box-shadow: inset 0 0 0 $outline-width --var($theme, 'indicator-outline');
+ }
+ }
+
+ %igx-stepper__step-header--current {
+ background: --var($theme, 'current-step-focus-background') !important;
+
+ %igx-stepper__step-title {
+ color: --var($theme, 'current-title-focus-color');
+ }
+
+ %igx-stepper__step-subtitle {
+ color: --var($theme, 'current-subtitle-focus-color');
+ }
+ }
+
+ %igx-stepper__step-header--invalid {
+ background: --var($theme, 'invalid-step-focus-background');
+
+ %igx-stepper__step-title {
+ color: --var($theme, 'invalid-title-focus-color');
+ }
+
+ %igx-stepper__step-subtitle {
+ color: --var($theme, 'invalid-subtitle-focus-color');
+ }
+ }
+ }
+
+ &:first-of-type {
+ %igx-stepper__step-header {
+ &::before {
+ visibility: hidden;
+ }
+ }
+ }
+
+ &:last-of-type {
+ %igx-stepper__step-content-wrapper {
+ &::before {
+ display: none;
+ }
+ }
+
+ %igx-stepper__step-header {
+ &::after {
+ visibility: hidden;
+ }
+ }
+ }
+ }
+
+ %igx-stepper__step-header {
+ display: flex;
+ padding: $step-header-padding;
+ position: relative;
+ line-height: normal;
+ flex-direction: column;
+ align-items: flex-start;
+ gap: $title-gap;
+ cursor: pointer;
+ background: --var($theme, 'step-background');
+ border-radius: --var($theme, 'border-radius-step-header');
+
+ &:hover {
+ background: --var($theme, 'step-hover-background');
+ color: --var($theme, 'title-hover-color');
+ }
+
+ @if $variant != material {
+ .igx-ripple__inner {
+ display: none;
+ }
+ }
+ }
+
+ %igx-stepper__step-indicator {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ position: relative;
+ font-size: rem(12px);
+ height: $indicator-size;
+ width: $indicator-size;
+ white-space: nowrap;
+ border-radius: --var($theme, 'border-radius-indicator');
+ color: --var($theme, 'indicator-color');
+ background: --var($theme, 'indicator-background');
+ box-shadow: 0 0 0 $outline-width --var($theme, 'indicator-outline');
+
+ @if $variant != 'bootstrap' {
+ > igx-icon {
+ width: calc(#{$indicator-size} - #{rem(6px)});
+ height: calc(#{$indicator-size} - #{rem(6px)});
+ font-size: calc(#{$indicator-size} - #{rem(6px)});
+ color: inherit;
+ }
+ }
+
+ div > igx-icon,
+ div > igx-avatar,
+ div > igx-circular-bar {
+ max-height: $indicator-size;
+ max-width: $indicator-size;
+ }
+ }
+
+ %igx-stepper__step-header--current {
+ background: --var($theme, 'current-step-background') !important;
+ color: --var($theme, 'current-title-color');
+
+ %igx-stepper__step-indicator {
+ color: --var($theme, 'current-indicator-color') !important;
+ background: --var($theme, 'current-indicator-background') !important;
+ box-shadow: 0 0 0 $outline-width --var($theme, 'current-indicator-outline') !important;
+ }
+
+ %igx-stepper__step-title {
+ color: --var($theme, 'current-title-color');
+ }
+
+ %igx-stepper__step-subtitle {
+ color: --var($theme, 'current-subtitle-color');
+ }
+
+ &:hover {
+ background: --var($theme, 'current-step-hover-background') !important;
+
+ %igx-stepper__step-title {
+ color: --var($theme, 'current-title-hover-color');
+ }
+
+ %igx-stepper__step-subtitle {
+ color: --var($theme, 'current-subtitle-hover-color');
+ }
+ }
+ }
+
+ %igx-stepper__step--disabled {
+ color: --var($theme, 'disabled-title-color');
+ pointer-events: none;
+ cursor: default;
+
+ %igx-stepper__step-indicator {
+ color: --var($theme, 'disabled-indicator-color');
+ background: --var($theme, 'disabled-indicator-background');
+ box-shadow: 0 0 0 $outline-width --var($theme, 'disabled-indicator-outline');
+ }
+
+ %igx-stepper__step-title {
+ color: --var($theme, 'disabled-title-color');
+ }
+
+ %igx-stepper__step-subtitle {
+ color: --var($theme, 'disabled-subtitle-color');
+ }
+ }
+
+ %igx-stepper__step-header--invalid {
+ background: --var($theme, 'invalid-step-background');
+ color: --var($theme, 'invalid-title-color');
+
+ %igx-stepper__step-indicator {
+ color: --var($theme, 'invalid-indicator-color');
+ background: --var($theme, 'invalid-indicator-background');
+ box-shadow: 0 0 0 $outline-width --var($theme, 'invalid-indicator-outline');
+ }
+
+ %igx-stepper__step-title {
+ color: --var($theme, 'invalid-title-color');
+ }
+
+ %igx-stepper__step-subtitle {
+ color: --var($theme, 'invalid-subtitle-color');
+ }
+
+ &:hover {
+ background: --var($theme, 'invalid-step-hover-background');
+
+ %igx-stepper__step-title {
+ color: --var($theme, 'invalid-title-hover-color');
+ }
+
+ %igx-stepper__step-subtitle {
+ color: --var($theme, 'invalid-subtitle-hover-color');
+ }
+ }
+ }
+
+ %igx-stepper__body-content {
+ display: block;
+ position: absolute;
+ top: 0;
+ #{$left}: 0;
+ #{$right}: 0;
+ bottom: 0;
+ width: 100%;
+ height: 100%;
+ overflow-y: auto;
+ overflow-x: hidden;
+ z-index: -1;
+ }
+
+ %igx-stepper__step-content-wrapper,
+ %igx-stepper__body-content {
+ padding: $step-body-padding;
+ }
+
+ %igx-stepper__body-content--active {
+ z-index: 1;
+ position: relative;
+ }
+
+ %igx-stepper__step-content-wrapper {
+ margin-#{$left}: $v-line-indent;
+ position: relative;
+ min-height: rem(32px);
+
+ &::before {
+ content: '';
+ position: absolute;
+ #{$left}: calc(-#{$separator-size} / 2);
+ top: calc(-#{$step-header-padding} + #{$title-gap});
+ bottom: calc(-#{$step-header-padding} + #{$title-gap});
+ width: $separator-size;
+ border-#{$left}: $separator-size unquote(--var($theme, 'step-separator-style')) --var($theme, 'step-separator-color');
+ }
+ }
+
+ %igx-stepper__step-title-wrapper {
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ min-width: rem(32px);
+
+ &:empty {
+ display: none;
+ }
+
+ > * {
+ display: block;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ overflow: hidden;
+ }
+ }
+
+ %igx-stepper__step--start,
+ %igx-stepper__step--end {
+ %igx-stepper__step-header {
+ flex-direction: row;
+ align-items: center;
+ //gap: $title-gap--horizontal;
+ }
+ }
+
+ %igx-stepper__step--start,
+ %igx-stepper__step--top {
+ %igx-stepper__step-title-wrapper {
+ order: -1;
+ }
+ }
+
+ %igx-stepper__step--completed {
+
+ %igx-stepper__step-header {
+ background: --var($theme, 'complete-step-background');
+
+ &:hover {
+ background: --var($theme, 'complete-step-hover-background');
+ %igx-stepper__step-title {
+ color: --var($theme, 'complete-title-hover-color');
+ }
+
+ %igx-stepper__step-subtitle {
+ color: --var($theme, 'complete-subtitle-hover-color');
+ }
+ }
+
+ &::after {
+ border-top-color: --var($theme, 'complete-step-separator-color') !important;
+ border-top-style: unquote(--var($theme, 'complete-step-separator-style')) !important;
+ }
+ }
+
+ %igx-stepper__step-indicator {
+ color: --var($theme, 'complete-indicator-color');
+ background: --var($theme, 'complete-indicator-background');
+ box-shadow: 0 0 0 $outline-width --var($theme, 'complete-indicator-outline');
+ }
+
+ %igx-stepper__step-title {
+ color: --var($theme, 'complete-title-color');
+ }
+
+ %igx-stepper__step-subtitle {
+ color: --var($theme, 'complete-subtitle-color');
+ }
+
+ &:focus {
+ %igx-stepper__step-header {
+ background: --var($theme, 'complete-step-focus-background');
+
+ %igx-stepper__step-title {
+ color: --var($theme, 'complete-title-focus-color');
+ }
+
+ %igx-stepper__step-subtitle {
+ color: --var($theme, 'complete-subtitle-focus-color');
+ }
+ }
+ }
+
+ %igx-stepper__step-content-wrapper {
+ &::before {
+ border-#{$left}-style: unquote(--var($theme, 'complete-step-separator-style'));
+ border-#{$left}-color: --var($theme, 'complete-step-separator-color');
+ }
+ }
+ }
+
+ %igx-stepper__step--completed + %igx-stepper__step {
+ &::before {
+ border-top-color: --var($theme, 'complete-step-separator-color') !important;
+ border-top-style: unquote(--var($theme, 'complete-step-separator-style')) !important;
+ }
+
+ %igx-stepper__step-header {
+ &::before {
+ border-top-color: --var($theme, 'complete-step-separator-color') !important;
+ border-top-style: unquote(--var($theme, 'complete-step-separator-style')) !important;
+ }
+ }
+ }
+
+ %igx-stepper__step--simple {
+ %igx-stepper__step-indicator {
+ min-width: $indicator-size;
+ min-height: $indicator-size;
+ width: initial;
+ height: initial;
+
+ div > igx-icon,
+ div > igx-avatar,
+ div > igx-circular-bar {
+ max-width: initial;
+ max-height: initial;
+ }
+ }
+ }
+
+ // HORIZONTAL MODE START
+ %igx-stepper--horizontal {
+ %igx-stepper__header {
+ flex-direction: row;
+ }
+
+ %igx-stepper__step {
+ overflow: hidden;
+ flex-direction: row;
+ flex-grow: 1;
+
+ &::before {
+ content: '';
+ width: auto;
+ min-width: rem(10px);
+ height: $separator-size;
+ flex: 1;
+ position: relative;
+ top: $separator-title-bottom;
+ border-top: $separator-size unquote(--var($theme, 'step-separator-style')) --var($theme, 'step-separator-color');
+ }
+
+ &:first-of-type {
+ flex-grow: 0;
+ min-width: 0;
+
+ &::before {
+ display: none;
+ }
+ }
+ }
+
+ %igx-stepper__step-header {
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: center;
+
+ &::before,
+ &::after {
+ content: '';
+ position: absolute;
+ height: $separator-size;
+ width: calc(50% - (#{$indicator-size} - #{$indicator-gap}));
+ top: $separator-title-bottom;
+ flex: 1;
+ border-top: $separator-size unquote(--var($theme, 'step-separator-style')) --var($theme, 'step-separator-color');
+ }
+
+ &::before {
+ #{$left}: 0;
+ }
+
+ &::after {
+ #{$right}: 0;
+ }
+ }
+
+ %igx-stepper__step--simple {
+ text-align: center;
+
+ %igx-stepper__step-header {
+ align-self: center;
+ padding: $step-header-padding-simple;
+ height: auto;
+
+ &::before,
+ &::after {
+ display: none;
+ }
+ }
+
+ &%igx-stepper__step {
+ &::before {
+ top: calc(50% - (#{$separator-size} / 2));
+ }
+ }
+ }
+
+ %igx-stepper__step-title-wrapper {
+ width: 100%;
+ }
+
+ %igx-stepper__step--top {
+ %igx-stepper__step-header {
+ justify-content: flex-end;
+
+ &::before,
+ &::after {
+ top: $separator-title-top;
+ }
+ }
+
+ &%igx-stepper__step {
+ &::before {
+ border-top: $separator-size unquote(--var($theme, 'step-separator-style')) --var($theme, 'step-separator-color');
+ top: $separator-title-top;
+ }
+ }
+ }
+
+ %igx-stepper__step--bottom {
+ %igx-stepper__step-header {
+ justify-content: flex-start;
+ }
+ }
+
+ %igx-stepper__step--top,
+ %igx-stepper__step--bottom {
+ %igx-stepper__step-title-wrapper {
+ text-align: center;
+ }
+
+ %igx-stepper__step-header {
+ flex-direction: column;
+ }
+ }
+
+ %igx-stepper__step--start {
+ %igx-stepper__step-title-wrapper {
+ text-align: #{$right};
+ }
+ }
+
+ %igx-stepper__step--start,
+ %igx-stepper__step--end {
+ %igx-stepper__step-indicator {
+ flex: 1 0 auto;
+ }
+
+ %igx-stepper__step-header {
+ @if $variant != 'fluent' {
+ padding: calc(#{$step-header-padding} / 2);
+ }
+
+ &::before,
+ &::after {
+ display: none;
+ }
+ }
+
+ &%igx-stepper__step {
+ &::before {
+ top: calc(50% - (#{$separator-size} / 2));
+ }
+ }
+ }
+
+ %igx-stepper__step-content {
+ &:focus {
+ outline: none;
+ }
+
+ &::before {
+ display: none;
+ }
+ }
+
+ %igx-stepper__step-content-wrapper {
+ text-align: center;
+ }
+ }
+ // HORIZONTAL MODE END
+}
+
+/// Adds typography styles for the igx-stepper component.
+/// Uses the 'body-2' category from the typographic scale.
+/// @group typography
+/// @param {Map} $type-scale - A typographic scale as produced by igx-type-scale.
+/// @param {Map} $categories [(title: 'body-2')] - The categories from the typographic scale used for type styles.
+/// @requires {mixin} igx-type-style
+@mixin igx-stepper-typography($type-scale, $categories: (title: 'body-2', subtitle: 'caption')) {
+ $title: map-get($categories, 'title');
+ $subtitle: map-get($categories, 'subtitle');
+
+ %igx-stepper__step-title {
+ @include igx-type-style($type-scale, $title) {
+ margin-top: 0;
+ margin-bottom: 0;
+ }
+ }
+
+ %igx-stepper__step-subtitle {
+ @include igx-type-style($type-scale, $subtitle) {
+ margin-top: 0;
+ margin-bottom: 0;
+ }
+ }
+
+ %igx-stepper__step-header--current {
+ %igx-stepper__step-title {
+ font-weight: 600;
+ }
+ }
+}
+
diff --git a/projects/igniteui-angular/src/lib/core/styles/themes/_core.scss b/projects/igniteui-angular/src/lib/core/styles/themes/_core.scss
index 6ee4b013c61..c67a9387807 100644
--- a/projects/igniteui-angular/src/lib/core/styles/themes/_core.scss
+++ b/projects/igniteui-angular/src/lib/core/styles/themes/_core.scss
@@ -70,6 +70,7 @@
@import '../components/splitter/splitter-component';
@import '../components/snackbar/snackbar-component';
@import '../components/switch/switch-component';
+@import '../components/stepper/stepper-component';
@import '../components/tabs/tabs-component';
@import '../components/toast/toast-component';
@import '../components/tooltip/tooltip-component';
diff --git a/projects/igniteui-angular/src/lib/core/styles/themes/_index.scss b/projects/igniteui-angular/src/lib/core/styles/themes/_index.scss
index e9f15f97bba..a179f339930 100644
--- a/projects/igniteui-angular/src/lib/core/styles/themes/_index.scss
+++ b/projects/igniteui-angular/src/lib/core/styles/themes/_index.scss
@@ -50,6 +50,7 @@
@import '../components/tabs/tabs-theme';
@import '../components/scrollbar/scrollbar-theme';
@import '../components/switch/switch-theme';
+@import '../components/stepper/stepper-theme';
@import '../components/snackbar/snackbar-theme';
@import '../components/slider/slider-theme';
@import '../components/splitter/splitter-theme';
@@ -445,6 +446,10 @@
));
}
+ @if not(index($exclude, 'igx-stepper')) {
+ @include igx-stepper(igx-stepper-theme($schema: $schema));
+ }
+
@if not(index($exclude, 'igx-tabs')) {
@include igx-tabs(igx-tabs-theme(
$schema: $schema,
diff --git a/projects/igniteui-angular/src/lib/core/styles/themes/schemas/dark/_index.scss b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/dark/_index.scss
index aea995689c5..e12f406a412 100644
--- a/projects/igniteui-angular/src/lib/core/styles/themes/schemas/dark/_index.scss
+++ b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/dark/_index.scss
@@ -55,6 +55,7 @@
@import './sparkline';
@import './splitter';
@import './switch';
+@import './stepper';
@import './tabs';
@import './time-picker';
@import './toast';
@@ -118,6 +119,7 @@
/// @property {Map} sparkline [$_dark-sparkline]
/// @property {Map} igx-splitter [$_dark-splitter]
/// @property {Map} igx-switch [$_dark-switch]
+/// @property {Map} igx-stepper [$_dark-stepper]
/// @property {Map} igx-tabs [$_dark-tabs]
/// @property {Map} igx-time-picker [$_dark-time-picker]
/// @property {Map} igx-toast [$_dark-toast]
@@ -177,6 +179,7 @@ $dark-schema: (
sparkline: $_dark-sparkline,
igx-splitter: $_dark-splitter,
igx-switch: $_dark-switch,
+ igx-stepper: $_dark-stepper,
igx-tabs: $_dark-tabs,
igx-time-picker: $_dark-time-picker,
igx-toast: $_dark-toast,
@@ -246,6 +249,7 @@ $dark-material-schema: $dark-schema;
/// @property {Map} sparkline [$_dark-fluent-sparkline],
/// @property {Map} igx-splitter [$_dark-fluent-splitter],
/// @property {Map} igx-switch [$_dark-fluent-switch],
+/// @property {Map} igx-stepper [$_dark-fluent-stepper],
/// @property {Map} igx-tabs [$_dark-fluent-tabs],
/// @property {Map} igx-time-picker [$_dark-fluent-time-picker],
/// @property {Map} igx-toast [$_dark-fluent-toast],
@@ -305,6 +309,7 @@ $dark-fluent-schema: (
sparkline: $_dark-fluent-sparkline,
igx-splitter: $_dark-fluent-splitter,
igx-switch: $_dark-fluent-switch,
+ igx-stepper: $_dark-fluent-stepper,
igx-tabs: $_dark-fluent-tabs,
igx-time-picker: $_dark-fluent-time-picker,
igx-toast: $_dark-fluent-toast,
@@ -369,6 +374,7 @@ $dark-fluent-schema: (
/// @property {Map} sparkline [$_dark-bootstrap-sparkline],
/// @property {Map} igx-splitter [$_dark-bootstrap-splitter],
/// @property {Map} igx-switch [$_dark-bootstrap-switch],
+/// @property {Map} igx-stepper [$_dark-bootstrap-stepper],
/// @property {Map} igx-tabs [$_dark-bootstrap-tabs],
/// @property {Map} igx-time-picker [$_dark-bootstrap-time-picker],
/// @property {Map} igx-toast [$_dark-bootstrap-toast],
@@ -428,6 +434,7 @@ $dark-bootstrap-schema: (
sparkline: $_dark-bootstrap-sparkline,
igx-splitter: $_dark-bootstrap-splitter,
igx-switch: $_dark-bootstrap-switch,
+ igx-stepper: $_dark-bootstrap-stepper,
igx-tabs: $_dark-bootstrap-tabs,
igx-time-picker: $_dark-bootstrap-time-picker,
igx-toast: $_dark-bootstrap-toast,
@@ -492,6 +499,7 @@ $dark-bootstrap-schema: (
/// @property {Map} sparkline [$_dark-indigo-sparkline]
/// @property {Map} igx-splitter [$_dark-indigo-splitter]
/// @property {Map} igx-switch [$_dark-indigo-switch]
+/// @property {Map} igx-stepper [$_dark-indigo-stepper]
/// @property {Map} igx-tabs [$_dark-indigo-tabs]
/// @property {Map} igx-time-picker [$_dark-indigo-time-picker]
/// @property {Map} igx-toast [$_dark-indigo-toast]
@@ -551,6 +559,7 @@ $dark-indigo-schema: (
sparkline: $_dark-indigo-sparkline,
igx-splitter: $_dark-indigo-splitter,
igx-switch: $_dark-indigo-switch,
+ igx-stepper: $_dark-indigo-stepper,
igx-tabs: $_dark-indigo-tabs,
igx-time-picker: $_dark-indigo-time-picker,
igx-toast: $_dark-indigo-toast,
diff --git a/projects/igniteui-angular/src/lib/core/styles/themes/schemas/dark/_stepper.scss b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/dark/_stepper.scss
new file mode 100644
index 00000000000..e21419ebcab
--- /dev/null
+++ b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/dark/_stepper.scss
@@ -0,0 +1,87 @@
+@import '../light/stepper';
+
+////
+/// @group schemas
+/// @access public
+/// @author Marin Popov
+////
+
+/// Generates a base dark stepper schema.
+/// @property {Map} current-indicator-color [igx-color: ('grays', 900)] - The color of the current step indicator.
+/// @property {Map} invalid-indicator-color [igx-color: ('grays', 900)] - The color of the invalid step indicator.
+/// @type {Map}
+$_base-stepper: (
+ current-indicator-color: (
+ igx-color: ('grays', 900)
+ ),
+
+ invalid-indicator-color: (
+ igx-color: ('grays', 900)
+ ),
+);
+
+/// Generates a dark stepper schema.
+/// @type {Map}
+/// @requires {function} extend
+/// @requires $_light-stepper
+/// @requires $_base-stepper
+/// @see $default-palette
+$_dark-stepper: extend(
+ $_light-stepper,
+ $_base-stepper
+);
+
+/// Generates a dark fluent stepper schema
+/// @type {Map}
+/// @requires {function} extend
+/// @requires $_fluent-stepper
+/// @requires $_base-stepper
+/// @see $default-palette
+$_dark-fluent-stepper: extend(
+ $_fluent-stepper,
+ $_base-stepper
+);
+
+/// Generates a dark bootstrap stepper schema.
+/// @type {Map}
+/// @property {Map} indicator-outline [igx-color: (igx-color: ('grays', 600)] - The outline color of the incomplete step indicator.
+/// @property {Map} disabled-indicator-outline [igx-color: ('grays', 300)] - The outline color of the disabled step indicator.
+/// @requires {function} extend
+/// @requires $_bootstrap-stepper
+/// @requires $_base-stepper
+/// @see $default-palette
+$_dark-bootstrap-stepper: extend(
+ $_bootstrap-stepper,
+ $_base-stepper,
+ (
+ indicator-outline: (
+ igx-color: ('grays', 600)
+ ),
+
+ disabled-indicator-outline: (
+ igx-color: ('grays', 300)
+ ),
+ )
+);
+
+/// Generates a dark indigo stepper schema.
+/// @type {Map}
+/// @property {Map} indicator-outline [igx-color: (igx-color: ('grays', 600)] - The outline color of the incomplete step indicator.
+/// @property {Map} disabled-indicator-outline [igx-color: ('grays', 300)] - The outline color of the disabled step indicator.
+/// @requires {function} extend
+/// @requires $_indigo-stepper
+/// @requires $_base-stepper
+/// @see $default-palette
+$_dark-indigo-stepper: extend(
+ $_indigo-stepper,
+ $_base-stepper,
+ (
+ indicator-outline: (
+ igx-color: ('grays', 600)
+ ),
+
+ disabled-indicator-outline: (
+ igx-color: ('grays', 300)
+ ),
+ )
+);
diff --git a/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_index.scss b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_index.scss
index b776bc62c36..f2c9d1acdc8 100644
--- a/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_index.scss
+++ b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_index.scss
@@ -55,6 +55,7 @@
@import './sparkline';
@import './splitter';
@import './switch';
+@import './stepper';
@import './tabs';
@import './time-picker';
@import './toast';
@@ -118,6 +119,7 @@
/// @property {Map} sparkline [$_light-sparkline]
/// @property {Map} igx-splitter [$_light-splitter]
/// @property {Map} igx-switch [$_light-switch]
+/// @property {Map} igx-stepper [$_light-stepper]
/// @property {Map} igx-tabs [$_light-tabs]
/// @property {Map} igx-time-picker [$_light-time-picker]
/// @property {Map} igx-toast [$_light-toast]
@@ -177,6 +179,7 @@ $light-schema: (
sparkline: $_light-sparkline,
igx-splitter: $_light-splitter,
igx-switch: $_light-switch,
+ igx-stepper: $_light-stepper,
igx-tabs: $_light-tabs,
igx-time-picker: $_light-time-picker,
igx-toast: $_light-toast,
@@ -247,6 +250,7 @@ $light-fluent-schema: (
sparkline: $_fluent-sparkline,
igx-splitter: $_fluent-splitter,
igx-switch: $_fluent-switch,
+ igx-stepper: $_fluent-stepper,
igx-tabs: $_fluent-tabs,
igx-time-picker: $_fluent-time-picker,
igx-toast: $_fluent-toast,
@@ -312,6 +316,7 @@ $light-bootstrap-schema: (
sparkline: $_bootstrap-sparkline,
igx-splitter: $_bootstrap-splitter,
igx-switch: $_bootstrap-switch,
+ igx-stepper: $_bootstrap-stepper,
igx-tabs: $_bootstrap-tabs,
igx-time-picker: $_bootstrap-time-picker,
igx-toast: $_bootstrap-toast,
@@ -377,6 +382,7 @@ $light-indigo-schema: (
sparkline: $_indigo-sparkline,
igx-splitter: $_indigo-splitter,
igx-switch: $_indigo-switch,
+ igx-stepper: $_indigo-stepper,
igx-tabs: $_indigo-tabs,
igx-time-picker: $_indigo-time-picker,
igx-toast: $_indigo-toast,
diff --git a/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_stepper.scss b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_stepper.scss
new file mode 100644
index 00000000000..3f4b2a0d76c
--- /dev/null
+++ b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_stepper.scss
@@ -0,0 +1,466 @@
+@import '../shape/stepper';
+
+/// @group schemas
+/// @access public
+/// @author Marin Popov
+////
+
+/// Generates a light stepper schema.
+/// @type {Map}
+///
+/// @property {Color} step-background [transparent] - The background of the step header.
+/// @property {Map} step-hover-background [igx-color: 'grays', 50)] - The background of the step header on hover.
+/// @property {Map} step-focus-background [igx-color: 'grays', 100)] - The background of the step header on focus.
+/// @property {Map} title-color [igx-color: ('grays', 900)] - The text color of the step title.
+/// @property {Map} title-hover-color [igx-color: ('grays', 900)] - The text color of the step title on hover.
+/// @property {Map} title-focus-color [igx-color: ('grays', 900)] - The text color of the step title on focus.
+/// @property {Map} subtitle-color [igx-color: ('grays', 700)] - The text color of the step subtitle.
+/// @property {Map} subtitle-hover-color [igx-color: ('grays', 700)] - The text color of the step subtitle on hover.
+/// @property {Map} subtitle-focus-color [igx-color: ('grays', 700)] - The text color of the step subtitle on focus.
+/// @property {Map} indicator-color [igx-color: (igx-contrast-color: ('grays', 400)] - The text color of the incomplete step indicator.
+/// @property {Map} indicator-background [igx-color: ('grays', 400)] - The background color of the incomplete step indicator.
+/// @property {Map} indicator-outline [igx-color: ('grays', 400)] - The outline color of the incomplete step indicator.
+///
+/// @property {Color} invalid-step-background [transparent] - The background of the invalid step header.
+/// @property {Map} invalid-step-hover-background [igx-color: 'grays', 50)] - The background of the invalid step header on hover.
+/// @property {Map} invalid-step-focus-background [igx-color: 'grays', 100)] - The background of the invalid step header on focus.
+/// @property {Map} invalid-title-color [igx-color: ('error')] - The color of the invalid step title.
+/// @property {Map} invalid-title-hover-color [igx-color: ('error')] - The color of the invalid step title on hover.
+/// @property {Map} invalid-title-focus-color [igx-color: ('error')] - The color of the invalid step title on focus.
+/// @property {Map} invalid-subtitle-color [igx-color: ('error')] - The text of the invalid step subtitle.
+/// @property {Map} invalid-subtitle-hover-color [igx-color: ('error')] - The color of the invalid step subtitle on hover.
+/// @property {Map} invalid-subtitle-focus-color [igx-color: ('error')] - The color of the invalid step subtitle on focus.
+/// @property {Map} invalid-indicator-color [igx-contrast-color: ('grays', 900)] - The color of the invalid step indicator.
+/// @property {Map} invalid-indicator-background [igx-color: ('error')] - The background color of the invalid step indicator.
+/// @property {Map} invalid-indicator-outline [igx-color: ('error')] - The outline color of the invalid step indicator.
+///
+/// @property {Color} current-step-background [transparent] - The background of the current step header.
+/// @property {Map} current-step-hover-background [igx-color: 'grays', 50)] - The background of the current step header on hover.
+/// @property {Map} current-step-focus-background [igx-color: 'grays', 100)] - The background of the current step header on focus.
+/// @property {Map} current-title-color [igx-color: ('grays', 900)] - The color of the current step title.
+/// @property {Map} current-title-hover-color [igx-color: ('grays', 900)] - The color of the current step title on hover.
+/// @property {Map} current-title-focus-color [igx-color: ('grays', 900)] - The color of the current step title on focus.
+/// @property {Map} current-subtitle-color [igx-color: ('grays', 700)] - The color of the current step subtitle.
+/// @property {Map} current-subtitle-hover-color [igx-color: ('grays', 700)] - The color of the current step subtitle on hover.
+/// @property {Map} current-subtitle-focus-color [igx-color: ('grays', 700)] - The color of the current step subtitle on focus.
+/// @property {Map} current-indicator-color [igx-contrast-color: ('grays', 900)] - The color of the current step indicator.
+/// @property {Map} current-indicator-background [igx-color: ('primary', 500)] - The background color of the current step indicator.
+/// @property {Map} current-indicator-outline [igx-color: ('primary', 500)] - The outline color of the current step indicator.
+///
+/// @property {Color} complete-step-background [transparent] - The background of the complete step header.
+/// @property {Map} complete-step-hover-background [igx-color: 'grays', 50)] - The background of the complete step header on hover.
+/// @property {Map} complete-step-focus-background [igx-color: 'grays', 100)] - The background of the complete step header on focus.
+/// @property {Map} complete-title-color [igx-color: ('grays', 900)] - The color of the complete step title.
+/// @property {Map} complete-title-hover-color [igx-color: ('grays', 900)] - The color of the complete step title on hover.
+/// @property {Map} complete-title-focus-color [igx-color: ('grays', 900)] - The color of the complete step title on focus.
+/// @property {Map} complete-subtitle-color [igx-color: ('grays', 700)] - The color of the complete step subtitle.
+/// @property {Map} complete-subtitle-hover-color [igx-color: ('grays', 700)] - The color of the complete step subtitle on hover.
+/// @property {Map} complete-subtitle-focus-color [igx-color: ('grays', 700)] - The color of the complete step subtitle on focus.
+/// @property {Map} complete-indicator-color [igx-contrast-color: ('grays', 900)] - The color of the completed step indicator.
+/// @property {Map} complete-indicator-background [igx-color: ('grays', 900)] - The background color of the completed step indicator.
+/// @property {Map} complete-indicator-outline [igx-color: ('grays', 900)] - The outline color of the completed step indicator.
+///
+/// @property {Map} disabled-title-color [igx-color: ('grays', 500)] - The title color of the disabled step.
+/// @property {Map} disabled-subtitle-color [igx-color: ('grays', 500)] - The subtitle color of the disabled step.
+/// @property {Map} disabled-indicator-color [igx-color: ('grays', 500)] - The color of the disabled step indicator, title, and subtitle.
+/// @property {Map} disabled-indicator-background [igx-color: ('grays', 200)] - The background color of the disabled step indicator.
+/// @property {Map} disabled-indicator-outline [igx-color: ('grays', 200)] - The outline color of the disabled step indicator.
+///
+/// @property {Map} step-separator-color [igx-color: ('grays', 300)] - The separator border-color of between the steps.
+/// @property {Map} complete-step-separator-color [igx-color: ('grays', 900)] - The separator border-color between the completed steps.
+/// @property {String} step-separator-style ['dashed'] - The separator border-style of between the steps.
+/// @property {String} complete-step-separator-style ['solid'] - The separator border-style between the completed steps.
+///
+/// @requires {function} extend
+/// @requires {Map} $_default-shape-stepper
+/// @see $default-palette
+$_light-stepper: extend(
+ $_default-shape-stepper,
+ (
+ variant: 'material',
+
+ // Step incomplete
+ step-background: transparent,
+ step-hover-background: (
+ igx-color: ('grays', 50)
+ ),
+ step-focus-background: (
+ igx-color: ('grays', 100)
+ ),
+
+ indicator-background: (
+ igx-color: ('grays', 400)
+ ),
+ indicator-outline: (
+ igx-color: ('grays', 400)
+ ),
+ indicator-color: (
+ igx-contrast-color: ('grays', 400)
+ ),
+
+ title-color: (
+ igx-color: ('grays', 900)
+ ),
+ title-hover-color: (
+ igx-color: ('grays', 900)
+ ),
+ title-focus-color: (
+ igx-color: ('grays', 900)
+ ),
+
+ subtitle-color: (
+ igx-color: ('grays', 700)
+ ),
+ subtitle-hover-color: (
+ igx-color: ('grays', 700)
+ ),
+ subtitle-focus-color: (
+ igx-color: ('grays', 700)
+ ),
+
+ // Complete
+ complete-step-background: transparent,
+ complete-step-hover-background: (
+ igx-color: ('grays', 50)
+ ),
+ complete-step-focus-background: (
+ igx-color: ('grays', 100)
+ ),
+
+ complete-indicator-background: (
+ igx-color: ('grays', 900)
+ ),
+ complete-indicator-outline: (
+ igx-color: ('grays', 900)
+ ),
+ complete-indicator-color: (
+ igx-contrast-color: ('grays', 900)
+ ),
+
+ complete-title-color: (
+ igx-color: ('grays', 900)
+ ),
+ complete-title-hover-color: (
+ igx-color: ('grays', 900)
+ ),
+ complete-title-focus-color: (
+ igx-color: ('grays', 900)
+ ),
+
+ complete-subtitle-color: (
+ igx-color: ('grays', 700)
+ ),
+ complete-subtitle-hover-color: (
+ igx-color: ('grays', 700)
+ ),
+ complete-subtitle-focus-color: (
+ igx-color: ('grays', 700)
+ ),
+
+ // Current
+ current-step-background: transparent,
+ current-step-hover-background: (
+ igx-color: ('grays', 50)
+ ),
+ current-step-focus-background: (
+ igx-color: ('grays', 100)
+ ),
+
+ current-indicator-background: (
+ igx-color: ('primary', 500)
+ ),
+
+ current-indicator-outline: (
+ igx-color: ('primary', 500)
+ ),
+
+ current-indicator-color: (
+ igx-contrast-color: ('grays', 900)
+ ),
+
+ current-title-color: (
+ igx-color: ('grays', 900)
+ ),
+ current-title-hover-color: (
+ igx-color: ('grays', 900)
+ ),
+ current-title-focus-color: (
+ igx-color: ('grays', 900)
+ ),
+
+ current-subtitle-color: (
+ igx-color: ('grays', 700)
+ ),
+ current-subtitle-hover-color: (
+ igx-color: ('grays', 700)
+ ),
+ current-subtitle-focus-color: (
+ igx-color: ('grays', 700)
+ ),
+
+ // Invalid
+ invalid-step-background: transparent,
+ invalid-step-hover-background: (
+ igx-color: ('grays', 50)
+ ),
+ invalid-step-focus-background: (
+ igx-color: ('grays', 100)
+ ),
+
+ invalid-indicator-background: (
+ igx-color: ('error')
+ ),
+ invalid-indicator-outline: (
+ igx-color: ('error')
+ ),
+ invalid-indicator-color: (
+ igx-contrast-color: ('grays', 900)
+ ),
+
+ invalid-title-color: (
+ igx-color: ('error')
+ ),
+ invalid-title-hover-color: (
+ igx-color: ('error')
+ ),
+ invalid-title-focus-color: (
+ igx-color: ('error')
+ ),
+
+ invalid-subtitle-color: (
+ igx-color: ('error')
+ ),
+ invalid-subtitle-hover-color: (
+ igx-color: ('error')
+ ),
+ invalid-subtitle-focus-color: (
+ igx-color: ('error')
+ ),
+
+ // Disabled
+ disabled-indicator-color: (
+ igx-color: ('grays', 500)
+ ),
+ disabled-indicator-background: (
+ igx-color: ('grays', 200)
+ ),
+ disabled-indicator-outline: (
+ igx-color: ('grays', 200)
+ ),
+ disabled-title-color: (
+ igx-color: ('grays', 500)
+ ),
+ disabled-subtitle-color: (
+ igx-color: ('grays', 500)
+ ),
+
+ // Separator
+ step-separator-color: (
+ igx-color: ('grays', 300)
+ ),
+ complete-step-separator-color: (
+ igx-color: ('grays', 900)
+ ),
+ step-separator-style: 'dashed',
+ complete-step-separator-style: 'solid',
+ )
+);
+
+/// Generates a fluent stepper schema.
+/// @type {Map}
+/// @property {Color} indicator-background [transparent] - The background color of the incomplete step indicator.
+/// @property {Color} indicator-outline [transparent] - The outline color of the incomplete step indicator.
+/// @property {Map} indicator-color [igx-color: ('grays', 900)] - The text color of the incomplete step indicator.
+/// @property {Map} complete-indicator-background [igx-color: ('grays', 200)] - The background color of the completed step indicator.
+/// @property {Color} complete-indicator-outline [transparent] - The outline color of the completed step indicator.
+/// @property {Map} complete-indicator-color [igx-contrast-color: ('grays', 200)] - The text color of the completed step indicator.
+/// @property {Map} complete-step-separator-color [igx-color: ('primary', 500)] - The separator border-color between the completed steps.
+/// @property {Color} disabled-indicator-background [transparent] - The background color of the disabled step indicator.
+/// @property {Color} disabled-indicator-outline [transparent] - The outline color of the disabled step indicator.
+///
+/// @requires {function} extend
+/// @requires {Map} $_light-stepper
+/// @requires {Map} $_fluent-shape-stepper
+$_fluent-stepper: extend(
+ $_light-stepper,
+ $_fluent-shape-stepper,
+ (
+ variant: 'fluent',
+
+ indicator-background: transparent,
+ indicator-outline: transparent,
+ indicator-color: (
+ igx-color: ('grays', 900)
+ ),
+
+ // Complete
+ complete-indicator-background: (
+ igx-color: ('grays', 200)
+ ),
+ complete-indicator-outline: transparent,
+ complete-indicator-color: (
+ igx-contrast-color: ('grays', 200)
+ ),
+ complete-step-separator-color: (
+ igx-color: ('primary', 500)
+ ),
+
+ // Disabled
+ disabled-indicator-background: transparent,
+ disabled-indicator-outline: transparent,
+ )
+);
+
+/// Generates a bootstrap stepper schema.
+/// @type {Map}
+/// @property {Color} indicator-color [igx-color: ('primary', 500)] - The text color of the incomplete step indicator.
+/// @property {Color} indicator-background [transparent] - The background color of the incomplete step indicator.
+/// @property {Map} indicator-outline [igx-color: ('grays', 300)] - The outline color of the incomplete step indicator.
+///
+/// @property {Map} current-title-color [igx-color: ('primary', 500)] - The color of the current step title.
+/// @property {Map} current-title-hover-color [igx-color: ('primary', 500)] - The color of the current step title on hover.
+/// @property {Map} current-title-focus-color [igx-color: ('primary', 500)] - The color of the current step title on focus.
+/// @property {Map} current-subtitle-color [igx-color: ('primary', 500)] - The color of the current step subtitle.
+/// @property {Map} current-subtitle-hover-color [igx-color: ('primary', 500)] - The color of the current step subtitle on hover.
+/// @property {Map} current-subtitle-focus-color [igx-color: ('primary', 500)] - The color of the current step subtitle on focus.
+///
+/// @property {Color} disabled-indicator-background [transparent] - The background color of the disabled step indicator.
+/// @property {Map} disabled-indicator-outline [igx-color: ('grays', 300)] - The outline color of the disabled step indicator.
+///
+/// @property {Map} complete-indicator-background [igx-color: ('grays', 300)] - The background color of the completed step indicator.
+/// @property {Map} complete-indicator-outline [igx-color: ('grays', 300)] - The outline color of the completed step indicator.
+/// @property {Map} complete-indicator-color [igx-color: ('grays', 300)] - The text color of the completed step indicator.
+///
+/// @property {Map} step-separator-color [igx-color: ('grays', 200)] - The separator border-color of between the steps.
+/// @property {Map} complete-step-separator-color [igx-color: ('primary', 500)] - The separator border-color between the completed steps.
+/// @property {String} step-separator-style ['solid'] - The separator border-style of between the steps.
+/// @property {String} complete-step-separator-style ['solid'] - The separator border-style between the completed steps.
+///
+/// @requires {function} extend
+/// @requires {Map} $_light-stepper
+/// @requires {Map} $_bootstrap-shape-stepper
+$_bootstrap-stepper: extend(
+ $_light-stepper,
+ $_bootstrap-shape-stepper,
+ (
+ variant: 'bootstrap',
+
+ indicator-background: transparent,
+ indicator-outline: (
+ igx-color: ('grays', 300)
+ ),
+ indicator-color: (
+ igx-color: ('primary', 500)
+ ),
+
+ // Current
+ current-title-color: (
+ igx-color: ('primary', 500)
+ ),
+ current-title-hover-color: (
+ igx-color: ('primary', 500)
+ ),
+ current-title-focus-color: (
+ igx-color: ('primary', 500)
+ ),
+ current-subtitle-color: (
+ igx-color: ('primary', 500)
+ ),
+ current-subtitle-hover-color: (
+ igx-color: ('primary', 500)
+ ),
+ current-subtitle-focus-color: (
+ igx-color: ('primary', 500)
+ ),
+
+ // Complete
+ complete-indicator-background: (
+ igx-color: ('grays', 300)
+ ),
+ complete-indicator-outline: (
+ igx-color: ('grays', 300)
+ ),
+ complete-indicator-color: (
+ igx-contrast-color: ('grays', 300)
+ ),
+
+ // Disabled
+ disabled-indicator-background: transparent,
+ disabled-indicator-outline: (
+ igx-color: ('grays', 300)
+ ),
+
+ // Separator
+ step-separator-color: (
+ igx-color: ('grays', 200)
+ ),
+ complete-step-separator-color: (
+ igx-color: ('primary', 500)
+ ),
+ step-separator-style: 'solid',
+ complete-step-separator-style: 'solid',
+ )
+);
+
+/// Generates an indigo stepper schema.
+/// @type {Map}
+/// @property {Map} indicator-color [igx-color: ('primary', 500)] - The text color of the incomplete step indicator.
+/// @property {Color} indicator-background [transparent] - The background color of the incomplete step indicator.
+/// @property {Map} indicator-outline [igx-color: ('grays', 300)] - The outline color of the incomplete step indicator.
+///
+/// @property {Map} complete-indicator-color [igx-color: ('primary', 500)] - The color of the completed step indicator.
+/// @property {Map} complete-indicator-background [igx-color: ('primary', 100)] - The background color of the completed step indicator.
+/// @property {Map} complete-indicator-outline [igx-color: ('primary', 100)] - The outline color of the completed step indicator.
+///
+/// @property {Color} disabled-indicator-background [transparent] - The background color of the disabled step indicator.
+/// @property {Map} disabled-indicator-outline [igx-color: ('grays', 200)] - The outline color of the disabled step indicator.
+///
+/// @property {Map} step-separator-color [igx-color: ('grays', 300)] - The separator border-color of between the steps.
+/// @property {Map} complete-step-separator-color [igx-color: ('primary', 500)] - The separator border-color between the completed steps.
+/// @property {String} step-separator-style ['solid'] - The separator border-style of between the steps.
+/// @property {String} complete-step-separator-style ['solid'] - The separator border-style between the completed steps.
+///
+/// @requires {function} extend
+/// @requires $_light-stepper
+$_indigo-stepper: extend(
+ $_light-stepper,
+ (
+ variant: 'indigo-design',
+
+ indicator-background: transparent,
+ indicator-outline: (
+ igx-color: ('grays', 300)
+ ),
+ indicator-color: (
+ igx-color: ('primary', 500)
+ ),
+
+ // Complete
+ complete-indicator-background: (
+ igx-color: ('primary', 100)
+ ),
+ complete-indicator-outline: (
+ igx-color: ('primary', 100)
+ ),
+ complete-indicator-color: (
+ igx-color: ('primary', 500)
+ ),
+
+ // Disabled
+ disabled-indicator-background: transparent,
+ disabled-indicator-outline: (
+ igx-color: ('grays', 200)
+ ),
+
+ // Separator
+ step-separator-color: (
+ igx-color: ('grays', 300)
+ ),
+ complete-step-separator-color: (
+ igx-color: ('primary', 500)
+ ),
+ step-separator-style: 'solid',
+ complete-step-separator-style: 'solid',
+ )
+);
+
diff --git a/projects/igniteui-angular/src/lib/core/styles/themes/schemas/round-light/_index.scss b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/round-light/_index.scss
index 4f95169691f..347ef9757b1 100644
--- a/projects/igniteui-angular/src/lib/core/styles/themes/schemas/round-light/_index.scss
+++ b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/round-light/_index.scss
@@ -40,6 +40,7 @@
@import '../light/slider';
@import '../light/snackbar';
@import '../light/switch';
+@import '../light/stepper';
@import '../light/tabs';
@import '../light/time-picker';
@import '../light/toast';
@@ -85,6 +86,7 @@
/// @property {Map} igx-slider [$_light-slider]
/// @property {Map} igx-snackbar [$_light-snackbar]
/// @property {Map} igx-switch [$_light-switch]
+/// @property {Map} igx-stepper [$_light-stepper]
/// @property {Map} igx-tabs [$_light-tabs]
/// @property {Map} igx-time-picker [$_light-time-picker]
/// @property {Map} igx-toast [$_light-toast]
@@ -112,6 +114,7 @@ $light-round-schema: (
igx-circular-bar: extend($_light-progress-circular, $_default-shape-progress),
igx-snackbar: extend($_light-snackbar, $_round-shape-snackbar),
igx-switch: extend($_light-switch, $_round-shape-switch),
+ igx-stepper: extend($_light-stepper, $_round-shape-stepper),
igx-tabs: extend($_light-tabs, $_round-shape-tabs),
igx-time-picker: extend($_light-time-picker, $_round-shape-time-picker),
igx-toast: extend($_light-toast, $_round-shape-toast),
diff --git a/projects/igniteui-angular/src/lib/core/styles/themes/schemas/shape/_stepper.scss b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/shape/_stepper.scss
new file mode 100644
index 00000000000..cf2eab72913
--- /dev/null
+++ b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/shape/_stepper.scss
@@ -0,0 +1,38 @@
+////
+/// @group schemas
+/// @access public
+/// @author Marin Popov
+////
+
+/// @type Map
+/// @property {Number} border-radius-indicator [1] - The border radius used for stepper indicator. Can be a fraction between 0 and 1, pixels, or percent.
+/// @property {Number} border-radius-step-header [0] - The border radius used for stepper step-header. Can be a fraction between 0 and 1, pixels, or percent.
+$_default-shape-stepper: (
+ border-radius-indicator: 1,
+ border-radius-step-header: 0
+);
+
+$_round-shape-stepper: (
+ border-radius-indicator: 1,
+ border-radius-step-header: 32px
+);
+
+$_square-shape-stepper: (
+ border-radius-indicator: 0,
+ border-radius-step-header: 0
+);
+
+/// @type Map
+$_fluent-shape-stepper: (
+ border-radius-indicator: 2px,
+ border-radius-step-header: 2px
+);
+
+/// @type Map
+$_bootstrap-shape-stepper: (
+ border-radius-indicator: 2px,
+ border-radius-step-header: 2px
+);
+
+/// @type Map
+$_indigo-shape-stepper: extend($_default-shape-stepper);
diff --git a/projects/igniteui-angular/src/lib/core/styles/themes/schemas/square-light/_index.scss b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/square-light/_index.scss
index a9d2a5f9cd3..4cf4a46debf 100644
--- a/projects/igniteui-angular/src/lib/core/styles/themes/schemas/square-light/_index.scss
+++ b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/square-light/_index.scss
@@ -40,6 +40,7 @@
@import '../light/slider';
@import '../light/snackbar';
@import '../light/switch';
+@import '../light/stepper';
@import '../light/tabs';
@import '../light/time-picker';
@import '../light/toast';
@@ -85,6 +86,7 @@
/// @property {Map} igx-slider [$_light-slider]
/// @property {Map} igx-snackbar [$_light-snackbar]
/// @property {Map} igx-switch [$_light-switch]
+/// @property {Map} igx-stepper [$_light-stepper]
/// @property {Map} igx-tabs [$_light-tabs]
/// @property {Map} igx-time-picker [$_light-time-picker]
/// @property {Map} igx-toast [$_light-toast]
@@ -112,6 +114,7 @@ $light-square-schema: (
igx-circular-bar: extend($_light-progress-circular, $_default-shape-progress),
igx-snackbar: extend($_light-snackbar, $_square-shape-snackbar),
igx-switch: extend($_light-switch, $_square-shape-switch),
+ igx-stepper: extend($_light-stepper, $_square-shape-stepper),
igx-tabs: extend($_light-tabs, $_square-shape-tabs),
igx-time-picker: extend($_light-time-picker, $_square-shape-time-picker),
igx-toast: extend($_light-toast, $_square-shape-toast),
diff --git a/projects/igniteui-angular/src/lib/core/styles/typography/_typography.scss b/projects/igniteui-angular/src/lib/core/styles/typography/_typography.scss
index c066145e58b..3b5786574bb 100644
--- a/projects/igniteui-angular/src/lib/core/styles/typography/_typography.scss
+++ b/projects/igniteui-angular/src/lib/core/styles/typography/_typography.scss
@@ -33,6 +33,7 @@
@import '../components/slider/slider-theme';
@import '../components/snackbar/snackbar-theme';
@import '../components/switch/switch-theme';
+@import '../components/stepper/stepper-theme';
@import '../components/tabs/tabs-theme';
@import '../components/time-picker/time-picker-theme';
@import '../components/toast/toast-theme';
@@ -72,6 +73,7 @@
@include igx-slider-typography($type-scale);
@include igx-snackbar-typography($type-scale);
@include igx-switch-typography($type-scale);
+ @include igx-stepper-typography($type-scale);
@include igx-tabs-typography($type-scale);
@include igx-time-picker-typography($type-scale);
@include igx-toast-typography($type-scale);
diff --git a/projects/igniteui-angular/src/lib/expansion-panel/toggle-animation-component.ts b/projects/igniteui-angular/src/lib/expansion-panel/toggle-animation-component.ts
index 081f2c97e7c..7a6cf5852f2 100644
--- a/projects/igniteui-angular/src/lib/expansion-panel/toggle-animation-component.ts
+++ b/projects/igniteui-angular/src/lib/expansion-panel/toggle-animation-component.ts
@@ -133,7 +133,8 @@ export abstract class ToggleAnimationPlayer implements ToggleAnimationOwner, OnD
if (opposite) {
if (opposite.hasStarted()) {
// .getPosition() still returns 0 sometimes, regardless of the fix for https://github.com/angular/angular/issues/18891;
- oppositePosition = (opposite as any)._renderer.engine.players[0].getPosition();
+ const renderer = (opposite as any)._renderer;
+ oppositePosition = renderer.engine.players[renderer.engine.players.length - 1].getPosition();
}
this.cleanUpPlayer(oppositeType);
diff --git a/projects/igniteui-angular/src/lib/stepper/README.md b/projects/igniteui-angular/src/lib/stepper/README.md
new file mode 100644
index 00000000000..725712c6178
--- /dev/null
+++ b/projects/igniteui-angular/src/lib/stepper/README.md
@@ -0,0 +1,123 @@
+# IgxStepperComponent
+
+## Description
+_**IgxStepperComponent** is a collection of **IgxStepComponent**s that delivers a wizard-like workflow:_
+
+A complete walkthrough of how to get started can be found [here](https://www.infragistics.com/products/ignite-ui-angular/angular/components/stepper).
+The specification for the stepper can be found [here](https://github.com/IgniteUI/igniteui-angular/wiki/Stepper-Specification)
+
+----------
+
+## Usage
+```html
+
+
+
+ {{step.indicator}}
+
+
+
+ {{step.title}}
+
+
+
+ ...
+
+
+
+```
+
+----------
+
+## Keyboard Navigation
+
+The keyboard can be used to navigate through all steps in the stpper.
+
+_Disabled steps are not counted as visible steps for the purpose of keyboard navigation._
+
+|Keys |Description|
+|---------------|-----------|
+| ARROW DOWN | Focuses the next step header in a vertical stepper. |
+| ARROW UP | Focuses the previous step header in a vertical stepper. |
+| TAB | Moves the focus to the next tabbable element. |
+| SHIFT + TAB | Moves the focus to the previous tabbable element. |
+| HOME | Moves the focus to the header of the FIRST enabled step in the _igx-stepper_ |
+| END | Moves the focus to the header of the LAST enabled step in the _igx-stepper_ |
+| ARROW RIGHT | Moves the focus to the header of the next accessible step in both orientations. |
+| ARROW LEFT | Moves the focus to the header of the previous accessible step in both orientations. |
+| ENTER / SPACE | Activates the currently focused step. |
+| CLICK | Activates the currently focused step. |
+
+_By design when the user presses the **Tab** key over the step header the focus will move to the step content container. In case the container should be skipped the developer should set the content container [tabIndex]="-1"_
+
+----------
+
+## API Summary
+
+### IgxStepperComponent
+
+#### Accessors
+
+**Get**
+
+ | Name | Description | Type |
+ |----------------|------------------------------------------------------------------------------|---------------------|
+ | steps | Gets the steps that are rendered in the stepper. | `IgxStepComponent[]` |
+
+
+#### Properties
+
+ | Name | Description | Type |
+ |----------------|------------------------------------------------------------------------------|----------------------------------------|
+ | id | The id of the stepper. Bound to attr.id | `string` |
+ | orientation | Gets/sets the orientation of the stepper. Default is `horizontal`. | `IgxStepperOrientation` |
+ | stepType| Gets/sets the type of the steps in the stepper. Default value is `full` | `IgxStepType` |
+ | titlePosition | Gets/sets the position of the titles in the stepper. Default value is `bottom` when the stepper is horizontally orientated and `end` when the layout is set to vertical. | `IgxStepperTitlePosition` |
+ | linear | Whether the validity of previous steps should be checked and only in case, it's valid to be able to move forward or not. Default value is `false`. | `boolean` |
+ | contentTop| Whether the steps content should be displayed above the steps header when the stepper orientation is Horizontal. Default value is `false`. | `boolean` |
+ | verticalAnimationType | Gets/sets the animation type of the stepper when the orientation direction is vertical. Default value is `grow`. | `VerticalAnimationType` |
+ | horizontalAnimationType | Gets/sets the animation type of the stepper when the orientation direction is horizontal. Default value is `slide`. |`HorizontalAnimationType` |
+ | animationDuration | 320 | `number` |
+
+#### Methods
+ | Name | Description | Parameters | Returns |
+ |-----------------|----------------------------|-------------------------|--------|
+ | navigateTo | Activates the step given by index. | `index: number` | `void` |
+ | next | Activates the next enabled step. | | `void` |
+ | prev | Activates the previous enabled step. | | `void` |
+ | reset | Resets the stepper to its initial state. | | `void` |
+
+#### Events
+
+ | Name | Description | Cancelable | Arguments |
+ |----------------|-------------------------------------------------------------------------|------------|------------|
+ | activeStepChanging | Emitted when the active step is about to change. | true | `{ oldIndex: number, newIndex: number, owner: IgxStepperComponent, cancel: boolean }` |
+ | activeStepChanged | Emitted when the active step is changed. | false | `{ index: number, owner: IgxStepperComponent }` |
+### IgxStepComponent
+
+#### Accessors
+
+**Get**
+
+ | Name | Description | Type |
+ |-----------------|-------------------------------------------------------------------------------|---------------------|
+ | index | Gets the step index inside of the stepper. | `number` |
+
+#### Properties
+
+ | Name | Description | Type |
+ |-----------------|-------------------------------------------------------------------------------|---------------------|
+ | id | The id of the step. Bound to attr.id | `string` |
+ | disabled | Gets/sets whether the step is interactable. | `boolean` |
+ | active | Gets/sets whether the step is activе. Two-way data binding. | `boolean` |
+ | optional | Gets/sets whether the step is optional. | `boolean` |
+ | complete | Gets/sets whether the step is completed. | `boolean` |
+ | isValid | Gets/sets whether the step is valid. Default value is `true`. | `boolean` |
+
+#### Events
+
+ | Name | Description | Cancelable | Parameters |
+ |-----------------|-------------------------------------------------------------------------------|------------|---------|
+ | activeChange | Emitted when the step's active property changes | false | `boolean` |
+
+
diff --git a/projects/igniteui-angular/src/lib/stepper/public_api.ts b/projects/igniteui-angular/src/lib/stepper/public_api.ts
new file mode 100644
index 00000000000..ca991bac1e5
--- /dev/null
+++ b/projects/igniteui-angular/src/lib/stepper/public_api.ts
@@ -0,0 +1,3 @@
+export * from './stepper.component';
+export * from './step/step.component';
+export * from './stepper.common';
diff --git a/projects/igniteui-angular/src/lib/stepper/step/step.component.html b/projects/igniteui-angular/src/lib/stepper/step/step.component.html
new file mode 100644
index 00000000000..c5e83f938a0
--- /dev/null
+++ b/projects/igniteui-angular/src/lib/stepper/step/step.component.html
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ index + 1 }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/projects/igniteui-angular/src/lib/stepper/step/step.component.ts b/projects/igniteui-angular/src/lib/stepper/step/step.component.ts
new file mode 100644
index 00000000000..5be601bdae0
--- /dev/null
+++ b/projects/igniteui-angular/src/lib/stepper/step/step.component.ts
@@ -0,0 +1,557 @@
+import { AnimationBuilder } from '@angular/animations';
+import {
+ AfterViewInit,
+ ChangeDetectorRef, Component, ContentChild, ElementRef,
+ EventEmitter, forwardRef, HostBinding, HostListener, Inject, Input, OnDestroy, Output, Renderer2, TemplateRef, ViewChild
+} from '@angular/core';
+import { takeUntil } from 'rxjs/operators';
+import { HorizontalAnimationType, Direction, IgxSlideComponentBase } from '../../carousel/carousel-base';
+import { PlatformUtil } from '../../core/utils';
+import { ToggleAnimationPlayer, ToggleAnimationSettings } from '../../expansion-panel/toggle-animation-component';
+import { IgxDirectionality } from '../../services/direction/directionality';
+import { IgxStep, IgxStepper, IgxStepperOrientation, IgxStepType, IGX_STEPPER_COMPONENT, IGX_STEP_COMPONENT } from '../stepper.common';
+import { IgxStepContentDirective, IgxStepIndicatorDirective } from '../stepper.directive';
+import { IgxStepperService } from '../stepper.service';
+
+let NEXT_ID = 0;
+
+/**
+ * The IgxStepComponent is used within the `igx-stepper` element and it holds the content of each step.
+ * It also supports custom indicators, title and subtitle.
+ *
+ * @igxModule IgxStepperModule
+ *
+ * @igxKeywords step
+ *
+ * @example
+ * ```html
+ *
+ * ...
+ *
+ * ...
+ *
+ * ...
+ *
+ * ```
+ */
+@Component({
+ selector: 'igx-step',
+ templateUrl: 'step.component.html',
+ providers: [
+ { provide: IGX_STEP_COMPONENT, useExisting: IgxStepComponent }
+ ]
+})
+export class IgxStepComponent extends ToggleAnimationPlayer implements IgxStep, AfterViewInit, OnDestroy, IgxSlideComponentBase {
+
+ /**
+ * Get/Set the `id` of the step component.
+ * Default value is `"igx-step-0"`;
+ * ```html
+ *
+ * ```
+ * ```typescript
+ * const stepId = this.step.id;
+ * ```
+ */
+ @HostBinding('attr.id')
+ @Input()
+ public id = `igx-step-${NEXT_ID++}`;
+
+ /**
+ * Get/Set whether the step is interactable.
+ *
+ * ```html
+ *
+ * ...
+ *
+ * ...
+ *
+ * ```
+ *
+ * ```typescript
+ * this.stepper.steps[1].disabled = true;
+ * ```
+ */
+ @Input()
+ public set disabled(value: boolean) {
+ this._disabled = value;
+ if (this.stepper.linear) {
+ this.stepperService.calculateLinearDisabledSteps();
+ }
+ }
+
+ public get disabled(): boolean {
+ return this._disabled;
+ }
+
+ /**
+ * Get/Set whether the step is completed.
+ *
+ * @remarks
+ * When set to `true` the following separator is styled `solid`.
+ *
+ * ```html
+ *
+ * ...
+ *
+ * ...
+ *
+ * ```
+ *
+ * ```typescript
+ * this.stepper.steps[1].completed = true;
+ * ```
+ */
+ @Input()
+ @HostBinding('class.igx-stepper__step--completed')
+ public completed = false;
+
+ /**
+ * Get/Set whether the step is valid.
+ *```html
+ *
+ * ...
+ *
+ Lorem ipsum dolor sit amet consectetur adipisicing elit. Cum eos asperiores, doloribus reiciendis, esse
+ earum, iusto expedita rem quo mollitia voluptatem quas saepe quia! Rem illum quo officia eum quisquam?
+
+
+
+
+
+
+
+
+
+
+
+
+ User Details
+ (Requred)
+
+
+
+
+
+
+ attach_money
+ Payment method
+ Currently you can pay only cash
+