@tour-kit/adoption
TypeScript Types
TypeScript types for FeatureConfig, AdoptionState, NudgeRule, UsageThreshold, and the @tour-kit/adoption API surface
Core Types
Feature
interface Feature {
id: string
name: string
trigger: FeatureTrigger
adoptionCriteria?: AdoptionCriteria
resources?: FeatureResources
priority?: number
category?: string
description?: string
premium?: boolean
}Prop
Type
FeatureTrigger
type FeatureTrigger =
| string // CSS selector
| { event: string } // Custom event
| { callback: () => boolean } // Programmatic checkExamples:
// CSS selector (click tracking)
trigger: '#dark-mode-toggle'
trigger: '[data-feature="export"]'
// Custom event
trigger: { event: 'export:complete' }
trigger: { event: 'ai:generated' }
// Callback (polled every 1s)
trigger: { callback: () => document.fullscreenElement !== null }AdoptionCriteria
interface AdoptionCriteria {
minUses?: number // default: 3
recencyDays?: number // default: 30
custom?: (usage: FeatureUsage) => boolean
}Prop
Type
FeatureResources
interface FeatureResources {
tourId?: string
hintIds?: string[]
}Prop
Type
FeatureUsage
interface FeatureUsage {
featureId: string
firstUsed: string | null // ISO date string
lastUsed: string | null // ISO date string
useCount: number
status: AdoptionStatus
}Prop
Type
AdoptionStatus
type AdoptionStatus = 'not_started' | 'exploring' | 'adopted' | 'churned'- not_started: Never used
- exploring: Used, but below
minUses - adopted: Meets adoption criteria
- churned: Was adopted, now inactive (exceeds
recencyDays)
FeatureWithUsage
interface FeatureWithUsage extends Feature {
usage: FeatureUsage
}Combines feature definition with current usage state.
Provider Types
AdoptionProviderProps
interface AdoptionProviderProps {
children: React.ReactNode
features: Feature[]
storage?: StorageConfig
nudge?: NudgeConfig
userId?: string
onAdoption?: (feature: Feature) => void
onChurn?: (feature: Feature) => void
onNudge?: (feature: Feature, action: 'shown' | 'clicked' | 'dismissed') => void
}StorageConfig
type StorageConfig =
| { type: 'localStorage'; key?: string }
| { type: 'memory' }
| { type: 'custom'; adapter: StorageAdapter }StorageAdapter
interface StorageAdapter {
getItem(key: string): Promise<string | null> | string | null
setItem(key: string, value: string): Promise<void> | void
removeItem(key: string): Promise<void> | void
}NudgeConfig
interface NudgeConfig {
enabled?: boolean // default: true
initialDelay?: number // default: 5000
cooldown?: number // default: 86400000 (24h)
maxPerSession?: number // default: 3
maxFeatures?: number // default: 1
}Hook Return Types
UseFeatureReturn
interface UseFeatureReturn {
feature: Feature | null
usage: FeatureUsage
isAdopted: boolean
status: AdoptionStatus
useCount: number
trackUsage: () => void
}AdoptionStats
interface AdoptionStats {
features: FeatureWithUsage[]
adoptionRate: number
adoptedCount: number
totalCount: number
byStatus: Record<AdoptionStatus, FeatureWithUsage[]>
byCategory: Record<string, { adopted: number; total: number; rate: number }>
}UseNudgeReturn
interface UseNudgeReturn {
pendingNudges: Feature[]
hasNudges: boolean
showNudge: (featureId: string) => void
dismissNudge: (featureId: string) => void
snoozeNudge: (featureId: string, durationMs: number) => void
handleNudgeClick: (featureId: string) => void
}Component Prop Types
AdoptionNudgeProps
interface AdoptionNudgeProps extends React.ComponentPropsWithoutRef<'div'> {
render?: (props: NudgeRenderProps) => React.ReactNode
delay?: number
position?: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left'
size?: 'sm' | 'md' | 'lg'
asChild?: boolean
}NudgeRenderProps
interface NudgeRenderProps {
feature: Feature
onDismiss: () => void
onSnooze: (durationMs: number) => void
onClick: () => void
}FeatureButtonProps
interface FeatureButtonProps extends React.ComponentPropsWithoutRef<'button'> {
featureId: string
showNewIndicator?: boolean
variant?: 'default' | 'secondary' | 'outline' | 'ghost' | 'destructive'
size?: 'sm' | 'md' | 'lg'
asChild?: boolean
}NewFeatureBadgeProps
interface NewFeatureBadgeProps extends React.ComponentPropsWithoutRef<'span'> {
featureId: string
text?: string
variant?: 'default' | 'secondary' | 'outline' | 'destructive'
size?: 'sm' | 'md' | 'lg'
}Dashboard Component Types
AdoptionDashboardProps
interface AdoptionDashboardProps {
showFilters?: boolean
showStats?: boolean
showChart?: boolean
showTable?: boolean
className?: string
}AdoptionStatCardProps
interface AdoptionStatCardProps {
title: string
value: string | number
description?: string
trend?: number
trendLabel?: string
icon?: React.ReactNode
variant?: 'default' | 'success' | 'warning' | 'danger'
size?: 'sm' | 'md' | 'lg'
}AdoptionTableProps
interface AdoptionTableProps {
sortBy?: 'name' | 'status' | 'useCount' | 'lastUsed' | 'category'
sortOrder?: 'asc' | 'desc'
showCategory?: boolean
showPriority?: boolean
features?: FeatureWithUsage[]
onRowClick?: (feature: FeatureWithUsage) => void
className?: string
}AdoptionCategoryChartProps
interface AdoptionCategoryChartProps {
showPercentages?: boolean
highlightCategory?: string
orientation?: 'horizontal' | 'vertical'
className?: string
}AdoptionStatusBadgeProps
interface AdoptionStatusBadgeProps {
status: AdoptionStatus
size?: 'sm' | 'md' | 'lg'
showIcon?: boolean
className?: string
}AdoptionFiltersProps
interface AdoptionFiltersProps {
filters: AdoptionFiltersState
onChange: (filters: AdoptionFiltersState) => void
categories?: string[]
className?: string
}AdoptionFiltersState
interface AdoptionFiltersState {
status: AdoptionStatus | 'all'
category: string | 'all'
search: string
}Usage Examples
Typed Feature Array
import type { Feature } from '@tour-kit/adoption'
const features: Feature[] = [
{
id: 'dark-mode',
name: 'Dark Mode',
trigger: '#dark-mode-toggle',
category: 'customization',
adoptionCriteria: {
minUses: 3,
recencyDays: 30,
},
},
]Typed Hook Usage
import { useFeature, type UseFeatureReturn } from '@tour-kit/adoption'
function Component() {
const feature: UseFeatureReturn = useFeature('my-feature')
feature.trackUsage() // ✓ Type-safe
feature.isAdopted // ✓ Type-safe
}Typed Component Props
import type { FeatureButtonProps } from '@tour-kit/adoption'
const buttonProps: FeatureButtonProps = {
featureId: 'export',
variant: 'default',
onClick: () => console.log('clicked'),
}Next Steps
- AdoptionProvider - Provider setup
- Hooks - Hook usage
- Components - Component props