@daltonr/pathwrite-react 0.2.1 → 0.4.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 CHANGED
@@ -2,6 +2,34 @@
2
2
 
3
3
  React hooks over `@daltonr/pathwrite-core`. Exposes path state as reactive React state via `useSyncExternalStore`, with stable action callbacks and an optional context provider.
4
4
 
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @daltonr/pathwrite-core @daltonr/pathwrite-react
9
+ ```
10
+
11
+ ## Exported Types
12
+
13
+ For convenience, this package re-exports core types so you don't need to import from `@daltonr/pathwrite-core`:
14
+
15
+ ```typescript
16
+ import {
17
+ PathShell, // React-specific
18
+ usePath, // React-specific
19
+ usePathContext, // React-specific
20
+ PathProvider, // React-specific
21
+ PathData, // Re-exported from core
22
+ PathDefinition, // Re-exported from core
23
+ PathEvent, // Re-exported from core
24
+ PathSnapshot, // Re-exported from core
25
+ PathStep, // Re-exported from core
26
+ PathStepContext, // Re-exported from core
27
+ SerializedPathState // Re-exported from core
28
+ } from "@daltonr/pathwrite-react";
29
+ ```
30
+
31
+ ---
32
+
5
33
  ## Setup
6
34
 
7
35
  ### Option A — `usePath` hook (component-scoped)
@@ -86,13 +114,14 @@ function NavButtons() {
86
114
  |----------|------|-------------|
87
115
  | `snapshot` | `PathSnapshot \| null` | Current snapshot. `null` when no path is active. Triggers a React re-render on change. |
88
116
  | `start(definition, data?)` | `function` | Start or re-start a path. |
89
- | `startSubPath(definition, data?)` | `function` | Push a sub-path. Requires an active path. |
117
+ | `startSubPath(definition, data?, meta?)` | `function` | Push a sub-path. Requires an active path. `meta` is returned unchanged to `onSubPathComplete` / `onSubPathCancel`. |
90
118
  | `next()` | `function` | Advance one step. Completes the path on the last step. |
91
119
  | `previous()` | `function` | Go back one step. No-op when already on the first step of a top-level path. |
92
120
  | `cancel()` | `function` | Cancel the active path (or sub-path). |
93
121
  | `goToStep(stepId)` | `function` | Jump directly to a step by ID. Calls `onLeave` / `onEnter` but bypasses guards and `shouldSkip`. |
94
122
  | `goToStepChecked(stepId)` | `function` | Jump to a step by ID, checking `canMoveNext` (forward) or `canMovePrevious` (backward) first. Navigation is blocked if the guard returns false. |
95
123
  | `setData(key, value)` | `function` | Update a single data value; triggers re-render via `stateChanged`. When `TData` is specified, `key` and `value` are type-checked against your data shape. |
124
+ | `restart(definition, data?)` | `function` | Tear down any active path (without firing hooks) and start the given path fresh. Safe to call at any time. Use for "Start over" / retry flows. |
96
125
 
97
126
  All action callbacks are **referentially stable** — safe to pass as props or include in dependency arrays without causing unnecessary re-renders.
98
127
 
@@ -138,9 +167,74 @@ These update automatically when data changes (e.g. after `setData`). Async guard
138
167
 
139
168
  Wrap a subtree in `<PathProvider>` so multiple components share the same engine instance. Consume with `usePathContext()`.
140
169
 
141
- ### `PathShell` context
170
+ ---
171
+
172
+ ## Default UI — `PathShell`
173
+
174
+ `<PathShell>` is a ready-made shell component that renders a progress indicator, step content, and navigation buttons. Pass a `steps` map to define per-step content.
175
+
176
+ ```tsx
177
+ import { PathShell } from "@daltonr/pathwrite-react";
178
+
179
+ <PathShell
180
+ path={myPath}
181
+ initialData={{ name: "" }}
182
+ onComplete={(data) => console.log("Done!", data)}
183
+ steps={{
184
+ details: <DetailsForm />,
185
+ review: <ReviewPanel />,
186
+ }}
187
+ />
188
+ ```
189
+
190
+ ### Props
191
+
192
+ | Prop | Type | Default | Description |
193
+ |------|------|---------|-------------|
194
+ | `path` | `PathDefinition` | *required* | The path to run. |
195
+ | `steps` | `Record<string, ReactNode>` | *required* | Map of step ID → content to render. |
196
+ | `initialData` | `PathData` | `{}` | Initial data passed to `engine.start()`. |
197
+ | `autoStart` | `boolean` | `true` | Start the path automatically on mount. |
198
+ | `onComplete` | `(data: PathData) => void` | — | Called when the path completes. |
199
+ | `onCancel` | `(data: PathData) => void` | — | Called when the path is cancelled. |
200
+ | `onEvent` | `(event: PathEvent) => void` | — | Called for every engine event. |
201
+ | `backLabel` | `string` | `"Back"` | Back button label. |
202
+ | `nextLabel` | `string` | `"Next"` | Next button label. |
203
+ | `finishLabel` | `string` | `"Finish"` | Finish button label (last step). |
204
+ | `cancelLabel` | `string` | `"Cancel"` | Cancel button label. |
205
+ | `hideCancel` | `boolean` | `false` | Hide the Cancel button. |
206
+ | `hideProgress` | `boolean` | `false` | Hide the progress indicator. |
207
+ | `className` | `string` | — | Extra CSS class on the root element. |
208
+ | `renderHeader` | `(snapshot) => ReactNode` | — | Render prop to replace the progress header. |
209
+ | `renderFooter` | `(snapshot, actions) => ReactNode` | — | Render prop to replace the navigation footer. |
210
+
211
+ ### Customising the header and footer
212
+
213
+ Use `renderHeader` and `renderFooter` to replace the built-in progress bar or navigation buttons with your own UI. Both receive the current `PathSnapshot`; `renderFooter` also receives a `PathShellActions` object with all navigation callbacks.
214
+
215
+ ```tsx
216
+ <PathShell
217
+ path={myPath}
218
+ steps={{ details: <DetailsForm />, review: <ReviewPanel /> }}
219
+ renderHeader={(snapshot) => (
220
+ <p>{snapshot.stepIndex + 1} / {snapshot.stepCount} — {snapshot.stepTitle}</p>
221
+ )}
222
+ renderFooter={(snapshot, actions) => (
223
+ <div>
224
+ <button onClick={actions.previous} disabled={snapshot.isFirstStep}>Back</button>
225
+ <button onClick={actions.next} disabled={!snapshot.canMoveNext}>
226
+ {snapshot.isLastStep ? "Finish" : "Next"}
227
+ </button>
228
+ </div>
229
+ )}
230
+ />
231
+ ```
232
+
233
+ `PathShellActions` contains: `next`, `previous`, `cancel`, `goToStep`, `goToStepChecked`, `setData`, `restart`.
234
+
235
+ ### Context sharing
142
236
 
143
- `<PathShell>` also provides context automatically. Step components rendered inside `<PathShell>` can call `usePathContext()` without a separate `<PathProvider>`:
237
+ `<PathShell>` provides a path context automatically step components rendered inside it can call `usePathContext()` without a separate `<PathProvider>`:
144
238
 
145
239
  ```tsx
146
240
  function DetailsForm() {
@@ -157,13 +251,12 @@ function DetailsForm() {
157
251
  path={myPath}
158
252
  initialData={{ name: "" }}
159
253
  onComplete={handleDone}
160
- steps={{
161
- details: <DetailsForm />,
162
- review: <ReviewPanel />,
163
- }}
254
+ steps={{ details: <DetailsForm />, review: <ReviewPanel /> }}
164
255
  />
165
256
  ```
166
257
 
258
+ ---
259
+
167
260
  ## Styling
168
261
 
169
262
  `<PathShell>` renders structural HTML with BEM-style `pw-shell__*` CSS classes but ships with no embedded styles. Import the optional stylesheet for sensible defaults:
@@ -181,11 +274,259 @@ All visual values are CSS custom properties (`--pw-*`), so you can theme without
181
274
  }
182
275
  ```
183
276
 
277
+ ### Available CSS Custom Properties
278
+
279
+ **Layout:**
280
+ - `--pw-shell-max-width` — Maximum width of the shell (default: `720px`)
281
+ - `--pw-shell-padding` — Internal padding (default: `24px`)
282
+ - `--pw-shell-gap` — Gap between header, body, footer (default: `20px`)
283
+ - `--pw-shell-radius` — Border radius for cards (default: `10px`)
284
+
285
+ **Colors:**
286
+ - `--pw-color-bg` — Background color (default: `#ffffff`)
287
+ - `--pw-color-border` — Border color (default: `#dbe4f0`)
288
+ - `--pw-color-text` — Primary text color (default: `#1f2937`)
289
+ - `--pw-color-muted` — Muted text color (default: `#5b677a`)
290
+ - `--pw-color-primary` — Primary/accent color (default: `#2563eb`)
291
+ - `--pw-color-primary-light` — Light primary for backgrounds (default: `rgba(37, 99, 235, 0.12)`)
292
+ - `--pw-color-btn-bg` — Button background (default: `#f8fbff`)
293
+ - `--pw-color-btn-border` — Button border (default: `#c2d0e5`)
294
+
295
+ **Validation:**
296
+ - `--pw-color-error` — Error text color (default: `#dc2626`)
297
+ - `--pw-color-error-bg` — Error background (default: `#fef2f2`)
298
+ - `--pw-color-error-border` — Error border (default: `#fecaca`)
299
+
300
+ **Progress Indicator:**
301
+ - `--pw-dot-size` — Step dot size (default: `32px`)
302
+ - `--pw-dot-font-size` — Font size inside dots (default: `13px`)
303
+ - `--pw-track-height` — Progress track height (default: `4px`)
304
+
305
+ **Buttons:**
306
+ - `--pw-btn-padding` — Button padding (default: `8px 16px`)
307
+ - `--pw-btn-radius` — Button border radius (default: `6px`)
308
+
184
309
  ---
185
310
 
186
- ## Design notes
311
+ ## Sub-Paths
312
+
313
+ Sub-paths allow you to nest multi-step workflows. Common use cases include:
314
+ - Running a child workflow per collection item (e.g., approve each document)
315
+ - Conditional drill-down flows (e.g., "Add payment method" modal)
316
+ - Reusable wizard components
317
+
318
+ ### Basic Sub-Path Flow
319
+
320
+ When a sub-path is active:
321
+ - The shell switches to show the sub-path's steps
322
+ - The progress bar displays sub-path steps (not main path steps)
323
+ - Pressing Back on the first sub-path step **cancels** the sub-path and returns to the parent
324
+ - `usePathContext()` returns the **sub-path** snapshot, not the parent's
325
+
326
+ ### Complete Example: Approver Collection
327
+
328
+ ```tsx
329
+ import type { PathData, PathDefinition } from "@daltonr/pathwrite-core";
330
+
331
+ // Sub-path data shape
332
+ interface ApproverReviewData extends PathData {
333
+ decision: "approve" | "reject" | "";
334
+ comments: string;
335
+ }
336
+
337
+ // Main path data shape
338
+ interface ApprovalWorkflowData extends PathData {
339
+ documentTitle: string;
340
+ approvers: string[];
341
+ approvals: Array<{ approver: string; decision: string; comments: string }>;
342
+ }
343
+
344
+ // Define the sub-path (approver review wizard)
345
+ const approverReviewPath: PathDefinition<ApproverReviewData> = {
346
+ id: "approver-review",
347
+ steps: [
348
+ { id: "review", title: "Review Document" },
349
+ {
350
+ id: "decision",
351
+ title: "Make Decision",
352
+ canMoveNext: ({ data }) =>
353
+ data.decision === "approve" || data.decision === "reject",
354
+ validationMessages: ({ data }) =>
355
+ !data.decision ? ["Please select Approve or Reject"] : []
356
+ },
357
+ { id: "comments", title: "Add Comments" }
358
+ ]
359
+ };
360
+
361
+ // Define the main path
362
+ const approvalWorkflowPath: PathDefinition<ApprovalWorkflowData> = {
363
+ id: "approval-workflow",
364
+ steps: [
365
+ {
366
+ id: "setup",
367
+ title: "Setup Approval",
368
+ canMoveNext: ({ data }) =>
369
+ (data.documentTitle ?? "").trim().length > 0 &&
370
+ data.approvers.length > 0
371
+ },
372
+ {
373
+ id: "run-approvals",
374
+ title: "Collect Approvals",
375
+ // Block "Next" until all approvers have completed their reviews
376
+ canMoveNext: ({ data }) =>
377
+ data.approvals.length === data.approvers.length,
378
+ validationMessages: ({ data }) => {
379
+ const remaining = data.approvers.length - data.approvals.length;
380
+ return remaining > 0
381
+ ? [`${remaining} approver(s) pending review`]
382
+ : [];
383
+ },
384
+ // When an approver finishes their sub-path, record the result
385
+ onSubPathComplete(subPathId, subPathData, ctx, meta) {
386
+ const approverName = meta?.approverName as string;
387
+ const result = subPathData as ApproverReviewData;
388
+ return {
389
+ approvals: [
390
+ ...ctx.data.approvals,
391
+ {
392
+ approver: approverName,
393
+ decision: result.decision,
394
+ comments: result.comments
395
+ }
396
+ ]
397
+ };
398
+ },
399
+ // If an approver cancels (presses Back on first step), you can track it
400
+ onSubPathCancel(subPathId, subPathData, ctx, meta) {
401
+ console.log(`${meta?.approverName} cancelled their review`);
402
+ // Optionally return data changes, or just log
403
+ }
404
+ },
405
+ { id: "summary", title: "Summary" }
406
+ ]
407
+ };
408
+
409
+ // Component
410
+ function ApprovalWorkflow() {
411
+ const { startSubPath } = usePathContext<ApprovalWorkflowData>();
412
+
413
+ function launchReviewForApprover(approverName: string, index: number) {
414
+ // Pass correlation data via `meta` — it's echoed back to onSubPathComplete
415
+ startSubPath(
416
+ approverReviewPath,
417
+ { decision: "", comments: "" },
418
+ { approverName, approverIndex: index }
419
+ );
420
+ }
187
421
 
188
- - **`useSyncExternalStore`** — the hook subscribes to the core `PathEngine` using React 18's `useSyncExternalStore`, giving tear-free reads with no `useEffect` timing gaps.
189
- - **Ref-based callback** — `onEvent` is stored in a ref so that a new closure on every render does not cause a re-subscription.
190
- - **No RxJS** — unlike the Angular adapter, there is no RxJS dependency. The hook is pure React.
422
+ return (
423
+ <PathShell
424
+ path={approvalWorkflowPath}
425
+ initialData={{ documentTitle: "", approvers: [], approvals: [] }}
426
+ steps={{
427
+ setup: <SetupStep />,
428
+ "run-approvals": <RunApprovalsStep onLaunchReview={launchReviewForApprover} />,
429
+ summary: <SummaryStep />,
430
+ // Sub-path steps (must be co-located in the same steps map)
431
+ review: <ReviewDocumentStep />,
432
+ decision: <MakeDecisionStep />,
433
+ comments: <AddCommentsStep />
434
+ }}
435
+ />
436
+ );
437
+ }
438
+ ```
439
+
440
+ ### Key Notes
441
+
442
+ **1. Sub-path steps must be co-located with main path steps**
443
+ All step content (main path + sub-path steps) lives in the same `steps` prop. When a sub-path is active, the shell renders the sub-path's step content. This means:
444
+ - Parent and sub-path step IDs **must not collide** (e.g., don't use `summary` in both)
445
+ - Sub-path step components can access parent data by referencing the parent path definition, but `usePathContext()` returns the **sub-path** snapshot
446
+
447
+ **2. The `meta` correlation field**
448
+ `startSubPath` accepts an optional third argument (`meta`) that is returned unchanged to `onSubPathComplete` and `onSubPathCancel`. Use it to correlate which collection item triggered the sub-path:
449
+
450
+ ```tsx
451
+ startSubPath(subPath, initialData, { itemIndex: 3, itemId: "abc" });
452
+
453
+ // In the parent step:
454
+ onSubPathComplete(subPathId, subPathData, ctx, meta) {
455
+ const itemIndex = meta?.itemIndex; // 3
456
+ }
457
+ ```
458
+
459
+ **3. Progress bar switches during sub-paths**
460
+ 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.
461
+
462
+ **4. Accessing parent path data from sub-path components**
463
+ There is currently no `useParentPathContext()` hook. If a sub-path step needs parent data (e.g., the document title), pass it via `initialData` when calling `startSubPath`:
464
+
465
+ ```tsx
466
+ startSubPath(approverReviewPath, {
467
+ decision: "",
468
+ comments: "",
469
+ documentTitle: snapshot.data.documentTitle // copy from parent
470
+ });
471
+ ```
472
+
473
+ ---
474
+
475
+ ## Guards and Lifecycle Hooks
476
+
477
+ ### Defensive Guards (Important!)
478
+
479
+ **Guards and `validationMessages` are evaluated *before* `onEnter` runs on first entry.**
480
+
481
+ If you access fields in a guard that `onEnter` is supposed to initialize, the guard will throw a `TypeError` on startup. Write guards defensively using nullish coalescing:
482
+
483
+ ```ts
484
+ // ✗ Unsafe — crashes if data.name is undefined
485
+ canMoveNext: ({ data }) => data.name.trim().length > 0
486
+
487
+ // ✓ Safe — handles undefined gracefully
488
+ canMoveNext: ({ data }) => (data.name ?? "").trim().length > 0
489
+ ```
490
+
491
+ Alternatively, pass `initialData` to `start()` / `<PathShell>` so all fields are present from the first snapshot:
492
+
493
+ ```tsx
494
+ <PathShell path={myPath} initialData={{ name: "", age: 0 }} />
495
+ ```
496
+
497
+ If a guard throws, the engine catches it, logs a warning, and returns `true` (allow navigation) as a safe default.
498
+
499
+ ### Async Guards and Validation Messages
500
+
501
+ Guards and `validationMessages` must be **synchronous** for inclusion in snapshots. Async functions are detected and warned about:
502
+ - Async `canMoveNext` / `canMovePrevious` default to `true` (optimistic)
503
+ - Async `validationMessages` default to `[]`
504
+
505
+ The async version is still enforced during actual navigation (when you call `next()` / `previous()`), but the snapshot won't reflect the pending state. If you need async validation, perform it in the guard and store the result in `data` so the guard can read it synchronously.
506
+
507
+ ### `isFirstEntry` Flag
508
+
509
+ The `PathStepContext` passed to all hooks includes an `isFirstEntry: boolean` flag. It's `true` the first time a step is visited, `false` on re-entry (e.g., after navigating back then forward again).
510
+
511
+ Use it to distinguish initialization from re-entry:
512
+
513
+ ```ts
514
+ {
515
+ id: "details",
516
+ onEnter: ({ isFirstEntry, data }) => {
517
+ if (isFirstEntry) {
518
+ // Only pre-fill on first visit, not when returning via Back
519
+ return { name: "Default Name" };
520
+ }
521
+ }
522
+ }
523
+ ```
524
+
525
+ **Important:** `onEnter` fires every time you enter the step. If you want "initialize once" behavior, either:
526
+ 1. Use `isFirstEntry` to conditionally return data
527
+ 2. Provide `initialData` to `start()` instead of using `onEnter`
528
+
529
+ ---
530
+
531
+ ## Design notes
191
532
 
package/dist/index.d.ts CHANGED
@@ -9,11 +9,11 @@ export interface UsePathReturn<TData extends PathData = PathData> {
9
9
  snapshot: PathSnapshot<TData> | null;
10
10
  /** Start (or restart) a path. */
11
11
  start: (path: PathDefinition<any>, initialData?: PathData) => void;
12
- /** Push a sub-path onto the stack. Requires an active path. */
13
- startSubPath: (path: PathDefinition<any>, initialData?: PathData) => void;
12
+ /** Push a sub-path onto the stack. Requires an active path. Pass an optional `meta` object for correlation — it is returned unchanged to the parent step's `onSubPathComplete` / `onSubPathCancel` hooks. */
13
+ startSubPath: (path: PathDefinition<any>, initialData?: PathData, meta?: Record<string, unknown>) => void;
14
14
  /** Advance one step. Completes the path on the last step. */
15
15
  next: () => void;
16
- /** Go back one step. Cancels the path from the first step. */
16
+ /** Go back one step. No-op when already on the first step of a top-level path. Pops back to the parent path when on the first step of a sub-path. */
17
17
  previous: () => void;
18
18
  /** Cancel the active path (or sub-path). */
19
19
  cancel: () => void;
@@ -23,6 +23,12 @@ export interface UsePathReturn<TData extends PathData = PathData> {
23
23
  goToStepChecked: (stepId: string) => void;
24
24
  /** Update a single data value; triggers a re-render via stateChanged. When `TData` is specified, `key` and `value` are type-checked against your data shape. */
25
25
  setData: <K extends string & keyof TData>(key: K, value: TData[K]) => void;
26
+ /**
27
+ * Tear down any active path (without firing hooks) and immediately start the
28
+ * given path fresh. Safe to call whether or not a path is currently active.
29
+ * Use for "Start over" / retry flows without remounting the component.
30
+ */
31
+ restart: (path: PathDefinition<any>, initialData?: PathData) => void;
26
32
  }
27
33
  export type PathProviderProps = PropsWithChildren<{
28
34
  /** Forwarded to the internal usePath hook. */
@@ -81,7 +87,10 @@ export interface PathShellActions {
81
87
  previous: () => void;
82
88
  cancel: () => void;
83
89
  goToStep: (stepId: string) => void;
90
+ goToStepChecked: (stepId: string) => void;
84
91
  setData: (key: string, value: unknown) => void;
92
+ /** Restart the shell's current path with its current `initialData`. */
93
+ restart: () => void;
85
94
  }
86
95
  /**
87
96
  * Default UI shell that renders a progress indicator, step content, and navigation
@@ -100,3 +109,4 @@ export interface PathShellActions {
100
109
  * ```
101
110
  */
102
111
  export declare function PathShell({ path: pathDef, steps, initialData, autoStart, onComplete, onCancel, onEvent, backLabel, nextLabel, finishLabel, cancelLabel, hideCancel, hideProgress, className, renderHeader, renderFooter, }: PathShellProps): ReactElement;
112
+ export type { PathData, PathDefinition, PathEvent, PathSnapshot, PathStep, PathStepContext, SerializedPathState } from "@daltonr/pathwrite-core";
package/dist/index.js CHANGED
@@ -29,14 +29,15 @@ export function usePath(options) {
29
29
  const snapshot = useSyncExternalStore(subscribe, getSnapshot);
30
30
  // Stable action callbacks
31
31
  const start = useCallback((path, initialData = {}) => engine.start(path, initialData), [engine]);
32
- const startSubPath = useCallback((path, initialData = {}) => engine.startSubPath(path, initialData), [engine]);
32
+ const startSubPath = useCallback((path, initialData = {}, meta) => engine.startSubPath(path, initialData, meta), [engine]);
33
33
  const next = useCallback(() => engine.next(), [engine]);
34
34
  const previous = useCallback(() => engine.previous(), [engine]);
35
35
  const cancel = useCallback(() => engine.cancel(), [engine]);
36
36
  const goToStep = useCallback((stepId) => engine.goToStep(stepId), [engine]);
37
37
  const goToStepChecked = useCallback((stepId) => engine.goToStepChecked(stepId), [engine]);
38
38
  const setData = useCallback((key, value) => engine.setData(key, value), [engine]);
39
- return { snapshot, start, startSubPath, next, previous, cancel, goToStep, goToStepChecked, setData };
39
+ const restart = useCallback((path, initialData = {}) => engine.restart(path, initialData), [engine]);
40
+ return { snapshot, start, startSubPath, next, previous, cancel, goToStep, goToStepChecked, setData, restart };
40
41
  }
41
42
  // ---------------------------------------------------------------------------
42
43
  // Context + Provider
@@ -90,7 +91,7 @@ export function PathShell({ path: pathDef, steps, initialData = {}, autoStart =
90
91
  onCancel?.(event.data);
91
92
  }
92
93
  });
93
- const { snapshot, start, next, previous, cancel, goToStep, setData } = pathReturn;
94
+ const { snapshot, start, next, previous, cancel, goToStep, goToStepChecked, setData, restart } = pathReturn;
94
95
  // Auto-start on mount
95
96
  const startedRef = useRef(false);
96
97
  useEffect(() => {
@@ -109,7 +110,10 @@ export function PathShell({ path: pathDef, steps, initialData = {}, autoStart =
109
110
  onClick: () => start(pathDef, initialData)
110
111
  }, "Start"))));
111
112
  }
112
- const actions = { next, previous, cancel, goToStep, setData };
113
+ const actions = {
114
+ next, previous, cancel, goToStep, goToStepChecked, setData,
115
+ restart: () => restart(pathDef, initialData)
116
+ };
113
117
  return createElement(PathContext.Provider, { value: pathReturn }, createElement("div", { className: cls("pw-shell", className) },
114
118
  // Header — progress indicator
115
119
  !hideProgress && (renderHeader
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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@daltonr/pathwrite-react",
3
- "version": "0.2.1",
3
+ "version": "0.4.0",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "description": "React adapter for @daltonr/pathwrite-core — hooks, context provider, and optional <PathShell> default UI.",
@@ -45,7 +45,7 @@
45
45
  "react": ">=18.0.0"
46
46
  },
47
47
  "dependencies": {
48
- "@daltonr/pathwrite-core": "^0.2.1"
48
+ "@daltonr/pathwrite-core": "^0.4.0"
49
49
  },
50
50
  "devDependencies": {
51
51
  "react": "^18.3.1",
package/src/index.ts CHANGED
@@ -30,11 +30,11 @@ export interface UsePathReturn<TData extends PathData = PathData> {
30
30
  snapshot: PathSnapshot<TData> | null;
31
31
  /** Start (or restart) a path. */
32
32
  start: (path: PathDefinition<any>, initialData?: PathData) => void;
33
- /** Push a sub-path onto the stack. Requires an active path. */
34
- startSubPath: (path: PathDefinition<any>, initialData?: PathData) => void;
33
+ /** Push a sub-path onto the stack. Requires an active path. Pass an optional `meta` object for correlation — it is returned unchanged to the parent step's `onSubPathComplete` / `onSubPathCancel` hooks. */
34
+ startSubPath: (path: PathDefinition<any>, initialData?: PathData, meta?: Record<string, unknown>) => void;
35
35
  /** Advance one step. Completes the path on the last step. */
36
36
  next: () => void;
37
- /** Go back one step. Cancels the path from the first step. */
37
+ /** Go back one step. No-op when already on the first step of a top-level path. Pops back to the parent path when on the first step of a sub-path. */
38
38
  previous: () => void;
39
39
  /** Cancel the active path (or sub-path). */
40
40
  cancel: () => void;
@@ -44,6 +44,12 @@ export interface UsePathReturn<TData extends PathData = PathData> {
44
44
  goToStepChecked: (stepId: string) => void;
45
45
  /** Update a single data value; triggers a re-render via stateChanged. When `TData` is specified, `key` and `value` are type-checked against your data shape. */
46
46
  setData: <K extends string & keyof TData>(key: K, value: TData[K]) => void;
47
+ /**
48
+ * Tear down any active path (without firing hooks) and immediately start the
49
+ * given path fresh. Safe to call whether or not a path is currently active.
50
+ * Use for "Start over" / retry flows without remounting the component.
51
+ */
52
+ restart: (path: PathDefinition<any>, initialData?: PathData) => void;
47
53
  }
48
54
 
49
55
  export type PathProviderProps = PropsWithChildren<{
@@ -96,8 +102,8 @@ export function usePath<TData extends PathData = PathData>(options?: UsePathOpti
96
102
  );
97
103
 
98
104
  const startSubPath = useCallback(
99
- (path: PathDefinition<any>, initialData: PathData = {}) =>
100
- engine.startSubPath(path, initialData),
105
+ (path: PathDefinition<any>, initialData: PathData = {}, meta?: Record<string, unknown>) =>
106
+ engine.startSubPath(path, initialData, meta),
101
107
  [engine]
102
108
  );
103
109
 
@@ -120,7 +126,13 @@ export function usePath<TData extends PathData = PathData>(options?: UsePathOpti
120
126
  [engine]
121
127
  ) as UsePathReturn<TData>["setData"];
122
128
 
123
- return { snapshot, start, startSubPath, next, previous, cancel, goToStep, goToStepChecked, setData };
129
+ const restart = useCallback(
130
+ (path: PathDefinition<any>, initialData: PathData = {}) =>
131
+ engine.restart(path, initialData),
132
+ [engine]
133
+ );
134
+
135
+ return { snapshot, start, startSubPath, next, previous, cancel, goToStep, goToStepChecked, setData, restart };
124
136
  }
125
137
 
126
138
  // ---------------------------------------------------------------------------
@@ -197,7 +209,10 @@ export interface PathShellActions {
197
209
  previous: () => void;
198
210
  cancel: () => void;
199
211
  goToStep: (stepId: string) => void;
212
+ goToStepChecked: (stepId: string) => void;
200
213
  setData: (key: string, value: unknown) => void;
214
+ /** Restart the shell's current path with its current `initialData`. */
215
+ restart: () => void;
201
216
  }
202
217
 
203
218
  /**
@@ -242,7 +257,7 @@ export function PathShell({
242
257
  }
243
258
  });
244
259
 
245
- const { snapshot, start, next, previous, cancel, goToStep, setData } = pathReturn;
260
+ const { snapshot, start, next, previous, cancel, goToStep, goToStepChecked, setData, restart } = pathReturn;
246
261
 
247
262
  // Auto-start on mount
248
263
  const startedRef = useRef(false);
@@ -272,7 +287,10 @@ export function PathShell({
272
287
  );
273
288
  }
274
289
 
275
- const actions: PathShellActions = { next, previous, cancel, goToStep, setData };
290
+ const actions: PathShellActions = {
291
+ next, previous, cancel, goToStep, goToStepChecked, setData,
292
+ restart: () => restart(pathDef, initialData)
293
+ };
276
294
 
277
295
  return createElement(PathContext.Provider, { value: pathReturn },
278
296
  createElement("div", { className: cls("pw-shell", className) },
@@ -375,7 +393,21 @@ function defaultFooter(
375
393
  // Helpers
376
394
  // ---------------------------------------------------------------------------
377
395
 
378
-
379
396
  function cls(...parts: (string | undefined | false | null)[]): string {
380
397
  return parts.filter(Boolean).join(" ");
381
398
  }
399
+
400
+ // ---------------------------------------------------------------------------
401
+ // Re-export core types for convenience
402
+ // ---------------------------------------------------------------------------
403
+
404
+ export type {
405
+ PathData,
406
+ PathDefinition,
407
+ PathEvent,
408
+ PathSnapshot,
409
+ PathStep,
410
+ PathStepContext,
411
+ SerializedPathState
412
+ } from "@daltonr/pathwrite-core";
413
+