@daltonr/pathwrite-react 0.2.0 → 0.3.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 +71 -7
- package/dist/index.d.ts +6 -5
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/index.ts +11 -10
- package/dist/index.css +0 -262
package/README.md
CHANGED
|
@@ -86,7 +86,7 @@ function NavButtons() {
|
|
|
86
86
|
|----------|------|-------------|
|
|
87
87
|
| `snapshot` | `PathSnapshot \| null` | Current snapshot. `null` when no path is active. Triggers a React re-render on change. |
|
|
88
88
|
| `start(definition, data?)` | `function` | Start or re-start a path. |
|
|
89
|
-
| `startSubPath(definition, data?)` | `function` | Push a sub-path. Requires an active path. |
|
|
89
|
+
| `startSubPath(definition, data?, meta?)` | `function` | Push a sub-path. Requires an active path. `meta` is returned unchanged to `onSubPathComplete` / `onSubPathCancel`. |
|
|
90
90
|
| `next()` | `function` | Advance one step. Completes the path on the last step. |
|
|
91
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). |
|
|
@@ -138,9 +138,74 @@ These update automatically when data changes (e.g. after `setData`). Async guard
|
|
|
138
138
|
|
|
139
139
|
Wrap a subtree in `<PathProvider>` so multiple components share the same engine instance. Consume with `usePathContext()`.
|
|
140
140
|
|
|
141
|
-
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
## Default UI — `PathShell`
|
|
144
|
+
|
|
145
|
+
`<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.
|
|
146
|
+
|
|
147
|
+
```tsx
|
|
148
|
+
import { PathShell } from "@daltonr/pathwrite-react";
|
|
149
|
+
|
|
150
|
+
<PathShell
|
|
151
|
+
path={myPath}
|
|
152
|
+
initialData={{ name: "" }}
|
|
153
|
+
onComplete={(data) => console.log("Done!", data)}
|
|
154
|
+
steps={{
|
|
155
|
+
details: <DetailsForm />,
|
|
156
|
+
review: <ReviewPanel />,
|
|
157
|
+
}}
|
|
158
|
+
/>
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Props
|
|
162
|
+
|
|
163
|
+
| Prop | Type | Default | Description |
|
|
164
|
+
|------|------|---------|-------------|
|
|
165
|
+
| `path` | `PathDefinition` | *required* | The path to run. |
|
|
166
|
+
| `steps` | `Record<string, ReactNode>` | *required* | Map of step ID → content to render. |
|
|
167
|
+
| `initialData` | `PathData` | `{}` | Initial data passed to `engine.start()`. |
|
|
168
|
+
| `autoStart` | `boolean` | `true` | Start the path automatically on mount. |
|
|
169
|
+
| `onComplete` | `(data: PathData) => void` | — | Called when the path completes. |
|
|
170
|
+
| `onCancel` | `(data: PathData) => void` | — | Called when the path is cancelled. |
|
|
171
|
+
| `onEvent` | `(event: PathEvent) => void` | — | Called for every engine event. |
|
|
172
|
+
| `backLabel` | `string` | `"Back"` | Back button label. |
|
|
173
|
+
| `nextLabel` | `string` | `"Next"` | Next button label. |
|
|
174
|
+
| `finishLabel` | `string` | `"Finish"` | Finish button label (last step). |
|
|
175
|
+
| `cancelLabel` | `string` | `"Cancel"` | Cancel button label. |
|
|
176
|
+
| `hideCancel` | `boolean` | `false` | Hide the Cancel button. |
|
|
177
|
+
| `hideProgress` | `boolean` | `false` | Hide the progress indicator. |
|
|
178
|
+
| `className` | `string` | — | Extra CSS class on the root element. |
|
|
179
|
+
| `renderHeader` | `(snapshot) => ReactNode` | — | Render prop to replace the progress header. |
|
|
180
|
+
| `renderFooter` | `(snapshot, actions) => ReactNode` | — | Render prop to replace the navigation footer. |
|
|
181
|
+
|
|
182
|
+
### Customising the header and footer
|
|
183
|
+
|
|
184
|
+
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.
|
|
142
185
|
|
|
143
|
-
|
|
186
|
+
```tsx
|
|
187
|
+
<PathShell
|
|
188
|
+
path={myPath}
|
|
189
|
+
steps={{ details: <DetailsForm />, review: <ReviewPanel /> }}
|
|
190
|
+
renderHeader={(snapshot) => (
|
|
191
|
+
<p>{snapshot.stepIndex + 1} / {snapshot.stepCount} — {snapshot.stepTitle}</p>
|
|
192
|
+
)}
|
|
193
|
+
renderFooter={(snapshot, actions) => (
|
|
194
|
+
<div>
|
|
195
|
+
<button onClick={actions.previous} disabled={snapshot.isFirstStep}>Back</button>
|
|
196
|
+
<button onClick={actions.next} disabled={!snapshot.canMoveNext}>
|
|
197
|
+
{snapshot.isLastStep ? "Finish" : "Next"}
|
|
198
|
+
</button>
|
|
199
|
+
</div>
|
|
200
|
+
)}
|
|
201
|
+
/>
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
`PathShellActions` contains: `next`, `previous`, `cancel`, `goToStep`, `goToStepChecked`, `setData`.
|
|
205
|
+
|
|
206
|
+
### Context sharing
|
|
207
|
+
|
|
208
|
+
`<PathShell>` provides a path context automatically — step components rendered inside it can call `usePathContext()` without a separate `<PathProvider>`:
|
|
144
209
|
|
|
145
210
|
```tsx
|
|
146
211
|
function DetailsForm() {
|
|
@@ -157,13 +222,12 @@ function DetailsForm() {
|
|
|
157
222
|
path={myPath}
|
|
158
223
|
initialData={{ name: "" }}
|
|
159
224
|
onComplete={handleDone}
|
|
160
|
-
steps={{
|
|
161
|
-
details: <DetailsForm />,
|
|
162
|
-
review: <ReviewPanel />,
|
|
163
|
-
}}
|
|
225
|
+
steps={{ details: <DetailsForm />, review: <ReviewPanel /> }}
|
|
164
226
|
/>
|
|
165
227
|
```
|
|
166
228
|
|
|
229
|
+
---
|
|
230
|
+
|
|
167
231
|
## Styling
|
|
168
232
|
|
|
169
233
|
`<PathShell>` renders structural HTML with BEM-style `pw-shell__*` CSS classes but ships with no embedded styles. Import the optional stylesheet for sensible defaults:
|
package/dist/index.d.ts
CHANGED
|
@@ -8,12 +8,12 @@ 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
|
|
12
|
-
/** Push a sub-path onto the stack. Requires an active path. */
|
|
13
|
-
startSubPath: (path: PathDefinition
|
|
11
|
+
start: (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.
|
|
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;
|
|
@@ -44,7 +44,7 @@ export declare function PathProvider({ children, onEvent }: PathProviderProps):
|
|
|
44
44
|
export declare function usePathContext<TData extends PathData = PathData>(): UsePathReturn<TData>;
|
|
45
45
|
export interface PathShellProps {
|
|
46
46
|
/** The path definition to drive. */
|
|
47
|
-
path: PathDefinition
|
|
47
|
+
path: PathDefinition<any>;
|
|
48
48
|
/** Map of step ID → content. The shell renders `steps[snapshot.stepId]` for the current step. */
|
|
49
49
|
steps: Record<string, ReactNode>;
|
|
50
50
|
/** Initial data passed to `engine.start()`. */
|
|
@@ -81,6 +81,7 @@ export interface PathShellActions {
|
|
|
81
81
|
previous: () => void;
|
|
82
82
|
cancel: () => void;
|
|
83
83
|
goToStep: (stepId: string) => void;
|
|
84
|
+
goToStepChecked: (stepId: string) => void;
|
|
84
85
|
setData: (key: string, value: unknown) => void;
|
|
85
86
|
}
|
|
86
87
|
/**
|
package/dist/index.js
CHANGED
|
@@ -29,7 +29,7 @@ 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]);
|
|
@@ -90,7 +90,7 @@ export function PathShell({ path: pathDef, steps, initialData = {}, autoStart =
|
|
|
90
90
|
onCancel?.(event.data);
|
|
91
91
|
}
|
|
92
92
|
});
|
|
93
|
-
const { snapshot, start, next, previous, cancel, goToStep, setData } = pathReturn;
|
|
93
|
+
const { snapshot, start, next, previous, cancel, goToStep, goToStepChecked, setData } = pathReturn;
|
|
94
94
|
// Auto-start on mount
|
|
95
95
|
const startedRef = useRef(false);
|
|
96
96
|
useEffect(() => {
|
|
@@ -109,7 +109,7 @@ export function PathShell({ path: pathDef, steps, initialData = {}, autoStart =
|
|
|
109
109
|
onClick: () => start(pathDef, initialData)
|
|
110
110
|
}, "Start"))));
|
|
111
111
|
}
|
|
112
|
-
const actions = { next, previous, cancel, goToStep, setData };
|
|
112
|
+
const actions = { next, previous, cancel, goToStep, goToStepChecked, setData };
|
|
113
113
|
return createElement(PathContext.Provider, { value: pathReturn }, createElement("div", { className: cls("pw-shell", className) },
|
|
114
114
|
// Header — progress indicator
|
|
115
115
|
!hideProgress && (renderHeader
|
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;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,
|
|
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.
|
|
3
|
+
"version": "0.3.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.",
|
|
@@ -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.
|
|
48
|
+
"@daltonr/pathwrite-core": "^0.3.0"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
51
|
"react": "^18.3.1",
|
package/src/index.ts
CHANGED
|
@@ -29,12 +29,12 @@ 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
|
|
33
|
-
/** Push a sub-path onto the stack. Requires an active path. */
|
|
34
|
-
startSubPath: (path: PathDefinition
|
|
32
|
+
start: (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.
|
|
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;
|
|
@@ -90,14 +90,14 @@ export function usePath<TData extends PathData = PathData>(options?: UsePathOpti
|
|
|
90
90
|
|
|
91
91
|
// Stable action callbacks
|
|
92
92
|
const start = useCallback(
|
|
93
|
-
(path: PathDefinition
|
|
93
|
+
(path: PathDefinition<any>, initialData: PathData = {}) =>
|
|
94
94
|
engine.start(path, initialData),
|
|
95
95
|
[engine]
|
|
96
96
|
);
|
|
97
97
|
|
|
98
98
|
const startSubPath = useCallback(
|
|
99
|
-
(path: PathDefinition
|
|
100
|
-
engine.startSubPath(path, initialData),
|
|
99
|
+
(path: PathDefinition<any>, initialData: PathData = {}, meta?: Record<string, unknown>) =>
|
|
100
|
+
engine.startSubPath(path, initialData, meta),
|
|
101
101
|
[engine]
|
|
102
102
|
);
|
|
103
103
|
|
|
@@ -159,7 +159,7 @@ export function usePathContext<TData extends PathData = PathData>(): UsePathRetu
|
|
|
159
159
|
|
|
160
160
|
export interface PathShellProps {
|
|
161
161
|
/** The path definition to drive. */
|
|
162
|
-
path: PathDefinition
|
|
162
|
+
path: PathDefinition<any>;
|
|
163
163
|
/** Map of step ID → content. The shell renders `steps[snapshot.stepId]` for the current step. */
|
|
164
164
|
steps: Record<string, ReactNode>;
|
|
165
165
|
/** Initial data passed to `engine.start()`. */
|
|
@@ -197,6 +197,7 @@ export interface PathShellActions {
|
|
|
197
197
|
previous: () => void;
|
|
198
198
|
cancel: () => void;
|
|
199
199
|
goToStep: (stepId: string) => void;
|
|
200
|
+
goToStepChecked: (stepId: string) => void;
|
|
200
201
|
setData: (key: string, value: unknown) => void;
|
|
201
202
|
}
|
|
202
203
|
|
|
@@ -242,7 +243,7 @@ export function PathShell({
|
|
|
242
243
|
}
|
|
243
244
|
});
|
|
244
245
|
|
|
245
|
-
const { snapshot, start, next, previous, cancel, goToStep, setData } = pathReturn;
|
|
246
|
+
const { snapshot, start, next, previous, cancel, goToStep, goToStepChecked, setData } = pathReturn;
|
|
246
247
|
|
|
247
248
|
// Auto-start on mount
|
|
248
249
|
const startedRef = useRef(false);
|
|
@@ -272,7 +273,7 @@ export function PathShell({
|
|
|
272
273
|
);
|
|
273
274
|
}
|
|
274
275
|
|
|
275
|
-
const actions: PathShellActions = { next, previous, cancel, goToStep, setData };
|
|
276
|
+
const actions: PathShellActions = { next, previous, cancel, goToStep, goToStepChecked, setData };
|
|
276
277
|
|
|
277
278
|
return createElement(PathContext.Provider, { value: pathReturn },
|
|
278
279
|
createElement("div", { className: cls("pw-shell", className) },
|
package/dist/index.css
DELETED
|
@@ -1,262 +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 (React / Vue):
|
|
10
|
-
* import "adapter-package/styles.css";
|
|
11
|
-
*
|
|
12
|
-
* Usage (Angular) — add to the styles array in angular.json:
|
|
13
|
-
* "node_modules/@daltonr/pathwrite-angular/dist/index.css"
|
|
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
|
-
/* Validation messages */
|
|
175
|
-
/* ------------------------------------------------------------------ */
|
|
176
|
-
:root {
|
|
177
|
-
--pw-color-error: #dc2626;
|
|
178
|
-
--pw-color-error-bg: #fef2f2;
|
|
179
|
-
--pw-color-error-border: #fecaca;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
.pw-shell__validation {
|
|
183
|
-
list-style: none;
|
|
184
|
-
margin: 0;
|
|
185
|
-
padding: 12px 16px;
|
|
186
|
-
background: var(--pw-color-error-bg);
|
|
187
|
-
border: 1px solid var(--pw-color-error-border);
|
|
188
|
-
border-radius: var(--pw-shell-radius);
|
|
189
|
-
display: flex;
|
|
190
|
-
flex-direction: column;
|
|
191
|
-
gap: 4px;
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
.pw-shell__validation-item {
|
|
195
|
-
font-size: 13px;
|
|
196
|
-
color: var(--pw-color-error);
|
|
197
|
-
padding-left: 16px;
|
|
198
|
-
position: relative;
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
.pw-shell__validation-item::before {
|
|
202
|
-
content: "•";
|
|
203
|
-
position: absolute;
|
|
204
|
-
left: 4px;
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
/* ------------------------------------------------------------------ */
|
|
208
|
-
/* Footer — navigation buttons */
|
|
209
|
-
/* ------------------------------------------------------------------ */
|
|
210
|
-
.pw-shell__footer {
|
|
211
|
-
display: flex;
|
|
212
|
-
justify-content: space-between;
|
|
213
|
-
align-items: center;
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
.pw-shell__footer-left,
|
|
217
|
-
.pw-shell__footer-right {
|
|
218
|
-
display: flex;
|
|
219
|
-
gap: 8px;
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
.pw-shell__btn {
|
|
223
|
-
border: 1px solid var(--pw-color-btn-border);
|
|
224
|
-
background: var(--pw-color-btn-bg);
|
|
225
|
-
color: var(--pw-color-text);
|
|
226
|
-
padding: var(--pw-btn-padding);
|
|
227
|
-
border-radius: var(--pw-btn-radius);
|
|
228
|
-
cursor: pointer;
|
|
229
|
-
font-size: 14px;
|
|
230
|
-
transition: background 0.15s ease, border-color 0.15s ease;
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
.pw-shell__btn:hover:not(:disabled) {
|
|
234
|
-
background: var(--pw-color-border);
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
.pw-shell__btn:disabled {
|
|
238
|
-
opacity: 0.5;
|
|
239
|
-
cursor: not-allowed;
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
.pw-shell__btn--next {
|
|
243
|
-
background: var(--pw-color-primary);
|
|
244
|
-
border-color: var(--pw-color-primary);
|
|
245
|
-
color: #fff;
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
.pw-shell__btn--next:hover:not(:disabled) {
|
|
249
|
-
background: #1d4ed8;
|
|
250
|
-
border-color: #1d4ed8;
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
.pw-shell__btn--cancel {
|
|
254
|
-
color: var(--pw-color-muted);
|
|
255
|
-
border-color: transparent;
|
|
256
|
-
background: transparent;
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
.pw-shell__btn--cancel:hover:not(:disabled) {
|
|
260
|
-
background: var(--pw-color-primary-light);
|
|
261
|
-
}
|
|
262
|
-
|