@churnkey/react 0.1.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/LICENSE +19 -0
- package/README.md +326 -0
- package/dist/chunk-CPBEP4NW.cjs +1059 -0
- package/dist/chunk-CPBEP4NW.cjs.map +1 -0
- package/dist/chunk-GCQ75J4G.js +102 -0
- package/dist/chunk-GCQ75J4G.js.map +1 -0
- package/dist/chunk-IFVMM2LB.js +1054 -0
- package/dist/chunk-IFVMM2LB.js.map +1 -0
- package/dist/chunk-QTMZI5I2.js +85 -0
- package/dist/chunk-QTMZI5I2.js.map +1 -0
- package/dist/chunk-SIYJ4R4B.cjs +113 -0
- package/dist/chunk-SIYJ4R4B.cjs.map +1 -0
- package/dist/chunk-XU7KDCXO.cjs +88 -0
- package/dist/chunk-XU7KDCXO.cjs.map +1 -0
- package/dist/core.cjs +49 -0
- package/dist/core.cjs.map +1 -0
- package/dist/core.d.cts +298 -0
- package/dist/core.d.ts +298 -0
- package/dist/core.js +4 -0
- package/dist/core.js.map +1 -0
- package/dist/headless.cjs +13 -0
- package/dist/headless.cjs.map +1 -0
- package/dist/headless.d.cts +30 -0
- package/dist/headless.d.ts +30 -0
- package/dist/headless.js +4 -0
- package/dist/headless.js.map +1 -0
- package/dist/index.cjs +960 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +39 -0
- package/dist/index.d.ts +39 -0
- package/dist/index.js +901 -0
- package/dist/index.js.map +1 -0
- package/dist/step-graph-ChdI-VXV.d.cts +540 -0
- package/dist/step-graph-ChdI-VXV.d.ts +540 -0
- package/dist/styles.css +760 -0
- package/package.json +83 -0
|
@@ -0,0 +1,540 @@
|
|
|
1
|
+
import { ReactNode, ReactElement, ComponentType } from 'react';
|
|
2
|
+
|
|
3
|
+
interface DirectAddress {
|
|
4
|
+
line1?: string;
|
|
5
|
+
line2?: string;
|
|
6
|
+
city?: string;
|
|
7
|
+
state?: string;
|
|
8
|
+
postalCode?: string;
|
|
9
|
+
/** ISO 3166-1 alpha-2 */
|
|
10
|
+
country?: string;
|
|
11
|
+
}
|
|
12
|
+
interface DirectCustomer {
|
|
13
|
+
id: string;
|
|
14
|
+
email?: string;
|
|
15
|
+
name?: string;
|
|
16
|
+
lastName?: string;
|
|
17
|
+
phone?: string;
|
|
18
|
+
/** ISO 4217 */
|
|
19
|
+
currency?: string;
|
|
20
|
+
addresses?: DirectAddress[];
|
|
21
|
+
metadata?: Record<string, unknown>;
|
|
22
|
+
}
|
|
23
|
+
interface DirectPrice {
|
|
24
|
+
id: string;
|
|
25
|
+
type?: 'standalone' | 'product';
|
|
26
|
+
active?: boolean;
|
|
27
|
+
productId?: string;
|
|
28
|
+
name?: string;
|
|
29
|
+
description?: string;
|
|
30
|
+
duration?: {
|
|
31
|
+
interval: 'day' | 'week' | 'month' | 'year';
|
|
32
|
+
intervalCount?: number;
|
|
33
|
+
};
|
|
34
|
+
amount: {
|
|
35
|
+
model?: 'fixed' | 'tiered';
|
|
36
|
+
/** Smallest currency unit (cents for USD). */
|
|
37
|
+
value: number;
|
|
38
|
+
currency?: string;
|
|
39
|
+
};
|
|
40
|
+
metadata?: Record<string, unknown>;
|
|
41
|
+
}
|
|
42
|
+
interface DirectCoupon {
|
|
43
|
+
id?: string;
|
|
44
|
+
name?: string;
|
|
45
|
+
percentOff?: number;
|
|
46
|
+
/** Smallest currency unit (cents for USD). */
|
|
47
|
+
amountOff?: number;
|
|
48
|
+
currency?: string;
|
|
49
|
+
duration?: 'once' | 'repeating' | 'forever';
|
|
50
|
+
durationInMonths?: number;
|
|
51
|
+
metadata?: Record<string, unknown>;
|
|
52
|
+
}
|
|
53
|
+
type SubscriptionStatus = {
|
|
54
|
+
name: 'active';
|
|
55
|
+
currentPeriod: {
|
|
56
|
+
start: Date | string;
|
|
57
|
+
end: Date | string;
|
|
58
|
+
};
|
|
59
|
+
} | {
|
|
60
|
+
name: 'trial';
|
|
61
|
+
trial: {
|
|
62
|
+
start: Date | string;
|
|
63
|
+
end: Date | string;
|
|
64
|
+
};
|
|
65
|
+
currentPeriod?: {
|
|
66
|
+
start: Date | string;
|
|
67
|
+
end: Date | string;
|
|
68
|
+
};
|
|
69
|
+
} | {
|
|
70
|
+
name: 'paused';
|
|
71
|
+
pause: {
|
|
72
|
+
start: Date | string;
|
|
73
|
+
end?: Date | string;
|
|
74
|
+
};
|
|
75
|
+
currentPeriod?: {
|
|
76
|
+
start: Date | string;
|
|
77
|
+
end: Date | string;
|
|
78
|
+
};
|
|
79
|
+
} | {
|
|
80
|
+
name: 'canceled';
|
|
81
|
+
canceledAt: Date | string;
|
|
82
|
+
} | {
|
|
83
|
+
name: 'unpaid';
|
|
84
|
+
currentPeriod?: {
|
|
85
|
+
start: Date | string;
|
|
86
|
+
end: Date | string;
|
|
87
|
+
};
|
|
88
|
+
} | {
|
|
89
|
+
name: 'future';
|
|
90
|
+
currentPeriod?: {
|
|
91
|
+
start: Date | string;
|
|
92
|
+
end: Date | string;
|
|
93
|
+
};
|
|
94
|
+
};
|
|
95
|
+
interface DirectSubscriptionItem {
|
|
96
|
+
id?: string;
|
|
97
|
+
price: DirectPrice;
|
|
98
|
+
quantity?: number;
|
|
99
|
+
}
|
|
100
|
+
interface DirectSubscription {
|
|
101
|
+
id: string;
|
|
102
|
+
customerId?: string;
|
|
103
|
+
start: Date | string;
|
|
104
|
+
status: SubscriptionStatus;
|
|
105
|
+
items: DirectSubscriptionItem[];
|
|
106
|
+
duration?: {
|
|
107
|
+
interval: 'day' | 'week' | 'month' | 'year';
|
|
108
|
+
intervalCount?: number;
|
|
109
|
+
};
|
|
110
|
+
end?: Date | string;
|
|
111
|
+
discounts?: Array<{
|
|
112
|
+
id?: string;
|
|
113
|
+
coupon?: DirectCoupon;
|
|
114
|
+
start?: Date | string;
|
|
115
|
+
end?: Date | string;
|
|
116
|
+
}>;
|
|
117
|
+
metadata?: Record<string, unknown>;
|
|
118
|
+
}
|
|
119
|
+
interface DiscountOffer {
|
|
120
|
+
type: 'discount';
|
|
121
|
+
couponId?: string;
|
|
122
|
+
percentOff?: number;
|
|
123
|
+
/** Smallest currency unit (cents for USD). */
|
|
124
|
+
amountOff?: number;
|
|
125
|
+
currency?: string;
|
|
126
|
+
durationInMonths?: number;
|
|
127
|
+
}
|
|
128
|
+
interface PauseOffer {
|
|
129
|
+
type: 'pause';
|
|
130
|
+
months: number;
|
|
131
|
+
interval?: 'month' | 'week';
|
|
132
|
+
datePicker?: boolean;
|
|
133
|
+
}
|
|
134
|
+
interface PlanChangeOffer {
|
|
135
|
+
type: 'plan_change';
|
|
136
|
+
plans: PlanOption[];
|
|
137
|
+
currentPlanId?: string;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Plan option in a `plan_change` offer — `DirectPrice` plus optional
|
|
141
|
+
* cancel-flow merchandising fields. Marketing fields are presentation-only
|
|
142
|
+
* and live on `PlanOption` rather than `DirectPrice` so `Direct` stays a
|
|
143
|
+
* clean billing-data shape reusable outside the cancel-flow context.
|
|
144
|
+
*/
|
|
145
|
+
interface PlanOption extends DirectPrice {
|
|
146
|
+
/** Short marketing line (e.g. "Most popular"). */
|
|
147
|
+
tagline?: string;
|
|
148
|
+
/** Bullet list of plan features shown on the card. */
|
|
149
|
+
features?: string[];
|
|
150
|
+
/** Pre-formatted "before" price rendered struck-through (e.g. "$49/mo"). */
|
|
151
|
+
msrp?: string;
|
|
152
|
+
}
|
|
153
|
+
interface TrialExtensionOffer {
|
|
154
|
+
type: 'trial_extension';
|
|
155
|
+
days: number;
|
|
156
|
+
}
|
|
157
|
+
interface ContactOffer {
|
|
158
|
+
type: 'contact';
|
|
159
|
+
url?: string;
|
|
160
|
+
label?: string;
|
|
161
|
+
}
|
|
162
|
+
interface RedirectOffer {
|
|
163
|
+
type: 'redirect';
|
|
164
|
+
url: string;
|
|
165
|
+
label: string;
|
|
166
|
+
}
|
|
167
|
+
interface CustomOfferConfig {
|
|
168
|
+
type: string;
|
|
169
|
+
data?: Record<string, unknown>;
|
|
170
|
+
}
|
|
171
|
+
type BuiltInOfferConfig = DiscountOffer | PauseOffer | PlanChangeOffer | TrialExtensionOffer | ContactOffer | RedirectOffer;
|
|
172
|
+
type OfferConfig = BuiltInOfferConfig | CustomOfferConfig;
|
|
173
|
+
type OfferDecision = OfferConfig & {
|
|
174
|
+
copy: OfferCopy;
|
|
175
|
+
decisionId?: string;
|
|
176
|
+
};
|
|
177
|
+
interface OfferCopy {
|
|
178
|
+
headline: string;
|
|
179
|
+
body: string;
|
|
180
|
+
cta: string;
|
|
181
|
+
declineCta: string;
|
|
182
|
+
}
|
|
183
|
+
type AcceptedOffer = OfferConfig & {
|
|
184
|
+
reasonId: string;
|
|
185
|
+
decisionId?: string;
|
|
186
|
+
result?: Record<string, unknown>;
|
|
187
|
+
};
|
|
188
|
+
interface ReasonConfig {
|
|
189
|
+
id: string;
|
|
190
|
+
label: string;
|
|
191
|
+
freeform?: boolean;
|
|
192
|
+
offer?: OfferConfig;
|
|
193
|
+
}
|
|
194
|
+
interface SurveyStep {
|
|
195
|
+
type: 'survey';
|
|
196
|
+
guid?: string;
|
|
197
|
+
title?: string;
|
|
198
|
+
description?: string;
|
|
199
|
+
reasons: ReasonConfig[];
|
|
200
|
+
classNames?: SurveyClassNames;
|
|
201
|
+
}
|
|
202
|
+
interface OfferStep {
|
|
203
|
+
type: 'offer';
|
|
204
|
+
guid?: string;
|
|
205
|
+
title?: string;
|
|
206
|
+
description?: string;
|
|
207
|
+
/**
|
|
208
|
+
* Offer attached to this step. Set this for proactive save offers shown
|
|
209
|
+
* outside a survey; the SDK also populates it automatically on synthetic
|
|
210
|
+
* offer steps spawned from survey choices.
|
|
211
|
+
*/
|
|
212
|
+
offer?: OfferDecision;
|
|
213
|
+
classNames?: OfferClassNames;
|
|
214
|
+
}
|
|
215
|
+
interface FeedbackStep {
|
|
216
|
+
type: 'feedback';
|
|
217
|
+
guid?: string;
|
|
218
|
+
title?: string;
|
|
219
|
+
description?: string;
|
|
220
|
+
placeholder?: string;
|
|
221
|
+
required?: boolean;
|
|
222
|
+
minLength?: number;
|
|
223
|
+
classNames?: FeedbackClassNames;
|
|
224
|
+
}
|
|
225
|
+
interface ConfirmStep {
|
|
226
|
+
type: 'confirm';
|
|
227
|
+
guid?: string;
|
|
228
|
+
title?: string;
|
|
229
|
+
description?: string;
|
|
230
|
+
confirmLabel?: string;
|
|
231
|
+
goBackLabel?: string;
|
|
232
|
+
classNames?: ConfirmClassNames;
|
|
233
|
+
}
|
|
234
|
+
interface SuccessStep {
|
|
235
|
+
type: 'success';
|
|
236
|
+
guid?: string;
|
|
237
|
+
savedTitle?: string;
|
|
238
|
+
savedDescription?: string;
|
|
239
|
+
cancelledTitle?: string;
|
|
240
|
+
cancelledDescription?: string;
|
|
241
|
+
classNames?: SuccessClassNames;
|
|
242
|
+
}
|
|
243
|
+
interface CustomStepConfig {
|
|
244
|
+
type: string;
|
|
245
|
+
guid?: string;
|
|
246
|
+
title?: string;
|
|
247
|
+
description?: string;
|
|
248
|
+
data?: Record<string, unknown>;
|
|
249
|
+
}
|
|
250
|
+
type BuiltInStep = SurveyStep | OfferStep | FeedbackStep | ConfirmStep | SuccessStep;
|
|
251
|
+
type Step = BuiltInStep | CustomStepConfig;
|
|
252
|
+
type BuiltInStepType = 'survey' | 'offer' | 'feedback' | 'confirm' | 'success';
|
|
253
|
+
interface SurveyClassNames {
|
|
254
|
+
root?: string;
|
|
255
|
+
title?: string;
|
|
256
|
+
description?: string;
|
|
257
|
+
reasonList?: string;
|
|
258
|
+
reasonButton?: string;
|
|
259
|
+
reasonButtonSelected?: string;
|
|
260
|
+
reasonLabel?: string;
|
|
261
|
+
freeformInput?: string;
|
|
262
|
+
continueButton?: string;
|
|
263
|
+
}
|
|
264
|
+
interface OfferClassNames {
|
|
265
|
+
root?: string;
|
|
266
|
+
title?: string;
|
|
267
|
+
description?: string;
|
|
268
|
+
card?: string;
|
|
269
|
+
headline?: string;
|
|
270
|
+
body?: string;
|
|
271
|
+
acceptButton?: string;
|
|
272
|
+
declineButton?: string;
|
|
273
|
+
discountBadge?: string;
|
|
274
|
+
priceComparison?: string;
|
|
275
|
+
pauseSlider?: string;
|
|
276
|
+
planGrid?: string;
|
|
277
|
+
planCard?: string;
|
|
278
|
+
planCardSelected?: string;
|
|
279
|
+
}
|
|
280
|
+
interface FeedbackClassNames {
|
|
281
|
+
root?: string;
|
|
282
|
+
title?: string;
|
|
283
|
+
description?: string;
|
|
284
|
+
textarea?: string;
|
|
285
|
+
characterCount?: string;
|
|
286
|
+
submitButton?: string;
|
|
287
|
+
}
|
|
288
|
+
interface ConfirmClassNames {
|
|
289
|
+
root?: string;
|
|
290
|
+
title?: string;
|
|
291
|
+
description?: string;
|
|
292
|
+
confirmButton?: string;
|
|
293
|
+
goBackButton?: string;
|
|
294
|
+
periodEndNotice?: string;
|
|
295
|
+
}
|
|
296
|
+
interface SuccessClassNames {
|
|
297
|
+
root?: string;
|
|
298
|
+
icon?: string;
|
|
299
|
+
title?: string;
|
|
300
|
+
description?: string;
|
|
301
|
+
closeButton?: string;
|
|
302
|
+
}
|
|
303
|
+
interface StructuralClassNames {
|
|
304
|
+
overlay?: string;
|
|
305
|
+
modal?: string;
|
|
306
|
+
closeButton?: string;
|
|
307
|
+
backButton?: string;
|
|
308
|
+
}
|
|
309
|
+
interface AppearanceVariables {
|
|
310
|
+
colorPrimary: string;
|
|
311
|
+
colorPrimaryHover: string;
|
|
312
|
+
colorBackground: string;
|
|
313
|
+
colorText: string;
|
|
314
|
+
colorTextSecondary: string;
|
|
315
|
+
colorBorder: string;
|
|
316
|
+
colorDanger: string;
|
|
317
|
+
colorSuccess: string;
|
|
318
|
+
fontFamily: string;
|
|
319
|
+
fontSize: string;
|
|
320
|
+
borderRadius: string;
|
|
321
|
+
}
|
|
322
|
+
interface Appearance {
|
|
323
|
+
/**
|
|
324
|
+
* `'auto'` follows the user's OS preference (`prefers-color-scheme`) and
|
|
325
|
+
* watches for changes. Default: `'light'`.
|
|
326
|
+
*/
|
|
327
|
+
colorScheme?: 'auto' | 'light' | 'dark';
|
|
328
|
+
variables?: Partial<AppearanceVariables>;
|
|
329
|
+
}
|
|
330
|
+
interface CustomStepProps {
|
|
331
|
+
step: CustomStepConfig;
|
|
332
|
+
customer: DirectCustomer | null;
|
|
333
|
+
onNext: (result?: Record<string, unknown>) => void;
|
|
334
|
+
onBack: () => void;
|
|
335
|
+
}
|
|
336
|
+
interface CustomOfferProps {
|
|
337
|
+
offer: OfferDecision;
|
|
338
|
+
customer: DirectCustomer | null;
|
|
339
|
+
onAccept: (result?: Record<string, unknown>) => Promise<void>;
|
|
340
|
+
onDecline: () => void;
|
|
341
|
+
isProcessing: boolean;
|
|
342
|
+
}
|
|
343
|
+
interface ComponentOverrides {
|
|
344
|
+
Modal?: (props: ModalProps) => ReactElement;
|
|
345
|
+
CloseButton?: (props: CloseButtonProps) => ReactElement;
|
|
346
|
+
BackButton?: (props: BackButtonProps) => ReactElement;
|
|
347
|
+
Survey?: (props: SurveyStepProps) => ReactElement;
|
|
348
|
+
Offer?: (props: OfferStepProps) => ReactElement;
|
|
349
|
+
Feedback?: (props: FeedbackStepProps) => ReactElement;
|
|
350
|
+
Confirm?: (props: ConfirmStepProps) => ReactElement;
|
|
351
|
+
Success?: (props: SuccessStepProps) => ReactElement;
|
|
352
|
+
ReasonButton?: (props: ReasonButtonProps) => ReactElement;
|
|
353
|
+
DiscountOffer?: (props: OfferStepProps) => ReactElement;
|
|
354
|
+
PauseOffer?: (props: OfferStepProps) => ReactElement;
|
|
355
|
+
PlanChangeOffer?: (props: OfferStepProps) => ReactElement;
|
|
356
|
+
TrialExtensionOffer?: (props: OfferStepProps) => ReactElement;
|
|
357
|
+
ContactOffer?: (props: OfferStepProps) => ReactElement;
|
|
358
|
+
RedirectOffer?: (props: OfferStepProps) => ReactElement;
|
|
359
|
+
}
|
|
360
|
+
type CustomComponents = Record<string, ComponentType<CustomStepProps> | ComponentType<CustomOfferProps>>;
|
|
361
|
+
interface ModalProps {
|
|
362
|
+
open: boolean;
|
|
363
|
+
onClose: () => void;
|
|
364
|
+
children: ReactNode;
|
|
365
|
+
className?: string;
|
|
366
|
+
}
|
|
367
|
+
interface CloseButtonProps {
|
|
368
|
+
onClose: () => void;
|
|
369
|
+
className?: string;
|
|
370
|
+
}
|
|
371
|
+
interface BackButtonProps {
|
|
372
|
+
onBack: () => void;
|
|
373
|
+
className?: string;
|
|
374
|
+
}
|
|
375
|
+
interface SurveyStepProps {
|
|
376
|
+
title: string;
|
|
377
|
+
description?: string;
|
|
378
|
+
reasons: ReasonConfig[];
|
|
379
|
+
selectedReason: string | null;
|
|
380
|
+
onSelectReason: (id: string) => void;
|
|
381
|
+
onNext: () => void;
|
|
382
|
+
classNames?: SurveyClassNames;
|
|
383
|
+
components?: Partial<ComponentOverrides>;
|
|
384
|
+
}
|
|
385
|
+
interface OfferStepProps {
|
|
386
|
+
title?: string;
|
|
387
|
+
description?: string;
|
|
388
|
+
offer: OfferDecision;
|
|
389
|
+
/**
|
|
390
|
+
* Accept the offer. The optional `result` is included on the resulting
|
|
391
|
+
* `AcceptedOffer` payload — used by offers that need a user choice (e.g.
|
|
392
|
+
* `plan_change` passes `{ planId }`).
|
|
393
|
+
*/
|
|
394
|
+
onAccept: (result?: Record<string, unknown>) => Promise<void>;
|
|
395
|
+
onDecline: () => void;
|
|
396
|
+
isProcessing: boolean;
|
|
397
|
+
classNames?: OfferClassNames;
|
|
398
|
+
/**
|
|
399
|
+
* Forwarded to the default `Offer` switcher so it can dispatch to per-type
|
|
400
|
+
* overrides (`DiscountOffer`, `PauseOffer`, etc). Custom `Offer`
|
|
401
|
+
* implementations can ignore this.
|
|
402
|
+
*/
|
|
403
|
+
components?: Partial<ComponentOverrides>;
|
|
404
|
+
}
|
|
405
|
+
interface FeedbackStepProps {
|
|
406
|
+
title: string;
|
|
407
|
+
description?: string;
|
|
408
|
+
placeholder?: string;
|
|
409
|
+
required: boolean;
|
|
410
|
+
minLength: number;
|
|
411
|
+
value: string;
|
|
412
|
+
onChange: (text: string) => void;
|
|
413
|
+
onSubmit: () => void;
|
|
414
|
+
classNames?: FeedbackClassNames;
|
|
415
|
+
}
|
|
416
|
+
interface ConfirmStepProps {
|
|
417
|
+
title: string;
|
|
418
|
+
description?: string;
|
|
419
|
+
confirmLabel: string;
|
|
420
|
+
goBackLabel: string;
|
|
421
|
+
periodEnd?: string;
|
|
422
|
+
onConfirm: () => Promise<void>;
|
|
423
|
+
onGoBack: () => void;
|
|
424
|
+
isProcessing: boolean;
|
|
425
|
+
classNames?: ConfirmClassNames;
|
|
426
|
+
}
|
|
427
|
+
interface SuccessStepProps {
|
|
428
|
+
outcome: 'saved' | 'cancelled';
|
|
429
|
+
offer?: OfferDecision;
|
|
430
|
+
title: string;
|
|
431
|
+
description?: string;
|
|
432
|
+
onClose: () => void;
|
|
433
|
+
classNames?: SuccessClassNames;
|
|
434
|
+
}
|
|
435
|
+
interface ReasonButtonProps {
|
|
436
|
+
reason: ReasonConfig;
|
|
437
|
+
index: number;
|
|
438
|
+
isSelected: boolean;
|
|
439
|
+
onSelect: (id: string) => void;
|
|
440
|
+
}
|
|
441
|
+
interface FlowState {
|
|
442
|
+
step: string;
|
|
443
|
+
currentStepId: string;
|
|
444
|
+
selectedReason: string | null;
|
|
445
|
+
feedback: string;
|
|
446
|
+
outcome: 'saved' | 'cancelled' | null;
|
|
447
|
+
isProcessing: boolean;
|
|
448
|
+
error: Error | null;
|
|
449
|
+
customer: DirectCustomer | null;
|
|
450
|
+
}
|
|
451
|
+
interface FlowConfig extends FlowCallbacks {
|
|
452
|
+
appId?: string;
|
|
453
|
+
customer?: DirectCustomer;
|
|
454
|
+
subscriptions?: DirectSubscription[];
|
|
455
|
+
session?: string;
|
|
456
|
+
apiBaseUrl?: string;
|
|
457
|
+
steps?: Step[];
|
|
458
|
+
/**
|
|
459
|
+
* Tags the session as live or test. Use `'test'` from staging so your
|
|
460
|
+
* dashboard can filter out non-production traffic. Defaults to `'live'`.
|
|
461
|
+
* In token mode the mode is encoded in the signed token and overrides
|
|
462
|
+
* this field.
|
|
463
|
+
*/
|
|
464
|
+
mode?: 'live' | 'test';
|
|
465
|
+
}
|
|
466
|
+
type OfferCallback = (offer: AcceptedOffer, customer: DirectCustomer | null) => Promise<void> | void;
|
|
467
|
+
type CancelCallback = (customer: DirectCustomer | null) => Promise<void> | void;
|
|
468
|
+
/**
|
|
469
|
+
* Two kinds of callbacks, distinguished by name:
|
|
470
|
+
*
|
|
471
|
+
* - `handle<Type>` runs the action. When defined, it replaces whatever
|
|
472
|
+
* Churnkey would do on the server — the consumer takes responsibility.
|
|
473
|
+
* In local mode (no token), handlers are the only path that does anything.
|
|
474
|
+
* - `on<Type>` is a listener that fires after the action. Side effects only —
|
|
475
|
+
* refetch state, log analytics, show a toast. Errors thrown here are
|
|
476
|
+
* swallowed; listeners can't flip the flow into an error state.
|
|
477
|
+
*
|
|
478
|
+
* `onAccept` is a catch-all that fires alongside the per-type listener.
|
|
479
|
+
*/
|
|
480
|
+
interface FlowCallbacks {
|
|
481
|
+
handleDiscount?: OfferCallback;
|
|
482
|
+
handlePause?: OfferCallback;
|
|
483
|
+
handlePlanChange?: OfferCallback;
|
|
484
|
+
handleTrialExtension?: OfferCallback;
|
|
485
|
+
handleCancel?: CancelCallback;
|
|
486
|
+
onAccept?: OfferCallback;
|
|
487
|
+
onDiscount?: OfferCallback;
|
|
488
|
+
onPause?: OfferCallback;
|
|
489
|
+
onPlanChange?: OfferCallback;
|
|
490
|
+
onTrialExtension?: OfferCallback;
|
|
491
|
+
onCancel?: CancelCallback;
|
|
492
|
+
onClose?: () => void;
|
|
493
|
+
onStepChange?: (step: string, prevStep: string) => void;
|
|
494
|
+
}
|
|
495
|
+
interface CancelFlowProps extends FlowCallbacks {
|
|
496
|
+
appId?: string;
|
|
497
|
+
customer?: DirectCustomer;
|
|
498
|
+
subscriptions?: DirectSubscription[];
|
|
499
|
+
session?: string;
|
|
500
|
+
steps?: Step[];
|
|
501
|
+
apiBaseUrl?: string;
|
|
502
|
+
/** See FlowConfig.mode. Ignored in token mode (the token is authoritative). */
|
|
503
|
+
mode?: 'live' | 'test';
|
|
504
|
+
appearance?: Appearance;
|
|
505
|
+
classNames?: StructuralClassNames;
|
|
506
|
+
components?: Partial<ComponentOverrides>;
|
|
507
|
+
customComponents?: CustomComponents;
|
|
508
|
+
layout?: {
|
|
509
|
+
desktop?: 'modal' | 'inline' | 'drawer';
|
|
510
|
+
mobile?: 'sheet' | 'fullscreen' | 'inline';
|
|
511
|
+
breakpoint?: number;
|
|
512
|
+
};
|
|
513
|
+
animation?: 'css' | 'framer' | 'none';
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
interface ResolvedStep {
|
|
517
|
+
guid: string;
|
|
518
|
+
type: string;
|
|
519
|
+
defaultNextStep?: string;
|
|
520
|
+
defaultPreviousStep?: string;
|
|
521
|
+
title?: string;
|
|
522
|
+
description?: string;
|
|
523
|
+
reasons?: ReasonConfig[];
|
|
524
|
+
offersAttached?: Record<string, string>;
|
|
525
|
+
numChoices?: number;
|
|
526
|
+
offer?: OfferDecision;
|
|
527
|
+
/** True if this step was synthesized from a survey choice. Used by stepIndex so synthetic offers share the survey's progress slot. */
|
|
528
|
+
surveyOffer?: boolean;
|
|
529
|
+
placeholder?: string;
|
|
530
|
+
required?: boolean;
|
|
531
|
+
minLength?: number;
|
|
532
|
+
savedTitle?: string;
|
|
533
|
+
savedDescription?: string;
|
|
534
|
+
cancelledTitle?: string;
|
|
535
|
+
cancelledDescription?: string;
|
|
536
|
+
data?: Record<string, unknown>;
|
|
537
|
+
classNames?: unknown;
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
export type { SurveyStep as $, AcceptedOffer as A, BackButtonProps as B, CancelFlowProps as C, DirectAddress as D, FlowState as E, FeedbackStepProps as F, OfferClassNames as G, OfferConfig as H, OfferCopy as I, OfferDecision as J, OfferStep as K, PlanChangeOffer as L, ModalProps as M, PlanOption as N, OfferStepProps as O, PauseOffer as P, ReasonConfig as Q, ReasonButtonProps as R, SuccessStepProps as S, RedirectOffer as T, ResolvedStep as U, Step as V, StructuralClassNames as W, SubscriptionStatus as X, SuccessClassNames as Y, SuccessStep as Z, SurveyClassNames as _, ConfirmStepProps as a, TrialExtensionOffer as a0, SurveyStepProps as b, CloseButtonProps as c, Appearance as d, AppearanceVariables as e, BuiltInOfferConfig as f, BuiltInStep as g, BuiltInStepType as h, ComponentOverrides as i, ConfirmClassNames as j, ConfirmStep as k, ContactOffer as l, CustomComponents as m, CustomOfferConfig as n, CustomOfferProps as o, CustomStepConfig as p, CustomStepProps as q, DirectCoupon as r, DirectCustomer as s, DirectPrice as t, DirectSubscription as u, DirectSubscriptionItem as v, DiscountOffer as w, FeedbackClassNames as x, FeedbackStep as y, FlowConfig as z };
|