From b4d9b1312993c39cd04da100237b1d3e87cb51d5 Mon Sep 17 00:00:00 2001 From: Sharma Date: Tue, 9 Dec 2025 15:40:22 +0530 Subject: [PATCH] Added override for the Multistep --- .../multi-step/multi-step.component.html | 98 ++++++ .../multi-step/multi-step.component.scss | 303 ++++++++++++++++++ .../multi-step/multi-step.component.spec.ts | 24 ++ .../multi-step/multi-step.component.ts | 91 ++++++ .../mediaco/sdk-mediaco-component-map.ts | 2 + 5 files changed, 518 insertions(+) create mode 100644 src/app/_samples/mediaco/components/multi-step/multi-step.component.html create mode 100644 src/app/_samples/mediaco/components/multi-step/multi-step.component.scss create mode 100644 src/app/_samples/mediaco/components/multi-step/multi-step.component.spec.ts create mode 100644 src/app/_samples/mediaco/components/multi-step/multi-step.component.ts diff --git a/src/app/_samples/mediaco/components/multi-step/multi-step.component.html b/src/app/_samples/mediaco/components/multi-step/multi-step.component.html new file mode 100644 index 00000000..ef316ac8 --- /dev/null +++ b/src/app/_samples/mediaco/components/multi-step/multi-step.component.html @@ -0,0 +1,98 @@ +
+
+
+
+
+
+ {{ i + 1 }} +
+
+
+ {{ mainStep.name }} +
+
+
+ +
    +
  • +
    + + + + +
    +
    + +
    +
  • +
+
+ + + + +
+
+
+ +
+
+ +
+
+
+ {{ i + 1 }} +
+
+
+
+ {{ mainStep.name }} +
+
+
+
+
+
+
+ +
    +
  • +
    + + + + +
    +
    + +
    +
  • +
+
+ + + + +
+
+
diff --git a/src/app/_samples/mediaco/components/multi-step/multi-step.component.scss b/src/app/_samples/mediaco/components/multi-step/multi-step.component.scss new file mode 100644 index 00000000..c6ddba31 --- /dev/null +++ b/src/app/_samples/mediaco/components/multi-step/multi-step.component.scss @@ -0,0 +1,303 @@ +.psdk-case-view-divider { + border-bottom: 0.0625rem solid var(--mat-sys-outline-variant); +} + +.psdk-icon { + padding: 0rem 0.125rem; + min-width: unset; +} + +.psdk-current-svg-icon { + width: 1rem; + filter: var(--app-primary-color-filter); +} + +.psdk-not-current-svg-icon { + width: 1rem; + filter: var(--app-neutral-color-filter); +} + +mat-vertical-stepper { + background-color: transparent; +} +mat-horizontal-stepper { + background-color: transparent; +} + +.psdk-sub-step-current { + padding-left: 0.625rem; + font-weight: bold; +} + +.psdk-sub-step-not-current { + padding-left: 0.625rem; +} + +.psdk-flow-container-top { + padding: 0rem 0.625rem; + border-radius: 0.3125rem; +} +.psdk-flow-container { + padding-left: 2.1875rem; +} + +.psdk-sub-step-list { + list-style: none; + padding-bottom: 0.625rem; +} + +.psdk-vertical-stepper { + background-color: transparent; + display: block; + text-align: left; +} + +.psdk-vertical-step { + display: block; +} + +.psdk-vertical-step-header { + overflow: hidden; + outline: none; + cursor: pointer; + position: relative; + box-sizing: content-box; + display: flex; + align-items: center; + height: 24px; + padding: 24px 24px; +} + +.psdk-vertical-step-icon { + margin-right: 12px; + border-radius: 50%; + height: 24px; + width: 24px; + flex-shrink: 0; + position: relative; +} + +.psdk-vertical-step-icon-content { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); +} + +.psdk-vertical-step-icon-selected { + margin-right: 12px; + border-radius: 50%; + height: 24px; + width: 24px; + flex-shrink: 0; + position: relative; +} + +.psdk-vertical-step-label { + display: inline-block; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + min-width: 50px; + vertical-align: middle; + font-size: 14px; + font-weight: 500; +} + +.psdk-vertical-step-label-selected { + display: inline-block; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + min-width: 50px; + vertical-align: middle; + font-size: 14px; + font-weight: 500; +} + +.psdk-vertical-step-body { + margin-left: 36px; + border: 0; + position: relative; + display: block; + text-align: left; +} +.psdk-vertical-step-line { + display: block; +} + +.psdk-vertical-step-line::before { + content: ''; + position: absolute; + left: 0; + border-left-width: 1px; + border-left-style: solid; + top: -16px; + bottom: -16px; +} + +.psdk-horizontal-stepper { + background-color: transparent; + display: block; +} + +.psdk-horizontal-step-icon { + border-radius: 50%; + height: 24px; + width: 24px; + flex-shrink: 0; + position: relative; + display: block; + margin-right: 8px; + flex: none; +} + +.psdk-horizontal-step-label { + display: inline-block; + min-width: 50px; + vertical-align: middle; + font-size: 14px; + font-weight: 500; + white-space: initial; +} + +@keyframes pulse { + 0% { + transform: scale(1); + box-shadow: 0 0 0 0 rgba(106, 27, 154, 0.7); + } + 70% { + transform: scale(1.05); + box-shadow: 0 0 0 10px rgba(106, 27, 154, 0); + } + 100% { + transform: scale(1); + box-shadow: 0 0 0 0 rgba(106, 27, 154, 0); + } +} + +/* --- Main Stepper Container --- */ +.psdk-horizontal-stepper-header-container { + display: flex; + align-items: flex-start; /* Aligns circles and lines from the top */ + justify-content: space-around; + padding: 24px 0; + padding-left: 1rem; + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif; +} + +/* --- Individual Step (Circle + Label) --- */ +.psdk-horizontal-step-header { + display: flex; + flex-direction: column; + align-items: center; + width: 120px; /* Provides consistent spacing for labels */ + text-align: center; + padding: 1rem 0; +} + +/* --- Step Icon Circle (dynamically classed container) --- */ +.psdk-horizontal-step-header > div:first-child { + width: 40px; + height: 40px; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + margin-bottom: 8px; /* Space between circle and label */ + position: relative; + z-index: 2; /* Ensures the circle is on top of the line */ + transition: + background-color 0.3s ease, + transform 0.3s ease; +} + +/* --- Icon Content (Number or Checkmark) --- */ +.psdk-horizontal-step-icon-content { + font-size: 16px; + font-weight: 500; +} + +/* --- Connecting Line --- */ +.psdk-horizontal-step-line { + height: 2px; + flex-grow: 1; + /* Position the line to be in the vertical middle of the circles */ + position: relative; + top: 19px; + z-index: 1; + margin: 1rem 0; + transition: background-color 0.3s ease; +} + +/* --- 1. Visited/Completed Step (e.g., "Personal Information") --- */ +.psdk-icon-visited { + background-color: #5a3a9b; /* Dark Purple */ + border: 1px solid #5a3a9b; +} + +/* Hide the step number in visited steps */ +.psdk-icon-visited .psdk-horizontal-step-icon-content span { + display: none; +} + +/* Create the checkmark using a pseudo-element */ +.psdk-icon-visited::after { + content: '✓'; + color: white; + font-size: 24px; + font-weight: bold; +} + +.psdk-label-visited .psdk-horizontal-step-text-label { + color: #333333; /* Dark text for active/completed labels */ + font-weight: 500; +} + +/* --- 2. Current Step (e.g., "Address") --- */ +.psdk-icon-current { + background-color: #5a3a9b; /* Dark Purple */ + border: 1px solid #5a3a9b; + animation: pulse 2s infinite cubic-bezier(0.66, 0, 0, 1); +} + +.psdk-icon-current .psdk-horizontal-step-icon-content { + color: white; /* White number */ + // animation: pulse 2s infinite cubic-bezier(0.66, 0, 0, 1); +} + +.psdk-label-current .psdk-horizontal-step-text-label { + color: #333333; /* Dark text */ + font-weight: 500; +} + +/* --- 3. Future Step (e.g., "Service") --- */ +.psdk-icon-future { + background-color: #e6e0e9; /* Light Gray */ + border: 1px solid #e6e0e9; +} + +.psdk-icon-future .psdk-horizontal-step-icon-content { + color: #49454f; +} + +.psdk-label-future .psdk-horizontal-step-text-label { + color: #49454f; +} + +/* --- 4. Connecting Line Color Logic --- */ + +/* Default line color is gray */ +.psdk-horizontal-step-line { + background-color: #e0e0e0; +} + +/* + * Use the :has() pseudo-class to style the line following a completed step. + * This looks inside a step header for a '.psdk-icon-visited' class and styles + * the next sibling element that is a '.psdk-horizontal-step-line'. +*/ +.psdk-horizontal-step-header:has(.psdk-icon-visited) + .psdk-horizontal-step-line { + background-color: #5a3a9b; /* Dark Purple Line */ + // animation: pulse 2s infinite cubic-bezier(0.66, 0, 0, 1); +} diff --git a/src/app/_samples/mediaco/components/multi-step/multi-step.component.spec.ts b/src/app/_samples/mediaco/components/multi-step/multi-step.component.spec.ts new file mode 100644 index 00000000..750b53b2 --- /dev/null +++ b/src/app/_samples/mediaco/components/multi-step/multi-step.component.spec.ts @@ -0,0 +1,24 @@ +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; + +import { MultiStepComponent } from './multi-step.component'; + +describe('MultiStepComponent', () => { + let component: MultiStepComponent; + let fixture: ComponentFixture; + + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [MultiStepComponent] + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(MultiStepComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/_samples/mediaco/components/multi-step/multi-step.component.ts b/src/app/_samples/mediaco/components/multi-step/multi-step.component.ts new file mode 100644 index 00000000..567f55d4 --- /dev/null +++ b/src/app/_samples/mediaco/components/multi-step/multi-step.component.ts @@ -0,0 +1,91 @@ +import { Component, OnInit, Input, Output, EventEmitter, forwardRef } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormGroup } from '@angular/forms'; +import { Utils, ComponentMapperComponent } from '@pega/angular-sdk-components'; + +@Component({ + selector: 'app-multi-step', + templateUrl: './multi-step.component.html', + styleUrls: ['./multi-step.component.scss'], + providers: [Utils], + imports: [CommonModule, forwardRef(() => ComponentMapperComponent)] +}) +export class MultiStepComponent implements OnInit { + @Input() pConn$: typeof PConnect; + @Input() formGroup$: FormGroup; + @Input() arMainButtons$: any[]; + @Input() arSecondaryButtons$: any[]; + @Input() arChildren$: any[]; + @Input() bIsVertical$: boolean; + @Input() arCurrentStepIndicies$: number[]; + @Input() arNavigationSteps$: any[]; + @Output() actionButtonClick: EventEmitter = new EventEmitter(); + + svgCurrent$: string; + svgNotCurrent$: string; + bShow$ = true; + + constructor(private utils: Utils) {} + + ngOnInit(): void { + // svg icons + this.svgCurrent$ = this.utils.getImageSrc('circle-solid', this.utils.getSDKStaticContentUrl()); + this.svgNotCurrent$ = this.utils.getImageSrc('circle-solid', this.utils.getSDKStaticContentUrl()); + } + + onActionButtonClick(oData: any) { + this.actionButtonClick.emit(oData); + } + + _getVIconClass(status): string { + if (status == 'current') { + return 'psdk-vertical-step-icon-selected'; + } + + return 'psdk-vertical-step-icon'; + } + + _getVLabelClass(status): string { + if (status == 'current') { + return 'psdk-vertical-step-label-selected'; + } + + return 'psdk-vertical-step-label'; + } + + _getVBodyClass(index: number): string { + if (index < this.arNavigationSteps$.length - 1) { + return 'psdk-vertical-step-body psdk-vertical-step-line'; + } + + return 'psdk-vertical-step-body'; + } + + _getHIconClass(status): string { + if (status == 'current') { + return 'psdk-icon-current'; + } + + if (status == 'success') { + return 'psdk-icon-visited'; + } + + return 'psdk-icon-future'; + } + + _getHLabelClass(status): string { + if (status == 'current') { + return 'psdk-label-current'; + } + + if (status == 'success') { + return 'psdk-label-visited'; + } + + return 'psdk-label-future'; + } + + _showHLine(index: number): boolean { + return index < this.arNavigationSteps$.length - 1; + } +} diff --git a/src/app/_samples/mediaco/sdk-mediaco-component-map.ts b/src/app/_samples/mediaco/sdk-mediaco-component-map.ts index a06de263..56943898 100644 --- a/src/app/_samples/mediaco/sdk-mediaco-component-map.ts +++ b/src/app/_samples/mediaco/sdk-mediaco-component-map.ts @@ -2,6 +2,7 @@ import { AppShellComponent } from './components/app-shell/app-shell.component'; import { BannerComponent } from './components/banner/banner.component'; import { ListViewComponent } from './components/list-view/list-view.component'; +import { MultiStepComponent } from './components/multi-step/multi-step.component'; import { QuickCreateComponent } from './components/quick-create/quick-create.component'; import { TodoComponent } from './components/todo/todo.component'; import { WssNavBarComponent } from './components/wss-nav-bar/wss-nav-bar.component'; @@ -15,6 +16,7 @@ const sdkMediaCoComponentMap = { AppShell: AppShellComponent, Banner: BannerComponent, ListView: ListViewComponent, + MultiStep: MultiStepComponent, QuickCreate: QuickCreateComponent, Todo: TodoComponent, WssNavBar: WssNavBarComponent