vw-detector
v2.0.5
Published
A lib that can be used to detect viewport width. You can use it to apply viewport specific features.
Downloads
4
Maintainers
Readme
VW Detector
A lib that can be used to detect viewport width. You can use it to apply viewport specific features.
Usage
import VW from "vw-detector";
const { matchesMediaQuery, subscribeMediaQuery, breakpoints } = VW;
// customizing breakpoints
VW.configureBreakpoints((previousBreakpoints) => ({
...previousBreakpoints,
sm: 600,
md: 900,
step: 2, // prevent query matching conflict, default 5
}));
const downSm = matchesMediaQuery(breakpoints.down("sm"));
console.log(downSm); // true (or) false
// subscribe callback
const unsubscribe = subscribeMediaQuery(breakpoints.down("sm"), (matches) => {
// this callback will be invoked once if the media query matches
// we need to type guard to prevent running callback body multiple times
if (matches) {
console.log("media query matches with the current viewport width");
}
});
unsubscribe(); // unsubscribe callback
// You can use other ways
subscribeMediaQuery(breakpoints.up("sm"));
subscribeMediaQuery(breakpoints.only("sm"));
subscribeMediaQuery(breakpoints.between("sm", "lg"));
React reusable custom hook
If you want to use this library in your React application, copy and paste this in your project and modify it base on your needs :
import { useEffect, useRef, useState } from "react";
import VW from "vw-detector";
const { matchesMediaQuery, subscribeMediaQuery, breakpoints } = VW;
export default function useMediaQuery(mediaQuery) {
// For initial value, check if current viewport width matches with the provided mediaQuery.
const [matches, setMatches] = useState(matchesMediaQuery(mediaQuery));
// To prevent setting same value multiple times.
const prevMatches = useRef(matches);
// We need to stringify media query to pass it into useEffect deps because breakpoints utility functions return array type..
// It will be new reference on every renders.
// For better performance, I will refactor returning array soon.
const stringifiedMediaQuery = JSON.stringify(mediaQuery);
useEffect(() => {
const unsubscribe = subscribeMediaQuery(
JSON.parse(stringifiedMediaQuery), // We need to parse stringified media query to transform it into array.
(matches) => {
if (prevMatches.current !== matches) {
prevMatches.current = matches;
setMatches(matches);
}
}
);
return () => {
unsubscribe();
};
}, [stringifiedMediaQuery]);
return matches;
}
And you can use it in your component like this :
import VW from "vw-detector";
import useMediaQuery from "./useMediaQuery";
export default function VWTest() {
const downSm = useMediaQuery(VW.breakpoints.down("sm"));
console.log(downSm);
//...
}
Default breakpoint values
{
xs: 0,
sm: 576,
md: 768,
lg: 992,
xl: 1200,
xxl: 1400,
step: 5, // this is not viewport width
}
If you are using TypeScript, you can extend breakpoint values type by using module augmentation:
declare module 'vw-detector/dist/types' {
interface BreakpointValues {
// Add properties here
xxxl?: number;
}
}
Version
2.0.2
configureBreakpoints
will not merge with your returned value meaning that you should do it on your own within your callback function as it receives previous configured or default breakpoint values.- Added type safe for SSR applications.
matchesMediaQuery
will return false if your app is running on server.I previously released version 2.0.1 without building for production. I apologize for the oversight.
API Reference
VW
has the following properties :
configureBreakpoints
matchesMediaQuery
subscribeMediaQuery
breakpoints
configureBreakpoints
Can be used to override and extend default breakpoint values. It accepts argument as a function type. That function will received previous configured breakpoints value. You must return breakpoints values.
Warning: Don't destructure this property. Otherwise, you will get
TypeError
when you invoke it.
VW.configureBreakpoints((previousBreakpoints) => ({
...previousBreakpoints,
sm: 600,
md: 900,
}));
matchesMediaQuery
Can be used to detect when this function is invoked. Return boolean.
const notSm = matchesMediaQuery(breakpoints.not("sm"));
console.log(notSm); // true (or) false
subscribeMediaQuery
Can be used to subscribe optional callback to be invoked on media query matches. It returns function to unsubscribe callback.
const unsubscribe = subscribeMediaQuery(breakpoints.down("sm"), (matches) => {
if (matches) {
console.log("media query matches with the current viewport width");
}
});
unsubscribe(); // unsubscribe callback
breakpoints
It provides utility functions which generate media queries that you can pass to the first argument of subscribeMediaQuery
.
breakpoints.down(breakpointKey);
breakpoints.up(breakpointKey);
breakpoints.only(breakpointKey);
breakpoints.not(breakpointKey);
breakpoints.between(fromBreakpointKey, toBreakpointKey);
if you are wondering how this methods work, read MUI
useMediaQuery
technique.