Skip to content
Merged

PD-5452 #2826

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions projects/orcid-ui-docs/src/app/app.routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,13 @@ export const routes: Routes = [
(m) => m.SkeletonPlaceholderPageComponent
),
},
{
path: 'step-view',
loadComponent: () =>
import('./pages/orcid-ui/step-view-page.component').then(
(m) => m.StepViewPageComponent
),
},
{
path: 'auth-challenge',
loadComponent: () =>
Expand Down
1 change: 1 addition & 0 deletions projects/orcid-ui-docs/src/app/docs-shell.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ <h1 class="docs-logo">Orcid UI</h1>
<a routerLink="/skeleton-placeholder" routerLinkActive="active">
Skeleton Placeholder
</a>
<a routerLink="/step-view" routerLinkActive="active"> Step View </a>
<a routerLink="/material-buttons-directives" routerLinkActive="active">
Material Buttons Directives
</a>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
<app-documentation-page
i18n-title="@@orcidUiDocs.stepView.title"
i18n-description="@@orcidUiDocs.stepView.description"
title="Step View"
description="A reusable step shell for guided flows with title/subtitle, projected body content, optional footer projection, and a primary action output."
>
<div controls>
<p>Change these values to preview `orcid-step-view` behavior:</p>
<div class="controls-grid">
<mat-form-field appearance="outline">
<mat-label>Title</mat-label>
<input matInput [(ngModel)]="config.title" />
</mat-form-field>

<mat-form-field appearance="outline">
<mat-label>Subtitle</mat-label>
<input matInput [(ngModel)]="config.subtitle" />
</mat-form-field>

<mat-form-field appearance="outline">
<mat-label>Primary action label</mat-label>
<input matInput [(ngModel)]="config.primaryLabel" />
</mat-form-field>

<mat-checkbox [(ngModel)]="config.primaryDisabled">
Disable primary action
</mat-checkbox>

<mat-checkbox [(ngModel)]="config.fullWidthActions">
Full width actions
</mat-checkbox>
</div>
</div>

<div examples>
<div class="example-container">
<orcid-step-view
[title]="config.title"
[subtitle]="config.subtitle"
[primaryLabel]="config.primaryLabel"
[primaryDisabled]="config.primaryDisabled"
[fullWidthActions]="config.fullWidthActions"
>
<p class="orc-ui-font-body body-copy">
Use this projected body region for form controls and explanatory text.
</p>
<p class="orc-ui-font-body-small body-copy">
The parent flow controls step transitions and handles output events.
</p>

<div orcidStepViewFooter class="preview-footer">
<button mat-button type="button">Projected footer action</button>
</div>
</orcid-step-view>
</div>
</div>

<div usage>
<pre><code class="language-html">&lt;orcid-step-view
[title]="title"
[subtitle]="subtitle"
[primaryLabel]="primaryLabel"
[primaryDisabled]="isPrimaryDisabled"
(primaryAction)="onPrimary()"
&gt;
&lt;div&gt;Step content goes here&lt;/div&gt;

&lt;div orcidStepViewFooter&gt;
&lt;button mat-button type="button"&gt;Extra footer control&lt;/button&gt;
&lt;/div&gt;
&lt;/orcid-step-view&gt;</code></pre>
</div>

<div inputs>
<h4>Inputs</h4>
<ul>
<li><code>title</code>: Main step title.</li>
<li>
<code>subtitle</code>: Optional secondary line (for step count copy).
</li>
<li><code>primaryLabel</code>: Optional primary button label.</li>
<li><code>primaryDisabled</code>: Disables primary action.</li>
<li>
<code>fullWidthActions</code>: Makes action buttons stretch to width.
</li>
</ul>

<h4>Outputs</h4>
<ul>
<li>
<code>primaryAction</code>: Emitted when primary action is clicked.
</li>
</ul>

<h4>Slots</h4>
<ul>
<li>Default slot: Main step body content.</li>
<li>
<code>[orcidStepViewFooter]</code>: Optional projected footer area.
</li>
</ul>
</div>
</app-documentation-page>
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
.controls-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
gap: 16px;
margin-top: 16px;
}

.example-container {
max-width: 680px;
}

.body-copy {
margin: 0;
}

.preview-footer {
display: flex;
justify-content: flex-end;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { CommonModule } from '@angular/common'
import { Component } from '@angular/core'
import { FormsModule } from '@angular/forms'
import { MatButtonModule } from '@angular/material/button'
import { MatCheckboxModule } from '@angular/material/checkbox'
import { MatFormFieldModule } from '@angular/material/form-field'
import { MatInputModule } from '@angular/material/input'
import { OrcidStepViewComponent } from '@orcid/ui'
import { DocumentationPageComponent } from '../../components/documentation-page/documentation-page.component'

@Component({
selector: 'orcid-step-view-page',
standalone: true,
imports: [
CommonModule,
FormsModule,
MatButtonModule,
MatCheckboxModule,
MatFormFieldModule,
MatInputModule,
OrcidStepViewComponent,
DocumentationPageComponent,
],
templateUrl: './step-view-page.component.html',
styleUrls: ['./step-view-page.component.scss'],
})
export class StepViewPageComponent {
config = {
title: 'Enable two-factor authentication',
subtitle: 'Step 1 of 2 - Authentication app',
primaryLabel: 'Next step - 2FA recovery codes',
primaryDisabled: false,
fullWidthActions: true,
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<section class="orcid-step-view">
<header class="orcid-step-view__header">
<img
*ngIf="showHeaderIcon"
class="orcid-step-view__icon"
[src]="headerIconSrc"
[alt]="headerIconAlt"
/>
<h2 class="orcid-step-view__title">{{ title }}</h2>
<p *ngIf="subtitle" class="orcid-step-view__subtitle">{{ subtitle }}</p>
</header>

<div class="orcid-step-view__body">
<ng-content></ng-content>
</div>

<footer class="orcid-step-view__footer">
<ng-content select="[orcidStepViewFooter]"></ng-content>
<div class="orcid-step-view__footer-divider"></div>
<div
class="orcid-step-view__actions"
[class.orcid-step-view__actions--full]="fullWidthActions"
>
<button
*ngIf="primaryLabel"
mat-flat-button
class="orcid-step-view__primary-action"
type="button"
[disabled]="primaryDisabled"
(click)="primaryAction.emit()"
>
{{ primaryLabel }}
</button>
</div>
</footer>
</section>
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
:host {
display: block;
}

.orcid-step-view {
background: var(--orcid-surface, #ffffff);
border: 1px solid var(--orcid-ui-background, #bdbdbd);
border-radius: var(--orcid-space-2, 8px);
padding: var(--orcid-space-xl, 64px);
display: flex;
flex-direction: column;
gap: var(--orcid-space-8, 32px);
}

.orcid-step-view__header {
display: flex;
flex-direction: column;
gap: var(--orcid-space-2, 8px);
text-align: center;
}

.orcid-step-view__icon {
width: 64px;
height: 64px;
margin: 0 auto;
margin-bottom: var(--orcid-space-m, 24px);
}

.orcid-step-view__title {
margin: 0;
color: var(--orcid-color-text-dark-high, #000000);
font-family: var(--orcid-font-family-sans, 'Noto Sans', sans-serif);
font-size: var(--orcid-font-size-heading-small, 24px);
font-weight: var(--orcid-font-weight-medium, 500);
line-height: 1.5;
}

.orcid-step-view__subtitle {
margin: 0;
color: rgba(0, 0, 0, 0.6);
font-family: var(--orcid-font-family-sans, 'Noto Sans', sans-serif);
font-size: var(--orcid-font-size-body-small, 14px);
font-weight: var(--orcid-font-weight-regular, 400);
line-height: 1.5;
}

.orcid-step-view__body {
display: flex;
flex-direction: column;
}

.orcid-step-view__footer {
display: flex;
flex-direction: column;
gap: var(--orcid-space-8, 32px);
}

.orcid-step-view__footer-divider {
width: 100%;
border-top: 1px solid var(--orcid-color-border-subtle, #dddddd);
}

.orcid-step-view__actions {
display: flex;
gap: var(--orcid-space-4, 16px);
justify-content: center;
}

.orcid-step-view__actions--full {
width: 100%;
}

.orcid-step-view__actions--full button {
flex: 1 1 auto;
}

.orcid-step-view__primary-action {
background-color: var(--orcid-color-brand-secondary-dark, #085c77) !important;
color: var(--orcid-color-text-light-high, #ffffff) !important;
}

.orcid-step-view__primary-action[disabled] {
opacity: 0.6;
}

@media (max-width: 767px) {
.orcid-step-view {
padding: var(--orcid-space-4, 16px);
border: 0;
border-radius: 0;
}

.orcid-step-view__icon {
margin-bottom: var(--orcid-space-s, 8px);
}

.orcid-step-view__actions {
flex-direction: column;
width: 100%;
}

.orcid-step-view__actions button {
width: 100%;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { Component, EventEmitter, Input, Output } from '@angular/core'
import { NgIf } from '@angular/common'
import { MatButtonModule } from '@angular/material/button'

@Component({
selector: 'orcid-step-view',
standalone: true,
imports: [NgIf, MatButtonModule],
templateUrl: './step-view.component.html',
styleUrls: ['./step-view.component.scss'],
})
export class OrcidStepViewComponent {
/** Main title displayed at the top of the step view. */
@Input() title = ''

/** Optional subtitle shown below title (e.g. Step 1 of 2). */
@Input() subtitle = ''

/** Show ORCID icon block in header. */
@Input() showHeaderIcon = true

/** Header icon source path. */
@Input() headerIconSrc = 'assets/vectors/orcid.logo.icon.svg'

/** Header icon alt text. */
@Input() headerIconAlt = 'orcid logo'

/** Optional text for the primary action button. */
@Input() primaryLabel = ''

/** Disables the primary action button when true. */
@Input() primaryDisabled = false

/** Whether footer buttons should fill the container width. */
@Input() fullWidthActions = true

@Output() primaryAction = new EventEmitter<void>()
}
1 change: 1 addition & 0 deletions projects/orcid-ui/src/public-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ export * from './lib/components/action-surface-container/action-surface-containe
export * from './lib/components/panel/panel.component'
export * from './lib/components/skeleton-placeholder/skeleton-placeholder.component'
export * from './lib/components/modal/modal.component'
export * from './lib/components/step-view/step-view.component'
Loading
Loading