Skip to content

Commit aef0e5a

Browse files
authored
feat: add content type generic for guide step content (#722)
1 parent b8b64e4 commit aef0e5a

File tree

5 files changed

+46
-22
lines changed

5 files changed

+46
-22
lines changed

examples/guide-example/src/App.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,14 @@ import "@knocklabs/react/dist/index.css";
1111
import { useEffect, useState } from "react";
1212
import { Link, Route, Routes } from "react-router";
1313

14+
interface ChangelogCardContent {
15+
headline: string;
16+
title: string;
17+
body: string;
18+
}
19+
1420
const ChangelogCard = () => {
15-
const { guide, step } = useGuide({ type: "changelog-card" });
21+
const { guide, step } = useGuide<ChangelogCardContent>({ type: "changelog-card" });
1622

1723
useEffect(() => {
1824
if (step) step.markAsSeen();

packages/client/src/clients/guide/client.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
mockDefaultGroup,
1616
} from "./helpers";
1717
import {
18+
Any,
1819
ConstructorOpts,
1920
DebugState,
2021
GetGuidesQueryParams,
@@ -446,7 +447,10 @@ export class KnockGuideClient {
446447
// Store selector
447448
//
448449

449-
selectGuides(state: StoreState, filters: SelectFilterParams = {}) {
450+
selectGuides<C = Any>(
451+
state: StoreState,
452+
filters: SelectFilterParams = {},
453+
): KnockGuide<C>[] {
450454
if (Object.keys(state.guides).length === 0) {
451455
return [];
452456
}
@@ -465,7 +469,10 @@ export class KnockGuideClient {
465469
return [...result.values()];
466470
}
467471

468-
selectGuide(state: StoreState, filters: SelectFilterParams = {}) {
472+
selectGuide<C = Any>(
473+
state: StoreState,
474+
filters: SelectFilterParams = {},
475+
): KnockGuide<C> | undefined {
469476
if (Object.keys(state.guides).length === 0) {
470477
return undefined;
471478
}

packages/client/src/clients/guide/types.ts

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ import { GenericData } from "@knocklabs/types";
44
// Fetch guides API
55
//
66

7+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
8+
export type Any = any;
9+
710
export interface StepMessageState {
811
id: string;
912
seen_at: string | null;
@@ -13,29 +16,28 @@ export interface StepMessageState {
1316
link_clicked_at: string | null;
1417
}
1518

16-
export interface GuideStepData {
19+
export interface GuideStepData<TContent = Any> {
1720
ref: string;
1821
schema_key: string;
1922
schema_semver: string;
2023
schema_variant_key: string;
2124
message: StepMessageState;
22-
// eslint-disable-next-line
23-
content: any;
25+
content: TContent;
2426
}
2527

2628
interface GuideActivationLocationRuleData {
2729
directive: "allow" | "block";
2830
pathname: string;
2931
}
3032

31-
export interface GuideData {
33+
export interface GuideData<TContent = Any> {
3234
__typename: "Guide";
3335
channel_id: string;
3436
id: string;
3537
key: string;
3638
type: string;
3739
semver: string;
38-
steps: GuideStepData[];
40+
steps: GuideStepData<TContent>[];
3941
activation_location_rules: GuideActivationLocationRuleData[];
4042
bypass_global_group_limit: boolean;
4143
inserted_at: string;
@@ -148,7 +150,8 @@ export type GuideSocketEvent =
148150
// Guide client
149151
//
150152

151-
export interface KnockGuideStep extends GuideStepData {
153+
export interface KnockGuideStep<TContent = Any>
154+
extends GuideStepData<TContent> {
152155
markAsSeen: () => void;
153156
markAsInteracted: (params?: { metadata?: GenericData }) => void;
154157
markAsArchived: () => void;
@@ -159,10 +162,10 @@ interface KnockGuideActivationLocationRule
159162
pattern: URLPattern;
160163
}
161164

162-
export interface KnockGuide extends GuideData {
163-
steps: KnockGuideStep[];
165+
export interface KnockGuide<TContent = Any> extends GuideData<TContent> {
166+
steps: KnockGuideStep<TContent>[];
164167
activation_location_rules: KnockGuideActivationLocationRule[];
165-
getStep: () => KnockGuideStep | undefined;
168+
getStep: () => KnockGuideStep<TContent> | undefined;
166169
}
167170

168171
type QueryKey = string;

packages/react-core/src/modules/guide/hooks/useGuide.ts

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,17 @@ import { useStore } from "@tanstack/react-store";
77

88
import { UseGuideContextReturn, useGuideContext } from "./useGuideContext";
99

10-
interface UseGuideReturn extends UseGuideContextReturn {
11-
guide: KnockGuide | undefined;
12-
step: KnockGuideStep | undefined;
10+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
11+
type Any = any;
12+
13+
interface UseGuideReturn<C = Any> extends UseGuideContextReturn {
14+
guide: KnockGuide<C> | undefined;
15+
step: KnockGuideStep<C> | undefined;
1316
}
1417

15-
export const useGuide = (filters: KnockGuideFilterParams): UseGuideReturn => {
18+
export const useGuide = <C = Any>(
19+
filters: KnockGuideFilterParams,
20+
): UseGuideReturn<C> => {
1621
const context = useGuideContext();
1722

1823
if (!filters.key && !filters.type) {
@@ -24,7 +29,7 @@ export const useGuide = (filters: KnockGuideFilterParams): UseGuideReturn => {
2429
const { client, colorMode } = context;
2530

2631
const guide = useStore(client.store, (state) =>
27-
client.selectGuide(state, filters),
32+
client.selectGuide<C>(state, filters),
2833
);
2934

3035
const step = guide && guide.getStep();

packages/react-core/src/modules/guide/hooks/useGuides.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,21 @@ import { useStore } from "@tanstack/react-store";
33

44
import { UseGuideContextReturn, useGuideContext } from "./useGuideContext";
55

6-
interface UseGuidesReturn extends UseGuideContextReturn {
7-
guides: KnockGuide[];
6+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
7+
type Any = any;
8+
9+
interface UseGuidesReturn<C = Any> extends UseGuideContextReturn {
10+
guides: KnockGuide<C>[];
811
}
912

10-
export const useGuides = (
13+
export const useGuides = <C = Any>(
1114
filters: Pick<KnockGuideFilterParams, "type">,
12-
): UseGuidesReturn => {
15+
): UseGuidesReturn<C> => {
1316
const context = useGuideContext();
1417
const { client, colorMode } = context;
1518

1619
const guides = useStore(client.store, (state) =>
17-
client.selectGuides(state, filters),
20+
client.selectGuides<C>(state, filters),
1821
);
1922

2023
return { client, colorMode, guides };

0 commit comments

Comments
 (0)