···
516
516
/* Make card content expand to fill available space */
517
517
.card-content {
518
518
flex: 1;
519
519
-
overflow: auto;
519
519
+
overflow: visible; /* Changed from auto to prevent scrollbars */
520
520
}
521
521
522
522
/* Style for resize handle */
···
538
538
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
539
539
border-radius: 8px;
540
540
background-color: white;
541
541
-
overflow: hidden;
541
541
+
overflow: visible; /* Changed from hidden to allow content to determine height */
542
542
}
543
543
544
544
.card-header {
···
220
220
setTimeout(updateCardHeights, 100);
221
221
};
222
222
223
223
-
// Improved card height calculation
223
223
+
// Improved card height calculation with extra buffer to avoid scrollbars
224
224
const updateCardHeights = useMemo(() => {
225
225
return () => {
226
226
const rowHeight = 50; // Same as your rowHeight prop
227
227
const margin = 20; // Same as your margin prop
228
228
+
const bufferFactor = 1.15; // Add 15% extra space to avoid scrollbars
228
229
const newHeights = {};
229
230
const currentWidth = window.innerWidth;
230
231
···
246
247
Object.keys(cardRefs.current).forEach(key => {
247
248
const element = cardRefs.current[key];
248
249
if (element) {
249
249
-
// Get the content element (assuming each card has a .card-content)
250
250
-
const contentElement = element.querySelector('.card-content') || element;
251
251
-
252
252
-
// Clone the element to measure its natural height without constraints
253
253
-
const clone = contentElement.cloneNode(true);
254
254
-
clone.style.position = 'absolute';
255
255
-
clone.style.visibility = 'hidden';
256
256
-
clone.style.width = `${availableWidth}px`;
257
257
-
clone.style.height = 'auto';
258
258
-
document.body.appendChild(clone);
259
259
-
260
260
-
// Measure natural height
261
261
-
const contentHeight = clone.scrollHeight;
262
262
-
263
263
-
// Remove the clone
264
264
-
document.body.removeChild(clone);
265
265
-
266
266
-
// Calculate grid height based on content
267
267
-
const gridHeight = Math.max(Math.ceil(contentHeight / rowHeight), 6);
250
250
+
// Get both the card and its content element
251
251
+
const cardElement = element.firstChild;
252
252
+
const contentElement = cardElement.querySelector('.card-content');
253
253
+
const headerElement = cardElement.querySelector('.card-header');
268
254
269
269
-
// Store the new height
270
270
-
newHeights[key] = gridHeight;
255
255
+
if (contentElement && headerElement) {
256
256
+
// Clone the content element to measure its natural height without constraints
257
257
+
const clone = contentElement.cloneNode(true);
258
258
+
clone.style.position = 'absolute';
259
259
+
clone.style.visibility = 'hidden';
260
260
+
clone.style.width = `${availableWidth - 32}px`; // Account for padding
261
261
+
clone.style.height = 'auto';
262
262
+
clone.style.overflow = 'visible'; // Ensure we get the full height
263
263
+
document.body.appendChild(clone);
264
264
+
265
265
+
// Measure natural height
266
266
+
const contentHeight = clone.scrollHeight;
267
267
+
268
268
+
// Remove the clone
269
269
+
document.body.removeChild(clone);
270
270
+
271
271
+
// Add header height and padding to content height
272
272
+
const headerHeight = headerElement.offsetHeight;
273
273
+
const totalCardHeight = (contentHeight * bufferFactor) + headerHeight;
274
274
+
275
275
+
// Convert to grid units with extra space to ensure no scrollbars
276
276
+
const gridHeight = Math.max(Math.ceil(totalCardHeight / rowHeight), 6);
277
277
+
278
278
+
// Store the new height
279
279
+
newHeights[key] = gridHeight;
280
280
+
}
271
281
}
272
282
});
273
283
···
291
301
292
302
// Update state with new heights
293
303
setCardHeights(newHeights);
304
304
+
305
305
+
// Remove any scrollbars by checking if content overflow exists
306
306
+
// This runs after state updates and DOM re-renders
307
307
+
setTimeout(() => {
308
308
+
Object.keys(cardRefs.current).forEach(key => {
309
309
+
const element = cardRefs.current[key];
310
310
+
if (element) {
311
311
+
const contentElement = element.querySelector('.card-content');
312
312
+
if (contentElement && contentElement.scrollHeight > contentElement.clientHeight) {
313
313
+
// Content still overflows, adjust the height further
314
314
+
const currentLayout = updatedLayouts[currentBreakpoint].find(item => item.i === key);
315
315
+
if (currentLayout) {
316
316
+
const additionalRows = Math.ceil((contentElement.scrollHeight - contentElement.clientHeight) / rowHeight) + 1;
317
317
+
const newGridHeight = currentLayout.h + additionalRows;
318
318
+
319
319
+
// Update just this specific card height
320
320
+
const newLayout = { ...currentLayout, h: newGridHeight };
321
321
+
updatedLayouts[currentBreakpoint] = updatedLayouts[currentBreakpoint].map(item =>
322
322
+
item.i === key ? newLayout : item
323
323
+
);
324
324
+
325
325
+
// Apply updates
326
326
+
setCurrentLayouts(updatedLayouts);
327
327
+
localStorage.setItem('userProfileLayouts', JSON.stringify(updatedLayouts));
328
328
+
}
329
329
+
}
330
330
+
}
331
331
+
});
332
332
+
}, 300);
294
333
};
295
334
}, [currentLayouts]);
296
335
···
371
410
fetchAccountData();
372
411
}, [username, navigate, updateCardHeights]);
373
412
374
374
-
// Add effect to initialize the layout on first render
413
413
+
// Add effect to initialize the layout on first render with multiple updates
414
414
+
// to ensure proper sizing as components load
375
415
useEffect(() => {
376
376
-
// Small delay to ensure DOM is ready
416
416
+
// Initial update after components mount
377
417
setTimeout(updateCardHeights, 300);
378
418
419
419
+
// Secondary update after any async content has likely loaded
420
420
+
setTimeout(updateCardHeights, 1000);
421
421
+
422
422
+
// Final update to catch any late-loading content
423
423
+
setTimeout(updateCardHeights, 2000);
424
424
+
379
425
// Add a resize observer to each card to handle content changes
380
426
const resizeObserver = new ResizeObserver(_.debounce(() => {
381
427
updateCardHeights();
428
428
+
// Additional update after a short delay to catch any cascading changes
429
429
+
setTimeout(updateCardHeights, 500);
382
430
}, 300));
383
431
432
432
+
// Observe both the cards and their content
384
433
Object.values(cardRefs.current).forEach(ref => {
385
434
if (ref) {
386
435
resizeObserver.observe(ref);
436
436
+
437
437
+
// Also observe the content element for more granular changes
438
438
+
const contentElement = ref.querySelector('.card-content');
439
439
+
if (contentElement) {
440
440
+
resizeObserver.observe(contentElement);
441
441
+
}
387
442
}
388
443
});
389
444