Reorganise code - use src folder

This commit is contained in:
Timothy Armes
2023-10-11 08:45:36 +02:00
committed by Owen Rees
parent 2dc5f477c9
commit b5061b1c78
89 changed files with 70 additions and 69 deletions
+85
View File
@@ -0,0 +1,85 @@
import { useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
import resolveConfig from "tailwindcss/resolveConfig";
import tailwindConfig from "@/../tailwind.config.js";
const config = resolveConfig(tailwindConfig);
const isSSR =
typeof window === "undefined" ||
!window.navigator ||
/ServerSideRendering|^Deno\//.test(window.navigator.userAgent);
const isBrowser = !isSSR;
const useIsomorphicEffect = isBrowser ? useLayoutEffect : useEffect;
export type CreatorReturnType = {
useBreakpoint<B>(breakpoint: B, defaultValue?: boolean): boolean;
useBreakpointEffect<B>(breakpoint: B, effect: (match: boolean) => void): void;
useBreakpointValue<B, T, U>(breakpoint: B, valid: T, invalid: U): T | U;
};
function create(screens: object | undefined) {
if (!screens) {
throw new Error(
"Failed to create breakpoint hooks, given `screens` value is invalid.",
);
}
function useBreakpoint(breakpoint: string, defaultValue: boolean = false) {
const [match, setMatch] = useState(() => defaultValue);
const matchRef = useRef(defaultValue);
useIsomorphicEffect(() => {
if (!(isBrowser && "matchMedia" in window)) return undefined;
function track() {
// @ts-expect-error accessing index with uncertain `screens` type
const value = (screens[breakpoint] as string) ?? "999999px";
const query = window.matchMedia(`(min-width: ${value})`);
matchRef.current = query.matches;
if (matchRef.current != match) {
setMatch(matchRef.current);
}
}
window.addEventListener("resize", track);
track();
return () => window.removeEventListener("resize", track);
});
return match;
}
function useBreakpointEffect<Breakpoint extends string>(
breakpoint: Breakpoint,
effect: (match: boolean) => void,
) {
const match = useBreakpoint(breakpoint);
useEffect(() => effect(match));
return null;
}
function useBreakpointValue<Breakpoint extends string, T, U>(
breakpoint: Breakpoint,
valid: T,
invalid: U,
) {
const match = useBreakpoint(breakpoint);
const value = useMemo(
() => (match ? valid : invalid),
[invalid, match, valid],
);
return value;
}
return {
useBreakpoint,
useBreakpointEffect,
useBreakpointValue,
} as CreatorReturnType;
}
export const { useBreakpoint, useBreakpointEffect, useBreakpointValue } =
create(config.theme!.screens);
+30
View File
@@ -0,0 +1,30 @@
import { Dispatch, SetStateAction, useEffect, useState } from "react";
function useDarkMode(): [string, Dispatch<SetStateAction<string>>] {
const prefersDarkMode =
typeof window !== "undefined" &&
window.matchMedia("(prefers-color-scheme: dark)").matches;
const [theme, setTheme] = useState(
typeof window !== "undefined"
? localStorage.theme || (prefersDarkMode ? "dark" : "light")
: "dark",
);
const colorTheme = theme === "dark" ? "light" : "dark";
useEffect(() => {
const root = window.document.documentElement;
root.classList.remove(colorTheme);
root.classList.add(theme);
if (typeof window !== "undefined") {
localStorage.setItem("theme", theme);
}
}, [colorTheme, theme]);
return [colorTheme, setTheme];
}
export default useDarkMode;
+49
View File
@@ -0,0 +1,49 @@
export const useDynamicViewportUnits = () => {
const setVh = function () {
var svh = document.documentElement.clientHeight * 0.01;
document.documentElement.style.setProperty("--1svh", svh + "px");
var dvh = window.innerHeight * 0.01;
document.documentElement.style.setProperty("--1dvh", dvh + "px");
};
const isMobile = function () {
if (
/Android|iPhone|iPad|iPod/i.test(navigator.userAgent) ||
(navigator.userAgent.match(/Mac/) &&
navigator.maxTouchPoints &&
navigator.maxTouchPoints > 2)
) {
return true;
}
return false;
};
// SSR support
if (typeof window === "undefined") {
return;
}
// Don't run polyfill if browser supports the units natively
if (
"CSS" in window &&
"supports" in window.CSS &&
window.CSS.supports("height: 100svh") &&
window.CSS.supports("height: 100dvh") &&
window.CSS.supports("height: 100lvh")
) {
return;
}
// Don't run on desktop browsers
if (!isMobile) {
return;
}
window.addEventListener("resize", setVh);
setVh();
return () => {
window.removeEventListener("resize", setVh);
};
};