0.0.2 • Published 4 years ago

@finlexlabs/stepper v0.0.2

Weekly downloads
1
License
-
Repository
-
Last release
4 years ago

Finlex Stepper (@finlexlabs/stepper)

Library Name: finlex-stepper Package Name: @finlexlabs/stepper Repo Name: fx-ng-components


Steps to Build & Publish Library

Package Renaming

Go to ./src/finlex-stepper/package.json Rename package name from finlex-stepper to @finlexlabs/stepper

Build

npm run build:stepper

It will build finlex-stepper using ng-packagr. The build artifacts will be stored in the dist/ directory.

Publishing

After building your library with ng build:stepper, go to the dist folder cd dist/finlex-stepper and run npm publish.


NOTE: Finlex Stepper is a modified version of Material Stepper Angular (@angular/stepper module) that is built on top of Angular Stepper CDK so in case you're not familiar with them already, following recoures will be a good start before you understand finlex-form-control and its functionality:

Background knowledge:

  1. Read here an intro to Angular's Material Stepper.
  2. Read here an intro to Angular's Stepper CDK.
  3. Read here for an intro into FinlexFormGroup, we use them in stepper to determine and revert if a stepControl has any changes.

Mostly all the behaviour of MatStepper is still possible. All the customizations from that behaviour are mentioned below.


(TL;DR) Simple example to use finlex-stepper with form:

module.ts

import { FinlexStepperModule } from '@finlex/components/finlex-stepper';

@NgModule({
  imports: [
    FinlexStepperModule
]
})
export class ProductsModule { }

controller.ts

// It is not necessary to have a form for stepper
  constructor(
  ){}

// this will set this.stepper value
@ViewChild('stepper', { static: false }) stepper;

const stepCreateProduct: FormGroup = new FinlexFormGroup({
    name: new FinlexFormControl({
        placeholder: 'placeholder text',
        value: this.product.name
    })
})

// It's only required to use function with stepper.next() if we want to make an async call before allowing to change the step.
onActionBeforeNextStep(){
    // do some async action
    this.productService.save(this.stepCreateProduct)
        .subscribe(() => {
            this.stepCreateProduct.commitValue();
            this.stepper.next(); // this will change the step
        })
}

view.ts

    <finlex-stepper #stepper>

        <finlex-step [stepControl]="stepCreateProduct"
                     [stepControlValue]="product">
            <ng-template matStepLabel>{{'STEP_WITH_ASYCN_CALL'}}</ng-template>
            <finlex-form-control fxFlex="40"
                                    [control]="stepCreateProduct.get('name')">
            </finlex-form-control>
            <button mat-button
                    [disabled]="stepCreateProduct.invalid"
                    (click)="onActionBeforeNextStep()">
                {{'NEXT_LABEL' | translate}}
            </button>
        </finlex-step>

        <finlex-step>
            <ng-template matStepLabel>{{'STEP_WITHOUT_FORM'}}</ng-template>
            <button mat-button
                    matStepperPrevious>
                {{'NEXT_LABEL' | translate}}
            </button>
        </finlex-step>

    </finlex-stepper>

FinlexStepperModule declarations

  • There are no changes to the following directives and they behave so far as it is: MatStepperNext, MatStepperPrevious, MatStepLabel. Feel free to use Angular API Doc links to understand them.

  • The stepper component called finlex-stepper is inspired by mat-vertical-stepper (which also inherits mat-stepper).

  • The step component called finlex-step inspired by mat-step.

    • The FinlexStep has a new @Input() binding called disable. If a step has disable true, the header icon of the step is rendered with a special design (low opacity) and its not possible to click on the step header to open the step.
  • The step header called finlex-step-header is inspired by mat-step-header but this component is not so relavent since its only used for internal renderring of stepper and has no affect in usage.


Customizations

  1. The support for matStepperIcon template has been removed since our UI toolkit doesn't require this feature. Instead, we always show step number as the default icon for every step (in any step state).

  2. FinlexStepper uses ngIf directive to prevent the stepper from rendering all steps at once (and hiding them in DOM), which was the default behavior. Instead, the ngIf ensures that only active step is rendered in DOM and therefore, when we change the step, the lifecycle of other step components is only triggered when that step is active.

  3. If a finlex-step has [disable] binding as true, the step header icon will be styled differently and it will not be possible to transition to this step.

  4. FinlexStepper does not use the [linear] binding of Material Stepper, instead it performs its own logic for similar behaviour by overriding the (click) binding of step header (when user clicks on other steps titles). This click function performs several checks before transition to another step:

    1. If the steps prior to the clicked step have stepControl, it checks that all the previous stepControl's are in valid state. Otherwise, the transition to the step is denied (nothing happens when clicking on the header). E.G. User is on Step 2 and Step 3 is invalid, so user cannot click on Step 4 directly.

    2. If the current step has stepControl that is dirty, it checks whether the current step is valid before doing the transition. If not, it shows a dialog to warn the user that their changes will be reset if they continue to change the step directly (without saving). If user continues, the stepControl changes are *reset before performing the transition.

    3. If the current step has stepControl that is dirty, it checks whether the step has any changes*. If yes, it shows a dialog to warn the user that their changes will be reset if they continue to change the step directly (without saving). If user continues, the stepControl changes are reset* before performing the transition.

To perofrm actions like "reset" and check if a stepControl has "changes", the stepControl should be of type FinlexFormGroup. To learn more about how FinlexFormGroup provides support for this, please read here.


Future Enhancement (suggestive):