Skip to content

Commit

Permalink
Fix for mobile viewport innerheight (#57)
Browse files Browse the repository at this point in the history
* separate actions and state in main store

* next config paths only in prod

* override and use css vars to calc min-h-screen

* hook for window resize to update css var for height (mobile fix)

* little refactor and use min-h-screen custom util class

* execute window resize hook in root app
  • Loading branch information
toreylittlefield committed Sep 22, 2023
1 parent fa9e38b commit 66d6266
Show file tree
Hide file tree
Showing 11 changed files with 86 additions and 13 deletions.
4 changes: 2 additions & 2 deletions packages/client/lib/components/LocationSearch.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useRef, useState } from 'react';
import useMainStore from '../../store/store';
import { useMainStoreActions } from '../../store/store';
import useOnClickOutside from '../hooks/useOnClickOutside';
import { SVGIcon } from './common/icons/SVGIcon';

Expand Down Expand Up @@ -27,7 +27,7 @@ const LocationSearch = () => {
const [value, setValue] = useState('');
const [results, setResults] = useState([]);
const searchRef = useRef(null);
const setGeoData = useMainStore((state) => state.setGeoData);
const { setGeoData } = useMainStoreActions();

let debounceTimerRef = useRef(null);

Expand Down
9 changes: 9 additions & 0 deletions packages/client/lib/components/Map.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ import {
import useFormStore from '../../store/formStore';
import useMainStore from '../../store/store';

/**
* Recommended approach for update the leaflet map
* @see https://react-leaflet.js.org/docs/api-map/#usemap
*
* @returns null
*/
const SetViewOnUserLocation = () => {
const geoData = useMainStore((state) => state.geoData);
const setLocation = useFormStore((state) => state.setLocation);
Expand Down Expand Up @@ -69,6 +75,9 @@ const SetViewOnUserLocation = () => {
return null;
};

/**
* Renders the main leaflet map with markers
*/
const Map = () => {
const geoData = useMainStore((state) => state.geoData);
const markers = useMainStore((state) => state.markers);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ const UpdateView = () => {
const markerRef = useRef(null);

return (
<div className="flex h-screen justify-center">
<div className="flex min-h-screen justify-center">
<div className="absolute top-10 z-[9999] w-11/12">
<input
type="text"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import useFormStore from '../../../../store/formStore';
import useMainStore from '../../../../store/store';
import { useMainStoreActions } from '../../../../store/store';
import { SVGIcon } from '../../common/icons/SVGIcon';

const SubmitReportForm = () => {
Expand All @@ -10,7 +10,7 @@ const SubmitReportForm = () => {
const title = useFormStore((state) => state.title);
const description = useFormStore((state) => state.description);
const location = useFormStore((state) => state.location);
const setMarkers = useMainStore((state) => state.setMarkers);
const { setMarkers } = useMainStoreActions();

const handleSubmit = (category, photos, title, description, location) => {
const formObj = {
Expand Down
4 changes: 3 additions & 1 deletion packages/client/lib/components/ReportForm/ReportForm.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@ const ReportForm = () => {
<div className="bg-background">
<form
noValidate
className={`flex min-h-screen flex-col ${step !== 5 ? 'p-2' : ''}`}
className={`flex h-full min-h-screen flex-col ${
step !== 5 ? 'p-2' : ''
}`}
>
{!isStepFive && (
<h1 className="text-2xl font-medium">Report your incident</h1>
Expand Down
33 changes: 33 additions & 0 deletions packages/client/lib/hooks/useResizeWindow.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { useEffect } from 'react';
import { useMainStoreActions } from '../../store/store';

/**
* This hook is used to observe the `window` object.
* and update the window dimensions in the store.
*/
export const useResizeWindow = () => {
const { setWindowDimensions } = useMainStoreActions();

useEffect(() => {
let timer = null;
window.onresize = () => {
// debounce the resize event to prevent too many re-renders
clearTimeout(timer);
timer = setTimeout(() => {
const innerHeight = window.innerHeight;
setWindowDimensions({
width: window.innerWidth,
height: innerHeight,
});

// set css variable for mobile browsers
let vh = innerHeight * 0.01;
document.documentElement.style.setProperty('--vh', `${vh}px`);
}, 100);
};
// cleanup listener
return () => {
window.onresize = null;
};
}, [setWindowDimensions]);
};
2 changes: 1 addition & 1 deletion packages/client/next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const CopyPlugin = require('copy-webpack-plugin');
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
basePath: '/pet-poison-alert',
basePath: process.env.NODE_ENV === 'development' ? '' : '/pet-poison-alert',
images: {
unoptimized: true, // TODO: remove this when we have a proper image pipeline
},
Expand Down
4 changes: 3 additions & 1 deletion packages/client/pages/_app.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import 'leaflet/dist/leaflet.css';
import { useResizeWindow } from '@/lib/hooks/useResizeWindow';
import '@/styles/globals.css';
import 'leaflet/dist/leaflet.css';
import type { AppProps } from 'next/app';

export default function App({ Component, pageProps }: AppProps) {
useResizeWindow();
return <Component {...pageProps} />;
}
27 changes: 22 additions & 5 deletions packages/client/store/store.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,32 @@
//@ts-check
import { create } from 'zustand';

const useMainStore = create((set) => ({
/**
* main global zustand store
* - stores the state
* - actions separated into the `useMainStoreActions` object
*/
const useMainStore = create(() => ({
geoData: { lat: -8.7445, lng: 115.182 },
markers: [],
setMarkers: (object) =>
set((state) => ({ markers: [...state.markers, object] })),
rootDimensions: { width: 0, height: 0 },
windowDimensions: { width: 0, height: 0 },
}));

/**
* state updater funcs for the main zustand store
*/
export const useMainStoreActions = () => ({
setGeoData: ({ lat, lng }) => {
console.info('setGeoData', lat, lng);
set({ geoData: { lat, lng } });
useMainStore.setState({ geoData: { lat, lng } });
},
}));
setMarkers: (object) =>
useMainStore.setState((state) => ({ markers: [...state.markers, object] })),
setRootDimensions: ({ width, height }) =>
useMainStore.setState({ rootDimensions: { width, height } }),
setWindowDimensions: ({ width, height }) =>
useMainStore.setState({ windowDimensions: { width, height } }),
});

export default useMainStore;
1 change: 1 addition & 0 deletions packages/client/styles/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
--color-primary: 168 85 247; /* rgb(168, 85, 247) */
--color-selected: 59 130 246; /* rgb(59, 130, 246) */
--color-warning: 250 204 21; /* rgb(250, 204, 21) */
--window-height: calc(var(--vh, 1vh) * 100);
}
}

Expand Down
9 changes: 9 additions & 0 deletions packages/client/tailwind.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,15 @@ module.exports = {
selected: 'rgb(var(--color-selected) / <alpha-value>)',
warning: 'rgb(var(--color-warning) / <alpha-value>)',
},
extend: {
// override the default utility class for `screen`
minHeight: {
screen: 'var(--window-height)',
},
height: {
screen: 'var(--window-height)',
},
},
},
plugins: [],
};

0 comments on commit 66d6266

Please sign in to comment.