48 lines
1.5 KiB
TypeScript
48 lines
1.5 KiB
TypeScript
import { useLayoutEffect, useState } from "react"
|
|
import { readCoarsePointerMatches } from "@/hooks/use-touch-nav"
|
|
|
|
/** Tailwind `md` breakpoint — split view never applies below this width. */
|
|
export const MD_MIN_PX = 768
|
|
|
|
const MD_MQ = `(min-width: ${MD_MIN_PX}px)`
|
|
const LANDSCAPE_MQ = "(orientation: landscape)"
|
|
|
|
/**
|
|
* User preference (settings UI later). When true, split view is enabled on md+
|
|
* even on non-touch desktops.
|
|
*/
|
|
export const MAIL_SPLIT_VIEW_USER_SETTING = false
|
|
|
|
export function readMailSplitViewMatches(): boolean {
|
|
if (typeof window === "undefined") return false
|
|
if (!window.matchMedia(MD_MQ).matches) return false
|
|
const coarse = readCoarsePointerMatches()
|
|
const tabletLandscape =
|
|
coarse && window.matchMedia(LANDSCAPE_MQ).matches
|
|
return tabletLandscape || MAIL_SPLIT_VIEW_USER_SETTING
|
|
}
|
|
|
|
export function useMailSplitView() {
|
|
const [splitView, setSplitView] = useState(false)
|
|
|
|
useLayoutEffect(() => {
|
|
const mqlMd = window.matchMedia(MD_MQ)
|
|
const mqlLandscape = window.matchMedia(LANDSCAPE_MQ)
|
|
const mqlCoarse = window.matchMedia(
|
|
"(hover: none) and (pointer: coarse)"
|
|
)
|
|
const update = () => setSplitView(readMailSplitViewMatches())
|
|
update()
|
|
mqlMd.addEventListener("change", update)
|
|
mqlLandscape.addEventListener("change", update)
|
|
mqlCoarse.addEventListener("change", update)
|
|
return () => {
|
|
mqlMd.removeEventListener("change", update)
|
|
mqlLandscape.removeEventListener("change", update)
|
|
mqlCoarse.removeEventListener("change", update)
|
|
}
|
|
}, [])
|
|
|
|
return splitView
|
|
}
|