diff --git a/.tool-versions b/.tool-versions
index e871cd693..d173c8890 100644
--- a/.tool-versions
+++ b/.tool-versions
@@ -1,2 +1,2 @@
-nodejs 24.12.0
+nodejs 24.13.0
yarn 1.22.22
diff --git a/examples/guide-example/src/App.tsx b/examples/guide-example/src/App.tsx
index ab59a88ce..9d3204fe8 100644
--- a/examples/guide-example/src/App.tsx
+++ b/examples/guide-example/src/App.tsx
@@ -65,6 +65,7 @@ function App() {
readyToTarget={true}
listenForUpdates={true}
colorMode={colorMode}
+ toolbar="v2"
>
Knock In-App Guide Example
diff --git a/package.json b/package.json
index 6c08dae8e..d08068038 100644
--- a/package.json
+++ b/package.json
@@ -52,6 +52,6 @@
"vitest": "^3.1.1"
},
"engines": {
- "node": ">=24.10.0"
+ "node": ">=24.13.0"
}
}
diff --git a/packages/client/src/clients/guide/client.ts b/packages/client/src/clients/guide/client.ts
index f3ee847e9..b83b8bdc2 100644
--- a/packages/client/src/clients/guide/client.ts
+++ b/packages/client/src/clients/guide/client.ts
@@ -295,6 +295,7 @@ export class KnockGuideClient {
guideGroups: [],
guideGroupDisplayLogs: {},
guides: {},
+ ineligibleGuides: {},
previewGuides: {},
queries: {},
location,
@@ -376,7 +377,12 @@ export class KnockGuideClient {
>(this.channelId, queryParams);
queryStatus = { status: "ok" };
- const { entries, guide_groups: groups, guide_group_display_logs } = data;
+ const {
+ entries,
+ guide_groups: groups,
+ guide_group_display_logs,
+ ineligible_guides,
+ } = data;
this.knock.log("[Guide] Loading fetched guides");
this.store.setState((state) => ({
@@ -384,6 +390,7 @@ export class KnockGuideClient {
guideGroups: groups?.length > 0 ? groups : [mockDefaultGroup(entries)],
guideGroupDisplayLogs: guide_group_display_logs || {},
guides: byKey(entries.map((g) => this.localCopy(g))),
+ ineligibleGuides: byKey(ineligible_guides),
queries: { ...state.queries, [queryKey]: queryStatus },
}));
} catch (e) {
diff --git a/packages/client/src/clients/guide/types.ts b/packages/client/src/clients/guide/types.ts
index f7112713b..9f52bd92e 100644
--- a/packages/client/src/clients/guide/types.ts
+++ b/packages/client/src/clients/guide/types.ts
@@ -63,6 +63,13 @@ export interface GuideGroupData {
updated_at: string;
}
+export type GuideIneligibilityData = {
+ __typename: "GuideIneligibilityMarker";
+ key: KnockGuide["key"];
+ reason: string;
+ message: string;
+};
+
export type GetGuidesQueryParams = {
data?: string;
tenant?: string;
@@ -74,6 +81,7 @@ export type GetGuidesResponse = {
entries: GuideData[];
guide_groups: GuideGroupData[];
guide_group_display_logs: Record
;
+ ineligible_guides: GuideIneligibilityData[];
};
//
@@ -200,6 +208,10 @@ export type StoreState = {
guideGroups: GuideGroupData[];
guideGroupDisplayLogs: Record;
guides: Record;
+ ineligibleGuides: Record<
+ GuideIneligibilityData["key"],
+ GuideIneligibilityData
+ >;
previewGuides: Record;
queries: Record;
location: string | undefined;
diff --git a/packages/client/test/clients/guide/guide.test.ts b/packages/client/test/clients/guide/guide.test.ts
index 999c93846..feb5afd7b 100644
--- a/packages/client/test/clients/guide/guide.test.ts
+++ b/packages/client/test/clients/guide/guide.test.ts
@@ -24,6 +24,7 @@ const mockStore = {
guideGroups: [],
guideGroupDisplayLogs: {},
guides: {},
+ ineligibleGuides: {},
previewGuides: {},
queries: {},
location: undefined,
@@ -45,6 +46,7 @@ const mockStore = {
guideGroups: [],
guideGroupDisplayLogs: {},
guides: {},
+ ineligibleGuides: {},
previewGuides: {},
queries: {},
location: undefined,
@@ -94,6 +96,7 @@ describe("KnockGuideClient", () => {
guideGroups: [],
guideGroupDisplayLogs: {},
guides: {},
+ ineligibleGuides: {},
previewGuides: {},
queries: {},
location: undefined,
@@ -104,6 +107,7 @@ describe("KnockGuideClient", () => {
guideGroups: [],
guideGroupDisplayLogs: {},
guides: {},
+ ineligibleGuides: {},
previewGuides: {},
queries: {},
location: undefined,
@@ -156,6 +160,7 @@ describe("KnockGuideClient", () => {
guideGroups: [],
guideGroupDisplayLogs: {},
guides: {},
+ ineligibleGuides: {},
previewGuides: {},
queries: {},
location: undefined,
@@ -184,6 +189,7 @@ describe("KnockGuideClient", () => {
guideGroups: [],
guideGroupDisplayLogs: {},
guides: {},
+ ineligibleGuides: {},
previewGuides: {},
queries: {},
location: "https://example.com",
@@ -200,6 +206,7 @@ describe("KnockGuideClient", () => {
guideGroups: [],
guideGroupDisplayLogs: {},
guides: {},
+ ineligibleGuides: {},
previewGuides: {},
queries: {},
location: undefined,
@@ -593,6 +600,7 @@ describe("KnockGuideClient", () => {
guideGroups: [mockDefaultGroup],
guideGroupDisplayLogs: {},
guides: { [mockGuide.key]: mockGuide },
+ ineligibleGuides: {},
previewGuides: {},
queries: {},
location: undefined,
@@ -623,6 +631,7 @@ describe("KnockGuideClient", () => {
guideGroups: [mockDefaultGroup],
guideGroupDisplayLogs: {},
guides: { [mockGuide.key]: mockGuide },
+ ineligibleGuides: {},
previewGuides: {},
queries: {},
location: undefined,
@@ -654,6 +663,7 @@ describe("KnockGuideClient", () => {
guideGroups: [mockDefaultGroup],
guideGroupDisplayLogs: {},
guides: { [mockGuide.key]: mockGuide },
+ ineligibleGuides: {},
previewGuides: {},
queries: {},
location: undefined,
@@ -689,6 +699,7 @@ describe("KnockGuideClient", () => {
guideGroups: [mockDefaultGroup],
guideGroupDisplayLogs: {},
guides: { [mockGuide.key]: mockGuide },
+ ineligibleGuides: {},
previewGuides: {},
queries: {},
location: undefined,
@@ -744,6 +755,7 @@ describe("KnockGuideClient", () => {
guideGroups: [mockDefaultGroup],
guideGroupDisplayLogs: {},
guides: { [unthrottledGuide.key]: unthrottledGuide },
+ ineligibleGuides: {},
previewGuides: {},
queries: {},
location: undefined,
@@ -798,6 +810,7 @@ describe("KnockGuideClient", () => {
guideGroups: [mockDefaultGroup],
guideGroupDisplayLogs: {},
guides: { [throttledGuide.key]: throttledGuide },
+ ineligibleGuides: {},
previewGuides: {},
queries: {},
location: undefined,
@@ -858,6 +871,7 @@ describe("KnockGuideClient", () => {
guideGroups: [mockDefaultGroup],
guideGroupDisplayLogs: {},
guides: { [unthrottledGuide.key]: unthrottledGuide },
+ ineligibleGuides: {},
previewGuides: {},
queries: {},
location: undefined,
@@ -1027,6 +1041,7 @@ describe("KnockGuideClient", () => {
guideGroups: [mockDefaultGroup],
guideGroupDisplayLogs: {},
guides: mockGuides,
+ ineligibleGuides: {},
previewGuides: {},
queries: {},
location: undefined,
@@ -1048,6 +1063,7 @@ describe("KnockGuideClient", () => {
guideGroups: [mockDefaultGroup],
guideGroupDisplayLogs: {},
guides: mockGuides,
+ ineligibleGuides: {},
previewGuides: {},
queries: {},
location: undefined,
@@ -1068,6 +1084,7 @@ describe("KnockGuideClient", () => {
guideGroups: [mockDefaultGroup],
guideGroupDisplayLogs: {},
guides: mockGuides,
+ ineligibleGuides: {},
previewGuides: {},
queries: {},
location: undefined,
@@ -1088,6 +1105,7 @@ describe("KnockGuideClient", () => {
guideGroups: [mockDefaultGroup],
guideGroupDisplayLogs: {},
guides: mockGuides,
+ ineligibleGuides: {},
previewGuides: {},
queries: {},
location: "https://example.com/dashboard",
@@ -1107,6 +1125,7 @@ describe("KnockGuideClient", () => {
guideGroups: [mockDefaultGroup],
guideGroupDisplayLogs: {},
guides: mockGuides,
+ ineligibleGuides: {},
previewGuides: {},
queries: {},
location: "https://example.com/settings",
@@ -1145,8 +1164,9 @@ describe("KnockGuideClient", () => {
queries: {},
location: "https://example.com/dashboard",
counter: 0,
+ ineligibleGuides: {},
previewGuides: {},
- debug: { forcedGuideKey: null },
+ debug: { forcedGuideKey: null, previewSessionId: null },
};
const client = new KnockGuideClient(mockKnock, channelId);
@@ -1180,8 +1200,9 @@ describe("KnockGuideClient", () => {
queries: {},
location: "https://example.com/dashboard",
counter: 0,
+ ineligibleGuides: {},
previewGuides: {},
- debug: { forcedGuideKey: null },
+ debug: { forcedGuideKey: null, previewSessionId: null },
};
const client = new KnockGuideClient(mockKnock, channelId);
@@ -1215,8 +1236,9 @@ describe("KnockGuideClient", () => {
queries: {},
location: "https://example.com/settings",
counter: 0,
+ ineligibleGuides: {},
previewGuides: {},
- debug: { forcedGuideKey: null },
+ debug: { forcedGuideKey: null, previewSessionId: null },
};
const client = new KnockGuideClient(mockKnock, channelId);
@@ -1250,8 +1272,9 @@ describe("KnockGuideClient", () => {
queries: {},
location: "https://example.com/user/settings",
counter: 0,
+ ineligibleGuides: {},
previewGuides: {},
- debug: { forcedGuideKey: null },
+ debug: { forcedGuideKey: null, previewSessionId: null },
};
const client = new KnockGuideClient(mockKnock, channelId);
@@ -1291,8 +1314,9 @@ describe("KnockGuideClient", () => {
queries: {},
location: "https://example.com/admin/settings",
counter: 0,
+ ineligibleGuides: {},
previewGuides: {},
- debug: { forcedGuideKey: null },
+ debug: { forcedGuideKey: null, previewSessionId: null },
};
const client = new KnockGuideClient(mockKnock, channelId);
@@ -1335,8 +1359,9 @@ describe("KnockGuideClient", () => {
queries: {},
location: "https://example.com/dashboard",
counter: 0,
+ ineligibleGuides: {},
previewGuides: {},
- debug: { forcedGuideKey: null },
+ debug: { forcedGuideKey: null, previewSessionId: null },
};
const client = new KnockGuideClient(mockKnock, channelId);
@@ -1370,8 +1395,9 @@ describe("KnockGuideClient", () => {
queries: {},
location: "https://example.com/dashboard",
counter: 0,
+ ineligibleGuides: {},
previewGuides: {},
- debug: { forcedGuideKey: null },
+ debug: { forcedGuideKey: null, previewSessionId: null },
};
const client = new KnockGuideClient(mockKnock, channelId);
@@ -1405,8 +1431,9 @@ describe("KnockGuideClient", () => {
queries: {},
location: "https://example.com/dashboard",
counter: 0,
+ ineligibleGuides: {},
previewGuides: {},
- debug: { forcedGuideKey: null },
+ debug: { forcedGuideKey: null, previewSessionId: null },
};
const client = new KnockGuideClient(mockKnock, channelId);
@@ -1445,6 +1472,7 @@ describe("KnockGuideClient", () => {
[g2.key]: g2,
[g3.key]: g3,
},
+ ineligibleGuides: {},
previewGuides: {},
queries: {},
location: "https://example.com/settings",
@@ -1463,6 +1491,7 @@ describe("KnockGuideClient", () => {
guideGroups: [mockDefaultGroup],
guideGroupDisplayLogs: {},
guides: mockGuides,
+ ineligibleGuides: {},
previewGuides: {},
queries: {},
location: undefined,
@@ -1493,6 +1522,7 @@ describe("KnockGuideClient", () => {
guideGroups: [mockDefaultGroup],
guideGroupDisplayLogs: {},
guides: mockGuides,
+ ineligibleGuides: {},
previewGuides: {},
queries: {},
location: undefined,
@@ -1571,6 +1601,7 @@ describe("KnockGuideClient", () => {
...mockGuides,
[mockGuideFour.key]: mockGuideFour,
},
+ ineligibleGuides: {},
previewGuides: {},
queries: {},
location: undefined,
@@ -1652,6 +1683,7 @@ describe("KnockGuideClient", () => {
],
},
},
+ ineligibleGuides: {},
previewGuides: {},
queries: {},
location: undefined,
@@ -1688,6 +1720,7 @@ describe("KnockGuideClient", () => {
...mockGuides,
[mockGuideThree.key]: archivedGuide,
},
+ ineligibleGuides: {},
previewGuides: {},
queries: {},
location: undefined,
@@ -1728,6 +1761,7 @@ describe("KnockGuideClient", () => {
...mockGuides,
[mockGuideTwo.key]: undefined as unknown as KnockGuide,
},
+ ineligibleGuides: {},
previewGuides: {
[mockGuideTwo.key]: previewGuide,
},
@@ -1774,6 +1808,7 @@ describe("KnockGuideClient", () => {
queries: {},
location: undefined,
counter: 0,
+ ineligibleGuides: {},
debug: {
forcedGuideKey: mockGuideTwo.key,
preview_session_id: "test-session-id",
@@ -1810,6 +1845,7 @@ describe("KnockGuideClient", () => {
queries: {},
location: undefined,
counter: 0,
+ ineligibleGuides: {},
debug: {
forcedGuideKey: mockGuideTwo.key,
preview_session_id: "test-session-id",
@@ -1836,6 +1872,7 @@ describe("KnockGuideClient", () => {
default: new Date().toISOString(),
},
guides: mockGuides,
+ ineligibleGuides: {},
previewGuides: {},
queries: {},
location: undefined,
@@ -1877,6 +1914,7 @@ describe("KnockGuideClient", () => {
bypass_global_group_limit: true,
},
},
+ ineligibleGuides: {},
previewGuides: {},
queries: {},
location: undefined,
@@ -1902,6 +1940,7 @@ describe("KnockGuideClient", () => {
default: new Date().toISOString(), // Throttle window started now
},
guides: mockGuides,
+ ineligibleGuides: {},
previewGuides: {},
queries: {},
location: undefined,
@@ -2015,6 +2054,7 @@ describe("KnockGuideClient", () => {
guideGroups: [mockDefaultGroup],
guideGroupDisplayLogs: {},
guides: mockGuides,
+ ineligibleGuides: {},
previewGuides: {},
queries: {},
location: undefined,
@@ -2085,6 +2125,7 @@ describe("KnockGuideClient", () => {
],
},
},
+ ineligibleGuides: {},
previewGuides: {},
queries: {},
location: undefined,
@@ -2105,6 +2146,7 @@ describe("KnockGuideClient", () => {
guideGroups: [mockDefaultGroup],
guideGroupDisplayLogs: {},
guides: {},
+ ineligibleGuides: {},
previewGuides: {
[mockGuideTwo.key]: mockGuideTwo,
},
@@ -2136,6 +2178,7 @@ describe("KnockGuideClient", () => {
active: false,
},
},
+ ineligibleGuides: {},
previewGuides: {},
queries: {},
location: undefined,
@@ -2166,6 +2209,7 @@ describe("KnockGuideClient", () => {
default: new Date().toISOString(), // Throttle window started now
},
guides: mockGuides,
+ ineligibleGuides: {},
previewGuides: {},
queries: {},
location: undefined,
@@ -2200,6 +2244,7 @@ describe("KnockGuideClient", () => {
...mockGuides,
[mockGuideTwo.key]: mockGuideWithBypass,
},
+ ineligibleGuides: {},
previewGuides: {},
queries: {},
location: undefined,
@@ -2228,6 +2273,7 @@ describe("KnockGuideClient", () => {
default: new Date().toISOString(), // Throttle window started now
},
guides: mockGuides,
+ ineligibleGuides: {},
previewGuides: {},
queries: {},
location: undefined,
@@ -2266,6 +2312,7 @@ describe("KnockGuideClient", () => {
default: tenMinutesAgo,
},
guides: mockGuides,
+ ineligibleGuides: {},
previewGuides: {},
queries: {},
location: undefined,
@@ -2342,6 +2389,7 @@ describe("KnockGuideClient", () => {
guideGroups: [],
guideGroupDisplayLogs: {},
guides: { [existingGuide.key]: existingGuide },
+ ineligibleGuides: {},
previewGuides: {},
queries: {},
location: undefined,
@@ -2396,6 +2444,7 @@ describe("KnockGuideClient", () => {
guideGroups: [],
guideGroupDisplayLogs: {},
guides: { [existingGuide.key]: existingGuide },
+ ineligibleGuides: {},
previewGuides: {},
queries: {},
location: undefined,
@@ -2442,6 +2491,7 @@ describe("KnockGuideClient", () => {
guideGroups: [],
guideGroupDisplayLogs: {},
guides: { [existingGuide.key]: existingGuide },
+ ineligibleGuides: {},
previewGuides: {},
queries: {},
location: undefined,
@@ -2535,6 +2585,7 @@ describe("KnockGuideClient", () => {
[mockGuideOne.key]: mockGuideOne,
[mockGuideTwo.key]: mockGuideTwo,
},
+ ineligibleGuides: {},
previewGuides: {},
queries: {},
location: undefined,
@@ -2591,6 +2642,7 @@ describe("KnockGuideClient", () => {
[mockGuideOne.key]: mockGuideOne,
[mockGuideTwo.key]: mockGuideTwo,
},
+ ineligibleGuides: {},
previewGuides: {},
queries: {},
location: undefined,
@@ -2860,6 +2912,7 @@ describe("KnockGuideClient", () => {
guideGroups: [],
guideGroupDisplayLogs: {},
guides: { [mockGuide.key]: mockGuide },
+ ineligibleGuides: {},
previewGuides: {},
queries: {},
location: undefined,
@@ -2912,6 +2965,7 @@ describe("KnockGuideClient", () => {
guideGroups: [],
guideGroupDisplayLogs: {},
guides: { [mockGuide.key]: mockGuide },
+ ineligibleGuides: {},
previewGuides: {},
queries: {},
location: undefined,
@@ -3009,6 +3063,7 @@ describe("KnockGuideClient", () => {
guideGroups: [],
guideGroupDisplayLogs: {},
guides: { [mockGuide.key]: mockGuide },
+ ineligibleGuides: {},
previewGuides: {},
queries: {},
location: undefined,
diff --git a/packages/react/src/index.ts b/packages/react/src/index.ts
index 80214ade0..97ee3fcfa 100644
--- a/packages/react/src/index.ts
+++ b/packages/react/src/index.ts
@@ -43,7 +43,6 @@ export {
Card,
CardView,
KnockGuideProvider,
- GuideToolbar as KnockGuideToolbar,
Modal,
ModalView,
} from "./modules/guide";
diff --git a/packages/react/src/modules/guide/components/GuideToolbar/index.ts b/packages/react/src/modules/guide/components/GuideToolbar/index.ts
deleted file mode 100644
index 54c13648f..000000000
--- a/packages/react/src/modules/guide/components/GuideToolbar/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export { GuideToolbar } from "./GuideToolbar";
diff --git a/packages/react/src/modules/guide/components/Toolbar/KnockButton.tsx b/packages/react/src/modules/guide/components/Toolbar/KnockButton.tsx
new file mode 100644
index 000000000..93ae8e55a
--- /dev/null
+++ b/packages/react/src/modules/guide/components/Toolbar/KnockButton.tsx
@@ -0,0 +1,51 @@
+import { Button } from "@telegraph/button";
+
+import { MAX_Z_INDEX } from "./helpers";
+import "./styles.css";
+
+type Props = {
+ onClick: () => void;
+};
+
+export const KnockButton = ({ onClick }: Props) => {
+ return (
+
+ );
+};
diff --git a/packages/react/src/modules/guide/components/GuideToolbar/GuideToolbar.tsx b/packages/react/src/modules/guide/components/Toolbar/V1.tsx
similarity index 58%
rename from packages/react/src/modules/guide/components/GuideToolbar/GuideToolbar.tsx
rename to packages/react/src/modules/guide/components/Toolbar/V1.tsx
index cb6d3989f..f0bc299aa 100644
--- a/packages/react/src/modules/guide/components/GuideToolbar/GuideToolbar.tsx
+++ b/packages/react/src/modules/guide/components/Toolbar/V1.tsx
@@ -6,13 +6,11 @@ import { Text } from "@telegraph/typography";
import { Minimize2, Undo2, Wrench } from "lucide-react";
import { useState } from "react";
+import { KnockButton } from "./KnockButton";
+import { MAX_Z_INDEX } from "./helpers";
import "./styles.css";
-// 'max' z index based on max value of a signed 32-bit int
-// Ref: https://stackoverflow.com/questions/491052/minimum-and-maximum-value-of-z-index/25461690#25461690
-const MAX_Z_INDEX = 2147483647;
-
-export const GuideToolbar = () => {
+export const V1 = () => {
const [isCollapsed, setIsCollapsed] = useState(false);
const { client } = useGuideContext();
@@ -31,46 +29,7 @@ export const GuideToolbar = () => {
};
if (isCollapsed) {
- return (
-
- );
+ return ;
}
return (
diff --git a/packages/react/src/modules/guide/components/Toolbar/V2.tsx b/packages/react/src/modules/guide/components/Toolbar/V2.tsx
new file mode 100644
index 000000000..55265ab20
--- /dev/null
+++ b/packages/react/src/modules/guide/components/Toolbar/V2.tsx
@@ -0,0 +1,50 @@
+import { Button } from "@telegraph/button";
+import { Box, Stack } from "@telegraph/layout";
+import { Text } from "@telegraph/typography";
+import { Minimize2 } from "lucide-react";
+import { useState } from "react";
+
+import { KnockButton } from "./KnockButton";
+import { MAX_Z_INDEX } from "./helpers";
+import "./styles.css";
+
+export const V2 = () => {
+ const [isCollapsed, setIsCollapsed] = useState(true);
+
+ return (
+
+ {isCollapsed ? (
+ setIsCollapsed(false)} />
+ ) : (
+
+
+
+ Toolbar v2 placeholder
+
+
+
+
+ )}
+
+ );
+};
diff --git a/packages/react/src/modules/guide/components/Toolbar/helpers.ts b/packages/react/src/modules/guide/components/Toolbar/helpers.ts
new file mode 100644
index 000000000..71f072fbc
--- /dev/null
+++ b/packages/react/src/modules/guide/components/Toolbar/helpers.ts
@@ -0,0 +1,3 @@
+// 'max' z index based on max value of a signed 32-bit int
+// Ref: https://stackoverflow.com/questions/491052/minimum-and-maximum-value-of-z-index/25461690#25461690
+export const MAX_Z_INDEX = 2147483647;
diff --git a/packages/react/src/modules/guide/components/Toolbar/index.ts b/packages/react/src/modules/guide/components/Toolbar/index.ts
new file mode 100644
index 000000000..aee2c5298
--- /dev/null
+++ b/packages/react/src/modules/guide/components/Toolbar/index.ts
@@ -0,0 +1,2 @@
+export { V1 as ToolbarV1 } from "./V1";
+export { V2 as ToolbarV2 } from "./V2";
diff --git a/packages/react/src/modules/guide/components/GuideToolbar/styles.css b/packages/react/src/modules/guide/components/Toolbar/styles.css
similarity index 100%
rename from packages/react/src/modules/guide/components/GuideToolbar/styles.css
rename to packages/react/src/modules/guide/components/Toolbar/styles.css
diff --git a/packages/react/src/modules/guide/components/index.ts b/packages/react/src/modules/guide/components/index.ts
index 8ebbde6b6..ac0527077 100644
--- a/packages/react/src/modules/guide/components/index.ts
+++ b/packages/react/src/modules/guide/components/index.ts
@@ -1,4 +1,4 @@
export { Banner, BannerView } from "./Banner";
export { Card, CardView } from "./Card";
-export { GuideToolbar } from "./GuideToolbar";
+export { ToolbarV1, ToolbarV2 } from "./Toolbar";
export { Modal, ModalView } from "./Modal";
diff --git a/packages/react/src/modules/guide/index.ts b/packages/react/src/modules/guide/index.ts
index ab8455a62..86f3b6ef5 100644
--- a/packages/react/src/modules/guide/index.ts
+++ b/packages/react/src/modules/guide/index.ts
@@ -5,6 +5,7 @@ export {
CardView,
Modal,
ModalView,
- GuideToolbar,
+ ToolbarV1,
+ ToolbarV2,
} from "./components";
export { KnockGuideProvider } from "./providers";
diff --git a/packages/react/src/modules/guide/providers/KnockGuideProvider.tsx b/packages/react/src/modules/guide/providers/KnockGuideProvider.tsx
index 2e5d0e751..16c145896 100644
--- a/packages/react/src/modules/guide/providers/KnockGuideProvider.tsx
+++ b/packages/react/src/modules/guide/providers/KnockGuideProvider.tsx
@@ -4,17 +4,26 @@ import {
} from "@knocklabs/react-core";
import React from "react";
-import { GuideToolbar } from "../components";
+import { ToolbarV1, ToolbarV2 } from "../components";
+
+type Props = KnockGuideProviderProps & {
+ toolbar?: "v1" | "v2";
+};
+
+// Re-export the core KnockGuideProvider, so we can add React specific
+// functionality like the Toolbar component which shouldn't be included in other
+// contexts (e.g. React Native).
+export const KnockGuideProvider: React.FC> = ({
+ children,
+ toolbar = "v1",
+ ...props
+}) => {
+ const Toolbar = toolbar === "v2" ? ToolbarV2 : ToolbarV1;
-// Re-export the core KnockGuideProvider, so we can add React specific functionality
-// like the GuideToolbar component which shouldn't be included in other contexts (e.g. React Native).
-export const KnockGuideProvider: React.FC<
- React.PropsWithChildren
-> = ({ children, ...props }) => {
return (
{children}
-
+
);
};
diff --git a/packages/react/test/guide/GuideToolbar.test.tsx b/packages/react/test/guide/GuideToolbar.test.tsx
index 107bce28c..4ea3a7933 100644
--- a/packages/react/test/guide/GuideToolbar.test.tsx
+++ b/packages/react/test/guide/GuideToolbar.test.tsx
@@ -2,7 +2,7 @@ import "@testing-library/jest-dom/vitest";
import { fireEvent, render } from "@testing-library/react";
import { describe, expect, test, vi } from "vitest";
-import { GuideToolbar } from "../../src/modules/guide/components/GuideToolbar/GuideToolbar";
+import { V1 as Toolbar } from "../../src/modules/guide/components/Toolbar/V1";
const mockDebugState: { forcedGuideKey: string | null } = {
forcedGuideKey: "test-guide-key",
@@ -32,11 +32,11 @@ vi.mock("@knocklabs/react-core", async () => {
};
});
-describe("GuideToolbar", () => {
+describe("Toolbar", () => {
test("renders debug component when forcedGuideKey exists", () => {
mockDebugState.forcedGuideKey = "test-guide-key";
- const { getByText } = render();
+ const { getByText } = render();
expect(getByText("Debug")).toBeInTheDocument();
expect(getByText("test-guide-key")).toBeInTheDocument();
expect(getByText("Exit")).toBeInTheDocument();
@@ -45,7 +45,7 @@ describe("GuideToolbar", () => {
test("does not render when forcedGuideKey is null", () => {
mockDebugState.forcedGuideKey = null;
- const { container } = render();
+ const { container } = render();
expect(container.firstChild).toBeNull();
});
@@ -64,7 +64,7 @@ describe("GuideToolbar", () => {
mockDebugState.forcedGuideKey = "test-guide-key";
- const { getByText } = render();
+ const { getByText } = render();
const exitButton = getByText("Exit");
fireEvent.click(exitButton);