fix: clickable trainers in day cards, remove trainer dropdown, fix layout shift
- Remove trainer dropdown from filter bar — filter by clicking names in schedule cards - Make trainer/type clickable in DayCard with gold highlight on active filter - Fix showcase layout shift: track max detail height to prevent section from shrinking - Remove key-based grid remount that re-triggered Reveal animations on filter change Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -283,7 +283,6 @@ export function Schedule({ data: schedule, classItems }: ScheduleProps) {
|
||||
{/* Desktop: grid layout */}
|
||||
<Reveal>
|
||||
<div
|
||||
key={`${locationMode}-${filterTrainer}-${filterType}-${filterStatus}`}
|
||||
className={`mt-8 hidden sm:grid grid-cols-1 gap-3 px-4 sm:px-6 lg:px-8 xl:px-6 ${filteredDays.length >= 7 ? "sm:grid-cols-2 lg:grid-cols-4 xl:grid-cols-7" : filteredDays.length >= 6 ? "sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-6" : filteredDays.length >= 4 ? "sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-5" : filteredDays.length === 3 ? "sm:grid-cols-2 lg:grid-cols-3" : filteredDays.length === 2 ? "sm:grid-cols-2" : "justify-items-center"}`}
|
||||
style={filteredDays.length === 1 ? undefined : filteredDays.length <= 3 && filteredDays.length > 0 ? { maxWidth: filteredDays.length * 340 + (filteredDays.length - 1) * 12, marginInline: "auto" } : undefined}
|
||||
>
|
||||
|
||||
@@ -25,10 +25,24 @@ export function ShowcaseLayout<T>({
|
||||
const selectorRef = useRef<HTMLDivElement>(null);
|
||||
const activeItemRef = useRef<HTMLButtonElement>(null);
|
||||
const detailRef = useRef<HTMLDivElement>(null);
|
||||
const detailWrapRef = useRef<HTMLDivElement>(null);
|
||||
const [minHeight, setMinHeight] = useState<number | undefined>(undefined);
|
||||
const measuredHeights = useRef<number[]>([]);
|
||||
const [isUserInteracting, setIsUserInteracting] = useState(false);
|
||||
const [displayIndex, setDisplayIndex] = useState(activeIndex);
|
||||
const [fading, setFading] = useState(false);
|
||||
|
||||
// Track max height across all seen items to prevent shrinking
|
||||
useEffect(() => {
|
||||
if (!detailRef.current || fading) return;
|
||||
const h = detailRef.current.offsetHeight;
|
||||
measuredHeights.current[displayIndex] = h;
|
||||
const maxH = Math.max(...measuredHeights.current.filter(Boolean));
|
||||
if (maxH > (minHeight ?? 0)) {
|
||||
setMinHeight(maxH);
|
||||
}
|
||||
}, [displayIndex, fading]);
|
||||
|
||||
useEffect(() => {
|
||||
if (activeIndex === displayIndex) return;
|
||||
setFading(true);
|
||||
@@ -116,16 +130,21 @@ export function ShowcaseLayout<T>({
|
||||
{/* Detail area */}
|
||||
<div className="lg:w-[60%]">
|
||||
<div
|
||||
ref={detailRef}
|
||||
className={`transition-all duration-300 ease-out ${
|
||||
fading
|
||||
? "opacity-0 translate-y-2"
|
||||
: "opacity-100 translate-y-0"
|
||||
}`}
|
||||
onTouchStart={handleTouchStart}
|
||||
onTouchEnd={handleTouchEnd}
|
||||
ref={detailWrapRef}
|
||||
style={minHeight != null ? { minHeight } : undefined}
|
||||
>
|
||||
{renderDetail(items[displayIndex], displayIndex)}
|
||||
<div
|
||||
ref={detailRef}
|
||||
className={`transition-all duration-300 ease-out ${
|
||||
fading
|
||||
? "opacity-0 translate-y-2"
|
||||
: "opacity-100 translate-y-0"
|
||||
}`}
|
||||
onTouchStart={handleTouchStart}
|
||||
onTouchEnd={handleTouchEnd}
|
||||
>
|
||||
{renderDetail(items[displayIndex], displayIndex)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Counter */}
|
||||
|
||||
Reference in New Issue
Block a user