@daltonr/pathwrite-react 0.1.5 → 0.2.1
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 +2 -1
- package/dist/index.d.ts +5 -3
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/index.ts +19 -6
- package/dist/index.css +0 -228
package/README.md
CHANGED
|
@@ -88,9 +88,10 @@ function NavButtons() {
|
|
|
88
88
|
| `start(definition, data?)` | `function` | Start or re-start a path. |
|
|
89
89
|
| `startSubPath(definition, data?)` | `function` | Push a sub-path. Requires an active path. |
|
|
90
90
|
| `next()` | `function` | Advance one step. Completes the path on the last step. |
|
|
91
|
-
| `previous()` | `function` | Go back one step.
|
|
91
|
+
| `previous()` | `function` | Go back one step. No-op when already on the first step of a top-level path. |
|
|
92
92
|
| `cancel()` | `function` | Cancel the active path (or sub-path). |
|
|
93
93
|
| `goToStep(stepId)` | `function` | Jump directly to a step by ID. Calls `onLeave` / `onEnter` but bypasses guards and `shouldSkip`. |
|
|
94
|
+
| `goToStepChecked(stepId)` | `function` | Jump to a step by ID, checking `canMoveNext` (forward) or `canMovePrevious` (backward) first. Navigation is blocked if the guard returns false. |
|
|
94
95
|
| `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. |
|
|
95
96
|
|
|
96
97
|
All action callbacks are **referentially stable** — safe to pass as props or include in dependency arrays without causing unnecessary re-renders.
|
package/dist/index.d.ts
CHANGED
|
@@ -8,9 +8,9 @@ export interface UsePathReturn<TData extends PathData = PathData> {
|
|
|
8
8
|
/** Current path snapshot, or `null` when no path is active. Triggers a React re-render on change. */
|
|
9
9
|
snapshot: PathSnapshot<TData> | null;
|
|
10
10
|
/** Start (or restart) a path. */
|
|
11
|
-
start: (path: PathDefinition
|
|
11
|
+
start: (path: PathDefinition<any>, initialData?: PathData) => void;
|
|
12
12
|
/** Push a sub-path onto the stack. Requires an active path. */
|
|
13
|
-
startSubPath: (path: PathDefinition
|
|
13
|
+
startSubPath: (path: PathDefinition<any>, initialData?: PathData) => void;
|
|
14
14
|
/** Advance one step. Completes the path on the last step. */
|
|
15
15
|
next: () => void;
|
|
16
16
|
/** Go back one step. Cancels the path from the first step. */
|
|
@@ -19,6 +19,8 @@ export interface UsePathReturn<TData extends PathData = PathData> {
|
|
|
19
19
|
cancel: () => void;
|
|
20
20
|
/** Jump directly to a step by ID. Calls onLeave / onEnter but bypasses guards and shouldSkip. */
|
|
21
21
|
goToStep: (stepId: string) => void;
|
|
22
|
+
/** Jump directly to a step by ID, checking the current step's canMoveNext (forward) or canMovePrevious (backward) guard first. Navigation is blocked if the guard returns false. */
|
|
23
|
+
goToStepChecked: (stepId: string) => void;
|
|
22
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. */
|
|
23
25
|
setData: <K extends string & keyof TData>(key: K, value: TData[K]) => void;
|
|
24
26
|
}
|
|
@@ -42,7 +44,7 @@ export declare function PathProvider({ children, onEvent }: PathProviderProps):
|
|
|
42
44
|
export declare function usePathContext<TData extends PathData = PathData>(): UsePathReturn<TData>;
|
|
43
45
|
export interface PathShellProps {
|
|
44
46
|
/** The path definition to drive. */
|
|
45
|
-
path: PathDefinition
|
|
47
|
+
path: PathDefinition<any>;
|
|
46
48
|
/** Map of step ID → content. The shell renders `steps[snapshot.stepId]` for the current step. */
|
|
47
49
|
steps: Record<string, ReactNode>;
|
|
48
50
|
/** Initial data passed to `engine.start()`. */
|
package/dist/index.js
CHANGED
|
@@ -34,8 +34,9 @@ export function usePath(options) {
|
|
|
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
|
+
const goToStepChecked = useCallback((stepId) => engine.goToStepChecked(stepId), [engine]);
|
|
37
38
|
const setData = useCallback((key, value) => engine.setData(key, value), [engine]);
|
|
38
|
-
return { snapshot, start, startSubPath, next, previous, cancel, goToStep, setData };
|
|
39
|
+
return { snapshot, start, startSubPath, next, previous, cancel, goToStep, goToStepChecked, setData };
|
|
39
40
|
}
|
|
40
41
|
// ---------------------------------------------------------------------------
|
|
41
42
|
// Context + Provider
|
|
@@ -116,6 +117,8 @@ export function PathShell({ path: pathDef, steps, initialData = {}, autoStart =
|
|
|
116
117
|
: defaultHeader(snapshot)),
|
|
117
118
|
// Body — step content
|
|
118
119
|
createElement("div", { className: "pw-shell__body" }, stepContent),
|
|
120
|
+
// Validation messages
|
|
121
|
+
snapshot.validationMessages.length > 0 && createElement("ul", { className: "pw-shell__validation" }, ...snapshot.validationMessages.map((msg, i) => createElement("li", { key: i, className: "pw-shell__validation-item" }, msg))),
|
|
119
122
|
// Footer — navigation buttons
|
|
120
123
|
renderFooter
|
|
121
124
|
? renderFooter(snapshot, actions)
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,aAAa,EACb,WAAW,EACX,UAAU,EACV,SAAS,EACT,MAAM,EACN,oBAAoB,EACrB,MAAM,OAAO,CAAC;AAEf,OAAO,EAGL,UAAU,EAGX,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,aAAa,EACb,WAAW,EACX,UAAU,EACV,SAAS,EACT,MAAM,EACN,oBAAoB,EACrB,MAAM,OAAO,CAAC;AAEf,OAAO,EAGL,UAAU,EAGX,MAAM,yBAAyB,CAAC;AAqCjC,8EAA8E;AAC9E,eAAe;AACf,8EAA8E;AAE9E,MAAM,UAAU,OAAO,CAAoC,OAAwB;IACjF,sDAAsD;IACtD,MAAM,SAAS,GAAG,MAAM,CAAoB,IAAI,CAAC,CAAC;IAClD,IAAI,SAAS,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;QAC/B,SAAS,CAAC,OAAO,GAAG,IAAI,UAAU,EAAE,CAAC;IACvC,CAAC;IACD,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,CAAC;IAEjC,4EAA4E;IAC5E,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAC5C,UAAU,CAAC,OAAO,GAAG,OAAO,EAAE,OAAO,CAAC;IAEtC,+DAA+D;IAC/D,MAAM,WAAW,GAAG,MAAM,CAA6B,IAAI,CAAC,CAAC;IAE7D,MAAM,SAAS,GAAG,WAAW,CAC3B,CAAC,QAAoB,EAAE,EAAE,CACvB,MAAM,CAAC,SAAS,CAAC,CAAC,KAAgB,EAAE,EAAE;QACpC,IAAI,KAAK,CAAC,IAAI,KAAK,cAAc,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAC9D,WAAW,CAAC,OAAO,GAAG,KAAK,CAAC,QAA+B,CAAC;QAC9D,CAAC;aAAM,IAAI,KAAK,CAAC,IAAI,KAAK,WAAW,IAAI,KAAK,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YACpE,WAAW,CAAC,OAAO,GAAG,IAAI,CAAC;QAC7B,CAAC;QACD,UAAU,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,CAAC;QAC5B,QAAQ,EAAE,CAAC;IACb,CAAC,CAAC,EACJ,CAAC,MAAM,CAAC,CACT,CAAC;IAEF,MAAM,WAAW,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,WAAW,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IAE/D,MAAM,QAAQ,GAAG,oBAAoB,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;IAE9D,0BAA0B;IAC1B,MAAM,KAAK,GAAG,WAAW,CACvB,CAAC,IAAyB,EAAE,cAAwB,EAAE,EAAE,EAAE,CACxD,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,WAAW,CAAC,EACjC,CAAC,MAAM,CAAC,CACT,CAAC;IAEF,MAAM,YAAY,GAAG,WAAW,CAC9B,CAAC,IAAyB,EAAE,cAAwB,EAAE,EAAE,EAAE,CACxD,MAAM,CAAC,YAAY,CAAC,IAAI,EAAE,WAAW,CAAC,EACxC,CAAC,MAAM,CAAC,CACT,CAAC;IAEF,MAAM,IAAI,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;IACxD,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;IAChE,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;IAE5D,MAAM,QAAQ,GAAG,WAAW,CAC1B,CAAC,MAAc,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,EAC3C,CAAC,MAAM,CAAC,CACT,CAAC;IAEF,MAAM,eAAe,GAAG,WAAW,CACjC,CAAC,MAAc,EAAE,EAAE,CAAC,MAAM,CAAC,eAAe,CAAC,MAAM,CAAC,EAClD,CAAC,MAAM,CAAC,CACT,CAAC;IAEF,MAAM,OAAO,GAAG,WAAW,CACzB,CAAiC,GAAM,EAAE,KAAe,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,KAAgB,CAAC,EAClG,CAAC,MAAM,CAAC,CAC0B,CAAC;IAErC,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,eAAe,EAAE,OAAO,EAAE,CAAC;AACvG,CAAC;AAED,8EAA8E;AAC9E,qBAAqB;AACrB,8EAA8E;AAE9E,MAAM,WAAW,GAAG,aAAa,CAAuB,IAAI,CAAC,CAAC;AAE9D;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAqB;IACnE,MAAM,IAAI,GAAG,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;IAClC,OAAO,aAAa,CAAC,WAAW,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,QAAQ,CAAC,CAAC;AACxE,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,cAAc;IAC5B,MAAM,GAAG,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC;IACpC,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAC;IAC1E,CAAC;IACD,OAAO,GAA2B,CAAC;AACrC,CAAC;AAiDD;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,SAAS,CAAC,EACxB,IAAI,EAAE,OAAO,EACb,KAAK,EACL,WAAW,GAAG,EAAE,EAChB,SAAS,GAAG,IAAI,EAChB,UAAU,EACV,QAAQ,EACR,OAAO,EACP,SAAS,GAAG,MAAM,EAClB,SAAS,GAAG,MAAM,EAClB,WAAW,GAAG,QAAQ,EACtB,WAAW,GAAG,QAAQ,EACtB,UAAU,GAAG,KAAK,EAClB,YAAY,GAAG,KAAK,EACpB,SAAS,EACT,YAAY,EACZ,YAAY,GACG;IACf,MAAM,UAAU,GAAG,OAAO,CAAC;QACzB,OAAO,CAAC,KAAK;YACX,OAAO,EAAE,CAAC,KAAK,CAAC,CAAC;YACjB,IAAI,KAAK,CAAC,IAAI,KAAK,WAAW;gBAAE,UAAU,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACzD,IAAI,KAAK,CAAC,IAAI,KAAK,WAAW;gBAAE,QAAQ,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACzD,CAAC;KACF,CAAC,CAAC;IAEH,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,UAAU,CAAC;IAElF,sBAAsB;IACtB,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IACjC,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,SAAS,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;YACrC,UAAU,CAAC,OAAO,GAAG,IAAI,CAAC;YAC1B,KAAK,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;QAC9B,CAAC;QACD,uDAAuD;IACzD,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,0CAA0C;IAC1C,MAAM,WAAW,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAEvE,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,aAAa,CAAC,WAAW,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,EAC9D,aAAa,CAAC,KAAK,EAAE,EAAE,SAAS,EAAE,GAAG,CAAC,UAAU,EAAE,SAAS,CAAC,EAAE,EAC5D,aAAa,CAAC,KAAK,EAAE,EAAE,SAAS,EAAE,iBAAiB,EAAE,EACnD,aAAa,CAAC,GAAG,EAAE,IAAI,EAAE,iBAAiB,CAAC,EAC3C,CAAC,SAAS,IAAI,aAAa,CAAC,QAAQ,EAAE;YACpC,IAAI,EAAE,QAAQ;YACd,SAAS,EAAE,qBAAqB;YAChC,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,WAAW,CAAC;SAC3C,EAAE,OAAO,CAAC,CACZ,CACF,CACF,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAqB,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;IAEhF,OAAO,aAAa,CAAC,WAAW,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,EAC9D,aAAa,CAAC,KAAK,EAAE,EAAE,SAAS,EAAE,GAAG,CAAC,UAAU,EAAE,SAAS,CAAC,EAAE;IAC5D,8BAA8B;IAC9B,CAAC,YAAY,IAAI,CAAC,YAAY;QAC5B,CAAC,CAAC,YAAY,CAAC,QAAQ,CAAC;QACxB,CAAC,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;IAC5B,sBAAsB;IACtB,aAAa,CAAC,KAAK,EAAE,EAAE,SAAS,EAAE,gBAAgB,EAAE,EAAE,WAAW,CAAC;IAClE,sBAAsB;IACtB,QAAQ,CAAC,kBAAkB,CAAC,MAAM,GAAG,CAAC,IAAI,aAAa,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,sBAAsB,EAAE,EACjG,GAAG,QAAQ,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAC5C,aAAa,CAAC,IAAI,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,SAAS,EAAE,2BAA2B,EAAE,EAAE,GAAG,CAAC,CAC7E,CACF;IACD,8BAA8B;IAC9B,YAAY;QACV,CAAC,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC;QACjC,CAAC,CAAC,aAAa,CAAC,QAAQ,EAAE,OAAO,EAAE;YAC/B,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU;SAC3D,CAAC,CACP,CACF,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,sCAAsC;AACtC,8EAA8E;AAE9E,SAAS,aAAa,CAAC,QAAsB;IAC3C,OAAO,aAAa,CAAC,KAAK,EAAE,EAAE,SAAS,EAAE,kBAAkB,EAAE,EAC3D,aAAa,CAAC,KAAK,EAAE,EAAE,SAAS,EAAE,iBAAiB,EAAE,EACnD,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAChC,aAAa,CAAC,KAAK,EAAE;QACnB,GAAG,EAAE,IAAI,CAAC,EAAE;QACZ,SAAS,EAAE,GAAG,CAAC,gBAAgB,EAAE,mBAAmB,IAAI,CAAC,MAAM,EAAE,CAAC;KACnE,EACC,aAAa,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,oBAAoB,EAAE,EACvD,IAAI,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAClD,EACD,aAAa,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,sBAAsB,EAAE,EACzD,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,EAAE,CACtB,CACF,CACF,CACF,EACD,aAAa,CAAC,KAAK,EAAE,EAAE,SAAS,EAAE,iBAAiB,EAAE,EACnD,aAAa,CAAC,KAAK,EAAE;QACnB,SAAS,EAAE,sBAAsB;QACjC,KAAK,EAAE,EAAE,KAAK,EAAE,GAAG,QAAQ,CAAC,QAAQ,GAAG,GAAG,GAAG,EAAE;KAChD,CAAC,CACH,CACF,CAAC;AACJ,CAAC;AAcD,SAAS,aAAa,CACpB,QAAsB,EACtB,OAAyB,EACzB,MAAoB;IAEpB,OAAO,aAAa,CAAC,KAAK,EAAE,EAAE,SAAS,EAAE,kBAAkB,EAAE,EAC3D,aAAa,CAAC,KAAK,EAAE,EAAE,SAAS,EAAE,uBAAuB,EAAE,EACzD,CAAC,QAAQ,CAAC,WAAW,IAAI,aAAa,CAAC,QAAQ,EAAE;QAC/C,IAAI,EAAE,QAAQ;QACd,SAAS,EAAE,mCAAmC;QAC9C,QAAQ,EAAE,QAAQ,CAAC,YAAY,IAAI,CAAC,QAAQ,CAAC,eAAe;QAC5D,OAAO,EAAE,OAAO,CAAC,QAAQ;KAC1B,EAAE,MAAM,CAAC,SAAS,CAAC,CACrB,EACD,aAAa,CAAC,KAAK,EAAE,EAAE,SAAS,EAAE,wBAAwB,EAAE,EAC1D,CAAC,MAAM,CAAC,UAAU,IAAI,aAAa,CAAC,QAAQ,EAAE;QAC5C,IAAI,EAAE,QAAQ;QACd,SAAS,EAAE,qCAAqC;QAChD,QAAQ,EAAE,QAAQ,CAAC,YAAY;QAC/B,OAAO,EAAE,OAAO,CAAC,MAAM;KACxB,EAAE,MAAM,CAAC,WAAW,CAAC,EACtB,aAAa,CAAC,QAAQ,EAAE;QACtB,IAAI,EAAE,QAAQ;QACd,SAAS,EAAE,mCAAmC;QAC9C,QAAQ,EAAE,QAAQ,CAAC,YAAY,IAAI,CAAC,QAAQ,CAAC,WAAW;QACxD,OAAO,EAAE,OAAO,CAAC,IAAI;KACtB,EAAE,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAChE,CACF,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,UAAU;AACV,8EAA8E;AAG9E,SAAS,GAAG,CAAC,GAAG,KAA4C;IAC1D,OAAO,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACzC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@daltonr/pathwrite-react",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
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.",
|
|
@@ -39,13 +39,13 @@
|
|
|
39
39
|
"scripts": {
|
|
40
40
|
"build": "tsc -p tsconfig.json && cp ../shell.css dist/index.css",
|
|
41
41
|
"clean": "rm -rf dist tsconfig.tsbuildinfo",
|
|
42
|
-
"prepublishOnly": "npm run clean && npm run build"
|
|
42
|
+
"prepublishOnly": "test -d dist && echo 'dist already built, skipping' || (npm run clean && npm run build)"
|
|
43
43
|
},
|
|
44
44
|
"peerDependencies": {
|
|
45
45
|
"react": ">=18.0.0"
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@daltonr/pathwrite-core": "^0.1
|
|
48
|
+
"@daltonr/pathwrite-core": "^0.2.1"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
51
|
"react": "^18.3.1",
|
package/src/index.ts
CHANGED
|
@@ -29,9 +29,9 @@ export interface UsePathReturn<TData extends PathData = PathData> {
|
|
|
29
29
|
/** Current path snapshot, or `null` when no path is active. Triggers a React re-render on change. */
|
|
30
30
|
snapshot: PathSnapshot<TData> | null;
|
|
31
31
|
/** Start (or restart) a path. */
|
|
32
|
-
start: (path: PathDefinition
|
|
32
|
+
start: (path: PathDefinition<any>, initialData?: PathData) => void;
|
|
33
33
|
/** Push a sub-path onto the stack. Requires an active path. */
|
|
34
|
-
startSubPath: (path: PathDefinition
|
|
34
|
+
startSubPath: (path: PathDefinition<any>, initialData?: PathData) => void;
|
|
35
35
|
/** Advance one step. Completes the path on the last step. */
|
|
36
36
|
next: () => void;
|
|
37
37
|
/** Go back one step. Cancels the path from the first step. */
|
|
@@ -40,6 +40,8 @@ export interface UsePathReturn<TData extends PathData = PathData> {
|
|
|
40
40
|
cancel: () => void;
|
|
41
41
|
/** Jump directly to a step by ID. Calls onLeave / onEnter but bypasses guards and shouldSkip. */
|
|
42
42
|
goToStep: (stepId: string) => void;
|
|
43
|
+
/** Jump directly to a step by ID, checking the current step's canMoveNext (forward) or canMovePrevious (backward) guard first. Navigation is blocked if the guard returns false. */
|
|
44
|
+
goToStepChecked: (stepId: string) => void;
|
|
43
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. */
|
|
44
46
|
setData: <K extends string & keyof TData>(key: K, value: TData[K]) => void;
|
|
45
47
|
}
|
|
@@ -88,13 +90,13 @@ export function usePath<TData extends PathData = PathData>(options?: UsePathOpti
|
|
|
88
90
|
|
|
89
91
|
// Stable action callbacks
|
|
90
92
|
const start = useCallback(
|
|
91
|
-
(path: PathDefinition
|
|
93
|
+
(path: PathDefinition<any>, initialData: PathData = {}) =>
|
|
92
94
|
engine.start(path, initialData),
|
|
93
95
|
[engine]
|
|
94
96
|
);
|
|
95
97
|
|
|
96
98
|
const startSubPath = useCallback(
|
|
97
|
-
(path: PathDefinition
|
|
99
|
+
(path: PathDefinition<any>, initialData: PathData = {}) =>
|
|
98
100
|
engine.startSubPath(path, initialData),
|
|
99
101
|
[engine]
|
|
100
102
|
);
|
|
@@ -108,12 +110,17 @@ export function usePath<TData extends PathData = PathData>(options?: UsePathOpti
|
|
|
108
110
|
[engine]
|
|
109
111
|
);
|
|
110
112
|
|
|
113
|
+
const goToStepChecked = useCallback(
|
|
114
|
+
(stepId: string) => engine.goToStepChecked(stepId),
|
|
115
|
+
[engine]
|
|
116
|
+
);
|
|
117
|
+
|
|
111
118
|
const setData = useCallback(
|
|
112
119
|
<K extends string & keyof TData>(key: K, value: TData[K]) => engine.setData(key, value as unknown),
|
|
113
120
|
[engine]
|
|
114
121
|
) as UsePathReturn<TData>["setData"];
|
|
115
122
|
|
|
116
|
-
return { snapshot, start, startSubPath, next, previous, cancel, goToStep, setData };
|
|
123
|
+
return { snapshot, start, startSubPath, next, previous, cancel, goToStep, goToStepChecked, setData };
|
|
117
124
|
}
|
|
118
125
|
|
|
119
126
|
// ---------------------------------------------------------------------------
|
|
@@ -152,7 +159,7 @@ export function usePathContext<TData extends PathData = PathData>(): UsePathRetu
|
|
|
152
159
|
|
|
153
160
|
export interface PathShellProps {
|
|
154
161
|
/** The path definition to drive. */
|
|
155
|
-
path: PathDefinition
|
|
162
|
+
path: PathDefinition<any>;
|
|
156
163
|
/** Map of step ID → content. The shell renders `steps[snapshot.stepId]` for the current step. */
|
|
157
164
|
steps: Record<string, ReactNode>;
|
|
158
165
|
/** Initial data passed to `engine.start()`. */
|
|
@@ -275,6 +282,12 @@ export function PathShell({
|
|
|
275
282
|
: defaultHeader(snapshot)),
|
|
276
283
|
// Body — step content
|
|
277
284
|
createElement("div", { className: "pw-shell__body" }, stepContent),
|
|
285
|
+
// Validation messages
|
|
286
|
+
snapshot.validationMessages.length > 0 && createElement("ul", { className: "pw-shell__validation" },
|
|
287
|
+
...snapshot.validationMessages.map((msg, i) =>
|
|
288
|
+
createElement("li", { key: i, className: "pw-shell__validation-item" }, msg)
|
|
289
|
+
)
|
|
290
|
+
),
|
|
278
291
|
// Footer — navigation buttons
|
|
279
292
|
renderFooter
|
|
280
293
|
? renderFooter(snapshot, actions)
|
package/dist/index.css
DELETED
|
@@ -1,228 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Pathwrite — Default Shell Stylesheet
|
|
3
|
-
*
|
|
4
|
-
* Optional CSS for the <PathShell> / <pw-shell> default UI components.
|
|
5
|
-
* Import this file if you want sensible out-of-the-box styling.
|
|
6
|
-
* Every visual value is a CSS custom property (--pw-*) so you can
|
|
7
|
-
* theme the shell without overriding selectors.
|
|
8
|
-
*
|
|
9
|
-
* Usage:
|
|
10
|
-
* import "@daltonr/pathwrite-react/styles.css"; // React
|
|
11
|
-
* import "@daltonr/pathwrite-vue/styles.css"; // Vue
|
|
12
|
-
* // Angular: add "node_modules/@daltonr/pathwrite-angular/dist/index.css"
|
|
13
|
-
* // to the styles array in angular.json
|
|
14
|
-
*/
|
|
15
|
-
|
|
16
|
-
/* ------------------------------------------------------------------ */
|
|
17
|
-
/* Custom property defaults */
|
|
18
|
-
/* ------------------------------------------------------------------ */
|
|
19
|
-
:root {
|
|
20
|
-
/* Layout */
|
|
21
|
-
--pw-shell-max-width: 720px;
|
|
22
|
-
--pw-shell-padding: 24px;
|
|
23
|
-
--pw-shell-gap: 20px;
|
|
24
|
-
--pw-shell-radius: 10px;
|
|
25
|
-
|
|
26
|
-
/* Colours */
|
|
27
|
-
--pw-color-bg: #ffffff;
|
|
28
|
-
--pw-color-border: #dbe4f0;
|
|
29
|
-
--pw-color-text: #1f2937;
|
|
30
|
-
--pw-color-muted: #5b677a;
|
|
31
|
-
--pw-color-primary: #2563eb;
|
|
32
|
-
--pw-color-primary-light: rgba(37, 99, 235, 0.12);
|
|
33
|
-
--pw-color-btn-bg: #f8fbff;
|
|
34
|
-
--pw-color-btn-border: #c2d0e5;
|
|
35
|
-
|
|
36
|
-
/* Progress */
|
|
37
|
-
--pw-dot-size: 32px;
|
|
38
|
-
--pw-dot-font-size: 13px;
|
|
39
|
-
--pw-track-height: 4px;
|
|
40
|
-
|
|
41
|
-
/* Buttons */
|
|
42
|
-
--pw-btn-padding: 8px 16px;
|
|
43
|
-
--pw-btn-radius: 6px;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/* ------------------------------------------------------------------ */
|
|
47
|
-
/* Shell root */
|
|
48
|
-
/* ------------------------------------------------------------------ */
|
|
49
|
-
.pw-shell {
|
|
50
|
-
max-width: var(--pw-shell-max-width);
|
|
51
|
-
margin: 0 auto;
|
|
52
|
-
display: flex;
|
|
53
|
-
flex-direction: column;
|
|
54
|
-
gap: var(--pw-shell-gap);
|
|
55
|
-
padding: var(--pw-shell-padding);
|
|
56
|
-
font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
|
|
57
|
-
color: var(--pw-color-text);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/* ------------------------------------------------------------------ */
|
|
61
|
-
/* Empty state */
|
|
62
|
-
/* ------------------------------------------------------------------ */
|
|
63
|
-
.pw-shell__empty {
|
|
64
|
-
text-align: center;
|
|
65
|
-
padding: 32px 16px;
|
|
66
|
-
color: var(--pw-color-muted);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
.pw-shell__start-btn {
|
|
70
|
-
margin-top: 12px;
|
|
71
|
-
border: 1px solid var(--pw-color-btn-border);
|
|
72
|
-
background: var(--pw-color-btn-bg);
|
|
73
|
-
color: var(--pw-color-text);
|
|
74
|
-
padding: var(--pw-btn-padding);
|
|
75
|
-
border-radius: var(--pw-btn-radius);
|
|
76
|
-
cursor: pointer;
|
|
77
|
-
font-size: 14px;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
/* ------------------------------------------------------------------ */
|
|
81
|
-
/* Header — progress indicator */
|
|
82
|
-
/* ------------------------------------------------------------------ */
|
|
83
|
-
.pw-shell__header {
|
|
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__steps {
|
|
91
|
-
display: flex;
|
|
92
|
-
justify-content: space-between;
|
|
93
|
-
margin-bottom: 12px;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
.pw-shell__step {
|
|
97
|
-
display: flex;
|
|
98
|
-
flex-direction: column;
|
|
99
|
-
align-items: center;
|
|
100
|
-
gap: 6px;
|
|
101
|
-
flex: 1;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
.pw-shell__step-dot {
|
|
105
|
-
width: var(--pw-dot-size);
|
|
106
|
-
height: var(--pw-dot-size);
|
|
107
|
-
border-radius: 50%;
|
|
108
|
-
display: flex;
|
|
109
|
-
align-items: center;
|
|
110
|
-
justify-content: center;
|
|
111
|
-
font-size: var(--pw-dot-font-size);
|
|
112
|
-
font-weight: 600;
|
|
113
|
-
border: 2px solid var(--pw-color-border);
|
|
114
|
-
background: var(--pw-color-bg);
|
|
115
|
-
color: var(--pw-color-muted);
|
|
116
|
-
transition: all 0.25s ease;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
.pw-shell__step--completed .pw-shell__step-dot {
|
|
120
|
-
background: var(--pw-color-primary);
|
|
121
|
-
border-color: var(--pw-color-primary);
|
|
122
|
-
color: #fff;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
.pw-shell__step--current .pw-shell__step-dot {
|
|
126
|
-
border-color: var(--pw-color-primary);
|
|
127
|
-
color: var(--pw-color-primary);
|
|
128
|
-
box-shadow: 0 0 0 3px var(--pw-color-primary-light);
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
.pw-shell__step-label {
|
|
132
|
-
font-size: 12px;
|
|
133
|
-
color: var(--pw-color-muted);
|
|
134
|
-
text-align: center;
|
|
135
|
-
white-space: nowrap;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
.pw-shell__step--current .pw-shell__step-label {
|
|
139
|
-
color: var(--pw-color-primary);
|
|
140
|
-
font-weight: 600;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
.pw-shell__step--completed .pw-shell__step-label {
|
|
144
|
-
color: var(--pw-color-text);
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
/* Track / fill */
|
|
148
|
-
.pw-shell__track {
|
|
149
|
-
height: var(--pw-track-height);
|
|
150
|
-
background: var(--pw-color-border);
|
|
151
|
-
border-radius: calc(var(--pw-track-height) / 2);
|
|
152
|
-
overflow: hidden;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
.pw-shell__track-fill {
|
|
156
|
-
height: 100%;
|
|
157
|
-
background: var(--pw-color-primary);
|
|
158
|
-
border-radius: calc(var(--pw-track-height) / 2);
|
|
159
|
-
transition: width 0.3s ease;
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
/* ------------------------------------------------------------------ */
|
|
163
|
-
/* Body — step content */
|
|
164
|
-
/* ------------------------------------------------------------------ */
|
|
165
|
-
.pw-shell__body {
|
|
166
|
-
background: var(--pw-color-bg);
|
|
167
|
-
border: 1px solid var(--pw-color-border);
|
|
168
|
-
border-radius: var(--pw-shell-radius);
|
|
169
|
-
padding: var(--pw-shell-padding);
|
|
170
|
-
min-height: 120px;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
/* ------------------------------------------------------------------ */
|
|
174
|
-
/* Footer — navigation buttons */
|
|
175
|
-
/* ------------------------------------------------------------------ */
|
|
176
|
-
.pw-shell__footer {
|
|
177
|
-
display: flex;
|
|
178
|
-
justify-content: space-between;
|
|
179
|
-
align-items: center;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
.pw-shell__footer-left,
|
|
183
|
-
.pw-shell__footer-right {
|
|
184
|
-
display: flex;
|
|
185
|
-
gap: 8px;
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
.pw-shell__btn {
|
|
189
|
-
border: 1px solid var(--pw-color-btn-border);
|
|
190
|
-
background: var(--pw-color-btn-bg);
|
|
191
|
-
color: var(--pw-color-text);
|
|
192
|
-
padding: var(--pw-btn-padding);
|
|
193
|
-
border-radius: var(--pw-btn-radius);
|
|
194
|
-
cursor: pointer;
|
|
195
|
-
font-size: 14px;
|
|
196
|
-
transition: background 0.15s ease, border-color 0.15s ease;
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
.pw-shell__btn:hover:not(:disabled) {
|
|
200
|
-
background: var(--pw-color-border);
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
.pw-shell__btn:disabled {
|
|
204
|
-
opacity: 0.5;
|
|
205
|
-
cursor: not-allowed;
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
.pw-shell__btn--next {
|
|
209
|
-
background: var(--pw-color-primary);
|
|
210
|
-
border-color: var(--pw-color-primary);
|
|
211
|
-
color: #fff;
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
.pw-shell__btn--next:hover:not(:disabled) {
|
|
215
|
-
background: #1d4ed8;
|
|
216
|
-
border-color: #1d4ed8;
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
.pw-shell__btn--cancel {
|
|
220
|
-
color: var(--pw-color-muted);
|
|
221
|
-
border-color: transparent;
|
|
222
|
-
background: transparent;
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
.pw-shell__btn--cancel:hover:not(:disabled) {
|
|
226
|
-
background: var(--pw-color-primary-light);
|
|
227
|
-
}
|
|
228
|
-
|