@daltonr/pathwrite-angular 0.4.0 → 0.6.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/README.md +266 -4
- package/dist/index.css +9 -0
- package/dist/index.d.ts +87 -4
- package/dist/index.js +97 -13
- package/dist/index.js.map +1 -1
- package/dist/shell.d.ts +27 -3
- package/dist/shell.js +83 -21
- package/dist/shell.js.map +1 -1
- package/package.json +4 -3
- package/src/index.ts +142 -14
- package/src/shell.ts +62 -11
package/dist/shell.d.ts
CHANGED
|
@@ -108,13 +108,20 @@ export declare class PathShellComponent implements OnInit, OnDestroy {
|
|
|
108
108
|
/** Label for the Next navigation button. */
|
|
109
109
|
nextLabel: string;
|
|
110
110
|
/** Label for the Next button when on the last step. */
|
|
111
|
-
|
|
111
|
+
completeLabel: string;
|
|
112
112
|
/** Label for the Cancel button. */
|
|
113
113
|
cancelLabel: string;
|
|
114
114
|
/** Hide the Cancel button entirely. */
|
|
115
115
|
hideCancel: boolean;
|
|
116
|
-
/** Hide the step progress indicator in the header. */
|
|
116
|
+
/** Hide the step progress indicator in the header. Also hidden automatically when the path has only one step. */
|
|
117
117
|
hideProgress: boolean;
|
|
118
|
+
/**
|
|
119
|
+
* Footer layout mode:
|
|
120
|
+
* - "auto" (default): Uses "form" for single-step top-level paths, "wizard" otherwise.
|
|
121
|
+
* - "wizard": Back button on left, Cancel and Submit together on right.
|
|
122
|
+
* - "form": Cancel on left, Submit alone on right. Back button never shown.
|
|
123
|
+
*/
|
|
124
|
+
footerLayout: "wizard" | "form" | "auto";
|
|
118
125
|
completed: EventEmitter<PathData>;
|
|
119
126
|
cancelled: EventEmitter<PathData>;
|
|
120
127
|
pathEvent: EventEmitter<PathEvent>;
|
|
@@ -132,6 +139,23 @@ export declare class PathShellComponent implements OnInit, OnDestroy {
|
|
|
132
139
|
ngOnInit(): void;
|
|
133
140
|
ngOnDestroy(): void;
|
|
134
141
|
doStart(): void;
|
|
142
|
+
/**
|
|
143
|
+
* Restart the active path from step 1 with the original `initialData`,
|
|
144
|
+
* without unmounting the shell. Call this via a `#shell` template reference:
|
|
145
|
+
*
|
|
146
|
+
* ```html
|
|
147
|
+
* <pw-shell #shell [path]="myPath" ...></pw-shell>
|
|
148
|
+
* <button (click)="shell.restart()">Try Again</button>
|
|
149
|
+
* ```
|
|
150
|
+
*/
|
|
151
|
+
restart(): Promise<void>;
|
|
152
|
+
/** Returns Object.entries(s.fieldMessages) for use in *ngFor. */
|
|
153
|
+
protected fieldEntries(s: PathSnapshot): [string, string][];
|
|
154
|
+
/** Resolves "auto" footerLayout based on snapshot. Single-step top-level → "form", otherwise → "wizard". */
|
|
155
|
+
protected getResolvedFooterLayout(s: PathSnapshot): "wizard" | "form";
|
|
156
|
+
/** Converts a camelCase or lowercase field key to a display label.
|
|
157
|
+
* e.g. "firstName" → "First Name", "email" → "Email" */
|
|
158
|
+
protected formatFieldKey(key: string): string;
|
|
135
159
|
static ɵfac: i0.ɵɵFactoryDeclaration<PathShellComponent, never>;
|
|
136
|
-
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; }; "
|
|
160
|
+
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; }; }, { "completed": "completed"; "cancelled": "cancelled"; "pathEvent": "pathEvent"; }, ["customHeader", "customFooter", "stepDirectives"], never, true, never>;
|
|
137
161
|
}
|
package/dist/shell.js
CHANGED
|
@@ -110,17 +110,24 @@ export class PathShellComponent {
|
|
|
110
110
|
/** Start the path automatically on ngOnInit. Set to false to call doStart() manually. */
|
|
111
111
|
this.autoStart = true;
|
|
112
112
|
/** Label for the Back navigation button. */
|
|
113
|
-
this.backLabel = "
|
|
113
|
+
this.backLabel = "Previous";
|
|
114
114
|
/** Label for the Next navigation button. */
|
|
115
115
|
this.nextLabel = "Next";
|
|
116
116
|
/** Label for the Next button when on the last step. */
|
|
117
|
-
this.
|
|
117
|
+
this.completeLabel = "Complete";
|
|
118
118
|
/** Label for the Cancel button. */
|
|
119
119
|
this.cancelLabel = "Cancel";
|
|
120
120
|
/** Hide the Cancel button entirely. */
|
|
121
121
|
this.hideCancel = false;
|
|
122
|
-
/** Hide the step progress indicator in the header. */
|
|
122
|
+
/** Hide the step progress indicator in the header. Also hidden automatically when the path has only one step. */
|
|
123
123
|
this.hideProgress = false;
|
|
124
|
+
/**
|
|
125
|
+
* Footer layout mode:
|
|
126
|
+
* - "auto" (default): Uses "form" for single-step top-level paths, "wizard" otherwise.
|
|
127
|
+
* - "wizard": Back button on left, Cancel and Submit together on right.
|
|
128
|
+
* - "form": Cancel on left, Submit alone on right. Back button never shown.
|
|
129
|
+
*/
|
|
130
|
+
this.footerLayout = "auto";
|
|
124
131
|
this.completed = new EventEmitter();
|
|
125
132
|
this.cancelled = new EventEmitter();
|
|
126
133
|
this.pathEvent = new EventEmitter();
|
|
@@ -161,8 +168,35 @@ export class PathShellComponent {
|
|
|
161
168
|
this.started = true;
|
|
162
169
|
this.facade.start(this.path, this.initialData);
|
|
163
170
|
}
|
|
171
|
+
/**
|
|
172
|
+
* Restart the active path from step 1 with the original `initialData`,
|
|
173
|
+
* without unmounting the shell. Call this via a `#shell` template reference:
|
|
174
|
+
*
|
|
175
|
+
* ```html
|
|
176
|
+
* <pw-shell #shell [path]="myPath" ...></pw-shell>
|
|
177
|
+
* <button (click)="shell.restart()">Try Again</button>
|
|
178
|
+
* ```
|
|
179
|
+
*/
|
|
180
|
+
restart() {
|
|
181
|
+
return this.facade.restart(this.path, this.initialData);
|
|
182
|
+
}
|
|
183
|
+
/** Returns Object.entries(s.fieldMessages) for use in *ngFor. */
|
|
184
|
+
fieldEntries(s) {
|
|
185
|
+
return Object.entries(s.fieldMessages);
|
|
186
|
+
}
|
|
187
|
+
/** Resolves "auto" footerLayout based on snapshot. Single-step top-level → "form", otherwise → "wizard". */
|
|
188
|
+
getResolvedFooterLayout(s) {
|
|
189
|
+
return this.footerLayout === "auto"
|
|
190
|
+
? (s.stepCount === 1 && s.nestingLevel === 0 ? "form" : "wizard")
|
|
191
|
+
: this.footerLayout;
|
|
192
|
+
}
|
|
193
|
+
/** Converts a camelCase or lowercase field key to a display label.
|
|
194
|
+
* e.g. "firstName" → "First Name", "email" → "Email" */
|
|
195
|
+
formatFieldKey(key) {
|
|
196
|
+
return key.replace(/([A-Z])/g, " $1").replace(/^./, c => c.toUpperCase()).trim();
|
|
197
|
+
}
|
|
164
198
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: PathShellComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
165
|
-
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",
|
|
199
|
+
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" }, 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: `
|
|
166
200
|
<!-- Empty state -->
|
|
167
201
|
<div class="pw-shell" *ngIf="!(facade.state$ | async)">
|
|
168
202
|
<div class="pw-shell__empty" *ngIf="!started">
|
|
@@ -178,7 +212,7 @@ export class PathShellComponent {
|
|
|
178
212
|
<ng-container *ngTemplateOutlet="customHeader.templateRef; context: { $implicit: s }"></ng-container>
|
|
179
213
|
</ng-container>
|
|
180
214
|
<ng-template #defaultHeader>
|
|
181
|
-
<div class="pw-shell__header" *ngIf="!hideProgress">
|
|
215
|
+
<div class="pw-shell__header" *ngIf="!hideProgress && (s.stepCount > 1 || s.nestingLevel > 0)">
|
|
182
216
|
<div class="pw-shell__steps">
|
|
183
217
|
<div
|
|
184
218
|
*ngFor="let step of s.steps; let i = index"
|
|
@@ -204,9 +238,11 @@ export class PathShellComponent {
|
|
|
204
238
|
</ng-container>
|
|
205
239
|
</div>
|
|
206
240
|
|
|
207
|
-
<!-- Validation messages -->
|
|
208
|
-
<ul class="pw-shell__validation" *ngIf="s.
|
|
209
|
-
<li *ngFor="let
|
|
241
|
+
<!-- Validation messages — labeled by field name -->
|
|
242
|
+
<ul class="pw-shell__validation" *ngIf="s.hasAttemptedNext && fieldEntries(s).length > 0">
|
|
243
|
+
<li *ngFor="let entry of fieldEntries(s)" class="pw-shell__validation-item">
|
|
244
|
+
<span *ngIf="entry[0] !== '_'" class="pw-shell__validation-label">{{ formatFieldKey(entry[0]) }}</span>{{ entry[1] }}
|
|
245
|
+
</li>
|
|
210
246
|
</ul>
|
|
211
247
|
|
|
212
248
|
<!-- Footer — custom or default navigation buttons -->
|
|
@@ -216,8 +252,17 @@ export class PathShellComponent {
|
|
|
216
252
|
<ng-template #defaultFooter>
|
|
217
253
|
<div class="pw-shell__footer">
|
|
218
254
|
<div class="pw-shell__footer-left">
|
|
255
|
+
<!-- Form mode: Cancel on the left -->
|
|
256
|
+
<button
|
|
257
|
+
*ngIf="getResolvedFooterLayout(s) === 'form' && !hideCancel"
|
|
258
|
+
type="button"
|
|
259
|
+
class="pw-shell__btn pw-shell__btn--cancel"
|
|
260
|
+
[disabled]="s.isNavigating"
|
|
261
|
+
(click)="facade.cancel()"
|
|
262
|
+
>{{ cancelLabel }}</button>
|
|
263
|
+
<!-- Wizard mode: Back on the left -->
|
|
219
264
|
<button
|
|
220
|
-
*ngIf="!s.isFirstStep"
|
|
265
|
+
*ngIf="getResolvedFooterLayout(s) === 'wizard' && !s.isFirstStep"
|
|
221
266
|
type="button"
|
|
222
267
|
class="pw-shell__btn pw-shell__btn--back"
|
|
223
268
|
[disabled]="s.isNavigating || !s.canMovePrevious"
|
|
@@ -225,19 +270,21 @@ export class PathShellComponent {
|
|
|
225
270
|
>{{ backLabel }}</button>
|
|
226
271
|
</div>
|
|
227
272
|
<div class="pw-shell__footer-right">
|
|
273
|
+
<!-- Wizard mode: Cancel on the right -->
|
|
228
274
|
<button
|
|
229
|
-
*ngIf="!hideCancel"
|
|
275
|
+
*ngIf="getResolvedFooterLayout(s) === 'wizard' && !hideCancel"
|
|
230
276
|
type="button"
|
|
231
277
|
class="pw-shell__btn pw-shell__btn--cancel"
|
|
232
278
|
[disabled]="s.isNavigating"
|
|
233
279
|
(click)="facade.cancel()"
|
|
234
280
|
>{{ cancelLabel }}</button>
|
|
281
|
+
<!-- Both modes: Submit on the right -->
|
|
235
282
|
<button
|
|
236
283
|
type="button"
|
|
237
284
|
class="pw-shell__btn pw-shell__btn--next"
|
|
238
|
-
[disabled]="s.isNavigating
|
|
285
|
+
[disabled]="s.isNavigating"
|
|
239
286
|
(click)="facade.next()"
|
|
240
|
-
>{{ s.isLastStep ?
|
|
287
|
+
>{{ s.isLastStep ? completeLabel : nextLabel }}</button>
|
|
241
288
|
</div>
|
|
242
289
|
</div>
|
|
243
290
|
</ng-template>
|
|
@@ -268,7 +315,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
268
315
|
<ng-container *ngTemplateOutlet="customHeader.templateRef; context: { $implicit: s }"></ng-container>
|
|
269
316
|
</ng-container>
|
|
270
317
|
<ng-template #defaultHeader>
|
|
271
|
-
<div class="pw-shell__header" *ngIf="!hideProgress">
|
|
318
|
+
<div class="pw-shell__header" *ngIf="!hideProgress && (s.stepCount > 1 || s.nestingLevel > 0)">
|
|
272
319
|
<div class="pw-shell__steps">
|
|
273
320
|
<div
|
|
274
321
|
*ngFor="let step of s.steps; let i = index"
|
|
@@ -294,9 +341,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
294
341
|
</ng-container>
|
|
295
342
|
</div>
|
|
296
343
|
|
|
297
|
-
<!-- Validation messages -->
|
|
298
|
-
<ul class="pw-shell__validation" *ngIf="s.
|
|
299
|
-
<li *ngFor="let
|
|
344
|
+
<!-- Validation messages — labeled by field name -->
|
|
345
|
+
<ul class="pw-shell__validation" *ngIf="s.hasAttemptedNext && fieldEntries(s).length > 0">
|
|
346
|
+
<li *ngFor="let entry of fieldEntries(s)" class="pw-shell__validation-item">
|
|
347
|
+
<span *ngIf="entry[0] !== '_'" class="pw-shell__validation-label">{{ formatFieldKey(entry[0]) }}</span>{{ entry[1] }}
|
|
348
|
+
</li>
|
|
300
349
|
</ul>
|
|
301
350
|
|
|
302
351
|
<!-- Footer — custom or default navigation buttons -->
|
|
@@ -306,8 +355,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
306
355
|
<ng-template #defaultFooter>
|
|
307
356
|
<div class="pw-shell__footer">
|
|
308
357
|
<div class="pw-shell__footer-left">
|
|
358
|
+
<!-- Form mode: Cancel on the left -->
|
|
309
359
|
<button
|
|
310
|
-
*ngIf="!
|
|
360
|
+
*ngIf="getResolvedFooterLayout(s) === 'form' && !hideCancel"
|
|
361
|
+
type="button"
|
|
362
|
+
class="pw-shell__btn pw-shell__btn--cancel"
|
|
363
|
+
[disabled]="s.isNavigating"
|
|
364
|
+
(click)="facade.cancel()"
|
|
365
|
+
>{{ cancelLabel }}</button>
|
|
366
|
+
<!-- Wizard mode: Back on the left -->
|
|
367
|
+
<button
|
|
368
|
+
*ngIf="getResolvedFooterLayout(s) === 'wizard' && !s.isFirstStep"
|
|
311
369
|
type="button"
|
|
312
370
|
class="pw-shell__btn pw-shell__btn--back"
|
|
313
371
|
[disabled]="s.isNavigating || !s.canMovePrevious"
|
|
@@ -315,19 +373,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
315
373
|
>{{ backLabel }}</button>
|
|
316
374
|
</div>
|
|
317
375
|
<div class="pw-shell__footer-right">
|
|
376
|
+
<!-- Wizard mode: Cancel on the right -->
|
|
318
377
|
<button
|
|
319
|
-
*ngIf="!hideCancel"
|
|
378
|
+
*ngIf="getResolvedFooterLayout(s) === 'wizard' && !hideCancel"
|
|
320
379
|
type="button"
|
|
321
380
|
class="pw-shell__btn pw-shell__btn--cancel"
|
|
322
381
|
[disabled]="s.isNavigating"
|
|
323
382
|
(click)="facade.cancel()"
|
|
324
383
|
>{{ cancelLabel }}</button>
|
|
384
|
+
<!-- Both modes: Submit on the right -->
|
|
325
385
|
<button
|
|
326
386
|
type="button"
|
|
327
387
|
class="pw-shell__btn pw-shell__btn--next"
|
|
328
|
-
[disabled]="s.isNavigating
|
|
388
|
+
[disabled]="s.isNavigating"
|
|
329
389
|
(click)="facade.next()"
|
|
330
|
-
>{{ s.isLastStep ?
|
|
390
|
+
>{{ s.isLastStep ? completeLabel : nextLabel }}</button>
|
|
331
391
|
</div>
|
|
332
392
|
</div>
|
|
333
393
|
</ng-template>
|
|
@@ -345,7 +405,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
345
405
|
type: Input
|
|
346
406
|
}], nextLabel: [{
|
|
347
407
|
type: Input
|
|
348
|
-
}],
|
|
408
|
+
}], completeLabel: [{
|
|
349
409
|
type: Input
|
|
350
410
|
}], cancelLabel: [{
|
|
351
411
|
type: Input
|
|
@@ -353,6 +413,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
353
413
|
type: Input
|
|
354
414
|
}], hideProgress: [{
|
|
355
415
|
type: Input
|
|
416
|
+
}], footerLayout: [{
|
|
417
|
+
type: Input
|
|
356
418
|
}], completed: [{
|
|
357
419
|
type: Output
|
|
358
420
|
}], cancelled: [{
|
package/dist/shell.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shell.js","sourceRoot":"","sources":["../src/shell.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,EACT,SAAS,EAET,KAAK,EACL,MAAM,EACN,YAAY,EACZ,YAAY,EACZ,eAAe,EAIf,MAAM,EACN,QAAQ,EACR,uBAAuB,EACxB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAC/B,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAO3C,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;;;AAsBrC,8EAA8E;AAC9E,oBAAoB;AACpB,8EAA8E;AAE9E;;;;;;;;;;GAUG;AAEH,MAAM,OAAO,iBAAiB;IAE5B,YAAmC,WAAiC;QAAjC,gBAAW,GAAX,WAAW,CAAsB;IAAG,CAAC;+GAF7D,iBAAiB;mGAAjB,iBAAiB;;4FAAjB,iBAAiB;kBAD7B,SAAS;mBAAC,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,IAAI,EAAE;gFAEP,MAAM;sBAAjD,KAAK;uBAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE;;AAI5C,8EAA8E;AAC9E,2BAA2B;AAC3B,8EAA8E;AAE9E;;;;;;;;;;;;GAYG;AAEH,MAAM,OAAO,wBAAwB;IACnC,YACkB,WAAqD;QAArD,gBAAW,GAAX,WAAW,CAA0C;IACpE,CAAC;+GAHO,wBAAwB;mGAAxB,wBAAwB;;4FAAxB,wBAAwB;kBADpC,SAAS;mBAAC,EAAE,QAAQ,EAAE,iBAAiB,EAAE,UAAU,EAAE,IAAI,EAAE;;AAO5D,8EAA8E;AAC9E,2BAA2B;AAC3B,8EAA8E;AAE9E;;;;;;;;;;;;;;GAcG;AAEH,MAAM,OAAO,wBAAwB;IACnC,YACkB,WAAgF;QAAhF,gBAAW,GAAX,WAAW,CAAqE;IAC/F,CAAC;+GAHO,wBAAwB;mGAAxB,wBAAwB;;4FAAxB,wBAAwB;kBADpC,SAAS;mBAAC,EAAE,QAAQ,EAAE,iBAAiB,EAAE,UAAU,EAAE,IAAI,EAAE;;AAO5D,8EAA8E;AAC9E,qBAAqB;AACrB,8EAA8E;AAE9E;;;;;;;;;;GAUG;
|
|
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.
|
|
3
|
+
"version": "0.6.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.",
|
|
@@ -29,7 +29,8 @@
|
|
|
29
29
|
"types": "./dist/shell.d.ts",
|
|
30
30
|
"import": "./dist/shell.js"
|
|
31
31
|
},
|
|
32
|
-
"./styles.css": "./dist/index.css"
|
|
32
|
+
"./styles.css": "./dist/index.css",
|
|
33
|
+
"./dist/index.css": "./dist/index.css"
|
|
33
34
|
},
|
|
34
35
|
"main": "dist/index.js",
|
|
35
36
|
"types": "dist/index.d.ts",
|
|
@@ -60,7 +61,7 @@
|
|
|
60
61
|
"@angular/compiler-cli": "^17.0.0"
|
|
61
62
|
},
|
|
62
63
|
"dependencies": {
|
|
63
|
-
"@daltonr/pathwrite-core": "^0.
|
|
64
|
+
"@daltonr/pathwrite-core": "^0.6.0"
|
|
64
65
|
},
|
|
65
66
|
"publishConfig": {
|
|
66
67
|
"access": "public"
|
package/src/index.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Injectable, OnDestroy, DestroyRef, signal, Signal } from "@angular/core";
|
|
1
|
+
import { Injectable, OnDestroy, DestroyRef, signal, Signal, inject } from "@angular/core";
|
|
2
2
|
import { BehaviorSubject, Observable, Subject } from "rxjs";
|
|
3
3
|
import {
|
|
4
4
|
PathData,
|
|
@@ -24,10 +24,10 @@ import {
|
|
|
24
24
|
*/
|
|
25
25
|
@Injectable()
|
|
26
26
|
export class PathFacade<TData extends PathData = PathData> implements OnDestroy {
|
|
27
|
-
private
|
|
27
|
+
private _engine = new PathEngine();
|
|
28
28
|
private readonly _state$ = new BehaviorSubject<PathSnapshot<TData> | null>(null);
|
|
29
29
|
private readonly _events$ = new Subject<PathEvent>();
|
|
30
|
-
private
|
|
30
|
+
private _unsubscribeFromEngine: () => void = () => {};
|
|
31
31
|
private readonly _stateSignal = signal<PathSnapshot<TData> | null>(null);
|
|
32
32
|
|
|
33
33
|
public readonly state$: Observable<PathSnapshot<TData> | null> = this._state$.asObservable();
|
|
@@ -36,7 +36,37 @@ export class PathFacade<TData extends PathData = PathData> implements OnDestroy
|
|
|
36
36
|
public readonly stateSignal: Signal<PathSnapshot<TData> | null> = this._stateSignal.asReadonly();
|
|
37
37
|
|
|
38
38
|
public constructor() {
|
|
39
|
-
this.
|
|
39
|
+
this.connectEngine(this._engine);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Adopt an externally-managed `PathEngine` — for example, the engine returned
|
|
44
|
+
* by `restoreOrStart()` from `@daltonr/pathwrite-store-http`.
|
|
45
|
+
*
|
|
46
|
+
* The facade immediately reflects the engine's current state and forwards all
|
|
47
|
+
* subsequent events. The **caller** is responsible for the engine's lifecycle
|
|
48
|
+
* (starting, cleanup); the facade only subscribes to it.
|
|
49
|
+
*
|
|
50
|
+
* ```typescript
|
|
51
|
+
* const { engine } = await restoreOrStart({ store, key, path, initialData, observers: [...] });
|
|
52
|
+
* facade.adoptEngine(engine);
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
public adoptEngine(engine: PathEngine): void {
|
|
56
|
+
// Disconnect from whatever engine we're currently listening to
|
|
57
|
+
this._unsubscribeFromEngine();
|
|
58
|
+
this._engine = engine;
|
|
59
|
+
this.connectEngine(engine);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
private connectEngine(engine: PathEngine): void {
|
|
63
|
+
// Seed state immediately — critical when restoring a persisted path since
|
|
64
|
+
// the engine is already running before the facade connects to it.
|
|
65
|
+
const current = engine.snapshot() as PathSnapshot<TData> | null;
|
|
66
|
+
this._state$.next(current);
|
|
67
|
+
this._stateSignal.set(current);
|
|
68
|
+
|
|
69
|
+
this._unsubscribeFromEngine = engine.subscribe((event) => {
|
|
40
70
|
this._events$.next(event);
|
|
41
71
|
if (event.type === "stateChanged" || event.type === "resumed") {
|
|
42
72
|
this._state$.next(event.snapshot as PathSnapshot<TData>);
|
|
@@ -49,13 +79,13 @@ export class PathFacade<TData extends PathData = PathData> implements OnDestroy
|
|
|
49
79
|
}
|
|
50
80
|
|
|
51
81
|
public ngOnDestroy(): void {
|
|
52
|
-
this.
|
|
82
|
+
this._unsubscribeFromEngine();
|
|
53
83
|
this._events$.complete();
|
|
54
84
|
this._state$.complete();
|
|
55
85
|
}
|
|
56
86
|
|
|
57
87
|
public start(path: PathDefinition<any>, initialData: PathData = {}): Promise<void> {
|
|
58
|
-
return this.
|
|
88
|
+
return this._engine.start(path, initialData);
|
|
59
89
|
}
|
|
60
90
|
|
|
61
91
|
/**
|
|
@@ -65,38 +95,38 @@ export class PathFacade<TData extends PathData = PathData> implements OnDestroy
|
|
|
65
95
|
* component that provides this facade.
|
|
66
96
|
*/
|
|
67
97
|
public restart(path: PathDefinition<any>, initialData: PathData = {}): Promise<void> {
|
|
68
|
-
return this.
|
|
98
|
+
return this._engine.restart(path, initialData);
|
|
69
99
|
}
|
|
70
100
|
|
|
71
101
|
public startSubPath(path: PathDefinition<any>, initialData: PathData = {}, meta?: Record<string, unknown>): Promise<void> {
|
|
72
|
-
return this.
|
|
102
|
+
return this._engine.startSubPath(path, initialData, meta);
|
|
73
103
|
}
|
|
74
104
|
|
|
75
105
|
public next(): Promise<void> {
|
|
76
|
-
return this.
|
|
106
|
+
return this._engine.next();
|
|
77
107
|
}
|
|
78
108
|
|
|
79
109
|
public previous(): Promise<void> {
|
|
80
|
-
return this.
|
|
110
|
+
return this._engine.previous();
|
|
81
111
|
}
|
|
82
112
|
|
|
83
113
|
public cancel(): Promise<void> {
|
|
84
|
-
return this.
|
|
114
|
+
return this._engine.cancel();
|
|
85
115
|
}
|
|
86
116
|
|
|
87
117
|
public setData<K extends string & keyof TData>(key: K, value: TData[K]): Promise<void> {
|
|
88
|
-
return this.
|
|
118
|
+
return this._engine.setData(key, value as unknown);
|
|
89
119
|
}
|
|
90
120
|
|
|
91
121
|
public goToStep(stepId: string): Promise<void> {
|
|
92
|
-
return this.
|
|
122
|
+
return this._engine.goToStep(stepId);
|
|
93
123
|
}
|
|
94
124
|
|
|
95
125
|
/** Jump to a step by ID, checking the current step's canMoveNext (forward) or
|
|
96
126
|
* canMovePrevious (backward) guard first. Navigation is blocked if the guard
|
|
97
127
|
* returns false. Throws if the step ID does not exist. */
|
|
98
128
|
public goToStepChecked(stepId: string): Promise<void> {
|
|
99
|
-
return this.
|
|
129
|
+
return this._engine.goToStepChecked(stepId);
|
|
100
130
|
}
|
|
101
131
|
|
|
102
132
|
public snapshot(): PathSnapshot<TData> | null {
|
|
@@ -104,6 +134,101 @@ export class PathFacade<TData extends PathData = PathData> implements OnDestroy
|
|
|
104
134
|
}
|
|
105
135
|
}
|
|
106
136
|
|
|
137
|
+
// ---------------------------------------------------------------------------
|
|
138
|
+
// injectPath() - Signal-based path access
|
|
139
|
+
// ---------------------------------------------------------------------------
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Return type of `injectPath()`. Provides signal-based reactive access to the
|
|
143
|
+
* path state and strongly-typed navigation actions. Mirrors React's `usePathContext()`
|
|
144
|
+
* return type for consistency across adapters.
|
|
145
|
+
*/
|
|
146
|
+
export interface InjectPathReturn<TData extends PathData = PathData> {
|
|
147
|
+
/** Current path snapshot as a signal. Returns `null` when no path is active. */
|
|
148
|
+
snapshot: Signal<PathSnapshot<TData> | null>;
|
|
149
|
+
/** Start (or restart) a path. */
|
|
150
|
+
start: (path: PathDefinition<any>, initialData?: PathData) => Promise<void>;
|
|
151
|
+
/** Push a sub-path onto the stack. */
|
|
152
|
+
startSubPath: (path: PathDefinition<any>, initialData?: PathData, meta?: Record<string, unknown>) => Promise<void>;
|
|
153
|
+
/** Advance one step. Completes the path on the last step. */
|
|
154
|
+
next: () => Promise<void>;
|
|
155
|
+
/** Go back one step. No-op when already on the first step. */
|
|
156
|
+
previous: () => Promise<void>;
|
|
157
|
+
/** Cancel the active path (or sub-path). */
|
|
158
|
+
cancel: () => Promise<void>;
|
|
159
|
+
/** Update a single data field. */
|
|
160
|
+
setData: <K extends string & keyof TData>(key: K, value: TData[K]) => Promise<void>;
|
|
161
|
+
/** Jump to a step by ID without checking guards. */
|
|
162
|
+
goToStep: (stepId: string) => Promise<void>;
|
|
163
|
+
/** Jump to a step by ID, checking guards first. */
|
|
164
|
+
goToStepChecked: (stepId: string) => Promise<void>;
|
|
165
|
+
/**
|
|
166
|
+
* Tears down any active path and immediately starts the given path fresh.
|
|
167
|
+
* Use for "Start over" / retry flows.
|
|
168
|
+
*/
|
|
169
|
+
restart: (path: PathDefinition<any>, initialData?: PathData) => Promise<void>;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Inject a PathFacade and return a signal-based API for use in Angular components.
|
|
174
|
+
* Requires `PathFacade` to be provided in the component's injector tree (either via
|
|
175
|
+
* `providers: [PathFacade]` in the component or a parent component).
|
|
176
|
+
*
|
|
177
|
+
* **This is the recommended way to consume Pathwrite in Angular components** — it
|
|
178
|
+
* provides the same ergonomic, framework-native API that React's `usePathContext()`
|
|
179
|
+
* and Vue's `usePath()` offer. No template references or manual facade injection needed.
|
|
180
|
+
*
|
|
181
|
+
* The optional generic `TData` narrows `snapshot().data` and `setData()` to your
|
|
182
|
+
* data shape. It is a **type-level assertion**, not a runtime guarantee.
|
|
183
|
+
*
|
|
184
|
+
* @example
|
|
185
|
+
* ```typescript
|
|
186
|
+
* @Component({
|
|
187
|
+
* selector: 'app-contact-step',
|
|
188
|
+
* standalone: true,
|
|
189
|
+
* providers: [PathFacade], // ← Provide at this component or a parent
|
|
190
|
+
* template: `
|
|
191
|
+
* @if (path.snapshot(); as s) {
|
|
192
|
+
* <div>Step: {{ s.activeStep?.title }}</div>
|
|
193
|
+
* <button (click)="path.next()">Next</button>
|
|
194
|
+
* }
|
|
195
|
+
* `
|
|
196
|
+
* })
|
|
197
|
+
* export class ContactStepComponent {
|
|
198
|
+
* protected readonly path = injectPath<ContactData>();
|
|
199
|
+
*
|
|
200
|
+
* updateName(name: string) {
|
|
201
|
+
* this.path.setData('name', name);
|
|
202
|
+
* }
|
|
203
|
+
* }
|
|
204
|
+
* ```
|
|
205
|
+
*
|
|
206
|
+
* @throws Error if PathFacade is not provided in the injector tree
|
|
207
|
+
*/
|
|
208
|
+
export function injectPath<TData extends PathData = PathData>(): InjectPathReturn<TData> {
|
|
209
|
+
const facade = inject(PathFacade, { optional: true }) as PathFacade<TData> | null;
|
|
210
|
+
|
|
211
|
+
if (!facade) {
|
|
212
|
+
throw new Error(
|
|
213
|
+
"injectPath() requires PathFacade to be provided. " +
|
|
214
|
+
"Add 'providers: [PathFacade]' to your component or a parent component."
|
|
215
|
+
);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
return {
|
|
219
|
+
snapshot: facade.stateSignal,
|
|
220
|
+
start: (path, initialData = {}) => facade.start(path, initialData),
|
|
221
|
+
startSubPath: (path, initialData = {}, meta) => facade.startSubPath(path, initialData, meta),
|
|
222
|
+
next: () => facade.next(),
|
|
223
|
+
previous: () => facade.previous(),
|
|
224
|
+
cancel: () => facade.cancel(),
|
|
225
|
+
setData: (key, value) => facade.setData(key, value),
|
|
226
|
+
goToStep: (stepId) => facade.goToStep(stepId),
|
|
227
|
+
goToStepChecked: (stepId) => facade.goToStepChecked(stepId),
|
|
228
|
+
restart: (path, initialData = {}) => facade.restart(path, initialData),
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
|
|
107
232
|
// ---------------------------------------------------------------------------
|
|
108
233
|
// Forms integration
|
|
109
234
|
// ---------------------------------------------------------------------------
|
|
@@ -176,6 +301,7 @@ export function syncFormGroup<TData extends PathData = PathData>(
|
|
|
176
301
|
// Re-export core types for convenience (users don't need to import from @daltonr/pathwrite-core)
|
|
177
302
|
export type {
|
|
178
303
|
PathData,
|
|
304
|
+
FieldErrors,
|
|
179
305
|
PathDefinition,
|
|
180
306
|
PathEvent,
|
|
181
307
|
PathSnapshot,
|
|
@@ -184,3 +310,5 @@ export type {
|
|
|
184
310
|
SerializedPathState
|
|
185
311
|
} from "@daltonr/pathwrite-core";
|
|
186
312
|
|
|
313
|
+
export { PathEngine } from "@daltonr/pathwrite-core";
|
|
314
|
+
|