@daltonr/pathwrite-angular 0.6.3 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2026 Richard Dalton
3
+ Copyright (c) 2026 Devjoy Ltd.
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -798,8 +798,8 @@ onSubPathComplete(subPathId, subPathData, ctx, meta) {
798
798
  }
799
799
  ```
800
800
 
801
- **3. Progress bar switches during sub-paths**
802
- When `snapshot.nestingLevel > 0`, you're in a sub-path. The `steps` array in the snapshot contains the sub-path's steps, not the main path's. The default PathShell progress bar shows sub-path progress. You can check `nestingLevel` to show a breadcrumb or "back to main flow" indicator.
801
+ **3. Root progress bar persists during sub-paths**
802
+ When `snapshot.nestingLevel > 0`, you're in a sub-path. The shell automatically renders a compact, muted **root progress bar** above the sub-path's own progress bar so users always see their place in the main flow. The `steps` array in the snapshot contains the sub-path's steps. Use `snapshot.rootProgress` (type `RootProgress`) in a custom `pwShellHeader` template to render your own persistent top-level indicator.
803
803
 
804
804
  **4. Accessing parent path data from sub-path components**
805
805
  There is currently no way to inject a "parent facade" in sub-path step components. If a sub-path step needs parent data (e.g., the document title), pass it via `initialData` when calling `startSubPath`:
@@ -1005,3 +1005,8 @@ Override any `--pw-*` variable to customise the appearance:
1005
1005
  - `--pw-btn-padding` — Button padding (default: `8px 16px`)
1006
1006
  - `--pw-btn-radius` — Button border radius (default: `6px`)
1007
1007
 
1008
+
1009
+ ---
1010
+
1011
+ © 2026 Devjoy Ltd. MIT License.
1012
+
package/dist/index.css CHANGED
@@ -77,6 +77,75 @@
77
77
  font-size: 14px;
78
78
  }
79
79
 
80
+ /* ------------------------------------------------------------------ */
81
+ /* Root progress — persistent top-level bar visible during sub-paths */
82
+ /* ------------------------------------------------------------------ */
83
+ .pw-shell__root-progress {
84
+ background: var(--pw-color-bg);
85
+ border: 1px solid var(--pw-color-border);
86
+ border-radius: var(--pw-shell-radius);
87
+ padding: 20px 24px 16px;
88
+ }
89
+
90
+ .pw-shell__root-progress .pw-shell__steps {
91
+ display: flex;
92
+ justify-content: space-between;
93
+ margin-bottom: 12px;
94
+ }
95
+
96
+ .pw-shell__root-progress .pw-shell__step {
97
+ display: flex;
98
+ flex-direction: column;
99
+ align-items: center;
100
+ gap: 6px;
101
+ flex: 1;
102
+ }
103
+
104
+ /* Merge root progress + sub-path header into a single card */
105
+ .pw-shell__root-progress + .pw-shell__header {
106
+ margin-top: calc(-1 * var(--pw-shell-gap));
107
+ border-top: 1px solid var(--pw-color-border);
108
+ border-top-left-radius: 0;
109
+ border-top-right-radius: 0;
110
+ padding: 12px 24px 12px;
111
+ opacity: 0.6;
112
+ }
113
+
114
+ .pw-shell__root-progress:has(+ .pw-shell__header) {
115
+ border-bottom-left-radius: 0;
116
+ border-bottom-right-radius: 0;
117
+ padding-bottom: 12px;
118
+ }
119
+
120
+ .pw-shell__root-progress + .pw-shell__header .pw-shell__steps {
121
+ margin-bottom: 6px;
122
+ }
123
+
124
+ .pw-shell__root-progress + .pw-shell__header .pw-shell__step-dot {
125
+ width: 22px;
126
+ height: 22px;
127
+ font-size: 10px;
128
+ }
129
+
130
+ .pw-shell__root-progress + .pw-shell__header .pw-shell__step-label {
131
+ font-size: 10px;
132
+ }
133
+
134
+ .pw-shell__root-progress + .pw-shell__header .pw-shell__track {
135
+ height: 3px;
136
+ }
137
+
138
+ /* Split layout — disable the merged-card effect */
139
+ .pw-shell--progress-split .pw-shell__root-progress + .pw-shell__header {
140
+ margin-top: 0;
141
+ border-top: 1px solid var(--pw-color-border);
142
+ border-radius: var(--pw-shell-radius);
143
+ }
144
+ .pw-shell--progress-split .pw-shell__root-progress:has(+ .pw-shell__header) {
145
+ border-radius: var(--pw-shell-radius);
146
+ padding-bottom: 16px;
147
+ }
148
+
80
149
  /* ------------------------------------------------------------------ */
81
150
  /* Header — progress indicator */
82
151
  /* ------------------------------------------------------------------ */
@@ -177,6 +246,9 @@
177
246
  --pw-color-error: #dc2626;
178
247
  --pw-color-error-bg: #fef2f2;
179
248
  --pw-color-error-border: #fecaca;
249
+ --pw-color-warning: #d97706;
250
+ --pw-color-warning-bg: #fffbeb;
251
+ --pw-color-warning-border: #fde68a;
180
252
  }
181
253
 
182
254
  .pw-shell__validation {
@@ -213,6 +285,43 @@
213
285
  content: ":";
214
286
  }
215
287
 
288
+ /* ------------------------------------------------------------------ */
289
+ /* Warning messages */
290
+ /* ------------------------------------------------------------------ */
291
+ .pw-shell__warnings {
292
+ list-style: none;
293
+ margin: 0;
294
+ padding: 12px 16px;
295
+ background: var(--pw-color-warning-bg);
296
+ border: 1px solid var(--pw-color-warning-border);
297
+ border-radius: var(--pw-shell-radius);
298
+ display: flex;
299
+ flex-direction: column;
300
+ gap: 4px;
301
+ }
302
+
303
+ .pw-shell__warnings-item {
304
+ font-size: 13px;
305
+ color: var(--pw-color-warning);
306
+ padding-left: 16px;
307
+ position: relative;
308
+ }
309
+
310
+ .pw-shell__warnings-item::before {
311
+ content: "•";
312
+ position: absolute;
313
+ left: 4px;
314
+ }
315
+
316
+ .pw-shell__warnings-label {
317
+ font-weight: 600;
318
+ margin-right: 3px;
319
+ }
320
+
321
+ .pw-shell__warnings-label::after {
322
+ content: ":";
323
+ }
324
+
216
325
  /* ------------------------------------------------------------------ */
217
326
  /* Footer — navigation buttons */
218
327
  /* ------------------------------------------------------------------ */
package/dist/index.d.ts CHANGED
@@ -56,6 +56,9 @@ export declare class PathFacade<TData extends PathData = PathData> implements On
56
56
  previous(): Promise<void>;
57
57
  cancel(): Promise<void>;
58
58
  setData<K extends string & keyof TData>(key: K, value: TData[K]): Promise<void>;
59
+ /** Reset the current step's data to what it was when the step was entered.
60
+ * Useful for "Clear" or "Reset" buttons that undo changes within a step. */
61
+ resetStep(): Promise<void>;
59
62
  goToStep(stepId: string): Promise<void>;
60
63
  /** Jump to a step by ID, checking the current step's canMoveNext (forward) or
61
64
  * canMovePrevious (backward) guard first. Navigation is blocked if the guard
@@ -85,6 +88,8 @@ export interface InjectPathReturn<TData extends PathData = PathData> {
85
88
  cancel: () => Promise<void>;
86
89
  /** Update a single data field. */
87
90
  setData: <K extends string & keyof TData>(key: K, value: TData[K]) => Promise<void>;
91
+ /** Reset the current step's data to what it was when the step was entered. */
92
+ resetStep: () => Promise<void>;
88
93
  /** Jump to a step by ID without checking guards. */
89
94
  goToStep: (stepId: string) => Promise<void>;
90
95
  /** Jump to a step by ID, checking guards first. */
@@ -173,5 +178,5 @@ export interface FormGroupLike {
173
178
  * ```
174
179
  */
175
180
  export declare function syncFormGroup<TData extends PathData = PathData>(facade: PathFacade<TData>, formGroup: FormGroupLike, destroyRef?: DestroyRef): () => void;
176
- export type { PathData, FieldErrors, PathDefinition, PathEvent, PathSnapshot, PathStep, PathStepContext, SerializedPathState } from "@daltonr/pathwrite-core";
181
+ export type { PathData, FieldErrors, PathDefinition, PathEvent, PathSnapshot, PathStep, PathStepContext, ProgressLayout, RootProgress, SerializedPathState } from "@daltonr/pathwrite-core";
177
182
  export { PathEngine } from "@daltonr/pathwrite-core";
package/dist/index.js CHANGED
@@ -98,6 +98,11 @@ export class PathFacade {
98
98
  setData(key, value) {
99
99
  return this._engine.setData(key, value);
100
100
  }
101
+ /** Reset the current step's data to what it was when the step was entered.
102
+ * Useful for "Clear" or "Reset" buttons that undo changes within a step. */
103
+ resetStep() {
104
+ return this._engine.resetStep();
105
+ }
101
106
  goToStep(stepId) {
102
107
  return this._engine.goToStep(stepId);
103
108
  }
@@ -166,6 +171,7 @@ export function injectPath() {
166
171
  previous: () => facade.previous(),
167
172
  cancel: () => facade.cancel(),
168
173
  setData: (key, value) => facade.setData(key, value),
174
+ resetStep: () => facade.resetStep(),
169
175
  goToStep: (stepId) => facade.goToStep(stepId),
170
176
  goToStepChecked: (stepId) => facade.goToStepChecked(stepId),
171
177
  restart: (path, initialData = {}) => facade.restart(path, initialData),
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/shell.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { TemplateRef, EventEmitter, QueryList, OnInit, OnDestroy, Injector } from "@angular/core";
2
- import { PathData, PathDefinition, PathEvent, PathSnapshot } from "@daltonr/pathwrite-core";
2
+ import { PathData, PathDefinition, PathEvent, PathSnapshot, ProgressLayout } from "@daltonr/pathwrite-core";
3
3
  import { PathFacade } from "./index";
4
4
  import * as i0 from "@angular/core";
5
5
  /**
@@ -129,6 +129,14 @@ export declare class PathShellComponent implements OnInit, OnDestroy {
129
129
  * - `"both"`: Render the shell summary AND whatever the step template renders.
130
130
  */
131
131
  validationDisplay: "summary" | "inline" | "both";
132
+ /**
133
+ * Controls how progress bars are arranged when a sub-path is active.
134
+ * - "merged" (default): Root and sub-path bars in one card.
135
+ * - "split": Root and sub-path bars as separate cards.
136
+ * - "rootOnly": Only the root bar — sub-path bar hidden.
137
+ * - "activeOnly": Only the active (sub-path) bar — root bar hidden.
138
+ */
139
+ progressLayout: ProgressLayout;
132
140
  completed: EventEmitter<PathData>;
133
141
  cancelled: EventEmitter<PathData>;
134
142
  pathEvent: EventEmitter<PathEvent>;
@@ -156,13 +164,15 @@ export declare class PathShellComponent implements OnInit, OnDestroy {
156
164
  * ```
157
165
  */
158
166
  restart(): Promise<void>;
159
- /** Returns Object.entries(s.fieldMessages) for use in *ngFor. */
167
+ /** Returns Object.entries(s.fieldErrors) for use in *ngFor. */
160
168
  protected fieldEntries(s: PathSnapshot): [string, string][];
169
+ /** Returns Object.entries(s.fieldWarnings) for use in *ngFor. */
170
+ protected warningEntries(s: PathSnapshot): [string, string][];
161
171
  /** Resolves "auto" footerLayout based on snapshot. Single-step top-level → "form", otherwise → "wizard". */
162
172
  protected getResolvedFooterLayout(s: PathSnapshot): "wizard" | "form";
163
173
  /** Converts a camelCase or lowercase field key to a display label.
164
174
  * e.g. "firstName" → "First Name", "email" → "Email" */
165
175
  protected formatFieldKey(key: string): string;
166
176
  static ɵfac: i0.ɵɵFactoryDeclaration<PathShellComponent, never>;
167
- static ɵcmp: i0.ɵɵComponentDeclaration<PathShellComponent, "pw-shell", never, { "path": { "alias": "path"; "required": true; }; "initialData": { "alias": "initialData"; "required": false; }; "autoStart": { "alias": "autoStart"; "required": false; }; "backLabel": { "alias": "backLabel"; "required": false; }; "nextLabel": { "alias": "nextLabel"; "required": false; }; "completeLabel": { "alias": "completeLabel"; "required": false; }; "cancelLabel": { "alias": "cancelLabel"; "required": false; }; "hideCancel": { "alias": "hideCancel"; "required": false; }; "hideProgress": { "alias": "hideProgress"; "required": false; }; "footerLayout": { "alias": "footerLayout"; "required": false; }; "validationDisplay": { "alias": "validationDisplay"; "required": false; }; }, { "completed": "completed"; "cancelled": "cancelled"; "pathEvent": "pathEvent"; }, ["customHeader", "customFooter", "stepDirectives"], never, true, never>;
177
+ static ɵcmp: i0.ɵɵComponentDeclaration<PathShellComponent, "pw-shell", never, { "path": { "alias": "path"; "required": true; }; "initialData": { "alias": "initialData"; "required": false; }; "autoStart": { "alias": "autoStart"; "required": false; }; "backLabel": { "alias": "backLabel"; "required": false; }; "nextLabel": { "alias": "nextLabel"; "required": false; }; "completeLabel": { "alias": "completeLabel"; "required": false; }; "cancelLabel": { "alias": "cancelLabel"; "required": false; }; "hideCancel": { "alias": "hideCancel"; "required": false; }; "hideProgress": { "alias": "hideProgress"; "required": false; }; "footerLayout": { "alias": "footerLayout"; "required": false; }; "validationDisplay": { "alias": "validationDisplay"; "required": false; }; "progressLayout": { "alias": "progressLayout"; "required": false; }; }, { "completed": "completed"; "cancelled": "cancelled"; "pathEvent": "pathEvent"; }, ["customHeader", "customFooter", "stepDirectives"], never, true, never>;
168
178
  }
package/dist/shell.js CHANGED
@@ -135,6 +135,14 @@ export class PathShellComponent {
135
135
  * - `"both"`: Render the shell summary AND whatever the step template renders.
136
136
  */
137
137
  this.validationDisplay = "inline";
138
+ /**
139
+ * Controls how progress bars are arranged when a sub-path is active.
140
+ * - "merged" (default): Root and sub-path bars in one card.
141
+ * - "split": Root and sub-path bars as separate cards.
142
+ * - "rootOnly": Only the root bar — sub-path bar hidden.
143
+ * - "activeOnly": Only the active (sub-path) bar — root bar hidden.
144
+ */
145
+ this.progressLayout = "merged";
138
146
  this.completed = new EventEmitter();
139
147
  this.cancelled = new EventEmitter();
140
148
  this.pathEvent = new EventEmitter();
@@ -187,9 +195,13 @@ export class PathShellComponent {
187
195
  restart() {
188
196
  return this.facade.restart(this.path, this.initialData);
189
197
  }
190
- /** Returns Object.entries(s.fieldMessages) for use in *ngFor. */
198
+ /** Returns Object.entries(s.fieldErrors) for use in *ngFor. */
191
199
  fieldEntries(s) {
192
- return Object.entries(s.fieldMessages);
200
+ return Object.entries(s.fieldErrors);
201
+ }
202
+ /** Returns Object.entries(s.fieldWarnings) for use in *ngFor. */
203
+ warningEntries(s) {
204
+ return Object.entries(s.fieldWarnings);
193
205
  }
194
206
  /** Resolves "auto" footerLayout based on snapshot. Single-step top-level → "form", otherwise → "wizard". */
195
207
  getResolvedFooterLayout(s) {
@@ -203,7 +215,7 @@ export class PathShellComponent {
203
215
  return key.replace(/([A-Z])/g, " $1").replace(/^./, c => c.toUpperCase()).trim();
204
216
  }
205
217
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: PathShellComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
206
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: PathShellComponent, isStandalone: true, selector: "pw-shell", inputs: { path: "path", initialData: "initialData", autoStart: "autoStart", backLabel: "backLabel", nextLabel: "nextLabel", completeLabel: "completeLabel", cancelLabel: "cancelLabel", hideCancel: "hideCancel", hideProgress: "hideProgress", footerLayout: "footerLayout", validationDisplay: "validationDisplay" }, outputs: { completed: "completed", cancelled: "cancelled", pathEvent: "pathEvent" }, providers: [PathFacade], queries: [{ propertyName: "customHeader", first: true, predicate: PathShellHeaderDirective, descendants: true }, { propertyName: "customFooter", first: true, predicate: PathShellFooterDirective, descendants: true }, { propertyName: "stepDirectives", predicate: PathStepDirective }], ngImport: i0, template: `
218
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: PathShellComponent, isStandalone: true, selector: "pw-shell", inputs: { path: "path", initialData: "initialData", autoStart: "autoStart", backLabel: "backLabel", nextLabel: "nextLabel", completeLabel: "completeLabel", cancelLabel: "cancelLabel", hideCancel: "hideCancel", hideProgress: "hideProgress", footerLayout: "footerLayout", validationDisplay: "validationDisplay", progressLayout: "progressLayout" }, outputs: { completed: "completed", cancelled: "cancelled", pathEvent: "pathEvent" }, providers: [PathFacade], queries: [{ propertyName: "customHeader", first: true, predicate: PathShellHeaderDirective, descendants: true }, { propertyName: "customFooter", first: true, predicate: PathShellFooterDirective, descendants: true }, { propertyName: "stepDirectives", predicate: PathStepDirective }], ngImport: i0, template: `
207
219
  <!-- Empty state -->
208
220
  <div class="pw-shell" *ngIf="!(facade.state$ | async)">
209
221
  <div class="pw-shell__empty" *ngIf="!started">
@@ -213,13 +225,30 @@ export class PathShellComponent {
213
225
  </div>
214
226
 
215
227
  <!-- Active path -->
216
- <div class="pw-shell" *ngIf="facade.state$ | async as s">
228
+ <div class="pw-shell" [ngClass]="progressLayout !== 'merged' ? 'pw-shell--progress-' + progressLayout : ''" *ngIf="facade.state$ | async as s">
229
+ <!-- Root progress — persistent top-level bar visible during sub-paths -->
230
+ <div class="pw-shell__root-progress" *ngIf="!hideProgress && s.rootProgress && progressLayout !== 'activeOnly'">
231
+ <div class="pw-shell__steps">
232
+ <div
233
+ *ngFor="let step of s.rootProgress!.steps; let i = index"
234
+ class="pw-shell__step"
235
+ [ngClass]="'pw-shell__step--' + step.status"
236
+ >
237
+ <span class="pw-shell__step-dot">{{ step.status === 'completed' ? '✓' : (i + 1) }}</span>
238
+ <span class="pw-shell__step-label">{{ step.title ?? step.id }}</span>
239
+ </div>
240
+ </div>
241
+ <div class="pw-shell__track">
242
+ <div class="pw-shell__track-fill" [style.width.%]="s.rootProgress!.progress * 100"></div>
243
+ </div>
244
+ </div>
245
+
217
246
  <!-- Header — custom or default progress indicator -->
218
247
  <ng-container *ngIf="customHeader; else defaultHeader">
219
248
  <ng-container *ngTemplateOutlet="customHeader.templateRef; context: { $implicit: s }"></ng-container>
220
249
  </ng-container>
221
250
  <ng-template #defaultHeader>
222
- <div class="pw-shell__header" *ngIf="!hideProgress && (s.stepCount > 1 || s.nestingLevel > 0)">
251
+ <div class="pw-shell__header" *ngIf="!hideProgress && (s.stepCount > 1 || s.nestingLevel > 0) && progressLayout !== 'rootOnly'">
223
252
  <div class="pw-shell__steps">
224
253
  <div
225
254
  *ngFor="let step of s.steps; let i = index"
@@ -239,7 +268,8 @@ export class PathShellComponent {
239
268
  <!-- Body — step content -->
240
269
  <div class="pw-shell__body">
241
270
  <ng-container *ngFor="let stepDir of stepDirectives">
242
- <ng-container *ngIf="stepDir.stepId === s.stepId">
271
+ <!-- Match by formId first (inner step of a StepChoice), then stepId -->
272
+ <ng-container *ngIf="stepDir.stepId === (s.formId ?? s.stepId)">
243
273
  <ng-container *ngTemplateOutlet="stepDir.templateRef; injector: shellInjector"></ng-container>
244
274
  </ng-container>
245
275
  </ng-container>
@@ -252,6 +282,13 @@ export class PathShellComponent {
252
282
  </li>
253
283
  </ul>
254
284
 
285
+ <!-- Warning messages — non-blocking, shown immediately (no hasAttemptedNext gate) -->
286
+ <ul class="pw-shell__warnings" *ngIf="validationDisplay !== 'inline' && warningEntries(s).length > 0">
287
+ <li *ngFor="let entry of warningEntries(s)" class="pw-shell__warnings-item">
288
+ <span *ngIf="entry[0] !== '_'" class="pw-shell__warnings-label">{{ formatFieldKey(entry[0]) }}</span>{{ entry[1] }}
289
+ </li>
290
+ </ul>
291
+
255
292
  <!-- Footer — custom or default navigation buttons -->
256
293
  <ng-container *ngIf="customFooter; else defaultFooter">
257
294
  <ng-container *ngTemplateOutlet="customFooter.templateRef; context: { $implicit: s, actions: shellActions }"></ng-container>
@@ -316,13 +353,30 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
316
353
  </div>
317
354
 
318
355
  <!-- Active path -->
319
- <div class="pw-shell" *ngIf="facade.state$ | async as s">
356
+ <div class="pw-shell" [ngClass]="progressLayout !== 'merged' ? 'pw-shell--progress-' + progressLayout : ''" *ngIf="facade.state$ | async as s">
357
+ <!-- Root progress — persistent top-level bar visible during sub-paths -->
358
+ <div class="pw-shell__root-progress" *ngIf="!hideProgress && s.rootProgress && progressLayout !== 'activeOnly'">
359
+ <div class="pw-shell__steps">
360
+ <div
361
+ *ngFor="let step of s.rootProgress!.steps; let i = index"
362
+ class="pw-shell__step"
363
+ [ngClass]="'pw-shell__step--' + step.status"
364
+ >
365
+ <span class="pw-shell__step-dot">{{ step.status === 'completed' ? '✓' : (i + 1) }}</span>
366
+ <span class="pw-shell__step-label">{{ step.title ?? step.id }}</span>
367
+ </div>
368
+ </div>
369
+ <div class="pw-shell__track">
370
+ <div class="pw-shell__track-fill" [style.width.%]="s.rootProgress!.progress * 100"></div>
371
+ </div>
372
+ </div>
373
+
320
374
  <!-- Header — custom or default progress indicator -->
321
375
  <ng-container *ngIf="customHeader; else defaultHeader">
322
376
  <ng-container *ngTemplateOutlet="customHeader.templateRef; context: { $implicit: s }"></ng-container>
323
377
  </ng-container>
324
378
  <ng-template #defaultHeader>
325
- <div class="pw-shell__header" *ngIf="!hideProgress && (s.stepCount > 1 || s.nestingLevel > 0)">
379
+ <div class="pw-shell__header" *ngIf="!hideProgress && (s.stepCount > 1 || s.nestingLevel > 0) && progressLayout !== 'rootOnly'">
326
380
  <div class="pw-shell__steps">
327
381
  <div
328
382
  *ngFor="let step of s.steps; let i = index"
@@ -342,7 +396,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
342
396
  <!-- Body — step content -->
343
397
  <div class="pw-shell__body">
344
398
  <ng-container *ngFor="let stepDir of stepDirectives">
345
- <ng-container *ngIf="stepDir.stepId === s.stepId">
399
+ <!-- Match by formId first (inner step of a StepChoice), then stepId -->
400
+ <ng-container *ngIf="stepDir.stepId === (s.formId ?? s.stepId)">
346
401
  <ng-container *ngTemplateOutlet="stepDir.templateRef; injector: shellInjector"></ng-container>
347
402
  </ng-container>
348
403
  </ng-container>
@@ -355,6 +410,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
355
410
  </li>
356
411
  </ul>
357
412
 
413
+ <!-- Warning messages — non-blocking, shown immediately (no hasAttemptedNext gate) -->
414
+ <ul class="pw-shell__warnings" *ngIf="validationDisplay !== 'inline' && warningEntries(s).length > 0">
415
+ <li *ngFor="let entry of warningEntries(s)" class="pw-shell__warnings-item">
416
+ <span *ngIf="entry[0] !== '_'" class="pw-shell__warnings-label">{{ formatFieldKey(entry[0]) }}</span>{{ entry[1] }}
417
+ </li>
418
+ </ul>
419
+
358
420
  <!-- Footer — custom or default navigation buttons -->
359
421
  <ng-container *ngIf="customFooter; else defaultFooter">
360
422
  <ng-container *ngTemplateOutlet="customFooter.templateRef; context: { $implicit: s, actions: shellActions }"></ng-container>
@@ -424,6 +486,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
424
486
  type: Input
425
487
  }], validationDisplay: [{
426
488
  type: Input
489
+ }], progressLayout: [{
490
+ type: Input
427
491
  }], completed: [{
428
492
  type: Output
429
493
  }], cancelled: [{
package/dist/shell.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"shell.js","sourceRoot":"","sources":["../src/shell.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"shell.js","sourceRoot":"","sources":["../src/shell.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@daltonr/pathwrite-angular",
3
- "version": "0.6.3",
3
+ "version": "0.8.0",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "description": "Angular adapter for @daltonr/pathwrite-core — RxJS observables, signal-friendly, with optional <pw-shell> default UI.",
@@ -46,9 +46,9 @@
46
46
  "prepublishOnly": "test -d dist && echo 'dist already built, skipping' || (npm run clean && npm run build)"
47
47
  },
48
48
  "peerDependencies": {
49
- "@angular/core": ">=16.0.0",
50
- "@angular/common": ">=16.0.0",
51
- "@angular/forms": ">=16.0.0",
49
+ "@angular/common": ">=17.0.0",
50
+ "@angular/core": ">=17.0.0",
51
+ "@angular/forms": ">=17.0.0",
52
52
  "rxjs": "^7.0.0"
53
53
  },
54
54
  "peerDependenciesMeta": {
@@ -57,11 +57,11 @@
57
57
  }
58
58
  },
59
59
  "devDependencies": {
60
- "@angular/compiler": "^17.0.0",
61
- "@angular/compiler-cli": "^17.0.0"
60
+ "@angular/compiler": "^17.3.12",
61
+ "@angular/compiler-cli": "^17.3.12"
62
62
  },
63
63
  "dependencies": {
64
- "@daltonr/pathwrite-core": "^0.6.3"
64
+ "@daltonr/pathwrite-core": "^0.8.0"
65
65
  },
66
66
  "publishConfig": {
67
67
  "access": "public"
package/src/index.ts CHANGED
@@ -118,6 +118,12 @@ export class PathFacade<TData extends PathData = PathData> implements OnDestroy
118
118
  return this._engine.setData(key, value as unknown);
119
119
  }
120
120
 
121
+ /** Reset the current step's data to what it was when the step was entered.
122
+ * Useful for "Clear" or "Reset" buttons that undo changes within a step. */
123
+ public resetStep(): Promise<void> {
124
+ return this._engine.resetStep();
125
+ }
126
+
121
127
  public goToStep(stepId: string): Promise<void> {
122
128
  return this._engine.goToStep(stepId);
123
129
  }
@@ -158,6 +164,8 @@ export interface InjectPathReturn<TData extends PathData = PathData> {
158
164
  cancel: () => Promise<void>;
159
165
  /** Update a single data field. */
160
166
  setData: <K extends string & keyof TData>(key: K, value: TData[K]) => Promise<void>;
167
+ /** Reset the current step's data to what it was when the step was entered. */
168
+ resetStep: () => Promise<void>;
161
169
  /** Jump to a step by ID without checking guards. */
162
170
  goToStep: (stepId: string) => Promise<void>;
163
171
  /** Jump to a step by ID, checking guards first. */
@@ -223,6 +231,7 @@ export function injectPath<TData extends PathData = PathData>(): InjectPathRetur
223
231
  previous: () => facade.previous(),
224
232
  cancel: () => facade.cancel(),
225
233
  setData: (key, value) => facade.setData(key, value),
234
+ resetStep: () => facade.resetStep(),
226
235
  goToStep: (stepId) => facade.goToStep(stepId),
227
236
  goToStepChecked: (stepId) => facade.goToStepChecked(stepId),
228
237
  restart: (path, initialData = {}) => facade.restart(path, initialData),
@@ -307,6 +316,8 @@ export type {
307
316
  PathSnapshot,
308
317
  PathStep,
309
318
  PathStepContext,
319
+ ProgressLayout,
320
+ RootProgress,
310
321
  SerializedPathState
311
322
  } from "@daltonr/pathwrite-core";
312
323
 
package/src/shell.ts CHANGED
@@ -21,7 +21,9 @@ import {
21
21
  PathData,
22
22
  PathDefinition,
23
23
  PathEvent,
24
- PathSnapshot
24
+ PathSnapshot,
25
+ ProgressLayout,
26
+ RootProgress
25
27
  } from "@daltonr/pathwrite-core";
26
28
  import { PathFacade } from "./index";
27
29
 
@@ -147,13 +149,30 @@ export class PathShellFooterDirective {
147
149
  </div>
148
150
 
149
151
  <!-- Active path -->
150
- <div class="pw-shell" *ngIf="facade.state$ | async as s">
152
+ <div class="pw-shell" [ngClass]="progressLayout !== 'merged' ? 'pw-shell--progress-' + progressLayout : ''" *ngIf="facade.state$ | async as s">
153
+ <!-- Root progress — persistent top-level bar visible during sub-paths -->
154
+ <div class="pw-shell__root-progress" *ngIf="!hideProgress && s.rootProgress && progressLayout !== 'activeOnly'">
155
+ <div class="pw-shell__steps">
156
+ <div
157
+ *ngFor="let step of s.rootProgress!.steps; let i = index"
158
+ class="pw-shell__step"
159
+ [ngClass]="'pw-shell__step--' + step.status"
160
+ >
161
+ <span class="pw-shell__step-dot">{{ step.status === 'completed' ? '✓' : (i + 1) }}</span>
162
+ <span class="pw-shell__step-label">{{ step.title ?? step.id }}</span>
163
+ </div>
164
+ </div>
165
+ <div class="pw-shell__track">
166
+ <div class="pw-shell__track-fill" [style.width.%]="s.rootProgress!.progress * 100"></div>
167
+ </div>
168
+ </div>
169
+
151
170
  <!-- Header — custom or default progress indicator -->
152
171
  <ng-container *ngIf="customHeader; else defaultHeader">
153
172
  <ng-container *ngTemplateOutlet="customHeader.templateRef; context: { $implicit: s }"></ng-container>
154
173
  </ng-container>
155
174
  <ng-template #defaultHeader>
156
- <div class="pw-shell__header" *ngIf="!hideProgress && (s.stepCount > 1 || s.nestingLevel > 0)">
175
+ <div class="pw-shell__header" *ngIf="!hideProgress && (s.stepCount > 1 || s.nestingLevel > 0) && progressLayout !== 'rootOnly'">
157
176
  <div class="pw-shell__steps">
158
177
  <div
159
178
  *ngFor="let step of s.steps; let i = index"
@@ -173,7 +192,8 @@ export class PathShellFooterDirective {
173
192
  <!-- Body — step content -->
174
193
  <div class="pw-shell__body">
175
194
  <ng-container *ngFor="let stepDir of stepDirectives">
176
- <ng-container *ngIf="stepDir.stepId === s.stepId">
195
+ <!-- Match by formId first (inner step of a StepChoice), then stepId -->
196
+ <ng-container *ngIf="stepDir.stepId === (s.formId ?? s.stepId)">
177
197
  <ng-container *ngTemplateOutlet="stepDir.templateRef; injector: shellInjector"></ng-container>
178
198
  </ng-container>
179
199
  </ng-container>
@@ -186,6 +206,13 @@ export class PathShellFooterDirective {
186
206
  </li>
187
207
  </ul>
188
208
 
209
+ <!-- Warning messages — non-blocking, shown immediately (no hasAttemptedNext gate) -->
210
+ <ul class="pw-shell__warnings" *ngIf="validationDisplay !== 'inline' && warningEntries(s).length > 0">
211
+ <li *ngFor="let entry of warningEntries(s)" class="pw-shell__warnings-item">
212
+ <span *ngIf="entry[0] !== '_'" class="pw-shell__warnings-label">{{ formatFieldKey(entry[0]) }}</span>{{ entry[1] }}
213
+ </li>
214
+ </ul>
215
+
189
216
  <!-- Footer — custom or default navigation buttons -->
190
217
  <ng-container *ngIf="customFooter; else defaultFooter">
191
218
  <ng-container *ngTemplateOutlet="customFooter.templateRef; context: { $implicit: s, actions: shellActions }"></ng-container>
@@ -265,6 +292,14 @@ export class PathShellComponent implements OnInit, OnDestroy {
265
292
  * - `"both"`: Render the shell summary AND whatever the step template renders.
266
293
  */
267
294
  @Input() validationDisplay: "summary" | "inline" | "both" = "inline";
295
+ /**
296
+ * Controls how progress bars are arranged when a sub-path is active.
297
+ * - "merged" (default): Root and sub-path bars in one card.
298
+ * - "split": Root and sub-path bars as separate cards.
299
+ * - "rootOnly": Only the root bar — sub-path bar hidden.
300
+ * - "activeOnly": Only the active (sub-path) bar — root bar hidden.
301
+ */
302
+ @Input() progressLayout: ProgressLayout = "merged";
268
303
 
269
304
  @Output() completed = new EventEmitter<PathData>();
270
305
  @Output() cancelled = new EventEmitter<PathData>();
@@ -328,9 +363,14 @@ export class PathShellComponent implements OnInit, OnDestroy {
328
363
  return this.facade.restart(this.path, this.initialData);
329
364
  }
330
365
 
331
- /** Returns Object.entries(s.fieldMessages) for use in *ngFor. */
366
+ /** Returns Object.entries(s.fieldErrors) for use in *ngFor. */
332
367
  protected fieldEntries(s: PathSnapshot): [string, string][] {
333
- return Object.entries(s.fieldMessages) as [string, string][];
368
+ return Object.entries(s.fieldErrors) as [string, string][];
369
+ }
370
+
371
+ /** Returns Object.entries(s.fieldWarnings) for use in *ngFor. */
372
+ protected warningEntries(s: PathSnapshot): [string, string][] {
373
+ return Object.entries(s.fieldWarnings) as [string, string][];
334
374
  }
335
375
 
336
376
  /** Resolves "auto" footerLayout based on snapshot. Single-step top-level → "form", otherwise → "wizard". */