mirror of
https://github.com/priyanshujain/margin-docs.git
synced 2026-10-03 11:37:04 +00:00
features
This commit is contained in:
commit
852cba1840
252 files changed
+55050
No files matched your search
@@ -0,0 +1,63 @@
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
export function useMediaQuery(query: string): boolean {
|
||||
const [matches, setMatches] = useState(() => window.matchMedia(query).matches);
|
||||
useEffect(() => {
|
||||
const mq = window.matchMedia(query);
|
||||
const onChange = () => setMatches(mq.matches);
|
||||
onChange();
|
||||
mq.addEventListener("change", onChange);
|
||||
return () => mq.removeEventListener("change", onChange);
|
||||
}, [query]);
|
||||
return matches;
|
||||
}
|
||||
|
||||
/**
|
||||
* Responsiveness is JS-driven: this writes `data-compact` on the root and the stylesheet keys off
|
||||
* that attribute, so there are essentially no media queries in app.css.
|
||||
*/
|
||||
export function useCompact(): boolean {
|
||||
const compact = useMediaQuery("(max-width: 899px)");
|
||||
useEffect(() => {
|
||||
document.documentElement.toggleAttribute("data-compact", compact);
|
||||
}, [compact]);
|
||||
return compact;
|
||||
}
|
||||
|
||||
/** Kept in step with the same two queries in index.html's boot script. */
|
||||
export const PHONE_QUERY = "(max-width: 640px)";
|
||||
export const TOUCH_QUERY = "(pointer: coarse)";
|
||||
|
||||
/**
|
||||
* A phone, meaning a window too narrow for the sidebar, the document and the sticky toolbar to
|
||||
* all be worth showing at once. The chrome collapses and the sidebar becomes an overlay instead
|
||||
* of a permanent column.
|
||||
*
|
||||
* Deliberately measured in CSS pixels rather than sniffed off the user agent: a phone in landscape
|
||||
* is 850 wide and wants the desktop layout back, a tablet at 768 has always wanted it, and a
|
||||
* narrow desktop window is a free way to exercise all of this without a device.
|
||||
*/
|
||||
export function usePhone(): boolean {
|
||||
const phone = useMediaQuery(PHONE_QUERY);
|
||||
useEffect(() => {
|
||||
document.documentElement.toggleAttribute("data-phone", phone);
|
||||
}, [phone]);
|
||||
return phone;
|
||||
}
|
||||
|
||||
/**
|
||||
* A coarse pointer, which is a different question from `usePhone`: a tablet is touch and not a
|
||||
* phone, and a narrow desktop window is a phone and not touch.
|
||||
*
|
||||
* This is the one that governs interaction rather than layout. Anything that only appears on hover
|
||||
* is unreachable here and has to have a tap that does the same job, and a gesture that starts on
|
||||
* pointerdown has to wait for a long press instead, because a finger cannot press without also
|
||||
* intending to maybe scroll.
|
||||
*/
|
||||
export function useTouch(): boolean {
|
||||
const touch = useMediaQuery(TOUCH_QUERY);
|
||||
useEffect(() => {
|
||||
document.documentElement.toggleAttribute("data-touch", touch);
|
||||
}, [touch]);
|
||||
return touch;
|
||||
}
|
||||
Reference in new issue
Block a user