feat: improve 'Group By' dropdown UI/UX in Grid tab (click-to-open and click-outside to close)

This commit is contained in:
Christian Vidal Wolf
2026-01-26 15:16:28 +01:00
parent 48f185e3bc
commit 18c4ef375b
+31 -8
View File
@@ -1,4 +1,4 @@
import React, { useState, useMemo, useEffect } from 'react';
import React, { useState, useMemo, useEffect, useRef } from 'react';
import {
LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer
} from 'recharts';
@@ -233,6 +233,19 @@ const DataGrid: React.FC<DataGridProps> = ({ data, hasCustomerFilter, adsData =
const [visibleMetrics, setVisibleMetrics] = useState<('sellOut' | 'units')[]>(['sellOut', 'units']);
const [showAdsMetrics, setShowAdsMetrics] = useState(true);
const [showAttributedSales, setShowAttributedSales] = useState(false);
const [showDimensionMenu, setShowDimensionMenu] = useState(false);
const dimensionRef = useRef<HTMLDivElement>(null);
// Close dimension menu on click outside
useEffect(() => {
const handleClickOutside = (event: MouseEvent) => {
if (dimensionRef.current && !dimensionRef.current.contains(event.target as Node)) {
setShowDimensionMenu(false);
}
};
document.addEventListener('mousedown', handleClickOutside);
return () => document.removeEventListener('mousedown', handleClickOutside);
}, []);
// Calculate Ads Summary for the Grid
const adsSummary = useMemo(() => {
@@ -682,15 +695,22 @@ const DataGrid: React.FC<DataGridProps> = ({ data, hasCustomerFilter, adsData =
<div className="flex flex-wrap items-center gap-3 w-full lg:w-auto">
{/* Dimensions Selector */}
<div className="relative group z-30">
<button className="flex items-center gap-2 px-3 py-2 bg-slate-800 hover:bg-slate-700 border border-slate-700 rounded-lg text-sm font-medium transition-colors">
<div className="relative z-30" ref={dimensionRef}>
<button
onClick={() => setShowDimensionMenu(!showDimensionMenu)}
className={`flex items-center gap-2 px-3 py-2 rounded-lg text-sm font-medium transition-all border shadow-sm ${showDimensionMenu ? 'bg-slate-700 text-white border-indigo-500/50 ring-1 ring-indigo-500/30' : 'bg-slate-800 text-slate-300 border-slate-700 hover:bg-slate-700'}`}
>
<span className="text-slate-300">Group By:</span>
<span className="text-white font-bold">{effectiveDimensions.length} Columns</span>
<svg className="w-4 h-4 text-slate-400" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor"><path strokeLinecap="round" strokeLinejoin="round" d="m19.5 8.25-7.5 7.5-7.5-7.5" /></svg>
<svg className={`w-4 h-4 text-slate-400 transition-transform duration-200 ${showDimensionMenu ? 'rotate-180' : ''}`} fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor"><path strokeLinecap="round" strokeLinejoin="round" d="m19.5 8.25-7.5 7.5-7.5-7.5" /></svg>
</button>
<div className="absolute top-full left-0 mt-2 w-48 bg-slate-900 border border-slate-700 rounded-xl shadow-xl p-2 hidden group-hover:block animate-fade-in">
{showDimensionMenu && (
<div className="absolute top-full left-0 mt-2 w-56 bg-slate-900 border border-slate-700 rounded-xl shadow-2xl p-2 animate-fade-in z-50">
<div className="px-2 py-1.5 mb-1 border-b border-slate-800">
<span className="text-[10px] font-black text-slate-500 uppercase tracking-widest">Select Columns</span>
</div>
{DIMENSION_OPTIONS.map(dim => (
<label key={dim.value} className="flex items-center gap-2 p-2 hover:bg-slate-800 rounded cursor-pointer">
<label key={dim.value} className="flex items-center gap-3 p-2.5 hover:bg-white/[0.03] rounded-lg cursor-pointer group transition-colors">
<input
type="checkbox"
checked={selectedDimensions.includes(dim.value)}
@@ -701,12 +721,15 @@ const DataGrid: React.FC<DataGridProps> = ({ data, hasCustomerFilter, adsData =
setSelectedDimensions([...selectedDimensions, dim.value]);
}
}}
className="rounded border-slate-600 bg-slate-800 text-primary focus:ring-primary"
className="w-4 h-4 rounded border-slate-600 bg-slate-800 text-indigo-500 focus:ring-indigo-500/50 transition-all"
/>
<span className="text-sm text-slate-300">{dim.label}</span>
<span className={`text-sm font-medium transition-colors ${selectedDimensions.includes(dim.value) ? 'text-white' : 'text-slate-400 group-hover:text-slate-300'}`}>
{dim.label}
</span>
</label>
))}
</div>
)}
</div>
{/* Filter Builder Trigger */}