From 5a31b91ab033baf1c63f9f414e50655fb1edce9b Mon Sep 17 00:00:00 2001 From: Jordan Eldredge Date: Sun, 6 Sep 2020 13:28:21 -0700 Subject: [PATCH] Account for scrollabar width --- src/App.css | 4 ---- src/App.js | 13 +++++++++---- src/SkinTable.js | 7 +++++-- src/hooks.js | 31 ++++++++++++++++++++++++++++--- 4 files changed, 42 insertions(+), 13 deletions(-) diff --git a/src/App.css b/src/App.css index 62e4ea90..8edbe29b 100644 --- a/src/App.css +++ b/src/App.css @@ -138,10 +138,6 @@ button:active { color: rgb(73, 83, 112); } -#infinite-skins { - margin-top: 46px; /* This matches the height of #search */ -} - #webamp { opacity: 0; transition: opacity 400ms ease-in-out; diff --git a/src/App.js b/src/App.js index 807debba..4faca54f 100644 --- a/src/App.js +++ b/src/App.js @@ -8,7 +8,7 @@ import SkinTable from "./SkinTable"; import FocusedSkin from "./FocusedSkin"; import * as Selectors from "./redux/selectors"; import { ABOUT_PAGE } from "./constants"; -import { useWindowSize } from "./hooks"; +import { useWindowSize, useScrollbarWidth } from "./hooks"; import { SCREENSHOT_WIDTH, SKIN_RATIO } from "./constants"; // Render your table @@ -21,9 +21,14 @@ const getTableDimensions = (windowWidth, scale) => { }; function App(props) { - const { windowWidth, windowHeight } = useWindowSize(); + const scrollbarWidth = useScrollbarWidth(); + const { + windowWidth: windowWidthWithScrollabar, + windowHeight, + } = useWindowSize(); + const { columnWidth, rowHeight, columnCount } = getTableDimensions( - windowWidth, + windowWidthWithScrollabar - scrollbarWidth, props.scale ); return ( @@ -35,7 +40,7 @@ function App(props) { columnWidth={columnWidth} rowHeight={rowHeight} windowHeight={windowHeight} - windowWidth={windowWidth} + windowWidth={windowWidthWithScrollabar} /> {props.aboutPage ? ( diff --git a/src/SkinTable.js b/src/SkinTable.js index e248e964..bda6251f 100644 --- a/src/SkinTable.js +++ b/src/SkinTable.js @@ -6,6 +6,8 @@ import * as Actions from "./redux/actionCreators"; import { FixedSizeGrid as Grid } from "react-window"; import Cell from "./Cell"; +const HEADING_HEIGHT = 46; + const SkinTable = ({ columnCount, columnWidth, @@ -35,7 +37,7 @@ const SkinTable = ({ gridRef.current.scrollTo({ scrollLeft: 0, scrollTop: 0 }); }, [skinCount]); return ( -
+
{skinCount > 0 || searchQuery === "" ? ( {Cell} diff --git a/src/hooks.js b/src/hooks.js index ddf07c80..92f8f815 100644 --- a/src/hooks.js +++ b/src/hooks.js @@ -1,9 +1,9 @@ import * as Utils from "./utils"; -import React from "react"; +import { useMemo, useState, useEffect } from "react"; export function useWindowSize() { - const [windowSize, setWindowSize] = React.useState(Utils.getWindowSize()); - React.useEffect(() => { + const [windowSize, setWindowSize] = useState(Utils.getWindowSize()); + useEffect(() => { // TODO: Consider thottle const handleResize = () => { setWindowSize(Utils.getWindowSize()); @@ -13,3 +13,28 @@ export function useWindowSize() { }, []); return windowSize; } + +// https://stackoverflow.com/a/13382873/1263117 +export function useScrollbarWidth() { + // TODO: Can this change over the lifetime of the window? + return useMemo(() => { + // Creating invisible container + const outer = document.createElement("div"); + outer.style.visibility = "hidden"; + outer.style.overflow = "scroll"; // forcing scrollbar to appear + outer.style.msOverflowStyle = "scrollbar"; // needed for WinJS apps + document.body.appendChild(outer); + + // Creating inner element and placing it in the container + const inner = document.createElement("div"); + outer.appendChild(inner); + + // Calculating difference between container's full width and the child width + const scrollbarWidth = outer.offsetWidth - inner.offsetWidth; + + // Removing temporary elements from the DOM + outer.parentNode.removeChild(outer); + + return scrollbarWidth; + }, []); +}