Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

css and js breakpoints don't match when the "show scroll bars" setting set to "always" on MacOS #1418

Open
2 of 6 tasks
hamsterhomka opened this issue Nov 28, 2023 · 4 comments
Labels
bug Something isn't working gluestack-style Issue related to gluestack-style

Comments

@hamsterhomka
Copy link

hamsterhomka commented Nov 28, 2023

Description

css and js breakpoints don't match when the "show scroll bars" setting set to "always" on MacOS. It happens because css counts the actual 1264px browser's window width as 1280px, whereas js useMedia() hook counts 1280px as 1280px. We can see that the issue is exactly in the 16px width scrollbar.

CodeSandbox/Snack link

No response

Steps to reproduce

Here's the example repo with the issue. https://github.com/hamsterhomka/gluestack-issue-breakpoints

  1. Set "show scroll bars" setting to "always" in Appearance settings on MacOs
  2. Start the dev server
  3. Try to change the window width
  4. See that the breakpoints don't match

gluestack-ui Version

1.0.0

Platform

  • Expo
  • React Native CLI
  • Next
  • Web
  • Android
  • iOS

Other Platform

No response

Additional Information

js box is not visible (1279px)
xl-js-not-visible

js box is visible (1282px)
xl-js-visible

css box is not visible (1264px)
xl-css-not-visible

css box is visible (1266px)
xl-css-visible

Here is a simple patch to fix it. I created a hook useInnerWidth() that returns window.innerWidth on web (that matches css breakpoints) and used it in useMedia() gluestack hook

@gluestack-style-react-npm-1.0.11-e64493965f.patch

diff --git a/lib/module/hooks/useMedia.js b/lib/module/hooks/useMedia.js
index 89d163981c9d889a3623a6826721dd3f9ab7f910..3aaedc0a00ffd4e7a2c208851ca194a1b3de925b 100644
--- a/lib/module/hooks/useMedia.js
+++ b/lib/module/hooks/useMedia.js
@@ -1,17 +1,45 @@
-import { useWindowDimensions } from 'react-native';
-import { isValidBreakpoint } from '../generateStylePropsFromCSSIds';
-import { useStyled } from '../StyledProvider';
-export const useMedia = () => {
-  var _theme$config;
-  const theme = useStyled();
+import { Platform, useWindowDimensions } from 'react-native'
+import { isValidBreakpoint } from '../generateStylePropsFromCSSIds'
+import { useStyled } from '../StyledProvider'
+import { useEffect, useState } from 'react'
+
+const useInnerWidth = () => {
   const {
     width
-  } = useWindowDimensions();
-  const mediaQueries = theme === null || theme === void 0 || (_theme$config = theme.config) === null || _theme$config === void 0 || (_theme$config = _theme$config.tokens) === null || _theme$config === void 0 ? void 0 : _theme$config.mediaQueries;
-  const breakpoints = {};
+  } = useWindowDimensions()
+
+  const initialWidth = Platform.OS === 'web' && typeof window !== 'undefined' ? window.innerWidth : width
+  const [innerWidth, setInnerWidth] = useState(initialWidth)
+
+  const handleResize = () => {
+    setInnerWidth(window.innerWidth)
+  }
+
+  useEffect(() => {
+    if (Platform.OS === 'web') {
+      setInnerWidth(window.innerWidth);
+
+      window.addEventListener('resize', handleResize);
+    }
+
+    return () => {
+      window.removeEventListener('resize', handleResize);
+    };
+  }, [])
+
+  return innerWidth
+}
+
+export const useMedia = () => {
+  var _theme$config
+  const theme = useStyled()
+  const width = useInnerWidth()
+
+  const mediaQueries = theme === null || theme === void 0 || (_theme$config = theme.config) === null || _theme$config === void 0 || (_theme$config = _theme$config.tokens) === null || _theme$config === void 0 ? void 0 : _theme$config.mediaQueries
+  const breakpoints = {}
   Object.keys(mediaQueries).forEach(currentBreakPoint => {
-    breakpoints[currentBreakPoint] = isValidBreakpoint(theme === null || theme === void 0 ? void 0 : theme.config, mediaQueries[currentBreakPoint], width);
-  });
-  return breakpoints;
-};
+    breakpoints[currentBreakPoint] = isValidBreakpoint(theme === null || theme === void 0 ? void 0 : theme.config, mediaQueries[currentBreakPoint], width)
+  })
+  return breakpoints
+}
 //# sourceMappingURL=useMedia.js.map
@hamsterhomka hamsterhomka added the bug Something isn't working label Nov 28, 2023
@hamsterhomka hamsterhomka changed the title css and js breakpoints don't match each other when "show scroll bars" setting set to "always" on MacOs css and js breakpoints don't match when the "show scroll bars" setting set to "always" on MacOs Nov 28, 2023
@hamsterhomka hamsterhomka changed the title css and js breakpoints don't match when the "show scroll bars" setting set to "always" on MacOs css and js breakpoints don't match when the "show scroll bars" setting set to "always" on MacOS Nov 28, 2023
@makkarMeenu makkarMeenu added the gluestack-style Issue related to gluestack-style label Nov 29, 2023
@Gluant101
Copy link
Contributor

Hey, our Devs will look into this. Thanks!

@Gluant101 Gluant101 moved this from Backlog to Todo in gluestack support Nov 30, 2023
@ankit-tailor
Copy link
Contributor

Hey @hamsterhomka, Thanks for reporting the issue. We'll look into it.

@hamsterhomka
Copy link
Author

Any updates on fixing this?

@surajahmed
Copy link
Contributor

@hamsterhomka We're internally using useWindowDimensions hook from react-native-web, which returns window viewport width. This causes the difference when scrollbar is rendered. We're going to use window.innerWidth instead of useWindowDimenstions. Thanks for reporting this. Hopefully we'll fix this in the coming release.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working gluestack-style Issue related to gluestack-style
Projects
Status: Backlog
Status: Todo
Development

No branches or pull requests

5 participants