@rightkit/onboarding 0.3.3 → 0.5.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 +3 -1
- package/dist/Onboarding.d.ts +1 -1
- package/dist/Onboarding.js +22 -7
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/steps.d.ts +7 -1
- package/dist/steps.js +26 -1
- package/dist/types.d.ts +36 -1
- package/package.json +16 -15
package/README.md
CHANGED
|
@@ -13,7 +13,7 @@ First-run onboarding framework for Right Suite apps. The legal agreement gate co
|
|
|
13
13
|
|
|
14
14
|
| Import | Contents |
|
|
15
15
|
|---|---|
|
|
16
|
-
| `@rightkit/onboarding` | `Onboarding`, `isLegalAccepted`, `onboardingStateKey`, `licenseStep`, `modelsStep`, `permissionsStep
|
|
16
|
+
| `@rightkit/onboarding` | `Onboarding`, `isLegalAccepted`, `onboardingStateKey`, `licenseStep`, `modelsStep`, `permissionsStep`, `signInStep` (Google/Apple/OAuth buttons that call the shared `rightkit-oauth` owner; copy says "Opens your browser"; never an in-app webview, Orthic-Labs/rightkit#279); types from `types.ts`, `ModelsStepOptions` |
|
|
17
17
|
| `@rightkit/onboarding/onboarding.css` | Stylesheet |
|
|
18
18
|
|
|
19
19
|
## Peer dependencies
|
|
@@ -43,6 +43,8 @@ import "@rightkit/onboarding/onboarding.css";
|
|
|
43
43
|
/>
|
|
44
44
|
```
|
|
45
45
|
|
|
46
|
+
Free or open-source apps without a legal gate pass `legalMode="none"` (no legal step, `legal` not needed, `appName` for the rail) or `legalMode="notice"` (no gate or acceptance; a first Notice step lists `legal.documents` as links). The default is `"gate"`.
|
|
47
|
+
|
|
46
48
|
Acceptance is stored as `legalAcceptance: { version, documentsHash, acceptedAt, eligibilityBasis }`. An app that already keeps its own acceptance receipt can pass `legalReceipt` (`read()` and `write(record)`) and keep that store as the source of truth. Steps can set `canContinue(context)`.
|
|
47
49
|
|
|
48
50
|
## When the legal gate re-prompts
|
package/dist/Onboarding.d.ts
CHANGED
|
@@ -2,4 +2,4 @@ import type { OnboardingProps, PersistedOnboardingState } from "./types.js";
|
|
|
2
2
|
/** True when the stored acceptance satisfies the host's requirement. */
|
|
3
3
|
export declare function isLegalAccepted(state: PersistedOnboardingState, requiredVersion?: string, custom?: (state: PersistedOnboardingState) => boolean, requiredDocumentsHash?: string): boolean;
|
|
4
4
|
export declare function onboardingStateKey(): string;
|
|
5
|
-
export declare function Onboarding({ settings, legal, steps, permissions, models, license, onComplete, onSkip, className, requiredVersion, requiredDocumentsHash, isAccepted, documentsHash, beforeLegalGate, requireModel, autoStartDownload, shouldAutoStart, onModelsStepEnter, modelsIntro, allowSkip, titlebar, dragRegion, legalDragRegion, legalReceipt }: OnboardingProps): import("react").JSX.Element;
|
|
5
|
+
export declare function Onboarding({ settings, legal, legalMode, appName, steps, permissions, models, license, onComplete, onSkip, className, requiredVersion, requiredDocumentsHash, isAccepted, documentsHash, beforeLegalGate, requireModel, autoStartDownload, shouldAutoStart, onModelsStepEnter, modelsIntro, allowSkip, titlebar, dragRegion, legalDragRegion, legalReceipt }: OnboardingProps): import("react").JSX.Element | null;
|
package/dist/Onboarding.js
CHANGED
|
@@ -79,7 +79,17 @@ function TitleStrip({ titlebar, dragRegion }) {
|
|
|
79
79
|
return null;
|
|
80
80
|
return _jsx("div", { className: "rk-onboarding__titlebar", "data-testid": "onboarding-titlebar", ...(dragRegion ? { "data-tauri-drag-region": "" } : {}), children: titlebar });
|
|
81
81
|
}
|
|
82
|
-
|
|
82
|
+
function NoticeList({ documents }) {
|
|
83
|
+
if (!documents.length)
|
|
84
|
+
return _jsx("p", { className: "rk-onboarding__muted", children: "No notices to show." });
|
|
85
|
+
return _jsx("ul", { className: "rk-onboarding__notices", children: documents.map((d) => _jsx("li", { children: d.onOpen ? _jsx("button", { type: "button", onClick: d.onOpen, children: d.title }) : d.url ? _jsx("a", { href: d.url, target: "_blank", rel: "noreferrer", children: d.title }) : d.title }, d.title)) });
|
|
86
|
+
}
|
|
87
|
+
export function Onboarding({ settings, legal, legalMode = "gate", appName, steps = [], permissions, models, license, onComplete, onSkip, className, requiredVersion, requiredDocumentsHash, isAccepted, documentsHash, beforeLegalGate, requireModel, autoStartDownload, shouldAutoStart, onModelsStepEnter, modelsIntro, allowSkip = true, titlebar, dragRegion, legalDragRegion = false, legalReceipt }) {
|
|
88
|
+
if (legalMode === "gate" && !legal)
|
|
89
|
+
throw new Error("Onboarding: `legal` is required when legalMode is \"gate\"");
|
|
90
|
+
const gated = legalMode === "gate";
|
|
91
|
+
/** Leading steps the user cannot navigate to: the Agreement stand-in in gate mode. */
|
|
92
|
+
const lead = gated ? 1 : 0;
|
|
83
93
|
const [state, setState] = useState(null);
|
|
84
94
|
const [saving, setSaving] = useState(false);
|
|
85
95
|
const [error, setError] = useState(null);
|
|
@@ -144,18 +154,19 @@ export function Onboarding({ settings, legal, steps = [], permissions, models, l
|
|
|
144
154
|
return () => { live = false; };
|
|
145
155
|
}, [settings, legalReceipt]);
|
|
146
156
|
const builtins = useMemo(() => [
|
|
147
|
-
{ id: "legal", label: "Agreement", title: "Review agreement", skippable: false, render: () => _jsx("p", { className: "rk-onboarding__muted", children: "Agreement accepted." }) },
|
|
157
|
+
...(gated ? [{ id: "legal", label: "Agreement", title: "Review agreement", skippable: false, render: () => _jsx("p", { className: "rk-onboarding__muted", children: "Agreement accepted." }) }] : []),
|
|
158
|
+
...(legalMode === "notice" ? [{ id: "notice", label: "Notice", title: "Notices", skippable: false, render: () => _jsx(NoticeList, { documents: legal?.documents ?? [] }) }] : []),
|
|
148
159
|
...(permissions ? [permissionsStep(permissions)] : []),
|
|
149
160
|
...(models ? [modelsStep(models, { required: requireModel, autoStartDownload, shouldAutoStart, onModelsStepEnter, intro: modelsIntro, startGuard: modelsStarted })] : []),
|
|
150
161
|
...(license ? [licenseStep(license)] : []),
|
|
151
162
|
...steps,
|
|
152
|
-
], [license, models, permissions, steps, requireModel, autoStartDownload, shouldAutoStart, onModelsStepEnter, modelsIntro]);
|
|
163
|
+
], [gated, legalMode, legal?.documents, license, models, permissions, steps, requireModel, autoStartDownload, shouldAutoStart, onModelsStepEnter, modelsIntro]);
|
|
153
164
|
const activeState = state ?? INITIAL;
|
|
154
|
-
const accepted = isLegalAccepted(activeState, requiredVersion, isAccepted, requiredDocumentsHash);
|
|
165
|
+
const accepted = !gated || isLegalAccepted(activeState, requiredVersion, isAccepted, requiredDocumentsHash);
|
|
155
166
|
const needsGate = state !== null && !accepted;
|
|
156
167
|
// The agreement gate does not depend on the saved step: until it is accepted, the active step is the first.
|
|
157
168
|
// Once accepted, the Agreement step (index 0) is never shown again when other steps exist.
|
|
158
|
-
const index = !accepted ? 0 : builtins.length >
|
|
169
|
+
const index = !accepted ? 0 : builtins.length > lead ? Math.max(lead, Math.min(activeState.currentStep, builtins.length - 1)) : 0;
|
|
159
170
|
const active = builtins[index];
|
|
160
171
|
const activeId = active?.id ?? "";
|
|
161
172
|
const setReady = useCallback((ready) => setReadyMap((m) => m[activeId] === ready ? m : { ...m, [activeId]: ready }), [activeId]);
|
|
@@ -198,11 +209,15 @@ export function Onboarding({ settings, legal, steps = [], permissions, models, l
|
|
|
198
209
|
};
|
|
199
210
|
if (error && !state)
|
|
200
211
|
return _jsxs("div", { className: cx("rk-onboarding", className), children: [_jsx("p", { className: "rk-onboarding__error", role: "alert", children: error }), _jsx(Button, { onClick: () => window.location.reload(), children: "Retry" })] });
|
|
212
|
+
if (state && !active)
|
|
213
|
+
return _jsxs("main", { className: cx("rk-onboarding", className), "data-testid": "onboarding", children: [_jsx("p", { className: "rk-onboarding__muted", children: "Nothing to set up." }), _jsx(Button, { variant: "primary", onClick: () => void runCallback(onComplete), children: "Finish setup" })] });
|
|
201
214
|
if (!state || !active)
|
|
202
215
|
return _jsx("div", { className: cx("rk-onboarding", className), "aria-busy": "true", children: _jsx("p", { className: "rk-onboarding__muted", children: "Loading setup\u2026" }) });
|
|
203
216
|
if (needsGate) {
|
|
204
217
|
if (!gateCleared)
|
|
205
218
|
return _jsxs("div", { className: cx("rk-onboarding", className), "aria-busy": "true", children: [_jsx(TitleStrip, { titlebar: titlebar, dragRegion: legalDragRegion }), _jsx("p", { className: "rk-onboarding__muted", children: "Loading setup\u2026" })] });
|
|
219
|
+
if (!legal)
|
|
220
|
+
return null;
|
|
206
221
|
const reacceptance = activeState.legalAccepted || activeState.legalAcceptance !== undefined;
|
|
207
222
|
return _jsxs("div", { className: cx("rk-onboarding rk-onboarding--legal", className), "data-testid": "onboarding-legal", "data-variant": reacceptance ? "re-acceptance" : "first-run", children: [_jsx(TitleStrip, { titlebar: titlebar, dragRegion: legalDragRegion }), _jsx(LegalGate, { ...legal, variant: reacceptance ? "re-acceptance" : "first-run", onQuit: () => void legal.onQuit?.(), onAgree: async ({ eligibilityBasis }) => {
|
|
208
223
|
const legalAcceptance = { version: requiredVersion ?? "1", documentsHash: documentsHash ?? requiredDocumentsHash ?? await hashDocuments(legal.documents), acceptedAt: new Date().toISOString(), eligibilityBasis };
|
|
@@ -222,6 +237,6 @@ export function Onboarding({ settings, legal, steps = [], permissions, models, l
|
|
|
222
237
|
} })] });
|
|
223
238
|
}
|
|
224
239
|
const body = active.render(context);
|
|
225
|
-
return _jsxs("main", { className: cx("rk-onboarding", className), "data-testid": "onboarding", "data-step-id": active.id, children: [_jsx(TitleStrip, { titlebar: titlebar, dragRegion: dragRegion }), _jsxs("aside", { className: "rk-onboarding__rail", children: [_jsx("div", { className: "rk-onboarding__brand", children: legal
|
|
226
|
-
void save({ currentStep: i }); }, children: [_jsx("span", { children: activeState.completed.includes(step.id) ? "✓" : i + 1 }), step.label] }, step.id)) })] }), _jsxs("section", { className: "rk-onboarding__main", children: [_jsxs("header", { children: [_jsxs("p", { className: "rk-onboarding__eyebrow", children: ["Step ", index + 1, " of ", builtins.length] }), _jsx("h1", { children: active.title }), active.description ? _jsx("p", { className: "rk-onboarding__description", children: active.description }) : null] }), _jsx("div", { className: "rk-onboarding__content", children: body }), error ? _jsx("p", { className: "rk-onboarding__error", role: "alert", children: error }) : null, _jsxs("footer", { children: [allowSkip ? _jsx(Button, { variant: "ghost", disabled: saving, onClick: () => { void save({ currentStep: index, skipped: true }).then((ok) => ok ? runCallback(onSkip) : undefined); }, children: "Set up later" }) : null, _jsx("span", { className: "rk-onboarding__hint", children: !canContinue && active.blockedHint ? active.blockedHint : null }), _jsx(Button, { variant: "secondary", disabled: index <=
|
|
240
|
+
return _jsxs("main", { className: cx("rk-onboarding", className), "data-testid": "onboarding", "data-step-id": active.id, children: [_jsx(TitleStrip, { titlebar: titlebar, dragRegion: dragRegion }), _jsxs("aside", { className: "rk-onboarding__rail", children: [_jsx("div", { className: "rk-onboarding__brand", children: appName ?? legal?.appName }), _jsx("nav", { "aria-label": "Setup progress", children: builtins.map((step, i) => _jsxs("button", { type: "button", className: cx("rk-onboarding__step", i === index && "is-active", activeState.completed.includes(step.id) && "is-done"), "aria-current": i === index ? "step" : undefined, disabled: gated && i === 0 && builtins.length > 1, onClick: () => { if (i >= lead && (i <= index || canContinue))
|
|
241
|
+
void save({ currentStep: i }); }, children: [_jsx("span", { children: activeState.completed.includes(step.id) ? "✓" : i + 1 }), step.label] }, step.id)) })] }), _jsxs("section", { className: "rk-onboarding__main", children: [_jsxs("header", { children: [_jsxs("p", { className: "rk-onboarding__eyebrow", children: ["Step ", index + 1, " of ", builtins.length] }), _jsx("h1", { children: active.title }), active.description ? _jsx("p", { className: "rk-onboarding__description", children: active.description }) : null] }), _jsx("div", { className: "rk-onboarding__content", children: body }), error ? _jsx("p", { className: "rk-onboarding__error", role: "alert", children: error }) : null, _jsxs("footer", { children: [allowSkip ? _jsx(Button, { variant: "ghost", disabled: saving, onClick: () => { void save({ currentStep: index, skipped: true }).then((ok) => ok ? runCallback(onSkip) : undefined); }, children: "Set up later" }) : null, _jsx("span", { className: "rk-onboarding__hint", children: !canContinue && active.blockedHint ? active.blockedHint : null }), _jsx(Button, { variant: "secondary", disabled: index <= lead || saving, onClick: () => void save({ currentStep: index - 1 }), children: "Back" }), _jsx(Button, { variant: "primary", disabled: saving || !canContinue, onClick: () => void markAndMove(index + 1, active.id), children: index === builtins.length - 1 ? "Finish setup" : "Continue" })] })] })] });
|
|
227
242
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { Onboarding, isLegalAccepted, onboardingStateKey } from "./Onboarding.js";
|
|
2
|
-
export { licenseStep, modelsStep, permissionsStep } from "./steps.js";
|
|
2
|
+
export { licenseStep, modelsStep, permissionsStep, signInStep } from "./steps.js";
|
|
3
3
|
export type { ModelsStepOptions } from "./steps.js";
|
|
4
4
|
export type * from "./types.js";
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { Onboarding, isLegalAccepted, onboardingStateKey } from "./Onboarding.js";
|
|
2
|
-
export { licenseStep, modelsStep, permissionsStep } from "./steps.js";
|
|
2
|
+
export { licenseStep, modelsStep, permissionsStep, signInStep } from "./steps.js";
|
package/dist/steps.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type ReactNode } from "react";
|
|
2
|
-
import type { LicenseBackend, ModelsAutoStart, ModelsBackend, OnboardingStep, PermissionsBackend } from "./types.js";
|
|
2
|
+
import type { SignInBackend, LicenseBackend, ModelsAutoStart, ModelsBackend, OnboardingStep, PermissionsBackend } from "./types.js";
|
|
3
3
|
export declare function permissionsStep(backend: PermissionsBackend, options?: {
|
|
4
4
|
label?: string;
|
|
5
5
|
title?: string;
|
|
@@ -26,3 +26,9 @@ export declare function licenseStep(backend: LicenseBackend, options?: {
|
|
|
26
26
|
title?: string;
|
|
27
27
|
description?: string;
|
|
28
28
|
}): OnboardingStep;
|
|
29
|
+
/** Sign-in step. Every button hands off to the shared owner and opens the user's default browser; no in-app webview. */
|
|
30
|
+
export declare function signInStep(backend: SignInBackend, options?: {
|
|
31
|
+
label?: string;
|
|
32
|
+
title?: string;
|
|
33
|
+
description?: string;
|
|
34
|
+
}): OnboardingStep;
|
package/dist/steps.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
1
|
+
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useCallback, useEffect, useRef, useState } from "react";
|
|
3
3
|
import { Button, Input, Badge } from "@rightkit/react-shell/react";
|
|
4
4
|
function ProgressBar({ value, label }) {
|
|
@@ -113,3 +113,28 @@ function LicenseBody({ backend }) {
|
|
|
113
113
|
export function licenseStep(backend, options = {}) {
|
|
114
114
|
return { id: "license", label: options.label ?? "Licence", title: options.title ?? "Choose how you’ll use this app", description: options.description ?? "Activate a licence, start a trial, or continue with the free plan.", skippable: true, render: () => _jsx(LicenseBody, { backend: backend }) };
|
|
115
115
|
}
|
|
116
|
+
function SignInBody({ backend }) {
|
|
117
|
+
const [account, setAccount] = useState({ signedIn: false });
|
|
118
|
+
const [busy, setBusy] = useState(null);
|
|
119
|
+
const [error, setError] = useState(null);
|
|
120
|
+
useEffect(() => { let live = true; backend.load().then((a) => { if (live)
|
|
121
|
+
setAccount(a); }, () => undefined); return () => { live = false; }; }, [backend]);
|
|
122
|
+
const start = async (provider) => {
|
|
123
|
+
setBusy(provider);
|
|
124
|
+
setError(null);
|
|
125
|
+
try {
|
|
126
|
+
setAccount(await backend.start(provider));
|
|
127
|
+
}
|
|
128
|
+
catch (e) {
|
|
129
|
+
setError(e instanceof Error ? e.message : "Sign-in did not finish.");
|
|
130
|
+
}
|
|
131
|
+
finally {
|
|
132
|
+
setBusy(null);
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
return _jsxs("div", { className: "rk-onboarding__signin", children: [account.signedIn ? _jsxs("p", { children: ["Signed in", account.account ? _jsxs(_Fragment, { children: [" as ", _jsx("strong", { children: account.account })] }) : null, "."] }) : null, _jsx("div", { className: "rk-onboarding__row-actions", children: backend.providers.map((p) => _jsx(Button, { size: "sm", variant: "secondary", disabled: busy !== null, onClick: () => void start(p.id), children: busy === p.id ? "Waiting for your browser…" : p.label ?? `Sign in with ${p.id === "google" ? "Google" : p.id === "apple" ? "Apple" : "your account"}` }, p.id)) }), _jsx("p", { className: "rk-onboarding__hint", children: _jsx("small", { children: "Opens your browser. You stay signed in to the accounts you already use there." }) }), error ? _jsx("p", { role: "alert", children: error }) : null] });
|
|
136
|
+
}
|
|
137
|
+
/** Sign-in step. Every button hands off to the shared owner and opens the user's default browser; no in-app webview. */
|
|
138
|
+
export function signInStep(backend, options = {}) {
|
|
139
|
+
return { id: "sign-in", label: options.label ?? "Sign in", title: options.title ?? "Sign in", description: options.description ?? "Sign-in opens your default browser, so you stay signed in to the accounts you already use there.", skippable: true, render: () => _jsx(SignInBody, { backend: backend }) };
|
|
140
|
+
}
|
package/dist/types.d.ts
CHANGED
|
@@ -57,6 +57,28 @@ export interface LicenseBackend {
|
|
|
57
57
|
purchaseUrl?: string;
|
|
58
58
|
openExternal?: (url: string) => void | Promise<void>;
|
|
59
59
|
}
|
|
60
|
+
export type SignInProvider = "google" | "apple" | "oauth";
|
|
61
|
+
/**
|
|
62
|
+
* Sign-in owned by `rightkit-oauth`. Every provider opens the user's DEFAULT browser (never an in-app webview, so existing
|
|
63
|
+
* browser sessions are kept); `start` must call the shared owner (`OAuthClient::sign_in_with_browser` through the app's
|
|
64
|
+
* command), not open a window of its own. Orthic-Labs/rightkit#279.
|
|
65
|
+
*/
|
|
66
|
+
export interface SignInBackend {
|
|
67
|
+
providers: readonly {
|
|
68
|
+
id: SignInProvider;
|
|
69
|
+
label?: string;
|
|
70
|
+
}[];
|
|
71
|
+
/** Account already signed in, if any. */
|
|
72
|
+
load(): Promise<{
|
|
73
|
+
signedIn: boolean;
|
|
74
|
+
account?: string;
|
|
75
|
+
}>;
|
|
76
|
+
/** Open the default browser for `provider` and resolve when the sign-in finishes (or reject / throw on failure or cancel). */
|
|
77
|
+
start(provider: SignInProvider): Promise<{
|
|
78
|
+
signedIn: boolean;
|
|
79
|
+
account?: string;
|
|
80
|
+
}>;
|
|
81
|
+
}
|
|
60
82
|
export type EligibilityBasis = "individual" | "enterprise";
|
|
61
83
|
/** Full record of one legal acceptance, persisted so version changes can re-prompt. */
|
|
62
84
|
export interface LegalAcceptanceRecord {
|
|
@@ -94,6 +116,7 @@ export interface OnboardingStepContext {
|
|
|
94
116
|
permissions?: PermissionsBackend;
|
|
95
117
|
models?: ModelsBackend;
|
|
96
118
|
license?: LicenseBackend;
|
|
119
|
+
signIn?: SignInBackend;
|
|
97
120
|
/** Readiness reported by steps via `setReady`, keyed by step id. */
|
|
98
121
|
ready: Readonly<Record<string, boolean>>;
|
|
99
122
|
/** Reports whether the active step is ready (used by `canContinue`). Stable per step. */
|
|
@@ -114,9 +137,21 @@ export interface OnboardingStep {
|
|
|
114
137
|
export interface LegalStepConfig extends Omit<LegalGateProps, "variant" | "onAgree" | "onQuit"> {
|
|
115
138
|
onQuit?: () => void;
|
|
116
139
|
}
|
|
140
|
+
/**
|
|
141
|
+
* How legal documents take part in onboarding.
|
|
142
|
+
* - `gate` (default): the blocking agreement gate comes first and is recorded (needs `legal`).
|
|
143
|
+
* - `notice`: no gate and no acceptance. A first "Notice" step lists the `legal` documents as links; Continue moves on (free or open-source apps that still hold their notice).
|
|
144
|
+
* - `none`: no legal step at all; `legal` is not needed.
|
|
145
|
+
*/
|
|
146
|
+
export type LegalMode = "gate" | "notice" | "none";
|
|
117
147
|
export interface OnboardingProps {
|
|
118
148
|
settings: SettingsBackend;
|
|
119
|
-
|
|
149
|
+
/** Required when `legalMode` is `gate` (default). Optional for `notice` (the documents shown) and `none`. */
|
|
150
|
+
legal?: LegalStepConfig;
|
|
151
|
+
/** Default `gate`. See `LegalMode`. */
|
|
152
|
+
legalMode?: LegalMode;
|
|
153
|
+
/** Name shown in the step rail. Default: `legal.appName`. */
|
|
154
|
+
appName?: string;
|
|
120
155
|
/** App-specific steps are appended after built-in steps, in supplied order. */
|
|
121
156
|
steps?: readonly OnboardingStep[];
|
|
122
157
|
permissions?: PermissionsBackend;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rightkit/onboarding",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "First-run onboarding framework: ordered steps, progress, skip/resume, legal gate first, permissions, model download and licence/trial steps.",
|
|
5
5
|
"license": "MIT OR Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -29,20 +29,21 @@
|
|
|
29
29
|
"react": ">=18 <21"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
|
-
"@rightkit/react-shell": "0.6.
|
|
33
|
-
"@rightkit/legal-ui": "0.
|
|
34
|
-
"@rightkit/qa-chrome": "0.1.
|
|
35
|
-
"@testing-library/jest-dom": "^
|
|
36
|
-
"@testing-library/
|
|
37
|
-
"@testing-library/
|
|
38
|
-
"@
|
|
39
|
-
"@types/react
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
"react
|
|
43
|
-
"
|
|
44
|
-
"
|
|
45
|
-
"
|
|
32
|
+
"@rightkit/react-shell": "0.6.8",
|
|
33
|
+
"@rightkit/legal-ui": "0.3.0",
|
|
34
|
+
"@rightkit/qa-chrome": "0.1.8",
|
|
35
|
+
"@testing-library/jest-dom": "^7.0.1",
|
|
36
|
+
"@testing-library/dom": "^10.4.2",
|
|
37
|
+
"@testing-library/react": "^16.3.3",
|
|
38
|
+
"@testing-library/user-event": "^14.6.8",
|
|
39
|
+
"@types/react": "^19.3.0",
|
|
40
|
+
"@types/react-dom": "^19.3.0",
|
|
41
|
+
"jsdom": "^30.1.3",
|
|
42
|
+
"react": "^19.3.1",
|
|
43
|
+
"react-dom": "^19.3.1",
|
|
44
|
+
"typescript": "^7.0.2",
|
|
45
|
+
"vite": "^8.3.4",
|
|
46
|
+
"vitest": "^5.0.5"
|
|
46
47
|
},
|
|
47
48
|
"publishConfig": {
|
|
48
49
|
"registry": "https://registry.npmjs.org",
|