mirror of
https://github.com/TheRealOwenRees/echecsfrance.git
synced 2026-07-23 04:26:57 +00:00
Reorganise code - use src folder
This commit is contained in:
@@ -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);
|
||||
@@ -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;
|
||||
@@ -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);
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user