featuredrop 1.1.0 → 1.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 +547 -4
- package/dist/admin.cjs +212 -0
- package/dist/admin.cjs.map +1 -0
- package/dist/admin.d.cts +176 -0
- package/dist/admin.d.ts +176 -0
- package/dist/admin.js +207 -0
- package/dist/admin.js.map +1 -0
- package/dist/angular.cjs +296 -0
- package/dist/angular.cjs.map +1 -0
- package/dist/angular.d.cts +233 -0
- package/dist/angular.d.ts +233 -0
- package/dist/angular.js +293 -0
- package/dist/angular.js.map +1 -0
- package/dist/bridges.cjs +401 -0
- package/dist/bridges.cjs.map +1 -0
- package/dist/bridges.d.cts +194 -0
- package/dist/bridges.d.ts +194 -0
- package/dist/bridges.js +394 -0
- package/dist/bridges.js.map +1 -0
- package/dist/ci.cjs +328 -0
- package/dist/ci.cjs.map +1 -0
- package/dist/ci.d.cts +176 -0
- package/dist/ci.d.ts +176 -0
- package/dist/ci.js +324 -0
- package/dist/ci.js.map +1 -0
- package/dist/featuredrop.cjs +1377 -0
- package/dist/featuredrop.cjs.map +1 -0
- package/dist/flags.cjs +51 -0
- package/dist/flags.cjs.map +1 -0
- package/dist/flags.d.cts +48 -0
- package/dist/flags.d.ts +48 -0
- package/dist/flags.js +47 -0
- package/dist/flags.js.map +1 -0
- package/dist/index.cjs +4734 -70
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1516 -9
- package/dist/index.d.ts +1516 -9
- package/dist/index.js +4660 -71
- package/dist/index.js.map +1 -1
- package/dist/preact.cjs +7790 -0
- package/dist/preact.cjs.map +1 -0
- package/dist/preact.d.cts +1213 -0
- package/dist/preact.d.ts +1213 -0
- package/dist/preact.js +7760 -0
- package/dist/preact.js.map +1 -0
- package/dist/react.cjs +6678 -159
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +852 -112
- package/dist/react.d.ts +852 -112
- package/dist/react.js +6657 -156
- package/dist/react.js.map +1 -1
- package/dist/schema.cjs +292 -0
- package/dist/schema.cjs.map +1 -0
- package/dist/schema.d.cts +345 -0
- package/dist/schema.d.ts +345 -0
- package/dist/schema.js +286 -0
- package/dist/schema.js.map +1 -0
- package/dist/solid.cjs +383 -0
- package/dist/solid.cjs.map +1 -0
- package/dist/solid.d.cts +246 -0
- package/dist/solid.d.ts +246 -0
- package/dist/solid.js +376 -0
- package/dist/solid.js.map +1 -0
- package/dist/svelte.cjs +339 -0
- package/dist/svelte.cjs.map +1 -0
- package/dist/svelte.js +334 -0
- package/dist/svelte.js.map +1 -0
- package/dist/testing.cjs +1543 -0
- package/dist/testing.cjs.map +1 -0
- package/dist/testing.d.cts +361 -0
- package/dist/testing.d.ts +361 -0
- package/dist/testing.js +1536 -0
- package/dist/testing.js.map +1 -0
- package/dist/vue.cjs +1094 -0
- package/dist/vue.cjs.map +1 -0
- package/dist/vue.js +1082 -0
- package/dist/vue.js.map +1 -0
- package/dist/web-components.cjs +493 -0
- package/dist/web-components.cjs.map +1 -0
- package/dist/web-components.d.cts +215 -0
- package/dist/web-components.d.ts +215 -0
- package/dist/web-components.js +487 -0
- package/dist/web-components.js.map +1 -0
- package/package.json +184 -3
package/dist/react.d.cts
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
1
|
import * as react from 'react';
|
|
3
2
|
import { ReactNode, CSSProperties, RefObject } from 'react';
|
|
3
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
4
4
|
|
|
5
5
|
/** Entry type label — determines default icon/color in UI */
|
|
6
6
|
type FeatureType = "feature" | "improvement" | "fix" | "breaking";
|
|
7
7
|
/** Priority level for announcements */
|
|
8
8
|
type FeaturePriority = "critical" | "normal" | "low";
|
|
9
|
+
/** Motion preset for built-in component transitions */
|
|
10
|
+
type FeatureDropAnimationPreset = "none" | "subtle" | "normal" | "playful";
|
|
9
11
|
/** Call-to-action for a feature entry */
|
|
10
12
|
interface FeatureCTA {
|
|
11
13
|
/** Button/link label */
|
|
@@ -13,6 +15,97 @@ interface FeatureCTA {
|
|
|
13
15
|
/** URL to navigate to */
|
|
14
16
|
url: string;
|
|
15
17
|
}
|
|
18
|
+
/** Variant-level overrides for A/B announcement testing */
|
|
19
|
+
interface FeatureVariant {
|
|
20
|
+
/** Optional variant-specific label override */
|
|
21
|
+
label?: string;
|
|
22
|
+
/** Optional variant-specific description override */
|
|
23
|
+
description?: string;
|
|
24
|
+
/** Optional variant-specific image override */
|
|
25
|
+
image?: string;
|
|
26
|
+
/** Optional variant-specific CTA override */
|
|
27
|
+
cta?: FeatureCTA;
|
|
28
|
+
/** Optional variant-specific metadata overrides */
|
|
29
|
+
meta?: Record<string, unknown>;
|
|
30
|
+
}
|
|
31
|
+
/** Audience targeting rule — determines which user segments see a feature */
|
|
32
|
+
interface AudienceRule {
|
|
33
|
+
/** Plans that should see this feature (e.g. ["pro", "enterprise"]) */
|
|
34
|
+
plan?: string[];
|
|
35
|
+
/** Roles that should see this feature (e.g. ["admin", "editor"]) */
|
|
36
|
+
role?: string[];
|
|
37
|
+
/** Regions that should see this feature (e.g. ["us", "eu"]) */
|
|
38
|
+
region?: string[];
|
|
39
|
+
/** Arbitrary key-value pairs for custom matching logic */
|
|
40
|
+
custom?: Record<string, unknown>;
|
|
41
|
+
}
|
|
42
|
+
/** User context for audience targeting */
|
|
43
|
+
interface UserContext {
|
|
44
|
+
/** Current user's plan (e.g. "pro", "free") */
|
|
45
|
+
plan?: string;
|
|
46
|
+
/** Current user's role (e.g. "admin", "viewer") */
|
|
47
|
+
role?: string;
|
|
48
|
+
/** Current user's region (e.g. "us", "eu") */
|
|
49
|
+
region?: string;
|
|
50
|
+
/** Arbitrary traits for custom matching logic */
|
|
51
|
+
traits?: Record<string, unknown>;
|
|
52
|
+
}
|
|
53
|
+
/** Custom audience matcher function */
|
|
54
|
+
type AudienceMatchFn = (audience: AudienceRule, userContext: UserContext) => boolean;
|
|
55
|
+
/** Feature flag resolver interface for gating announcement visibility */
|
|
56
|
+
interface FeatureFlagBridge {
|
|
57
|
+
isEnabled: (flagKey: string, userContext?: UserContext) => boolean;
|
|
58
|
+
}
|
|
59
|
+
/** Dependency gates for progressive feature discovery */
|
|
60
|
+
interface FeatureDependencies {
|
|
61
|
+
/** Features the user must have seen before this one can surface */
|
|
62
|
+
seen?: string[];
|
|
63
|
+
/** Features the user must have clicked before this one can surface */
|
|
64
|
+
clicked?: string[];
|
|
65
|
+
/** Features the user must have dismissed before this one can surface */
|
|
66
|
+
dismissed?: string[];
|
|
67
|
+
}
|
|
68
|
+
/** Runtime context used by trigger evaluation */
|
|
69
|
+
interface TriggerContext {
|
|
70
|
+
/** Current app route/path */
|
|
71
|
+
path?: string;
|
|
72
|
+
/** Named events observed in this session */
|
|
73
|
+
events?: ReadonlySet<string>;
|
|
74
|
+
/** Named milestone flags reached in this session */
|
|
75
|
+
milestones?: ReadonlySet<string>;
|
|
76
|
+
/** Usage counters keyed by event/pattern name */
|
|
77
|
+
usage?: Record<string, number>;
|
|
78
|
+
/** Session elapsed time in milliseconds */
|
|
79
|
+
elapsedMs?: number;
|
|
80
|
+
/** Scroll completion percentage (0-100) */
|
|
81
|
+
scrollPercent?: number;
|
|
82
|
+
/** Optional additional trigger context */
|
|
83
|
+
metadata?: Record<string, unknown>;
|
|
84
|
+
}
|
|
85
|
+
type FeatureTrigger = {
|
|
86
|
+
type: "page";
|
|
87
|
+
match: string | RegExp;
|
|
88
|
+
} | {
|
|
89
|
+
type: "usage";
|
|
90
|
+
event: string;
|
|
91
|
+
minActions?: number;
|
|
92
|
+
} | {
|
|
93
|
+
type: "time";
|
|
94
|
+
minSeconds: number;
|
|
95
|
+
} | {
|
|
96
|
+
type: "milestone";
|
|
97
|
+
event: string;
|
|
98
|
+
} | {
|
|
99
|
+
type: "frustration";
|
|
100
|
+
pattern: string;
|
|
101
|
+
threshold?: number;
|
|
102
|
+
} | {
|
|
103
|
+
type: "scroll";
|
|
104
|
+
minPercent?: number;
|
|
105
|
+
} | {
|
|
106
|
+
type: "custom";
|
|
107
|
+
evaluate: (context: TriggerContext) => boolean;
|
|
108
|
+
};
|
|
16
109
|
/** A single feature entry in the manifest */
|
|
17
110
|
interface FeatureEntry {
|
|
18
111
|
/** Unique identifier for the feature */
|
|
@@ -21,6 +114,20 @@ interface FeatureEntry {
|
|
|
21
114
|
label: string;
|
|
22
115
|
/** Optional longer description (supports markdown in UI components) */
|
|
23
116
|
description?: string;
|
|
117
|
+
/**
|
|
118
|
+
* Semantic version targeting.
|
|
119
|
+
* If provided as an object, requires `appVersion` to be supplied to the provider/helpers.
|
|
120
|
+
* - introduced: earliest app version that includes this feature
|
|
121
|
+
* - showNewUntil: stop showing "new" once appVersion reaches this
|
|
122
|
+
* - deprecatedAt: hide feature for app versions at or above this (optional safety)
|
|
123
|
+
* - showIn: range string, e.g. ">=2.5.0 <3.0.0"
|
|
124
|
+
*/
|
|
125
|
+
version?: string | {
|
|
126
|
+
introduced?: string;
|
|
127
|
+
showNewUntil?: string;
|
|
128
|
+
deprecatedAt?: string;
|
|
129
|
+
showIn?: string;
|
|
130
|
+
};
|
|
24
131
|
/** ISO date when this feature was released */
|
|
25
132
|
releasedAt: string;
|
|
26
133
|
/** ISO date after which the "new" badge should stop showing */
|
|
@@ -29,10 +136,12 @@ interface FeatureEntry {
|
|
|
29
136
|
sidebarKey?: string;
|
|
30
137
|
/** Optional grouping category (e.g. "ai", "billing", "core") */
|
|
31
138
|
category?: string;
|
|
139
|
+
/** Optional product scope (`"*"`, `"askverdict"`, etc.) for multi-product manifests */
|
|
140
|
+
product?: string;
|
|
32
141
|
/** Optional URL to link to (e.g. docs page, changelog entry) */
|
|
33
142
|
url?: string;
|
|
34
|
-
/** Optional
|
|
35
|
-
|
|
143
|
+
/** Optional feature flag key; requires a flag bridge to evaluate */
|
|
144
|
+
flagKey?: string;
|
|
36
145
|
/** Entry type — determines default icon/color in UI components */
|
|
37
146
|
type?: FeatureType;
|
|
38
147
|
/** Priority level — critical entries get special treatment in UI */
|
|
@@ -45,6 +154,16 @@ interface FeatureEntry {
|
|
|
45
154
|
publishAt?: string;
|
|
46
155
|
/** Optional arbitrary metadata */
|
|
47
156
|
meta?: Record<string, unknown>;
|
|
157
|
+
/** A/B variants keyed by variant name (e.g. control, treatment_a) */
|
|
158
|
+
variants?: Record<string, FeatureVariant>;
|
|
159
|
+
/** Percentage split per variant (same order as variants object keys) */
|
|
160
|
+
variantSplit?: number[];
|
|
161
|
+
/** Audience targeting — if set, only matching users see this feature */
|
|
162
|
+
audience?: AudienceRule;
|
|
163
|
+
/** Dependency requirements (progressive disclosure sequencing) */
|
|
164
|
+
dependsOn?: FeatureDependencies;
|
|
165
|
+
/** Contextual trigger rule */
|
|
166
|
+
trigger?: FeatureTrigger;
|
|
48
167
|
}
|
|
49
168
|
/** The full feature manifest — an array of feature entries */
|
|
50
169
|
type FeatureManifest = readonly FeatureEntry[];
|
|
@@ -81,6 +200,112 @@ interface AnalyticsCallbacks {
|
|
|
81
200
|
onAllDismissed?: () => void;
|
|
82
201
|
}
|
|
83
202
|
|
|
203
|
+
interface ThrottleOptions {
|
|
204
|
+
maxSimultaneousBadges?: number;
|
|
205
|
+
maxSimultaneousSpotlights?: number;
|
|
206
|
+
maxToastsPerSession?: number;
|
|
207
|
+
minTimeBetweenModals?: number;
|
|
208
|
+
minTimeBetweenTours?: number;
|
|
209
|
+
sessionCooldown?: number;
|
|
210
|
+
respectDoNotDisturb?: boolean;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
type AdoptionEventType = "feature_seen" | "feature_clicked" | "feature_dismissed" | "tour_started" | "tour_completed" | "tour_skipped" | "checklist_task_completed" | "checklist_completed" | "survey_submitted" | "feedback_submitted" | "announcement_shown" | "cta_clicked";
|
|
214
|
+
interface AdoptionEvent {
|
|
215
|
+
type: AdoptionEventType;
|
|
216
|
+
featureId?: string;
|
|
217
|
+
tourId?: string;
|
|
218
|
+
variant?: string;
|
|
219
|
+
timestamp: string;
|
|
220
|
+
sessionId?: string;
|
|
221
|
+
userId?: string;
|
|
222
|
+
metadata?: Record<string, unknown>;
|
|
223
|
+
}
|
|
224
|
+
type AdoptionEventInput = Omit<AdoptionEvent, "timestamp"> & {
|
|
225
|
+
timestamp?: string;
|
|
226
|
+
};
|
|
227
|
+
interface AnalyticsAdapter {
|
|
228
|
+
track: (event: AdoptionEvent) => void | Promise<void>;
|
|
229
|
+
trackBatch?: (events: AdoptionEvent[]) => void | Promise<void>;
|
|
230
|
+
}
|
|
231
|
+
interface AnalyticsCollectorOptions {
|
|
232
|
+
adapter: AnalyticsAdapter;
|
|
233
|
+
batchSize?: number;
|
|
234
|
+
flushInterval?: number;
|
|
235
|
+
sampleRate?: number;
|
|
236
|
+
enabled?: boolean;
|
|
237
|
+
sessionId?: string;
|
|
238
|
+
userId?: string;
|
|
239
|
+
now?: () => Date;
|
|
240
|
+
random?: () => number;
|
|
241
|
+
}
|
|
242
|
+
declare class AnalyticsCollector {
|
|
243
|
+
private adapter;
|
|
244
|
+
private queue;
|
|
245
|
+
private batchSize;
|
|
246
|
+
private flushInterval;
|
|
247
|
+
private sampleRate;
|
|
248
|
+
private enabled;
|
|
249
|
+
private now;
|
|
250
|
+
private random;
|
|
251
|
+
private sessionId?;
|
|
252
|
+
private userId?;
|
|
253
|
+
private timer;
|
|
254
|
+
private flushing;
|
|
255
|
+
constructor(options: AnalyticsCollectorOptions);
|
|
256
|
+
setEnabled(enabled: boolean): void;
|
|
257
|
+
setContext(context: {
|
|
258
|
+
sessionId?: string;
|
|
259
|
+
userId?: string;
|
|
260
|
+
}): void;
|
|
261
|
+
getQueueSize(): number;
|
|
262
|
+
track(event: AdoptionEventInput): void;
|
|
263
|
+
flush(): Promise<void>;
|
|
264
|
+
destroy(): Promise<void>;
|
|
265
|
+
private startTimer;
|
|
266
|
+
}
|
|
267
|
+
interface FeatureEngagementMetrics {
|
|
268
|
+
seen: number;
|
|
269
|
+
clicked: number;
|
|
270
|
+
dismissed: number;
|
|
271
|
+
}
|
|
272
|
+
interface AdoptionMetrics {
|
|
273
|
+
getAdoptionRate: (featureId: string) => number;
|
|
274
|
+
getTourCompletionRate: (tourId: string) => number;
|
|
275
|
+
getChecklistCompletionRate: (checklistId: string) => number;
|
|
276
|
+
getFeatureEngagement: (featureId: string) => FeatureEngagementMetrics;
|
|
277
|
+
getVariantPerformance: (featureId: string) => Record<string, number>;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
interface FeatureDropTranslations {
|
|
281
|
+
newBadge: string;
|
|
282
|
+
whatsNewTitle: string;
|
|
283
|
+
markAllRead: string;
|
|
284
|
+
allCaughtUp: string;
|
|
285
|
+
close: string;
|
|
286
|
+
changelogTitle: string;
|
|
287
|
+
searchPlaceholder: string;
|
|
288
|
+
allCategories: string;
|
|
289
|
+
noUpdatesYet: string;
|
|
290
|
+
loadMore: string;
|
|
291
|
+
share: string;
|
|
292
|
+
skipToEntries: string;
|
|
293
|
+
newFeatureCount: (count: number) => string;
|
|
294
|
+
stepOf: (current: number, total: number) => string;
|
|
295
|
+
back: string;
|
|
296
|
+
next: string;
|
|
297
|
+
skip: string;
|
|
298
|
+
finish: string;
|
|
299
|
+
gotIt: string;
|
|
300
|
+
announcement: string;
|
|
301
|
+
feedbackTitle: string;
|
|
302
|
+
feedbackTrigger: string;
|
|
303
|
+
feedbackSubmitted: string;
|
|
304
|
+
submit: string;
|
|
305
|
+
cancel: string;
|
|
306
|
+
askLater: string;
|
|
307
|
+
}
|
|
308
|
+
|
|
84
309
|
interface FeatureDropProviderProps {
|
|
85
310
|
/** The feature manifest — typically a frozen array of FeatureEntry objects */
|
|
86
311
|
manifest: FeatureManifest;
|
|
@@ -88,6 +313,33 @@ interface FeatureDropProviderProps {
|
|
|
88
313
|
storage: StorageAdapter;
|
|
89
314
|
/** Optional analytics callbacks — pipe to your analytics provider */
|
|
90
315
|
analytics?: AnalyticsCallbacks;
|
|
316
|
+
/** Optional error callback for monitoring caught component errors */
|
|
317
|
+
onError?: (error: unknown, context?: {
|
|
318
|
+
component?: string;
|
|
319
|
+
componentStack?: string;
|
|
320
|
+
}) => void;
|
|
321
|
+
/** User context for audience targeting (plan, role, region, traits) */
|
|
322
|
+
userContext?: UserContext;
|
|
323
|
+
/** Custom audience matcher — overrides default AND/OR matching logic */
|
|
324
|
+
matchAudience?: AudienceMatchFn;
|
|
325
|
+
/** Current app version (semver) for version-pinned features */
|
|
326
|
+
appVersion?: string;
|
|
327
|
+
/** Current product scope for multi-product manifests */
|
|
328
|
+
product?: string;
|
|
329
|
+
/** Announcement throttling and session cooldown controls */
|
|
330
|
+
throttle?: ThrottleOptions;
|
|
331
|
+
/** Stable identifier for A/B variant assignment (e.g. userId) */
|
|
332
|
+
variantKey?: string;
|
|
333
|
+
/** Optional adoption analytics collector */
|
|
334
|
+
collector?: AnalyticsCollector;
|
|
335
|
+
/** Feature flag bridge for evaluating `feature.flagKey` visibility */
|
|
336
|
+
flagBridge?: FeatureFlagBridge;
|
|
337
|
+
/** Locale code for built-in component translations (e.g. "en", "fr", "es") */
|
|
338
|
+
locale?: string;
|
|
339
|
+
/** Animation preset for built-in component transitions */
|
|
340
|
+
animation?: FeatureDropAnimationPreset;
|
|
341
|
+
/** Custom translation overrides for built-in component strings */
|
|
342
|
+
translations?: Partial<FeatureDropTranslations>;
|
|
91
343
|
children: ReactNode;
|
|
92
344
|
}
|
|
93
345
|
/**
|
|
@@ -96,13 +348,83 @@ interface FeatureDropProviderProps {
|
|
|
96
348
|
* Wrap your app (or a subtree) with this provider to enable
|
|
97
349
|
* `useFeatureDrop`, `useNewFeature`, `useNewCount`, and other hooks.
|
|
98
350
|
*/
|
|
99
|
-
declare function FeatureDropProvider({ manifest, storage, analytics, children, }: FeatureDropProviderProps): react_jsx_runtime.JSX.Element;
|
|
351
|
+
declare function FeatureDropProvider({ manifest, storage, analytics, onError, userContext, matchAudience: matchAudienceFn, appVersion, product, throttle, variantKey, collector, flagBridge, locale, animation, translations: translationOverrides, children, }: FeatureDropProviderProps): react_jsx_runtime.JSX.Element;
|
|
352
|
+
|
|
353
|
+
interface FeatureDropTheme {
|
|
354
|
+
colors: {
|
|
355
|
+
primary: string;
|
|
356
|
+
background: string;
|
|
357
|
+
text: string;
|
|
358
|
+
textMuted: string;
|
|
359
|
+
border: string;
|
|
360
|
+
success: string;
|
|
361
|
+
warning: string;
|
|
362
|
+
error: string;
|
|
363
|
+
};
|
|
364
|
+
fonts: {
|
|
365
|
+
family: string;
|
|
366
|
+
sizeBase: string;
|
|
367
|
+
sizeSm: string;
|
|
368
|
+
sizeLg: string;
|
|
369
|
+
};
|
|
370
|
+
spacing: {
|
|
371
|
+
xs: string;
|
|
372
|
+
sm: string;
|
|
373
|
+
md: string;
|
|
374
|
+
lg: string;
|
|
375
|
+
xl: string;
|
|
376
|
+
};
|
|
377
|
+
radii: {
|
|
378
|
+
sm: string;
|
|
379
|
+
md: string;
|
|
380
|
+
lg: string;
|
|
381
|
+
full: string;
|
|
382
|
+
};
|
|
383
|
+
shadows: {
|
|
384
|
+
sm: string;
|
|
385
|
+
md: string;
|
|
386
|
+
lg: string;
|
|
387
|
+
};
|
|
388
|
+
zIndex: {
|
|
389
|
+
base: number;
|
|
390
|
+
tooltip: number;
|
|
391
|
+
modal: number;
|
|
392
|
+
overlay: number;
|
|
393
|
+
};
|
|
394
|
+
}
|
|
395
|
+
type FeatureDropThemePreset = "light" | "dark" | "auto" | "minimal" | "vibrant";
|
|
396
|
+
type FeatureDropThemeOverrides = {
|
|
397
|
+
[K in keyof FeatureDropTheme]?: Partial<FeatureDropTheme[K]>;
|
|
398
|
+
};
|
|
399
|
+
type FeatureDropThemeInput = FeatureDropThemePreset | FeatureDropThemeOverrides | FeatureDropTheme;
|
|
400
|
+
|
|
401
|
+
interface ThemeProviderProps {
|
|
402
|
+
/** Theme preset ("light" | "dark" | "auto" | "minimal" | "vibrant") or custom theme overrides */
|
|
403
|
+
theme?: FeatureDropThemeInput;
|
|
404
|
+
/** Optional CSS class for the wrapper element */
|
|
405
|
+
className?: string;
|
|
406
|
+
/** Optional inline style merged after theme CSS variables */
|
|
407
|
+
style?: CSSProperties;
|
|
408
|
+
children: ReactNode;
|
|
409
|
+
}
|
|
410
|
+
/**
|
|
411
|
+
* Applies FeatureDrop theme tokens as CSS custom properties to a subtree.
|
|
412
|
+
*
|
|
413
|
+
* All featuredrop components inside this provider inherit the resolved theme.
|
|
414
|
+
*/
|
|
415
|
+
declare function ThemeProvider({ theme, className, style, children, }: ThemeProviderProps): react_jsx_runtime.JSX.Element;
|
|
100
416
|
|
|
101
417
|
interface FeatureDropContextValue {
|
|
418
|
+
/** Full manifest provided to the provider */
|
|
419
|
+
manifest: FeatureEntry[] | readonly FeatureEntry[];
|
|
102
420
|
/** All currently "new" features */
|
|
103
421
|
newFeatures: FeatureEntry[];
|
|
422
|
+
/** New features currently queued by throttling rules */
|
|
423
|
+
queuedFeatures: FeatureEntry[];
|
|
104
424
|
/** Count of new features */
|
|
105
425
|
newCount: number;
|
|
426
|
+
/** Count before throttling (all pending new features) */
|
|
427
|
+
totalNewCount: number;
|
|
106
428
|
/** All new features sorted by priority then release date */
|
|
107
429
|
newFeaturesSorted: FeatureEntry[];
|
|
108
430
|
/** Check if a sidebar key has any new features */
|
|
@@ -113,6 +435,54 @@ interface FeatureDropContextValue {
|
|
|
113
435
|
dismissAll: () => Promise<void>;
|
|
114
436
|
/** Get the feature entry for a sidebar key (if it's new) */
|
|
115
437
|
getFeature: (sidebarKey: string) => FeatureEntry | undefined;
|
|
438
|
+
/** Whether quiet mode (Do Not Disturb) is enabled */
|
|
439
|
+
quietMode: boolean;
|
|
440
|
+
/** Enable/disable quiet mode */
|
|
441
|
+
setQuietMode: (enabled: boolean) => void;
|
|
442
|
+
/** Mark a feature as seen for dependency-chain resolution */
|
|
443
|
+
markFeatureSeen: (featureId: string) => void;
|
|
444
|
+
/** Mark a feature as clicked for dependency-chain resolution */
|
|
445
|
+
markFeatureClicked: (featureId: string) => void;
|
|
446
|
+
/** Remaining toasts allowed in this session under throttle rules */
|
|
447
|
+
getRemainingToastSlots: () => number;
|
|
448
|
+
/** Mark toasts as shown in this session */
|
|
449
|
+
markToastsShown: (featureIds: string[]) => void;
|
|
450
|
+
/** Whether a modal can open right now under throttle rules */
|
|
451
|
+
canShowModal: (priority?: FeaturePriority) => boolean;
|
|
452
|
+
/** Record a modal display timestamp */
|
|
453
|
+
markModalShown: () => void;
|
|
454
|
+
/** Whether a tour can start right now under throttle rules */
|
|
455
|
+
canShowTour: () => boolean;
|
|
456
|
+
/** Record a tour start timestamp */
|
|
457
|
+
markTourShown: () => void;
|
|
458
|
+
/** Acquire/release spotlight slots under maxSimultaneousSpotlights */
|
|
459
|
+
acquireSpotlightSlot: (id: string, priority?: FeaturePriority) => boolean;
|
|
460
|
+
releaseSpotlightSlot: (id: string) => void;
|
|
461
|
+
/** Number of currently active spotlight slots */
|
|
462
|
+
activeSpotlightCount: number;
|
|
463
|
+
/** Emit an adoption analytics event (collector-backed when configured) */
|
|
464
|
+
trackAdoptionEvent: (event: AdoptionEventInput) => void;
|
|
465
|
+
/** Report a component/runtime error to provider-level monitoring hooks */
|
|
466
|
+
reportError: (error: unknown, context?: {
|
|
467
|
+
component?: string;
|
|
468
|
+
componentStack?: string;
|
|
469
|
+
}) => void;
|
|
470
|
+
/** Active locale code used by built-in UI strings */
|
|
471
|
+
locale: string;
|
|
472
|
+
/** Text direction derived from locale */
|
|
473
|
+
direction: "ltr" | "rtl";
|
|
474
|
+
/** Active motion preset for built-in component transitions */
|
|
475
|
+
animation: FeatureDropAnimationPreset;
|
|
476
|
+
/** Resolved translation strings for built-in React components */
|
|
477
|
+
translations: FeatureDropTranslations;
|
|
478
|
+
/** Track a named usage event for trigger rules */
|
|
479
|
+
trackUsageEvent: (event: string, delta?: number) => void;
|
|
480
|
+
/** Track a named trigger event for trigger rules */
|
|
481
|
+
trackTriggerEvent: (event: string) => void;
|
|
482
|
+
/** Mark a milestone for trigger rules */
|
|
483
|
+
trackMilestone: (event: string) => void;
|
|
484
|
+
/** Manually override current path for page trigger rules */
|
|
485
|
+
setTriggerPath: (path: string) => void;
|
|
116
486
|
}
|
|
117
487
|
declare const FeatureDropContext: react.Context<FeatureDropContextValue | null>;
|
|
118
488
|
|
|
@@ -181,6 +551,189 @@ interface UseTabNotificationOptions {
|
|
|
181
551
|
*/
|
|
182
552
|
declare function useTabNotification(options?: UseTabNotificationOptions): void;
|
|
183
553
|
|
|
554
|
+
declare function useAdoptionAnalytics(events: AdoptionEvent[]): AdoptionMetrics;
|
|
555
|
+
|
|
556
|
+
interface TourStep {
|
|
557
|
+
id: string;
|
|
558
|
+
target: string | RefObject<HTMLElement | null>;
|
|
559
|
+
title: string;
|
|
560
|
+
content: string | ReactNode;
|
|
561
|
+
placement?: "top" | "bottom" | "left" | "right" | "auto";
|
|
562
|
+
action?: "click" | "input" | "custom";
|
|
563
|
+
advanceOn?: {
|
|
564
|
+
selector: string;
|
|
565
|
+
event: string;
|
|
566
|
+
};
|
|
567
|
+
highlightTarget?: boolean;
|
|
568
|
+
beforeStep?: () => Promise<void>;
|
|
569
|
+
afterStep?: () => Promise<void>;
|
|
570
|
+
skipable?: boolean;
|
|
571
|
+
}
|
|
572
|
+
interface TourRenderProps {
|
|
573
|
+
isActive: boolean;
|
|
574
|
+
step: TourStep | null;
|
|
575
|
+
stepIndex: number;
|
|
576
|
+
totalSteps: number;
|
|
577
|
+
startTour: () => void;
|
|
578
|
+
nextStep: () => void;
|
|
579
|
+
prevStep: () => void;
|
|
580
|
+
skipTour: () => void;
|
|
581
|
+
closeTour: () => void;
|
|
582
|
+
}
|
|
583
|
+
interface TourProps {
|
|
584
|
+
id: string;
|
|
585
|
+
steps: TourStep[];
|
|
586
|
+
onComplete?: () => void;
|
|
587
|
+
onSkip?: (stepId: string) => void;
|
|
588
|
+
onTourStarted?: () => void;
|
|
589
|
+
onTourCompleted?: () => void;
|
|
590
|
+
onTourSkipped?: (stepId: string) => void;
|
|
591
|
+
onStepViewed?: (step: TourStep, index: number) => void;
|
|
592
|
+
overlay?: boolean;
|
|
593
|
+
showProgress?: boolean;
|
|
594
|
+
keyboard?: boolean;
|
|
595
|
+
persistence?: boolean;
|
|
596
|
+
children?: (props: TourRenderProps) => ReactNode;
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
interface TourSnapshot {
|
|
600
|
+
isActive: boolean;
|
|
601
|
+
currentStepIndex: number;
|
|
602
|
+
currentStep: TourStep | null;
|
|
603
|
+
totalSteps: number;
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
interface UseTourResult {
|
|
607
|
+
startTour: () => void;
|
|
608
|
+
nextStep: () => void;
|
|
609
|
+
prevStep: () => void;
|
|
610
|
+
skipTour: () => void;
|
|
611
|
+
closeTour: () => void;
|
|
612
|
+
currentStep: TourSnapshot["currentStep"];
|
|
613
|
+
currentStepIndex: number;
|
|
614
|
+
totalSteps: number;
|
|
615
|
+
isActive: boolean;
|
|
616
|
+
}
|
|
617
|
+
declare function useTour(id: string): UseTourResult;
|
|
618
|
+
|
|
619
|
+
interface TourSequenceItem {
|
|
620
|
+
featureId: string;
|
|
621
|
+
tourId: string;
|
|
622
|
+
}
|
|
623
|
+
interface UseTourSequencerResult {
|
|
624
|
+
nextTourId: string | null;
|
|
625
|
+
nextFeatureId: string | null;
|
|
626
|
+
remainingTours: number;
|
|
627
|
+
startNextTour: () => boolean;
|
|
628
|
+
}
|
|
629
|
+
declare function useTourSequencer(sequence: TourSequenceItem[]): UseTourSequencerResult;
|
|
630
|
+
|
|
631
|
+
interface UseChecklistResult {
|
|
632
|
+
completeTask: (taskId: string) => void;
|
|
633
|
+
resetChecklist: () => void;
|
|
634
|
+
dismissChecklist: () => void;
|
|
635
|
+
toggleCollapsed: () => void;
|
|
636
|
+
isComplete: boolean;
|
|
637
|
+
progress: {
|
|
638
|
+
completed: number;
|
|
639
|
+
total: number;
|
|
640
|
+
percent: number;
|
|
641
|
+
};
|
|
642
|
+
tasks: Array<{
|
|
643
|
+
id: string;
|
|
644
|
+
completed: boolean;
|
|
645
|
+
}>;
|
|
646
|
+
dismissed: boolean;
|
|
647
|
+
collapsed: boolean;
|
|
648
|
+
}
|
|
649
|
+
declare function useChecklist(id: string): UseChecklistResult;
|
|
650
|
+
|
|
651
|
+
type SurveyType = "nps" | "csat" | "ces" | "custom";
|
|
652
|
+
type SurveyQuestionType = "single-choice" | "multi-choice" | "text";
|
|
653
|
+
interface SurveyQuestion {
|
|
654
|
+
id: string;
|
|
655
|
+
type: SurveyQuestionType;
|
|
656
|
+
prompt: string;
|
|
657
|
+
options?: string[];
|
|
658
|
+
required?: boolean;
|
|
659
|
+
}
|
|
660
|
+
interface SurveyTriggerRules {
|
|
661
|
+
signupAt?: string | Date;
|
|
662
|
+
minDaysSinceSignup?: number;
|
|
663
|
+
featureUsageIds?: string[];
|
|
664
|
+
pageMatch?: string | RegExp | ((path: string) => boolean);
|
|
665
|
+
sampleRate?: number;
|
|
666
|
+
maxFrequencyDays?: number;
|
|
667
|
+
askLaterCooldownDays?: number;
|
|
668
|
+
}
|
|
669
|
+
interface SurveyPayload {
|
|
670
|
+
id: string;
|
|
671
|
+
type: SurveyType;
|
|
672
|
+
prompt?: string;
|
|
673
|
+
score?: number;
|
|
674
|
+
responses?: Record<string, unknown>;
|
|
675
|
+
feedback?: string;
|
|
676
|
+
timestamp: string;
|
|
677
|
+
url: string;
|
|
678
|
+
featureId?: string;
|
|
679
|
+
metadata?: Record<string, unknown>;
|
|
680
|
+
}
|
|
681
|
+
interface SurveyRenderProps {
|
|
682
|
+
isOpen: boolean;
|
|
683
|
+
isSubmitting: boolean;
|
|
684
|
+
submitted: boolean;
|
|
685
|
+
canShow: boolean;
|
|
686
|
+
error: string | null;
|
|
687
|
+
type: SurveyType;
|
|
688
|
+
score: number | null;
|
|
689
|
+
feedback: string;
|
|
690
|
+
responses: Record<string, unknown>;
|
|
691
|
+
show: (options?: {
|
|
692
|
+
force?: boolean;
|
|
693
|
+
}) => boolean;
|
|
694
|
+
hide: () => void;
|
|
695
|
+
askLater: () => void;
|
|
696
|
+
setScore: (value: number | null) => void;
|
|
697
|
+
setFeedback: (value: string) => void;
|
|
698
|
+
setResponse: (questionId: string, value: unknown) => void;
|
|
699
|
+
submit: () => Promise<boolean>;
|
|
700
|
+
}
|
|
701
|
+
interface SurveyProps {
|
|
702
|
+
id: string;
|
|
703
|
+
type: SurveyType;
|
|
704
|
+
prompt?: string;
|
|
705
|
+
featureId?: string;
|
|
706
|
+
questions?: SurveyQuestion[];
|
|
707
|
+
trigger?: "auto" | "manual";
|
|
708
|
+
triggerRules?: SurveyTriggerRules;
|
|
709
|
+
defaultOpen?: boolean;
|
|
710
|
+
showAskLater?: boolean;
|
|
711
|
+
submitLabel?: string;
|
|
712
|
+
askLaterLabel?: string;
|
|
713
|
+
closeLabel?: string;
|
|
714
|
+
title?: string;
|
|
715
|
+
metadata?: Record<string, unknown>;
|
|
716
|
+
onSubmit: (payload: SurveyPayload) => Promise<void> | void;
|
|
717
|
+
onAskLater?: () => void;
|
|
718
|
+
onDismiss?: () => void;
|
|
719
|
+
className?: string;
|
|
720
|
+
style?: CSSProperties;
|
|
721
|
+
children?: (props: SurveyRenderProps) => ReactNode;
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
interface UseSurveyResult {
|
|
725
|
+
show: (options?: {
|
|
726
|
+
force?: boolean;
|
|
727
|
+
}) => boolean;
|
|
728
|
+
hide: () => void;
|
|
729
|
+
askLater: () => void;
|
|
730
|
+
isOpen: boolean;
|
|
731
|
+
submitted: boolean;
|
|
732
|
+
canShow: boolean;
|
|
733
|
+
type: SurveyType;
|
|
734
|
+
}
|
|
735
|
+
declare function useSurvey(id: string): UseSurveyResult;
|
|
736
|
+
|
|
184
737
|
interface NewBadgeRenderProps {
|
|
185
738
|
/** Whether the feature is currently new */
|
|
186
739
|
isNew: boolean;
|
|
@@ -205,26 +758,17 @@ interface NewBadgeProps {
|
|
|
205
758
|
/** Render prop for full customization */
|
|
206
759
|
children?: (props: NewBadgeRenderProps) => ReactNode;
|
|
207
760
|
}
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
*
|
|
211
|
-
* Styled via CSS custom properties — zero CSS framework dependency:
|
|
212
|
-
* - `--featuredrop-color` — text/dot color
|
|
213
|
-
* - `--featuredrop-bg` — pill background
|
|
214
|
-
* - `--featuredrop-font-size` — font size
|
|
215
|
-
* - `--featuredrop-dot-size` — dot diameter
|
|
216
|
-
* - `--featuredrop-glow` — dot glow color
|
|
217
|
-
* - `--featuredrop-count-size` — count badge size
|
|
218
|
-
* - `--featuredrop-count-color` — count text color
|
|
219
|
-
* - `--featuredrop-count-bg` — count background
|
|
220
|
-
*
|
|
221
|
-
* Use `data-featuredrop` attribute for CSS selector styling.
|
|
222
|
-
*/
|
|
223
|
-
declare function NewBadge({ variant, show, count, label, onDismiss, dismissOnClick, className, style, children, }: NewBadgeProps): react_jsx_runtime.JSX.Element | null;
|
|
761
|
+
|
|
762
|
+
type ReactionCounts = Record<string, number>;
|
|
224
763
|
|
|
225
764
|
interface ChangelogEntryRenderProps {
|
|
226
765
|
feature: FeatureEntry;
|
|
227
766
|
dismiss: () => void;
|
|
767
|
+
onFeatureClick?: () => void;
|
|
768
|
+
reactions?: ReactionCounts;
|
|
769
|
+
userReaction?: string | null;
|
|
770
|
+
canReact?: boolean;
|
|
771
|
+
react?: (reaction: string) => void;
|
|
228
772
|
}
|
|
229
773
|
interface ChangelogWidgetRenderProps {
|
|
230
774
|
/** Whether the widget is currently open */
|
|
@@ -261,12 +805,16 @@ interface ChangelogWidgetProps {
|
|
|
261
805
|
emptyLabel?: string;
|
|
262
806
|
/** Max height for the feed area. Default: "400px" */
|
|
263
807
|
maxHeight?: string;
|
|
808
|
+
/** Date display mode for entry metadata. Default: "absolute" */
|
|
809
|
+
dateFormat?: "absolute" | "relative";
|
|
264
810
|
/** Analytics callbacks */
|
|
265
811
|
analytics?: AnalyticsCallbacks;
|
|
266
812
|
/** Additional CSS class for the container */
|
|
267
813
|
className?: string;
|
|
268
814
|
/** Additional inline styles for the container */
|
|
269
815
|
style?: CSSProperties;
|
|
816
|
+
/** Optional component-scoped theme preset or overrides */
|
|
817
|
+
theme?: FeatureDropThemeInput;
|
|
270
818
|
/** Render prop for full customization — receives widget state */
|
|
271
819
|
children?: (props: ChangelogWidgetRenderProps) => ReactNode;
|
|
272
820
|
/** Custom render for each entry — receives feature + dismiss callback */
|
|
@@ -276,31 +824,13 @@ interface ChangelogWidgetProps {
|
|
|
276
824
|
count: number;
|
|
277
825
|
onClick: () => void;
|
|
278
826
|
}) => ReactNode;
|
|
827
|
+
/** Show reaction controls on each entry. Default: false */
|
|
828
|
+
showReactions?: boolean;
|
|
829
|
+
/** Reaction options. Default: 👍 ❤️ 🎉 👀 👎 */
|
|
830
|
+
reactions?: string[];
|
|
831
|
+
/** Callback fired when a reaction is persisted */
|
|
832
|
+
onReaction?: (feature: FeatureEntry, reaction: string, counts: ReactionCounts) => void;
|
|
279
833
|
}
|
|
280
|
-
/**
|
|
281
|
-
* Changelog widget — the #1 feature for feature discovery tools.
|
|
282
|
-
*
|
|
283
|
-
* Renders a trigger button with an unread count badge and a
|
|
284
|
-
* slide-out panel, modal, or popover with the changelog feed.
|
|
285
|
-
*
|
|
286
|
-
* Styled via CSS custom properties — zero framework dependency.
|
|
287
|
-
* Use `children` render prop for full headless control.
|
|
288
|
-
*
|
|
289
|
-
* @example
|
|
290
|
-
* ```tsx
|
|
291
|
-
* <ChangelogWidget variant="panel" />
|
|
292
|
-
* ```
|
|
293
|
-
*
|
|
294
|
-
* @example Headless mode
|
|
295
|
-
* ```tsx
|
|
296
|
-
* <ChangelogWidget>
|
|
297
|
-
* {({ isOpen, toggle, features, count }) => (
|
|
298
|
-
* <MyCustomUI ... />
|
|
299
|
-
* )}
|
|
300
|
-
* </ChangelogWidget>
|
|
301
|
-
* ```
|
|
302
|
-
*/
|
|
303
|
-
declare function ChangelogWidget({ variant, title, triggerLabel, showCount, markAllLabel, showMarkAll, emptyLabel, maxHeight, analytics, className, style, children, renderEntry, renderTrigger, }: ChangelogWidgetProps): react_jsx_runtime.JSX.Element;
|
|
304
834
|
|
|
305
835
|
interface SpotlightRenderProps {
|
|
306
836
|
/** The feature being spotlighted */
|
|
@@ -340,25 +870,6 @@ interface SpotlightProps {
|
|
|
340
870
|
/** Render prop for full customization */
|
|
341
871
|
children?: (props: SpotlightRenderProps) => ReactNode;
|
|
342
872
|
}
|
|
343
|
-
/**
|
|
344
|
-
* Pulsing beacon that attaches to any DOM element to highlight a new feature.
|
|
345
|
-
*
|
|
346
|
-
* Clicking the beacon reveals a tooltip with feature info.
|
|
347
|
-
* After dismissal, the beacon disappears permanently for this user.
|
|
348
|
-
*
|
|
349
|
-
* @example
|
|
350
|
-
* ```tsx
|
|
351
|
-
* const ref = useRef<HTMLButtonElement>(null);
|
|
352
|
-
* <button ref={ref}>Analytics</button>
|
|
353
|
-
* <Spotlight featureId="analytics-v2" targetRef={ref} />
|
|
354
|
-
* ```
|
|
355
|
-
*
|
|
356
|
-
* @example With CSS selector
|
|
357
|
-
* ```tsx
|
|
358
|
-
* <Spotlight featureId="analytics-v2" targetSelector="#analytics-btn" />
|
|
359
|
-
* ```
|
|
360
|
-
*/
|
|
361
|
-
declare function Spotlight({ featureId, targetRef, targetSelector, placement, beaconSize, autoDismiss, autoDismissDelay, analytics, className, tooltipContent, children, }: SpotlightProps): react_jsx_runtime.JSX.Element | null;
|
|
362
873
|
|
|
363
874
|
type BannerVariant = "info" | "success" | "warning" | "announcement";
|
|
364
875
|
interface BannerRenderProps {
|
|
@@ -389,28 +900,6 @@ interface BannerProps {
|
|
|
389
900
|
/** Render prop for full customization */
|
|
390
901
|
children?: (props: BannerRenderProps) => ReactNode;
|
|
391
902
|
}
|
|
392
|
-
/**
|
|
393
|
-
* Announcement banner for major feature launches or important notices.
|
|
394
|
-
*
|
|
395
|
-
* Shows at the top of the page (sticky/fixed) or inline in content.
|
|
396
|
-
* Auto-expires using the same `showNewUntil` logic as badges.
|
|
397
|
-
* Styled via CSS custom properties for each variant.
|
|
398
|
-
*
|
|
399
|
-
* @example
|
|
400
|
-
* ```tsx
|
|
401
|
-
* <Banner featureId="v2-launch" variant="announcement" />
|
|
402
|
-
* ```
|
|
403
|
-
*
|
|
404
|
-
* @example Headless
|
|
405
|
-
* ```tsx
|
|
406
|
-
* <Banner featureId="v2-launch">
|
|
407
|
-
* {({ feature, dismiss }) => (
|
|
408
|
-
* <div>New: {feature?.label} <button onClick={dismiss}>x</button></div>
|
|
409
|
-
* )}
|
|
410
|
-
* </Banner>
|
|
411
|
-
* ```
|
|
412
|
-
*/
|
|
413
|
-
declare function Banner({ featureId, variant, dismissible, position, analytics, className, style, children, }: BannerProps): react_jsx_runtime.JSX.Element | null;
|
|
414
903
|
|
|
415
904
|
interface ToastRenderProps {
|
|
416
905
|
/** Features currently showing as toasts */
|
|
@@ -443,31 +932,282 @@ interface ToastProps {
|
|
|
443
932
|
dismiss: () => void;
|
|
444
933
|
}) => ReactNode;
|
|
445
934
|
}
|
|
446
|
-
/**
|
|
447
|
-
* Toast notification component for feature announcements.
|
|
448
|
-
*
|
|
449
|
-
* Shows brief popups for new features. Auto-dismisses after a timeout.
|
|
450
|
-
* Stacks multiple toasts with configurable max visible count.
|
|
451
|
-
*
|
|
452
|
-
* @example
|
|
453
|
-
* ```tsx
|
|
454
|
-
* <Toast position="bottom-right" maxVisible={3} />
|
|
455
|
-
* ```
|
|
456
|
-
*
|
|
457
|
-
* @example Specific features
|
|
458
|
-
* ```tsx
|
|
459
|
-
* <Toast featureIds={["ai-journal", "analytics-v2"]} />
|
|
460
|
-
* ```
|
|
461
|
-
*
|
|
462
|
-
* @example Headless
|
|
463
|
-
* ```tsx
|
|
464
|
-
* <Toast>
|
|
465
|
-
* {({ toasts, dismiss }) => toasts.map(t => (
|
|
466
|
-
* <div key={t.id}>{t.label} <button onClick={() => dismiss(t.id)}>x</button></div>
|
|
467
|
-
* ))}
|
|
468
|
-
* </Toast>
|
|
469
|
-
* ```
|
|
470
|
-
*/
|
|
471
|
-
declare function Toast({ featureIds, maxVisible, autoDismissMs, position, analytics, className, style, children, renderToast, }: ToastProps): react_jsx_runtime.JSX.Element | null;
|
|
472
935
|
|
|
473
|
-
|
|
936
|
+
type PaginationMode = "infinite-scroll" | "load-more" | "numbered";
|
|
937
|
+
interface ChangelogPageProps {
|
|
938
|
+
pageSize?: number;
|
|
939
|
+
pagination?: PaginationMode;
|
|
940
|
+
showFilters?: boolean;
|
|
941
|
+
showSearch?: boolean;
|
|
942
|
+
categories?: string[];
|
|
943
|
+
emptyState?: ReactNode;
|
|
944
|
+
renderEntry?: (entry: FeatureEntry, index: number) => ReactNode;
|
|
945
|
+
formatDate?: (date: string) => string;
|
|
946
|
+
dateFormat?: "absolute" | "relative";
|
|
947
|
+
basePath?: string;
|
|
948
|
+
manifest?: FeatureManifest;
|
|
949
|
+
className?: string;
|
|
950
|
+
style?: CSSProperties;
|
|
951
|
+
theme?: FeatureDropThemeInput;
|
|
952
|
+
showReactions?: boolean;
|
|
953
|
+
reactions?: string[];
|
|
954
|
+
onReaction?: (entry: FeatureEntry, reaction: string, counts: ReactionCounts) => void;
|
|
955
|
+
}
|
|
956
|
+
|
|
957
|
+
interface ChecklistTask {
|
|
958
|
+
id: string;
|
|
959
|
+
title: string;
|
|
960
|
+
description?: string;
|
|
961
|
+
completed?: boolean;
|
|
962
|
+
completionEvent?: string;
|
|
963
|
+
action?: {
|
|
964
|
+
type: "tour" | "link" | "callback";
|
|
965
|
+
target: string;
|
|
966
|
+
};
|
|
967
|
+
icon?: ReactNode;
|
|
968
|
+
estimatedTime?: string;
|
|
969
|
+
}
|
|
970
|
+
interface ChecklistRenderProps {
|
|
971
|
+
tasks: ChecklistTask[];
|
|
972
|
+
completedIds: Set<string>;
|
|
973
|
+
completeTask: (taskId: string) => void;
|
|
974
|
+
resetChecklist: () => void;
|
|
975
|
+
dismissChecklist: () => void;
|
|
976
|
+
isComplete: boolean;
|
|
977
|
+
progress: {
|
|
978
|
+
completed: number;
|
|
979
|
+
total: number;
|
|
980
|
+
percent: number;
|
|
981
|
+
};
|
|
982
|
+
collapsed: boolean;
|
|
983
|
+
toggleCollapsed: () => void;
|
|
984
|
+
}
|
|
985
|
+
interface ChecklistProps {
|
|
986
|
+
id: string;
|
|
987
|
+
tasks: ChecklistTask[];
|
|
988
|
+
position?: "bottom-right" | "bottom-left" | "top-right" | "top-left" | "inline";
|
|
989
|
+
collapsible?: boolean;
|
|
990
|
+
showProgress?: boolean;
|
|
991
|
+
onComplete?: () => void;
|
|
992
|
+
dismissible?: boolean;
|
|
993
|
+
actionHandlers?: Record<string, () => void>;
|
|
994
|
+
children?: (props: ChecklistRenderProps) => ReactNode;
|
|
995
|
+
}
|
|
996
|
+
|
|
997
|
+
interface HotspotProps {
|
|
998
|
+
id: string;
|
|
999
|
+
target: string;
|
|
1000
|
+
type?: "info" | "new" | "help";
|
|
1001
|
+
frequency?: "once" | "every-session" | "always";
|
|
1002
|
+
children: ReactNode;
|
|
1003
|
+
}
|
|
1004
|
+
interface TooltipGroupProps {
|
|
1005
|
+
maxVisible?: number;
|
|
1006
|
+
children: ReactNode;
|
|
1007
|
+
}
|
|
1008
|
+
|
|
1009
|
+
type FeedbackEmoji = "thumbs-up" | "thumbs-down" | "heart" | "thinking" | "fire";
|
|
1010
|
+
interface FeedbackPayload {
|
|
1011
|
+
featureId?: string;
|
|
1012
|
+
text: string;
|
|
1013
|
+
category?: string;
|
|
1014
|
+
emoji?: FeedbackEmoji;
|
|
1015
|
+
screenshot?: Blob;
|
|
1016
|
+
url: string;
|
|
1017
|
+
timestamp: string;
|
|
1018
|
+
metadata?: Record<string, unknown>;
|
|
1019
|
+
}
|
|
1020
|
+
type FeedbackRateLimit = "none" | "1-per-feature" | "1-per-session";
|
|
1021
|
+
interface FeedbackWidgetRenderProps {
|
|
1022
|
+
isOpen: boolean;
|
|
1023
|
+
isSubmitting: boolean;
|
|
1024
|
+
isRateLimited: boolean;
|
|
1025
|
+
submitted: boolean;
|
|
1026
|
+
text: string;
|
|
1027
|
+
category: string;
|
|
1028
|
+
emoji: FeedbackEmoji | null;
|
|
1029
|
+
screenshot: Blob | null;
|
|
1030
|
+
error: string | null;
|
|
1031
|
+
open: () => void;
|
|
1032
|
+
close: () => void;
|
|
1033
|
+
setText: (value: string) => void;
|
|
1034
|
+
setCategory: (value: string) => void;
|
|
1035
|
+
setEmoji: (value: FeedbackEmoji | null) => void;
|
|
1036
|
+
captureScreenshot: () => Promise<void>;
|
|
1037
|
+
submit: () => Promise<void>;
|
|
1038
|
+
}
|
|
1039
|
+
interface FeedbackWidgetProps {
|
|
1040
|
+
featureId?: string;
|
|
1041
|
+
onSubmit: (payload: FeedbackPayload) => Promise<void> | void;
|
|
1042
|
+
showScreenshot?: boolean;
|
|
1043
|
+
showEmoji?: boolean;
|
|
1044
|
+
rateLimit?: FeedbackRateLimit;
|
|
1045
|
+
categories?: string[];
|
|
1046
|
+
metadata?: Record<string, unknown>;
|
|
1047
|
+
screenshotCapture?: () => Promise<Blob | null | undefined>;
|
|
1048
|
+
triggerLabel?: string;
|
|
1049
|
+
title?: string;
|
|
1050
|
+
className?: string;
|
|
1051
|
+
style?: CSSProperties;
|
|
1052
|
+
children?: (props: FeedbackWidgetRenderProps) => ReactNode;
|
|
1053
|
+
}
|
|
1054
|
+
|
|
1055
|
+
interface AnnouncementSlide {
|
|
1056
|
+
id?: string;
|
|
1057
|
+
title: string;
|
|
1058
|
+
description?: string;
|
|
1059
|
+
image?: string;
|
|
1060
|
+
videoUrl?: string;
|
|
1061
|
+
primaryCta?: FeatureCTA;
|
|
1062
|
+
secondaryCta?: FeatureCTA;
|
|
1063
|
+
}
|
|
1064
|
+
interface AnnouncementModalRenderProps {
|
|
1065
|
+
isOpen: boolean;
|
|
1066
|
+
currentSlide: AnnouncementSlide | null;
|
|
1067
|
+
currentSlideIndex: number;
|
|
1068
|
+
totalSlides: number;
|
|
1069
|
+
open: () => void;
|
|
1070
|
+
close: () => void;
|
|
1071
|
+
nextSlide: () => void;
|
|
1072
|
+
prevSlide: () => void;
|
|
1073
|
+
dismiss: () => void;
|
|
1074
|
+
}
|
|
1075
|
+
interface AnnouncementModalProps {
|
|
1076
|
+
id?: string;
|
|
1077
|
+
featureId?: string;
|
|
1078
|
+
feature?: FeatureEntry;
|
|
1079
|
+
trigger?: "auto" | "manual";
|
|
1080
|
+
defaultOpen?: boolean;
|
|
1081
|
+
slides?: AnnouncementSlide[];
|
|
1082
|
+
frequency?: "once" | "every-session" | "always";
|
|
1083
|
+
dismissible?: boolean;
|
|
1084
|
+
mobileBreakpoint?: number;
|
|
1085
|
+
onOpen?: () => void;
|
|
1086
|
+
onDismiss?: () => void;
|
|
1087
|
+
onPrimaryCtaClick?: (slide: AnnouncementSlide, index: number) => void;
|
|
1088
|
+
onSecondaryCtaClick?: (slide: AnnouncementSlide, index: number) => void;
|
|
1089
|
+
className?: string;
|
|
1090
|
+
style?: CSSProperties;
|
|
1091
|
+
children?: (props: AnnouncementModalRenderProps) => ReactNode;
|
|
1092
|
+
}
|
|
1093
|
+
|
|
1094
|
+
interface SpotlightChainStep {
|
|
1095
|
+
id?: string;
|
|
1096
|
+
target: string;
|
|
1097
|
+
title?: string;
|
|
1098
|
+
content: ReactNode;
|
|
1099
|
+
autoAdvanceMs?: number;
|
|
1100
|
+
}
|
|
1101
|
+
interface SpotlightChainRenderProps {
|
|
1102
|
+
isActive: boolean;
|
|
1103
|
+
currentStep: SpotlightChainStep | null;
|
|
1104
|
+
currentStepIndex: number;
|
|
1105
|
+
totalSteps: number;
|
|
1106
|
+
start: () => void;
|
|
1107
|
+
next: () => void;
|
|
1108
|
+
skip: () => void;
|
|
1109
|
+
}
|
|
1110
|
+
interface SpotlightChainProps {
|
|
1111
|
+
steps: SpotlightChainStep[];
|
|
1112
|
+
startOnMount?: boolean;
|
|
1113
|
+
autoAdvance?: boolean;
|
|
1114
|
+
autoAdvanceMs?: number;
|
|
1115
|
+
onComplete?: () => void;
|
|
1116
|
+
onStepViewed?: (step: SpotlightChainStep, index: number) => void;
|
|
1117
|
+
onSkip?: (step: SpotlightChainStep | null, index: number) => void;
|
|
1118
|
+
children?: (props: SpotlightChainRenderProps) => ReactNode;
|
|
1119
|
+
}
|
|
1120
|
+
|
|
1121
|
+
interface FeatureRequestRecord {
|
|
1122
|
+
id: string;
|
|
1123
|
+
featureId?: string;
|
|
1124
|
+
title: string;
|
|
1125
|
+
description?: string;
|
|
1126
|
+
category?: string;
|
|
1127
|
+
votes: number;
|
|
1128
|
+
createdAt: string;
|
|
1129
|
+
updatedAt: string;
|
|
1130
|
+
}
|
|
1131
|
+
type FeatureRequestSort = "votes" | "recent";
|
|
1132
|
+
|
|
1133
|
+
interface FeatureRequestButtonRenderProps {
|
|
1134
|
+
votes: number;
|
|
1135
|
+
hasVoted: boolean;
|
|
1136
|
+
vote: () => void;
|
|
1137
|
+
request: FeatureRequestRecord | null;
|
|
1138
|
+
}
|
|
1139
|
+
interface FeatureRequestButtonProps {
|
|
1140
|
+
featureId: string;
|
|
1141
|
+
requestId?: string;
|
|
1142
|
+
requestTitle?: string;
|
|
1143
|
+
label?: string;
|
|
1144
|
+
onVote?: (result: {
|
|
1145
|
+
voted: boolean;
|
|
1146
|
+
request: FeatureRequestRecord;
|
|
1147
|
+
}) => void;
|
|
1148
|
+
className?: string;
|
|
1149
|
+
style?: CSSProperties;
|
|
1150
|
+
children?: (props: FeatureRequestButtonRenderProps) => ReactNode;
|
|
1151
|
+
}
|
|
1152
|
+
|
|
1153
|
+
interface FeatureRequestPayload extends FeatureRequestRecord {
|
|
1154
|
+
metadata?: Record<string, unknown>;
|
|
1155
|
+
}
|
|
1156
|
+
interface FeatureRequestFormRenderProps {
|
|
1157
|
+
requests: FeatureRequestRecord[];
|
|
1158
|
+
sortBy: FeatureRequestSort;
|
|
1159
|
+
title: string;
|
|
1160
|
+
description: string;
|
|
1161
|
+
category: string;
|
|
1162
|
+
isSubmitting: boolean;
|
|
1163
|
+
error: string | null;
|
|
1164
|
+
setTitle: (value: string) => void;
|
|
1165
|
+
setDescription: (value: string) => void;
|
|
1166
|
+
setCategory: (value: string) => void;
|
|
1167
|
+
setSortBy: (value: FeatureRequestSort) => void;
|
|
1168
|
+
submit: () => Promise<void>;
|
|
1169
|
+
vote: (requestId: string) => void;
|
|
1170
|
+
}
|
|
1171
|
+
interface FeatureRequestFormProps {
|
|
1172
|
+
onSubmit?: (request: FeatureRequestPayload) => Promise<void> | void;
|
|
1173
|
+
onWebhook?: (request: FeatureRequestPayload) => Promise<void> | void;
|
|
1174
|
+
categories?: string[];
|
|
1175
|
+
defaultSort?: FeatureRequestSort;
|
|
1176
|
+
metadata?: Record<string, unknown>;
|
|
1177
|
+
className?: string;
|
|
1178
|
+
style?: CSSProperties;
|
|
1179
|
+
children?: (props: FeatureRequestFormRenderProps) => ReactNode;
|
|
1180
|
+
}
|
|
1181
|
+
|
|
1182
|
+
declare const NewBadge: react.ComponentType<NewBadgeProps>;
|
|
1183
|
+
|
|
1184
|
+
declare const ChangelogWidget: react.ComponentType<ChangelogWidgetProps>;
|
|
1185
|
+
|
|
1186
|
+
declare const Spotlight: react.ComponentType<SpotlightProps>;
|
|
1187
|
+
|
|
1188
|
+
declare const Banner: react.ComponentType<BannerProps>;
|
|
1189
|
+
|
|
1190
|
+
declare const Toast: react.ComponentType<ToastProps>;
|
|
1191
|
+
|
|
1192
|
+
declare const ChangelogPage: react.ComponentType<ChangelogPageProps>;
|
|
1193
|
+
|
|
1194
|
+
declare const Tour: react.ComponentType<TourProps>;
|
|
1195
|
+
|
|
1196
|
+
declare const Checklist: react.ComponentType<ChecklistProps>;
|
|
1197
|
+
|
|
1198
|
+
declare const Hotspot: react.ComponentType<HotspotProps>;
|
|
1199
|
+
declare const TooltipGroup: react.ComponentType<TooltipGroupProps>;
|
|
1200
|
+
|
|
1201
|
+
declare const FeedbackWidget: react.ComponentType<FeedbackWidgetProps>;
|
|
1202
|
+
|
|
1203
|
+
declare const AnnouncementModal: react.ComponentType<AnnouncementModalProps>;
|
|
1204
|
+
|
|
1205
|
+
declare const SpotlightChain: react.ComponentType<SpotlightChainProps>;
|
|
1206
|
+
|
|
1207
|
+
declare const Survey: react.ComponentType<SurveyProps>;
|
|
1208
|
+
|
|
1209
|
+
declare const FeatureRequestButton: react.ComponentType<FeatureRequestButtonProps>;
|
|
1210
|
+
|
|
1211
|
+
declare const FeatureRequestForm: react.ComponentType<FeatureRequestFormProps>;
|
|
1212
|
+
|
|
1213
|
+
export { AnnouncementModal, type AnnouncementModalProps, type AnnouncementModalRenderProps, type AnnouncementSlide, Banner, type BannerProps, type BannerRenderProps, type BannerVariant, type ChangelogEntryRenderProps, ChangelogPage, type ChangelogPageProps, ChangelogWidget, type ChangelogWidgetProps, type ChangelogWidgetRenderProps, Checklist, type ChecklistProps, type ChecklistRenderProps, type ChecklistTask, FeatureDropContext, type FeatureDropContextValue, FeatureDropProvider, type FeatureDropProviderProps, FeatureRequestButton, type FeatureRequestButtonProps, type FeatureRequestButtonRenderProps, FeatureRequestForm, type FeatureRequestFormProps, type FeatureRequestFormRenderProps, type FeatureRequestPayload, type FeedbackEmoji, type FeedbackPayload, type FeedbackRateLimit, FeedbackWidget, type FeedbackWidgetProps, type FeedbackWidgetRenderProps, Hotspot, type HotspotProps, NewBadge, type NewBadgeProps, type NewBadgeRenderProps, type PaginationMode, Spotlight, SpotlightChain, type SpotlightChainProps, type SpotlightChainRenderProps, type SpotlightChainStep, type SpotlightProps, type SpotlightRenderProps, Survey, type SurveyPayload, type SurveyProps, type SurveyQuestion, type SurveyQuestionType, type SurveyRenderProps, type SurveyTriggerRules, type SurveyType, ThemeProvider, type ThemeProviderProps, Toast, type ToastProps, type ToastRenderProps, TooltipGroup, type TooltipGroupProps, Tour, type TourProps, type TourRenderProps, type TourSequenceItem, type TourStep, type UseChecklistResult, type UseNewFeatureResult, type UseSurveyResult, type UseTabNotificationOptions, type UseTourResult, type UseTourSequencerResult, useAdoptionAnalytics, useChecklist, useFeatureDrop, useNewCount, useNewFeature, useSurvey, useTabNotification, useTour, useTourSequencer };
|