From 79d97a6c26c82d2d564639946b56ef32cc16697d Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 1 Feb 2026 07:10:58 +0000 Subject: [PATCH 1/3] fix: Replace responsive Col props with fixed spans to prevent infinite loop Antd's Row/Col components with responsive breakpoints (xs, sm, lg, etc.) internally use a responsiveObserver that subscribes to media query changes. When many components use responsive breakpoints (like items in a list), media query changes (e.g., Safari toolbar appearing/disappearing on iOS) can trigger cascading re-renders leading to React's maximum update depth error. This fix: - Replaces responsive Col props with fixed span values in queue-list.tsx, queue-list-item.tsx, and climbs-list.tsx - Adds CSS media queries in climbs-list.module.css for responsive 2-column layout on larger screens - Follows CLAUDE.md guidelines to use CSS media queries instead of JavaScript-based breakpoint detection https://claude.ai/code/session_018BBna6eD1vCRKfZSdK11QR --- .../components/board-page/climbs-list.module.css | 16 ++++++++++++++++ .../app/components/board-page/climbs-list.tsx | 5 +++-- .../components/queue-control/queue-list-item.tsx | 8 ++++---- .../app/components/queue-control/queue-list.tsx | 12 ++++++------ 4 files changed, 29 insertions(+), 12 deletions(-) create mode 100644 packages/web/app/components/board-page/climbs-list.module.css diff --git a/packages/web/app/components/board-page/climbs-list.module.css b/packages/web/app/components/board-page/climbs-list.module.css new file mode 100644 index 00000000..1f1a4e98 --- /dev/null +++ b/packages/web/app/components/board-page/climbs-list.module.css @@ -0,0 +1,16 @@ +/* Responsive grid column for climbs list + Uses CSS media queries instead of antd's responsive Col props + to avoid JavaScript-based breakpoint detection issues */ +.climbCol { + /* Default: full width on small screens */ + flex: 0 0 100%; + max-width: 100%; +} + +/* lg breakpoint (992px+): 2 columns */ +@media (min-width: 992px) { + .climbCol { + flex: 0 0 50%; + max-width: 50%; + } +} diff --git a/packages/web/app/components/board-page/climbs-list.tsx b/packages/web/app/components/board-page/climbs-list.tsx index b9542624..0190a863 100644 --- a/packages/web/app/components/board-page/climbs-list.tsx +++ b/packages/web/app/components/board-page/climbs-list.tsx @@ -7,6 +7,7 @@ import { useQueueContext } from '../graphql-queue'; import ClimbCard from '../climb-card/climb-card'; import { ClimbCardSkeleton } from './board-page-skeleton'; import { useSearchParams } from 'next/navigation'; +import styles from './climbs-list.module.css'; type ClimbsListProps = ParsedBoardRouteParameters & { boardDetails: BoardDetails; @@ -15,7 +16,7 @@ type ClimbsListProps = ParsedBoardRouteParameters & { const ClimbsListSkeleton = ({ aspectRatio }: { aspectRatio: number }) => { return Array.from({ length: 10 }, (_, i) => ( - + )); @@ -134,7 +135,7 @@ const ClimbsList = ({ boardDetails, initialClimbs }: ClimbsListProps) => {
{climbs.map((climb) => ( - +
{ climbsRefs.current[climb.uuid] = el; diff --git a/packages/web/app/components/queue-control/queue-list-item.tsx b/packages/web/app/components/queue-control/queue-list-item.tsx index ee0f3a53..6b37d996 100644 --- a/packages/web/app/components/queue-control/queue-list-item.tsx +++ b/packages/web/app/components/queue-control/queue-list-item.tsx @@ -328,13 +328,13 @@ const QueueListItem: React.FC = ({ onDoubleClick={() => setCurrentClimbQueueItem(item)} > - + - + = ({ /> {item.addedByUser && ( - + } /> )} - + (({ boardDetails, o }} > - + (({ boardDetails, o onNavigate={onClimbNavigate} /> - + - +