Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@buildinams/use-match-media

Package Overview
Dependencies
Maintainers
3
Versions
7
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@buildinams/use-match-media - npm Package Compare versions

Comparing version 0.1.0 to 0.2.1

.prettierrc.js

15

dist/index.d.ts

@@ -6,7 +6,10 @@ import { Config, EventHandler, Query } from "./types";

* @param query - The query to match for.
* @param config - _Optional_ configuration object.
* @param config.defaultValue - _Optional_ fallback value that is returned in
* SSR and first match of any unique query. Defaults to `false`.
* @param config.isEnabled - _Optional_ whether or not to listen to events.
* Defaults to `true`.
* @param config.layoutEffect - _Optional_ whether or not to use
* `useLayoutEffect` instead of `useEffect` on client. Defaults to `false`.
*
* @param config - Optional configuration object.
* @param config.defaultValue - Fallback value that is returned in SSR and first match of any unique query. Defaults to `false`.
* @param config.isEnabled - Lets you specify whether to listen for events or not. Defaults to `true`.
*
* @example

@@ -22,4 +25,4 @@ * useMatchMedia("(pointer: coarse)") -> Checks if the browser matches coarse;

*/
declare const useMatchMedia: (query: string, config?: Config) => boolean;
declare const useMatchMedia: <TConfig extends Config = Config, TDefaultValue extends TConfig["defaultValue"] = TConfig["defaultValue"] extends undefined ? undefined : TConfig["defaultValue"] extends null ? null : never>(query: string, config?: TConfig | undefined) => boolean | TDefaultValue;
export default useMatchMedia;
export type { EventHandler, Query };
export type { Config, EventHandler, Query };

166

dist/index.js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const react_1 = require("react");
const useIsomorphicEffect_1 = require("./useIsomorphicEffect");
const queries = new Map();
const getExistingMatch = (query, defaultValue = false) => {
const matchedQuery = queries.get(query);
// If query already exists, return its matched value, else default value
return matchedQuery ? matchedQuery.matchMedia.matches : defaultValue;
};
const createEventHandler = (query) => (event) => {
const matchedQuery = queries.get(query);
if (matchedQuery) {
matchedQuery.existingListeners.forEach((listener) => listener(event));
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
const addListener = (query, listener) => {
const matchedQuery = queries.get(query);
// If query already exists, add this new listener to existing array
if (matchedQuery) {
matchedQuery.existingListeners.push(listener);
return matchedQuery.matchMedia.matches;
}
// Else, first query, so create it...
const newQuery = {
matchMedia: window.matchMedia(query),
existingListeners: [listener],
eventHandler: createEventHandler(query),
};
queries.set(query, newQuery);
// Listen to changes with fallback
const currentMatchMedia = newQuery.matchMedia;
if (!currentMatchMedia.addEventListener) {
currentMatchMedia.addListener(newQuery.eventHandler);
}
else {
currentMatchMedia.addEventListener("change", newQuery.eventHandler);
}
return newQuery.matchMedia.matches;
};
const removeListener = (query, listener) => {
const matchedQuery = queries.get(query);
// If this matches, filter out this listener from existing array
if (matchedQuery) {
matchedQuery.existingListeners = matchedQuery.existingListeners.filter((l) => l !== listener);
}
// Ignore unsubscribe below if theres any more existing listeners
if (!matchedQuery || matchedQuery.existingListeners.length > 0)
return;
// Unsubscribe from changes with fallback
const currentMatchMedia = matchedQuery.matchMedia;
if (!currentMatchMedia.removeEventListener) {
currentMatchMedia.removeListener(matchedQuery.eventHandler);
}
else {
currentMatchMedia.removeEventListener("change", matchedQuery.eventHandler);
}
queries.delete(query);
};
Object.defineProperty(exports, "__esModule", { value: true });
const react_1 = __importStar(require("react"));
const useIsomorphicLayoutEffect_1 = require("./useIsomorphicLayoutEffect");
const QUERIES = new Map();
/**

@@ -64,7 +33,10 @@ * Stateful hook that uses the matchMedia API.

* @param query - The query to match for.
* @param config - _Optional_ configuration object.
* @param config.defaultValue - _Optional_ fallback value that is returned in
* SSR and first match of any unique query. Defaults to `false`.
* @param config.isEnabled - _Optional_ whether or not to listen to events.
* Defaults to `true`.
* @param config.layoutEffect - _Optional_ whether or not to use
* `useLayoutEffect` instead of `useEffect` on client. Defaults to `false`.
*
* @param config - Optional configuration object.
* @param config.defaultValue - Fallback value that is returned in SSR and first match of any unique query. Defaults to `false`.
* @param config.isEnabled - Lets you specify whether to listen for events or not. Defaults to `true`.
*
* @example

@@ -81,4 +53,66 @@ * useMatchMedia("(pointer: coarse)") -> Checks if the browser matches coarse;

const useMatchMedia = (query, config) => {
const [matches, setMatches] = (0, react_1.useState)(getExistingMatch(query, config === null || config === void 0 ? void 0 : config.defaultValue));
(0, useIsomorphicEffect_1.useIsomorphicEffect)(() => {
const getExistingMatch = (0, react_1.useCallback)(() => {
const matchedQuery = QUERIES.get(query);
// If query already exists, return its matched value
if (matchedQuery)
return matchedQuery.matchMedia.matches;
// Else, return config default value if it exists or fallback (false)
return config && "defaultValue" in config
? config.defaultValue
: false;
}, [config, query]);
const createEventHandler = (query) => (event) => {
const matchedQuery = QUERIES.get(query);
if (matchedQuery) {
matchedQuery.existingListeners.forEach((listener) => listener(event));
}
};
const addListener = (0, react_1.useCallback)((query, listener) => {
const matchedQuery = QUERIES.get(query);
// If query already exists, add this new listener to existing array
if (matchedQuery) {
matchedQuery.existingListeners.push(listener);
return matchedQuery.matchMedia.matches;
}
// Else, first query, so create it...
const newQuery = {
matchMedia: window.matchMedia(query),
existingListeners: [listener],
eventHandler: createEventHandler(query),
};
QUERIES.set(query, newQuery);
// Listen to changes with fallback
const currentMatchMedia = newQuery.matchMedia;
if (!currentMatchMedia.addEventListener) {
currentMatchMedia.addListener(newQuery.eventHandler);
}
else {
currentMatchMedia.addEventListener("change", newQuery.eventHandler);
}
return newQuery.matchMedia.matches;
}, []);
const removeListener = (0, react_1.useCallback)((query, listener) => {
const matchedQuery = QUERIES.get(query);
// If this matches, filter out this listener from existing array
if (matchedQuery) {
matchedQuery.existingListeners = matchedQuery.existingListeners.filter((l) => l !== listener);
}
// Ignore unsubscribe below if theres any more existing listeners
if (!matchedQuery || matchedQuery.existingListeners.length > 0)
return;
// Unsubscribe from changes with fallback
const currentMatchMedia = matchedQuery.matchMedia;
if (!currentMatchMedia.removeEventListener) {
currentMatchMedia.removeListener(matchedQuery.eventHandler);
}
else {
currentMatchMedia.removeEventListener("change", matchedQuery.eventHandler);
}
QUERIES.delete(query);
}, []);
const [matches, setMatches] = (0, react_1.useState)(getExistingMatch);
const useEffect = (config === null || config === void 0 ? void 0 : config.layoutEffect)
? useIsomorphicLayoutEffect_1.useIsomorphicLayoutEffect
: react_1.default.useEffect;
useEffect(() => {
var _a;

@@ -89,11 +123,11 @@ if ((_a = config === null || config === void 0 ? void 0 : config.isEnabled) !== null && _a !== void 0 ? _a : true) {

};
// On mount we only checked if there was an existing match. So here we
// set matches again in case this is the first of this query
const matches = addListener(query, listener);
setMatches(matches);
return () => {
removeListener(query, listener);
};
return () => removeListener(query, listener);
}
}, [query]);
}, [config === null || config === void 0 ? void 0 : config.isEnabled, query, addListener, removeListener]);
return matches;
};
exports.default = useMatchMedia;

@@ -1,8 +0,2 @@

export type EventHandler = (event: MediaQueryListEvent) => void;
export interface Query {
matchMedia: MediaQueryList;
existingListeners: EventHandler[];
eventHandler: EventHandler;
}
export interface Config {
export type Config = {
/**

@@ -12,8 +6,16 @@ * Fallback value that is returned in SSR and first match of any unique query.

*/
defaultValue?: boolean;
defaultValue?: boolean | null;
/** Whether or not to listen to events. Defaults to `true`. */
isEnabled?: boolean;
/**
* This can be used to conditionally enable / disable the event listener.
* Defaults to `true`.
* Whether or not to use `useLayoutEffect` instead of `useEffect` on client.
* Defaults to `false`.
*/
isEnabled?: boolean;
}
layoutEffect?: boolean;
};
export type EventHandler = (event: MediaQueryListEvent) => void;
export type Query = {
matchMedia: MediaQueryList;
existingListeners: EventHandler[];
eventHandler: EventHandler;
};
import type { Config } from "@jest/types";
const config: Config.InitialOptions = {
verbose: true,
testEnvironment: "jsdom",
roots: ["<rootDir>/tests"],
verbose: true,
testEnvironment: "jsdom",
roots: ["<rootDir>/tests"],
};
export default config;
{
"name": "@buildinams/use-match-media",
"description": "Stateful hook that uses the matchMedia API.",
"version": "0.1.0",
"license": "MIT",
"author": "Build in Amsterdam <development@buildinamsterdam.com> (https://www.buildinamsterdam.com/)",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"homepage": "https://github.com/buildinamsterdam/use-match-media#readme",
"repository": {
"type": "git",
"url": "https://github.com/buildinamsterdam/use-match-media.git"
},
"bugs": {
"url": "https://github.com/buildinamsterdam/use-match-media/issues"
},
"keywords": [
"react",
"hook",
"react-hook",
"match-media",
"media-query"
],
"scripts": {
"build": "tsc",
"build:types": "tsc --emitDeclarationOnly",
"prepublishOnly": "npm run build",
"test": "jest",
"test:watch": "jest --watch",
"coverage": "jest --coverage",
"lint": "NODE_ENV=test npm-run-all --parallel lint:*",
"lint:script": "eslint \"src/**/*.{ts,tsx}\"",
"lint:format": "prettier \"**/*.{md,yml}\" --check",
"lint:type-check": "tsc --noEmit",
"fix": "npm-run-all --sequential fix:*",
"fix:js": "eslint \"src/**/*.{js,jsx,ts,tsx}\" --fix",
"fix:format": "prettier \"**/*.{md,yml}\" --write",
"depcheck": "npx npm-check --update"
},
"peerDependencies": {
"react": ">=17.0.0 || 18"
},
"devDependencies": {
"@babel/preset-env": "^7.22.7",
"@babel/preset-typescript": "^7.22.5",
"@buildinams/lint": "^0.2.1",
"@testing-library/react": "^14.0.0",
"@types/jest": "^29.5.3",
"@types/node": "^20.4.1",
"@types/react": "^18.2.14",
"@types/react-dom": "^18.2.6",
"babel": "^6.23.0",
"jest": "^29.6.1",
"jest-environment-jsdom": "^29.6.1",
"jest-matchmedia-mock": "^1.1.0",
"npm-run-all": "^4.1.5",
"react-dom": "^18.0.0",
"ts-jest": "^29.1.1",
"ts-node": "^10.9.1",
"typescript": "^5.1.6"
}
"name": "@buildinams/use-match-media",
"description": "Stateful hook that uses the matchMedia API.",
"version": "0.2.1",
"license": "MIT",
"author": "Build in Amsterdam <development@buildinamsterdam.com> (https://www.buildinamsterdam.com/)",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"homepage": "https://github.com/buildinamsterdam/use-match-media#readme",
"repository": {
"type": "git",
"url": "https://github.com/buildinamsterdam/use-match-media.git"
},
"bugs": {
"url": "https://github.com/buildinamsterdam/use-match-media/issues"
},
"keywords": [
"react",
"hook",
"react-hook",
"match-media",
"media-query"
],
"scripts": {
"build": "tsc",
"build:types": "tsc --emitDeclarationOnly",
"prepublishOnly": "npm run build",
"test": "jest",
"test:watch": "jest --watch",
"coverage": "jest --coverage",
"lint": "NODE_ENV=test npm-run-all --parallel lint:*",
"lint:script": "eslint \"src/**/*.{ts,tsx}\"",
"lint:format": "prettier \"**/*.{md,yml}\" --check",
"lint:type-check": "tsc --noEmit",
"fix": "npm-run-all --sequential fix:*",
"fix:js": "eslint \"src/**/*.{js,jsx,ts,tsx}\" --fix",
"fix:format": "prettier \"**/*.{md,yml}\" --write",
"depcheck": "npx npm-check --update"
},
"peerDependencies": {
"react": ">=17.0.0 || 18"
},
"devDependencies": {
"@babel/preset-env": "^7.23.8",
"@babel/preset-typescript": "^7.23.3",
"@buildinams/lint": "^0.4.0",
"@testing-library/react": "^14.1.2",
"@types/jest": "^29.5.11",
"@types/node": "^20.11.3",
"@types/react": "^18.2.48",
"@types/react-dom": "^18.2.18",
"babel": "^6.23.0",
"jest": "^29.7.0",
"jest-environment-jsdom": "^29.7.0",
"jest-matchmedia-mock": "^1.1.0",
"npm-run-all": "^4.1.5",
"react-dom": "^18.0.0",
"ts-jest": "^29.1.1",
"ts-node": "^10.9.2",
"typescript": "^5.3.3"
}
}

@@ -49,3 +49,3 @@ # use-match-media

If you want to provide a default value for the initial render (and in server), you can pass it as `defaultValue` within the _optional_ config object.
If you want to provide a default value for the initial render (and in server), you can pass it as `defaultValue` within the _optional_ config object. This accepts `boolean`, `undefined`, or `null`. For example:

@@ -56,3 +56,3 @@ ```tsx

const MyComponent = () => {
const isMobile = useMatchMedia("(max-width: 768px)", { defaultValue: true });
const isSmall = useMatchMedia("(max-width: 768px)", { defaultValue: true });
...

@@ -65,3 +65,4 @@ };

- The default value will only be used on the initial render and SSR. By the second render, the hook will use the actual value matched.
- If left `undefined`, the default value will be `false`.
- If theres already a match for the query, the hook will use the actual value matched instead of the default value.
- If left blank, the default value will be `false`.

@@ -78,3 +79,3 @@ ## Conditionally Listening to Events

const isMobile = useMatchMedia("(max-width: 768px)", { isEnabled });
const isSmall = useMatchMedia("(max-width: 768px)", { isEnabled });
...

@@ -84,2 +85,17 @@ };

## Using Layout Effect
By default, the hook will use `useEffect` to listen to events. However, you can use `useLayoutEffect` instead by passing `layoutEffect` in the config object. For example:
```tsx
import useMatchMedia from "@buildinams/use-match-media";
const MyComponent = () => {
const isSmall = useMatchMedia("(max-width: 768px)", { layoutEffect: true });
...
};
```
This is SSR safe, and will only use `useLayoutEffect` on the client.
## Requirements

@@ -86,0 +102,0 @@

@@ -1,75 +0,8 @@

import { useState } from "react";
import React, { useCallback, useState } from "react";
import { Config, EventHandler, Query } from "./types";
import { useIsomorphicEffect } from "./useIsomorphicEffect";
import { useIsomorphicLayoutEffect } from "./useIsomorphicLayoutEffect";
const queries = new Map<string, Query>();
const QUERIES = new Map<string, Query>();
const getExistingMatch = (query: string, defaultValue = false) => {
const matchedQuery = queries.get(query);
// If query already exists, return its matched value, else default value
return matchedQuery ? matchedQuery.matchMedia.matches : defaultValue;
};
const createEventHandler = (query: string) => (event: MediaQueryListEvent) => {
const matchedQuery = queries.get(query);
if (matchedQuery) {
matchedQuery.existingListeners.forEach((listener) => listener(event));
}
};
const addListener = (query: string, listener: EventHandler) => {
const matchedQuery = queries.get(query);
// If query already exists, add this new listener to existing array
if (matchedQuery) {
matchedQuery.existingListeners.push(listener);
return matchedQuery.matchMedia.matches;
}
// Else, first query, so create it...
const newQuery = {
matchMedia: window.matchMedia(query),
existingListeners: [listener],
eventHandler: createEventHandler(query),
};
queries.set(query, newQuery);
// Listen to changes with fallback
const currentMatchMedia = newQuery.matchMedia;
if (!currentMatchMedia.addEventListener) {
currentMatchMedia.addListener(newQuery.eventHandler);
} else {
currentMatchMedia.addEventListener("change", newQuery.eventHandler);
}
return newQuery.matchMedia.matches;
};
const removeListener = (query: string, listener: EventHandler) => {
const matchedQuery = queries.get(query);
// If this matches, filter out this listener from existing array
if (matchedQuery) {
matchedQuery.existingListeners = matchedQuery.existingListeners.filter(
(l) => l !== listener
);
}
// Ignore unsubscribe below if theres any more existing listeners
if (!matchedQuery || matchedQuery.existingListeners.length > 0) return;
// Unsubscribe from changes with fallback
const currentMatchMedia = matchedQuery.matchMedia;
if (!currentMatchMedia.removeEventListener) {
currentMatchMedia.removeListener(matchedQuery.eventHandler);
} else {
currentMatchMedia.removeEventListener("change", matchedQuery.eventHandler);
}
queries.delete(query);
};
/**

@@ -79,7 +12,10 @@ * Stateful hook that uses the matchMedia API.

* @param query - The query to match for.
* @param config - _Optional_ configuration object.
* @param config.defaultValue - _Optional_ fallback value that is returned in
* SSR and first match of any unique query. Defaults to `false`.
* @param config.isEnabled - _Optional_ whether or not to listen to events.
* Defaults to `true`.
* @param config.layoutEffect - _Optional_ whether or not to use
* `useLayoutEffect` instead of `useEffect` on client. Defaults to `false`.
*
* @param config - Optional configuration object.
* @param config.defaultValue - Fallback value that is returned in SSR and first match of any unique query. Defaults to `false`.
* @param config.isEnabled - Lets you specify whether to listen for events or not. Defaults to `true`.
*
* @example

@@ -95,23 +31,118 @@ * useMatchMedia("(pointer: coarse)") -> Checks if the browser matches coarse;

*/
const useMatchMedia = (query: string, config?: Config) => {
const [matches, setMatches] = useState(
getExistingMatch(query, config?.defaultValue)
);
const useMatchMedia = <
TConfig extends Config = Config,
TDefaultValue extends
| TConfig["defaultValue"]
| never = TConfig["defaultValue"] extends undefined
? undefined
: TConfig["defaultValue"] extends null
? null
: never,
>(
query: string,
config?: TConfig,
) => {
const getExistingMatch = useCallback(() => {
const matchedQuery = QUERIES.get(query);
useIsomorphicEffect(() => {
if (config?.isEnabled ?? true) {
const listener = (event: MediaQueryListEvent) => {
setMatches(event.matches);
};
// If query already exists, return its matched value
if (matchedQuery) return matchedQuery.matchMedia.matches;
const matches = addListener(query, listener);
setMatches(matches);
// Else, return config default value if it exists or fallback (false)
return config && "defaultValue" in config
? (config.defaultValue as TDefaultValue)
: false;
}, [config, query]);
return () => {
removeListener(query, listener);
};
}
}, [query]);
const createEventHandler =
(query: string) => (event: MediaQueryListEvent) => {
const matchedQuery = QUERIES.get(query);
return matches;
if (matchedQuery) {
matchedQuery.existingListeners.forEach((listener) => listener(event));
}
};
const addListener = useCallback((query: string, listener: EventHandler) => {
const matchedQuery = QUERIES.get(query);
// If query already exists, add this new listener to existing array
if (matchedQuery) {
matchedQuery.existingListeners.push(listener);
return matchedQuery.matchMedia.matches;
}
// Else, first query, so create it...
const newQuery = {
matchMedia: window.matchMedia(query),
existingListeners: [listener],
eventHandler: createEventHandler(query),
};
QUERIES.set(query, newQuery);
// Listen to changes with fallback
const currentMatchMedia = newQuery.matchMedia;
if (!currentMatchMedia.addEventListener) {
currentMatchMedia.addListener(newQuery.eventHandler);
} else {
currentMatchMedia.addEventListener("change", newQuery.eventHandler);
}
return newQuery.matchMedia.matches;
}, []);
const removeListener = useCallback(
(query: string, listener: EventHandler) => {
const matchedQuery = QUERIES.get(query);
// If this matches, filter out this listener from existing array
if (matchedQuery) {
matchedQuery.existingListeners = matchedQuery.existingListeners.filter(
(l) => l !== listener,
);
}
// Ignore unsubscribe below if theres any more existing listeners
if (!matchedQuery || matchedQuery.existingListeners.length > 0) return;
// Unsubscribe from changes with fallback
const currentMatchMedia = matchedQuery.matchMedia;
if (!currentMatchMedia.removeEventListener) {
currentMatchMedia.removeListener(matchedQuery.eventHandler);
} else {
currentMatchMedia.removeEventListener(
"change",
matchedQuery.eventHandler,
);
}
QUERIES.delete(query);
},
[],
);
const [matches, setMatches] = useState<boolean | TDefaultValue>(
getExistingMatch,
);
const useEffect = config?.layoutEffect
? useIsomorphicLayoutEffect
: React.useEffect;
useEffect(() => {
if (config?.isEnabled ?? true) {
const listener = (event: MediaQueryListEvent) => {
setMatches(event.matches);
};
// On mount we only checked if there was an existing match. So here we
// set matches again in case this is the first of this query
const matches = addListener(query, listener);
setMatches(matches);
return () => removeListener(query, listener);
}
}, [config?.isEnabled, query, addListener, removeListener]);
return matches;
};

@@ -121,2 +152,2 @@

export type { EventHandler, Query };
export type { Config, EventHandler, Query };

@@ -1,21 +0,24 @@

export type EventHandler = (event: MediaQueryListEvent) => void;
export type Config = {
/**
* Fallback value that is returned in SSR and first match of any unique query.
* Defaults to `false`.
*/
defaultValue?: boolean | null;
export interface Query {
matchMedia: MediaQueryList;
existingListeners: EventHandler[];
eventHandler: EventHandler;
}
/** Whether or not to listen to events. Defaults to `true`. */
isEnabled?: boolean;
export interface Config {
/**
* Fallback value that is returned in SSR and first match of any unique query.
* Defaults to `false`.
*/
defaultValue?: boolean;
/**
* Whether or not to use `useLayoutEffect` instead of `useEffect` on client.
* Defaults to `false`.
*/
layoutEffect?: boolean;
};
/**
* This can be used to conditionally enable / disable the event listener.
* Defaults to `true`.
*/
isEnabled?: boolean;
}
export type EventHandler = (event: MediaQueryListEvent) => void;
export type Query = {
matchMedia: MediaQueryList;
existingListeners: EventHandler[];
eventHandler: EventHandler;
};

@@ -9,54 +9,96 @@ import { renderHook } from "@testing-library/react";

describe("The hook", () => {
beforeEach(() => {
matchMedia = new MatchMediaMock();
});
beforeEach(() => {
matchMedia = new MatchMediaMock();
});
afterEach(() => {
matchMedia.clear();
});
afterEach(() => {
matchMedia.clear();
});
it("should return 'false' if query doesn't match", () => {
matchMedia.useMediaQuery("(pointer: fine)");
it("should return 'false' if query doesn't match", () => {
matchMedia.useMediaQuery("(pointer: fine)");
const { result } = renderHook(() => useMatchMedia("(pointer: coarse)"));
const { result } = renderHook(() => useMatchMedia("(pointer: coarse)"));
expect(result.current).toEqual(false);
});
expect(result.current).toEqual(false);
});
it("should return 'true' if query matches", () => {
matchMedia.useMediaQuery("(pointer: coarse)");
it("should return default value 'true' if query doesn't match", () => {
const { result } = renderHook(() =>
useMatchMedia("(pointer: coarse)", {
defaultValue: true,
const { result } = renderHook(() => useMatchMedia("(pointer: coarse)"));
// Under the hood, the hook instantly runs 'useEffect' in tests so we
// need to disable it to be able to test the default value
isEnabled: false,
}),
);
expect(result.current).toEqual(true);
});
expect(result.current).toEqual(true);
});
it("should only create one listener for the same query", async () => {
const query = "(pointer: coarse)";
it("should return default value 'null' if query doesn't match", () => {
const { result } = renderHook(() =>
useMatchMedia("(pointer: coarse)", {
defaultValue: null,
renderHook(() => useMatchMedia(query));
renderHook(() => useMatchMedia(query));
// Under the hood, the hook instantly runs 'useEffect' in tests so we
// need to disable it to be able to test the default value
isEnabled: false,
}),
);
expect(matchMedia.getListeners(query).length).toEqual(1);
});
expect(result.current).toEqual(null);
});
it("should cleanup after unmounting", () => {
const query = "(pointer: coarse)";
it("should return default value 'undefined' if query doesn't match", () => {
const { result } = renderHook(() =>
useMatchMedia("(pointer: coarse)", {
defaultValue: undefined,
const { unmount } = renderHook(() => useMatchMedia("(pointer: coarse)"));
// Under the hood, the hook instantly runs 'useEffect' in tests so we
// need to disable it to be able to test the default value
isEnabled: false,
}),
);
expect(matchMedia.getListeners(query).length).toEqual(1);
expect(result.current).toEqual(undefined);
});
unmount();
it("should return 'true' if query matches", () => {
matchMedia.useMediaQuery("(pointer: coarse)");
expect(matchMedia.getListeners(query).length).toEqual(0);
});
const { result } = renderHook(() => useMatchMedia("(pointer: coarse)"));
it("doesn't add event listener if listen is set to 'false' on mount", () => {
const query = "(pointer: coarse)";
expect(result.current).toEqual(true);
});
renderHook(() => useMatchMedia(query, { isEnabled: false }));
it("should only create one listener for the same query", async () => {
const query = "(pointer: coarse)";
expect(matchMedia.getListeners(query).length).toEqual(0);
});
renderHook(() => useMatchMedia(query));
renderHook(() => useMatchMedia(query));
expect(matchMedia.getListeners(query).length).toEqual(1);
});
it("should cleanup after unmounting", () => {
const query = "(pointer: coarse)";
const { unmount } = renderHook(() => useMatchMedia("(pointer: coarse)"));
expect(matchMedia.getListeners(query).length).toEqual(1);
unmount();
expect(matchMedia.getListeners(query).length).toEqual(0);
});
it("doesn't add event listener if listen is set to 'false' on mount", () => {
const query = "(pointer: coarse)";
renderHook(() => useMatchMedia(query, { isEnabled: false }));
expect(matchMedia.getListeners(query).length).toEqual(0);
});
});

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc