feat: enhance tooltip and global styles for improved visibility; implement custom tooltip rendering in CategoryTrendChart and enforce opacity settings in globals.css for Radix Portal and Recharts tooltips
All checks were successful
Deploy with Docker Compose / deploy (push) Successful in 4m7s
All checks were successful
Deploy with Docker Compose / deploy (push) Successful in 4m7s
This commit is contained in:
@@ -381,6 +381,29 @@
|
|||||||
opacity: 1 !important;
|
opacity: 1 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Forcer l'opacité sur les wrappers Radix Portal */
|
||||||
|
[data-radix-portal],
|
||||||
|
[data-radix-portal] > *,
|
||||||
|
[data-radix-popper-content-wrapper],
|
||||||
|
[data-radix-popper-content-wrapper] > * {
|
||||||
|
opacity: 1 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Forcer l'opacité sur les tooltips Recharts */
|
||||||
|
.recharts-tooltip-wrapper,
|
||||||
|
.recharts-tooltip-wrapper > *,
|
||||||
|
.recharts-tooltip-wrapper > div,
|
||||||
|
.recharts-tooltip-wrapper > div > *,
|
||||||
|
.recharts-tooltip-cursor {
|
||||||
|
opacity: 1 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Forcer l'opacité et le background opaque sur le contenu du tooltip */
|
||||||
|
.recharts-tooltip-wrapper > div {
|
||||||
|
background-color: var(--background) !important;
|
||||||
|
opacity: 1 !important;
|
||||||
|
}
|
||||||
|
|
||||||
/* Glassmorphism effect très prononcé */
|
/* Glassmorphism effect très prononcé */
|
||||||
.glass {
|
.glass {
|
||||||
background: var(--card);
|
background: var(--card);
|
||||||
|
|||||||
@@ -166,11 +166,67 @@ export function CategoryTrendChart({
|
|||||||
tick={{ fill: "var(--muted-foreground)" }}
|
tick={{ fill: "var(--muted-foreground)" }}
|
||||||
/>
|
/>
|
||||||
<Tooltip
|
<Tooltip
|
||||||
formatter={(value: number) => formatCurrency(value)}
|
content={({ active, payload, label }) => {
|
||||||
contentStyle={{
|
if (!active || !payload?.length) return null;
|
||||||
backgroundColor: "var(--card)",
|
|
||||||
border: "1px solid var(--border)",
|
// Filtrer seulement les catégories qui ont une valeur
|
||||||
borderRadius: "8px",
|
const entriesWithValue = payload.filter(
|
||||||
|
(entry) => entry.value !== undefined && entry.value !== null && Number(entry.value) !== 0
|
||||||
|
);
|
||||||
|
|
||||||
|
if (entriesWithValue.length === 0) return null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="px-2.5 py-2 rounded-lg shadow-lg"
|
||||||
|
style={{
|
||||||
|
backgroundColor: "var(--background)",
|
||||||
|
border: "1px solid var(--border)",
|
||||||
|
opacity: 1,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div className="text-xs font-medium text-foreground mb-1.5 pb-1 border-b border-border/50">
|
||||||
|
{label}
|
||||||
|
</div>
|
||||||
|
<div className="space-y-1">
|
||||||
|
{entriesWithValue.map((entry, index) => {
|
||||||
|
const categoryId = entry.dataKey as string;
|
||||||
|
const categoryInfo = getCategoryInfo(categoryId);
|
||||||
|
const categoryName = getCategoryName(categoryId);
|
||||||
|
const value = entry.value as number;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
key={`tooltip-${categoryId}-${index}`}
|
||||||
|
className="flex items-center gap-1.5"
|
||||||
|
>
|
||||||
|
{categoryInfo ? (
|
||||||
|
<CategoryIcon
|
||||||
|
icon={categoryInfo.icon}
|
||||||
|
color={categoryInfo.color}
|
||||||
|
size={12}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<div
|
||||||
|
className="w-3 h-3 rounded-full shrink-0"
|
||||||
|
style={{ backgroundColor: "#94a3b8" }}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
<span className="text-xs text-foreground flex-1 min-w-0 truncate">
|
||||||
|
{categoryName}
|
||||||
|
</span>
|
||||||
|
<span className="text-xs font-semibold text-foreground tabular-nums whitespace-nowrap">
|
||||||
|
{formatCurrency(value)}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
wrapperStyle={{
|
||||||
|
opacity: 1,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<Legend
|
<Legend
|
||||||
@@ -179,8 +235,9 @@ export function CategoryTrendChart({
|
|||||||
const allCategoryIds = Array.from(categoryTotals.keys());
|
const allCategoryIds = Array.from(categoryTotals.keys());
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-wrap justify-center gap-x-4 gap-y-1 mt-2">
|
<div className="max-h-[60px] overflow-y-auto overflow-x-hidden pr-2 mt-2">
|
||||||
{allCategoryIds.map((categoryId) => {
|
<div className="flex flex-wrap justify-center gap-x-4 gap-y-1">
|
||||||
|
{allCategoryIds.map((categoryId) => {
|
||||||
const categoryInfo = getCategoryInfo(categoryId);
|
const categoryInfo = getCategoryInfo(categoryId);
|
||||||
const categoryName = getCategoryName(categoryId);
|
const categoryName = getCategoryName(categoryId);
|
||||||
if (!categoryInfo && categoryId !== "uncategorized")
|
if (!categoryInfo && categoryId !== "uncategorized")
|
||||||
@@ -233,6 +290,7 @@ export function CategoryTrendChart({
|
|||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
@@ -259,6 +317,7 @@ export function CategoryTrendChart({
|
|||||||
strokeWidth={isSelected ? 2 : 1}
|
strokeWidth={isSelected ? 2 : 1}
|
||||||
strokeOpacity={isSelected ? 1 : 0.3}
|
strokeOpacity={isSelected ? 1 : 0.3}
|
||||||
dot={false}
|
dot={false}
|
||||||
|
connectNulls={true}
|
||||||
hide={!isSelected && selectedCategories.length > 0}
|
hide={!isSelected && selectedCategories.length > 0}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user