Streak Components
Badges, cards, calendars for streak display
Leaderboard Components
Tables, podiums, mini boards
Achievement Components
Grids, cards, progress, modals
Fully Customizable
Override styles and behavior
Overview
All engagement components are available from @sylphx/sdk/react. They automatically connect to your engagement config and handle data fetching, loading states, and error handling.
import {
// Streak components
StreakBadge,
StreakCard,
StreakCalendar,
// Leaderboard components
LeaderboardTable,
LeaderboardPodium,
LeaderboardMini,
UserRankBadge,
// Achievement components
AchievementGrid,
AchievementCard,
AchievementBadge,
AchievementProgress,
AchievementModal,
TotalPoints,
// Hooks (for custom UI)
useStreak,
useLeaderboard,
useAchievements,
useAchievementProgress,
useEngagementEvents,
} from '@sylphx/sdk/react'Streak Components
StreakBadge
Compact streak indicator for headers and profiles:
<StreakBadge streakId="daily_login" />
// Renders: 🔥 7
// With customization
<StreakBadge
streakId="daily_login"
showIcon={true} // Show flame icon (default: true)
showLabel={false} // Show "days" label (default: false)
emptyText="Start streak" // Text when streak is 0
className="text-lg" // Custom classes
/>| Property | Type | Description |
|---|---|---|
streakIdrequired | string | ID of the streak to display |
showIcon | boolean | Show flame icon (default: true) |
showLabel | boolean | Show "days" label (default: false) |
emptyText | string | Text when streak is 0 |
className | string | Custom CSS classes |
StreakCard
Full-featured streak display with milestone progress:
<StreakCard streakId="daily_login" />
// With all options
<StreakCard
streakId="daily_login"
showMilestoneProgress // Progress bar to next milestone
showBestStreak // Display all-time best
showRecordButton // Button to record activity
showRecoveryOption // Show recovery if streak broken
onMilestone={(m) => { // Callback when milestone hit
celebrate(m)
}}
onRecord={(result) => { // Callback after recording
console.log('Recorded!', result)
}}
/>| Property | Type | Description |
|---|---|---|
streakIdrequired | string | ID of the streak |
showMilestoneProgress | boolean | Show progress bar to next milestone |
showBestStreak | boolean | Display all-time best streak |
showRecordButton | boolean | Include button to record activity |
showRecoveryOption | boolean | Show recovery UI if streak was broken |
onMilestone | (milestone: number) => void | Callback when milestone is reached |
onRecord | (result: StreakResult) => void | Callback after recording activity |
StreakCalendar
Monthly calendar showing active days:
<StreakCalendar
streakId="daily_login"
month={new Date()}
/>
// With customization
<StreakCalendar
streakId="daily_login"
month={new Date()}
highlightMilestones // Mark milestone days
showWeekNumbers // Show week numbers
startOnMonday // Start week on Monday (default: Sunday)
activeClassName="bg-primary" // Class for active days
milestoneClassName="ring-2" // Class for milestone days
/>Leaderboard Components
LeaderboardTable
Full leaderboard table with pagination:
<LeaderboardTable leaderboardId="weekly_points" />
// With all options
<LeaderboardTable
leaderboardId="weekly_points"
limit={20} // Entries per page
highlightUser // Highlight current user's row
showPercentile // Show percentile for user
showAvatar // Show user avatars
showChange // Show rank change (↑ ↓)
stickyHeader // Keep header visible on scroll
onUserClick={(userId) => { // Click handler for rows
router.push(`/profile/${userId}`)
}}
/>| Property | Type | Description |
|---|---|---|
leaderboardIdrequired | string | ID of the leaderboard |
limit | number | Entries per page (default: 20) |
highlightUser | boolean | Highlight current user |
showPercentile | boolean | Show percentile for current user |
showAvatar | boolean | Show user avatars |
showChange | boolean | Show rank change indicators |
stickyHeader | boolean | Keep header visible on scroll |
onUserClick | (userId: string) => void | Click handler for rows |
LeaderboardPodium
Visual podium display for top 3:
<LeaderboardPodium leaderboardId="weekly_points" />
// Customization
<LeaderboardPodium
leaderboardId="weekly_points"
showScore // Show scores under names
showAvatar // Show user avatars
animated // Animate on load
size="lg" // sm, md, lg
/>LeaderboardMini
Compact leaderboard for sidebars:
<LeaderboardMini
leaderboardId="weekly_points"
entries={5} // Number of entries to show
/>
// With current user's rank
<LeaderboardMini
leaderboardId="weekly_points"
entries={5}
showUserRank // Always show current user's rank
/>UserRankBadge
Display current user's rank:
<UserRankBadge leaderboardId="weekly_points" />
// Renders: "#5 of 847 (Top 1%)"
<UserRankBadge
leaderboardId="weekly_points"
showPercentile // Show percentile (default: true)
showTotal // Show total entries (default: true)
compact // Compact mode: just "#5"
/>Achievement Components
AchievementGrid
Grid display of all achievements:
<AchievementGrid />
// With all options
<AchievementGrid
groupByCategory // Group by category
groupByTier // Group by tier (bronze, silver, etc.)
showProgress // Show progress bars for progress-based
showLocked // Show locked achievements (default: true)
hideSecrets // Hide secret achievements entirely
columns={4} // Number of columns
onAchievementClick={(id) => {
showAchievementDetail(id)
}}
/>| Property | Type | Description |
|---|---|---|
groupByCategory | boolean | Group achievements by category |
groupByTier | boolean | Group achievements by tier |
showProgress | boolean | Show progress bars for progress-based achievements |
showLocked | boolean | Show locked achievements (default: true) |
hideSecrets | boolean | Hide secret achievements entirely |
columns | number | Number of grid columns |
onAchievementClick | (id: string) => void | Click handler |
AchievementCard
Single achievement card:
<AchievementCard achievementId="power_user" />
// Customization
<AchievementCard
achievementId="power_user"
size="lg" // sm, md, lg
showDescription // Show description text
showPoints // Show point value
showProgress // Show progress if applicable
showUnlockDate // Show when unlocked
/>AchievementBadge
Compact badge icon:
<AchievementBadge achievementId="power_user" />
// Array of badges (e.g., for profile)
<div className="flex gap-1">
<AchievementBadge achievementId="first_steps" />
<AchievementBadge achievementId="power_user" />
<AchievementBadge achievementId="centurion" />
</div>AchievementProgress
Progress bar for progress-based achievements:
<AchievementProgress achievementId="centurion" />
// Customization
<AchievementProgress
achievementId="centurion"
showLabel // Show "45/100" label
showPercentage // Show "45%" label
height="sm" // sm, md, lg bar height
color="primary" // primary, success, warning
/>AchievementModal
Celebration modal shown on unlock:
// Add to your layout - shows automatically when achievements unlock
<AchievementModal />
// With customization
<AchievementModal
autoShow // Auto-show on unlock (default: true)
celebrationDuration={3000} // Confetti duration in ms
showPoints // Show points earned
showShare // Show share button
onClose={() => {}} // Close callback
onShare={(achievement) => { // Share callback
shareToSocial(achievement)
}}
/>TotalPoints
Display user's total achievement points:
<TotalPoints />
// Renders: "🏅 450 points"
<TotalPoints
showIcon={false} // Hide medal icon
showLabel={false} // Just show number
className="text-2xl font-bold"
/>Custom UI with Hooks
Build completely custom UIs using the underlying hooks:
'use client'
import { useStreak } from '@sylphx/sdk/react'
function CustomStreakUI() {
const {
streak, // StreakData | null
recordActivity, // () => Promise<StreakResult>
recoverStreak, // () => Promise<RecoveryResult>
isLoading, // boolean
error, // Error | null
} = useStreak('daily_login')
// streak shape:
// {
// current: number,
// best: number,
// recordedToday: boolean,
// lastActivityAt: Date | null,
// canRecover: boolean,
// nextMilestone: number | null,
// progressToMilestone: number, // 0-100
// }
return (
<div>
<p>Current: {streak?.current}</p>
<p>Best: {streak?.best}</p>
<p>Next milestone: {streak?.nextMilestone}</p>
<button
onClick={recordActivity}
disabled={streak?.recordedToday}
>
Check In
</button>
</div>
)
}Styling & Theming
All components support custom styling via className props and CSS variables:
// Method 1: className prop
<StreakCard
streakId="daily_login"
className="bg-gradient-to-r from-orange-500 to-red-500"
/>
// Method 2: CSS variables (global theming)
:root {
--sylphx-streak-color: #f97316;
--sylphx-achievement-bronze: #b87333;
--sylphx-achievement-silver: #c0c0c0;
--sylphx-achievement-gold: #ffd700;
--sylphx-achievement-platinum: #e5e4e2;
--sylphx-leaderboard-highlight: hsl(var(--primary));
}
// Method 3: Component variants (if using @sylphx/ui)
<StreakCard
variant="gradient" // 'default' | 'gradient' | 'minimal'
colorScheme="orange" // 'default' | 'orange' | 'green' | 'purple'
/>
// Method 4: Fully custom with hooks
const { streak } = useStreak('daily_login')
return <MyCustomStreakComponent data={streak} />