Skip to content

Commit 489d0c7

Browse files
authored
fix the rolling numbers issue
Add rolling numbers effect to footer stats using SlotCounter
2 parents 88f2f88 + 280cc23 commit 489d0c7

File tree

1 file changed

+72
-4
lines changed

1 file changed

+72
-4
lines changed

src/theme/Footer/Layout/index.tsx

Lines changed: 72 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,16 @@ 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+
animateOnVisible={true}
122+
duration={1200}
123+
delay={100}
124+
sequentialAnimationMode={true}
125+
/>
126+
{parseStatValue(stats.activeUsers).suffix}
127+
</div>
109128
<div className="stat-label">Active Learners</div>
110129
</div>
111130
</div>
@@ -117,7 +136,16 @@ export default function FooterLayout({
117136
</svg>
118137
</div>
119138
<div className="stat-content">
120-
<div className="stat-number">{stats.tutorials}</div>
139+
<div className="stat-number">
140+
<SlotCounter
141+
value={parseStatValue(stats.tutorials).numericValue}
142+
animateOnVisible={true}
143+
duration={1200}
144+
delay={200}
145+
sequentialAnimationMode={true}
146+
/>
147+
{parseStatValue(stats.tutorials).suffix}
148+
</div>
121149
<div className="stat-label">Tutorials</div>
122150
</div>
123151
</div>
@@ -129,7 +157,16 @@ export default function FooterLayout({
129157
</svg>
130158
</div>
131159
<div className="stat-content">
132-
<div className="stat-number">{stats.successRate}</div>
160+
<div className="stat-number">
161+
<SlotCounter
162+
value={parseStatValue(stats.successRate).numericValue}
163+
animateOnVisible={true}
164+
duration={1200}
165+
delay={300}
166+
sequentialAnimationMode={true}
167+
/>
168+
{parseStatValue(stats.successRate).suffix}
169+
</div>
133170
<div className="stat-label">Success Rate</div>
134171
</div>
135172
</div>
@@ -141,7 +178,38 @@ export default function FooterLayout({
141178
</svg>
142179
</div>
143180
<div className="stat-content">
144-
<div className="stat-number">{stats.supportHours}</div>
181+
<div className="stat-number">
182+
{stats.supportHours === '24/7' ? (
183+
<>
184+
<SlotCounter
185+
value={24}
186+
animateOnVisible={true}
187+
duration={1200}
188+
delay={400}
189+
sequentialAnimationMode={true}
190+
/>
191+
/
192+
<SlotCounter
193+
value={7}
194+
animateOnVisible={true}
195+
duration={1200}
196+
delay={500}
197+
sequentialAnimationMode={true}
198+
/>
199+
</>
200+
) : (
201+
<>
202+
<SlotCounter
203+
value={parseStatValue(stats.supportHours).numericValue}
204+
animateOnVisible={true}
205+
duration={1200}
206+
delay={400}
207+
sequentialAnimationMode={true}
208+
/>
209+
{parseStatValue(stats.supportHours).suffix}
210+
</>
211+
)}
212+
</div>
145213
<div className="stat-label">Support</div>
146214
</div>
147215
</div>

0 commit comments

Comments
 (0)