Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# tiny-use-media

Small (0.5 Kb) react hook for getting media breakpoints state info in runtime
Small (0.6 Kb) react hook for getting media breakpoints state info in runtime

## Usage

Expand Down Expand Up @@ -66,6 +66,14 @@ E.g. output for screen size of 900px
}
```

## ESM
If you need ESM module it can be found here
[here](https://github.com/komlev/tiny-use-media-esm)
or installed with
```
npm i tiny-use-media-esm --save
```

## License

MIT
69 changes: 35 additions & 34 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { useMemo, useState, useEffect } from "react";
import { useEffect, useMemo, useState } from "react";

let isClient = typeof window !== "undefined",
getCurrent = (queries) => {
let index = queries.findIndex((query) => isClient && !query.q.matches),
queryIndex = (~index ? index : queries.length) - 1;
return queryIndex >= 0 ? queries[queryIndex].bp : void 0;
return queryIndex >= 0 ? queries[queryIndex].bp : undefined;
},
getResult = (queries) => {
let current = getCurrent(queries),
Expand All @@ -14,39 +15,39 @@ let isClient = typeof window !== "undefined",
}, {});
res.current = current;
return res;
},
useMedia = (breakpoints) => {
let queries = useMemo(
() =>
Object.keys(breakpoints)
.sort((a, b) => +breakpoints[a] - +breakpoints[b])
.map((bp) => {
let q = isClient
? window.matchMedia(`(min-width:${breakpoints[bp]}px)`)
: void 0;
return { q, bp };
}),
Object.values(breakpoints)
);
let [result, setResult] = useState(getResult(queries));
useEffect(() => {
let handler = () => setResult(getResult(queries));
};

export let useMedia = (breakpoints) => {
let queries = useMemo(
() =>
Object.keys(breakpoints)
.sort((a, b) => +breakpoints[a] - +breakpoints[b])
.map((bp) => {
let q = isClient
? window.matchMedia(`(min-width:${breakpoints[bp]}px)`)
: undefined;
return { q, bp };
}),
Object.values(breakpoints)
);
let [result, setResult] = useState(getResult(queries));
useEffect(() => {
let handler = () => setResult(getResult(queries));
queries.forEach((query) => {
try {
query.q.addEventListener("change", handler);
} catch (e) {
query.q.addListener(handler);
}
});
return () =>
queries.forEach((query) => {
try {
query.q.addEventListener("change", handler);
} catch (err) {
query.q.addListener(handler);
query.q.removeEventListener("change", handler);
} catch (e) {
query.q.removeListener(handler);
}
});
return () =>
queries.forEach((query) => {
try {
query.q.removeEventListener("change", handler);
} catch (err) {
query.q.removeListener(handler);
}
});
}, [queries]);
return result;
};
export { useMedia };
}, [queries]);
return result;
};
16 changes: 14 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,23 @@
{
"name": "tiny-use-media",
"description": "react hook for getting breakpoints state in runtime",
"version": "1.0.5",
"browser": "./index.js",
"version": "1.0.6",
"main": "./dist/useMedia.umd.js",
"module": "./dist/useMedia.es.js",
"files": [
"dist"
],
"author": {
"name": "Valeriy Komlev",
"email": "[email protected]",
"url": "https://komlev.me/"
},
"exports": {
".": {
"import": "./dist/useMedia.es.js",
"require": "./dist/useMedia.umd.js"
}
},
"repository": {
"type": "git",
"url": "https://github.com/komlev/tiny-use-media.git"
Expand All @@ -23,9 +33,11 @@
],
"license": "MIT",
"scripts": {
"build": "vite build",
"publish": "clean-publish"
},
"devDependencies": {
"vite": "^2.9.12",
"clean-publish": "^4.0.0"
},
"peerDependencies": {
Expand Down
20 changes: 20 additions & 0 deletions vite.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
const path = require("path");
const { defineConfig } = require("vite");

module.exports = defineConfig({
build: {
lib: {
entry: path.resolve(__dirname, "index.js"),
name: "useMedia",
fileName: (format) => `useMedia.${format}.js`,
},
rollupOptions: {
external: ["react"],
output: {
globals: {
react: "React",
},
},
},
},
});