Skip to content

Commit 3254557

Browse files
authored
fix(svg): use unique IDs in GrowthTrendChart to prevent SVG defs collisions (JhaSourav07#2148)
Co-authored-by: Sourav Jha <25BCS12964@cuchd.in>
2 parents 0c9e059 + 45b5c70 commit 3254557

2 files changed

Lines changed: 16 additions & 12 deletions

File tree

components/dashboard/GrowthTrendChart.test.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,8 @@ describe('GrowthTrendChart', () => {
111111
const defs = container.querySelector('defs');
112112
expect(defs).not.toBeNull();
113113

114-
const gradientA = container.querySelector('#gradient-area-a');
115-
const gradientB = container.querySelector('#gradient-area-b');
114+
const gradientA = container.querySelector('linearGradient[id$="-gradient-area-a"]');
115+
const gradientB = container.querySelector('linearGradient[id$="-gradient-area-b"]');
116116
expect(gradientA).not.toBeNull();
117117
expect(gradientB).not.toBeNull();
118118
expect(gradientA?.tagName).toBe('linearGradient');
@@ -129,8 +129,8 @@ describe('GrowthTrendChart', () => {
129129
/>
130130
);
131131

132-
const glowA = container.querySelector('#glow-line-a');
133-
const glowB = container.querySelector('#glow-line-b');
132+
const glowA = container.querySelector('filter[id$="-glow-line-a"]');
133+
const glowB = container.querySelector('filter[id$="-glow-line-b"]');
134134
expect(glowA).not.toBeNull();
135135
expect(glowB).not.toBeNull();
136136
expect(glowA?.tagName).toBe('filter');

components/dashboard/GrowthTrendChart.tsx

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
'use client';
22

3+
import { useId } from 'react';
34
import { motion } from 'framer-motion';
45

56
interface GrowthTrendChartProps {
@@ -15,6 +16,9 @@ export default function GrowthTrendChart({
1516
labelA,
1617
labelB,
1718
}: GrowthTrendChartProps) {
19+
// Generate unique IDs to prevent SVG <defs> collisions when multiple instances render
20+
const instanceId = useId();
21+
1822
// 1. Generate chronological list of the last 12 months
1923
const months: Array<{
2024
key: string;
@@ -124,19 +128,19 @@ export default function GrowthTrendChart({
124128
<div className="relative w-full h-[180px] overflow-hidden">
125129
<svg viewBox={`0 0 ${width} ${height}`} className="w-full h-full overflow-visible">
126130
<defs>
127-
<linearGradient id="gradient-area-a" x1="0" y1="0" x2="0" y2="1">
131+
<linearGradient id={`${instanceId}-gradient-area-a`} x1="0" y1="0" x2="0" y2="1">
128132
<stop offset="0%" stopColor="#06b6d4" stopOpacity="0.16" />
129133
<stop offset="100%" stopColor="#06b6d4" stopOpacity="0" />
130134
</linearGradient>
131-
<linearGradient id="gradient-area-b" x1="0" y1="0" x2="0" y2="1">
135+
<linearGradient id={`${instanceId}-gradient-area-b`} x1="0" y1="0" x2="0" y2="1">
132136
<stop offset="0%" stopColor="#a855f7" stopOpacity="0.16" />
133137
<stop offset="100%" stopColor="#a855f7" stopOpacity="0" />
134138
</linearGradient>
135-
<filter id="glow-line-a" x="-10%" y="-10%" width="120%" height="120%">
139+
<filter id={`${instanceId}-glow-line-a`} x="-10%" y="-10%" width="120%" height="120%">
136140
<feGaussianBlur stdDeviation="2.5" result="blur" />
137141
<feComposite in="SourceGraphic" in2="blur" operator="over" />
138142
</filter>
139-
<filter id="glow-line-b" x="-10%" y="-10%" width="120%" height="120%">
143+
<filter id={`${instanceId}-glow-line-b`} x="-10%" y="-10%" width="120%" height="120%">
140144
<feGaussianBlur stdDeviation="2.5" result="blur" />
141145
<feComposite in="SourceGraphic" in2="blur" operator="over" />
142146
</filter>
@@ -161,14 +165,14 @@ export default function GrowthTrendChart({
161165
{/* Paths (Area) */}
162166
<motion.path
163167
d={areaStrA}
164-
fill="url(#gradient-area-a)"
168+
fill={`url(#${instanceId}-gradient-area-a)`}
165169
initial={{ opacity: 0 }}
166170
animate={{ opacity: 1 }}
167171
transition={{ duration: 0.8 }}
168172
/>
169173
<motion.path
170174
d={areaStrB}
171-
fill="url(#gradient-area-b)"
175+
fill={`url(#${instanceId}-gradient-area-b)`}
172176
initial={{ opacity: 0 }}
173177
animate={{ opacity: 1 }}
174178
transition={{ duration: 0.8, delay: 0.15 }}
@@ -182,7 +186,7 @@ export default function GrowthTrendChart({
182186
strokeWidth="2.5"
183187
strokeLinecap="round"
184188
strokeLinejoin="round"
185-
filter="url(#glow-line-a)"
189+
filter={`url(#${instanceId}-glow-line-a)`}
186190
initial={{ pathLength: 0 }}
187191
animate={{ pathLength: 1 }}
188192
transition={{ duration: 1.2, ease: 'easeOut' }}
@@ -194,7 +198,7 @@ export default function GrowthTrendChart({
194198
strokeWidth="2.5"
195199
strokeLinecap="round"
196200
strokeLinejoin="round"
197-
filter="url(#glow-line-b)"
201+
filter={`url(#${instanceId}-glow-line-b)`}
198202
initial={{ pathLength: 0 }}
199203
animate={{ pathLength: 1 }}
200204
transition={{ duration: 1.2, ease: 'easeOut', delay: 0.15 }}

0 commit comments

Comments
 (0)