Skip to content

Commit 84d8858

Browse files
CopilotAdez017
andcommitted
Implement rolling numbers effect on footer stats using SlotCounter
Co-authored-by: Adez017 <[email protected]>
1 parent f340267 commit 84d8858

File tree

1 file changed

+60
-4
lines changed

1 file changed

+60
-4
lines changed

src/theme/Footer/Layout/index.tsx

Lines changed: 60 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import React, {type ReactNode, useState, useEffect} from 'react';
33
import Link from "@docusaurus/Link";
44
import type {Props} from '@theme/Footer/Layout';
5+
import SlotCounter from "react-slot-counter";
56
import './enhanced-footer.css';
67

78
// Dynamic stats interface
@@ -12,6 +13,15 @@ interface FooterStats {
1213
supportHours: string;
1314
}
1415

16+
// Helper function to parse stat values for SlotCounter
17+
const parseStatValue = (statValue: string) => {
18+
// Extract numeric part and suffix from strings like "52K+", "215+", "95%", "24/7"
19+
const numericMatch = statValue.match(/^(\d+)/);
20+
const numericValue = numericMatch ? parseInt(numericMatch[1]) : 0;
21+
const suffix = statValue.replace(/^\d+/, '');
22+
return { numericValue, suffix };
23+
};
24+
1525
export default function FooterLayout({
1626
style,
1727
links,
@@ -105,7 +115,14 @@ export default function FooterLayout({
105115
</svg>
106116
</div>
107117
<div className="stat-content">
108-
<div className="stat-number">{stats.activeUsers}</div>
118+
<div className="stat-number">
119+
<SlotCounter
120+
value={parseStatValue(stats.activeUsers).numericValue}
121+
autoAnimationStart={true}
122+
duration={1.2}
123+
/>
124+
{parseStatValue(stats.activeUsers).suffix}
125+
</div>
109126
<div className="stat-label">Active Learners</div>
110127
</div>
111128
</div>
@@ -117,7 +134,14 @@ export default function FooterLayout({
117134
</svg>
118135
</div>
119136
<div className="stat-content">
120-
<div className="stat-number">{stats.tutorials}</div>
137+
<div className="stat-number">
138+
<SlotCounter
139+
value={parseStatValue(stats.tutorials).numericValue}
140+
autoAnimationStart={true}
141+
duration={1.2}
142+
/>
143+
{parseStatValue(stats.tutorials).suffix}
144+
</div>
121145
<div className="stat-label">Tutorials</div>
122146
</div>
123147
</div>
@@ -129,7 +153,14 @@ export default function FooterLayout({
129153
</svg>
130154
</div>
131155
<div className="stat-content">
132-
<div className="stat-number">{stats.successRate}</div>
156+
<div className="stat-number">
157+
<SlotCounter
158+
value={parseStatValue(stats.successRate).numericValue}
159+
autoAnimationStart={true}
160+
duration={1.2}
161+
/>
162+
{parseStatValue(stats.successRate).suffix}
163+
</div>
133164
<div className="stat-label">Success Rate</div>
134165
</div>
135166
</div>
@@ -141,7 +172,32 @@ export default function FooterLayout({
141172
</svg>
142173
</div>
143174
<div className="stat-content">
144-
<div className="stat-number">{stats.supportHours}</div>
175+
<div className="stat-number">
176+
{stats.supportHours === '24/7' ? (
177+
<>
178+
<SlotCounter
179+
value={24}
180+
autoAnimationStart={true}
181+
duration={1.2}
182+
/>
183+
/
184+
<SlotCounter
185+
value={7}
186+
autoAnimationStart={true}
187+
duration={1.2}
188+
/>
189+
</>
190+
) : (
191+
<>
192+
<SlotCounter
193+
value={parseStatValue(stats.supportHours).numericValue}
194+
autoAnimationStart={true}
195+
duration={1.2}
196+
/>
197+
{parseStatValue(stats.supportHours).suffix}
198+
</>
199+
)}
200+
</div>
145201
<div className="stat-label">Support</div>
146202
</div>
147203
</div>

0 commit comments

Comments
 (0)