Skip to content

Commit 137c5a6

Browse files
committed
improve the useResizeState and useResponsiveState api
1 parent c18f8a4 commit 137c5a6

File tree

5 files changed

+77
-65
lines changed

5 files changed

+77
-65
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@atomico/hooks",
33
"description": "Series of utilities in hooks format to extend the operation of Atomico",
4-
"version": "3.39.0",
4+
"version": "3.40.0",
55
"type": "module",
66
"workspaces": [
77
"src/**/*"

src/use-resize-state/use-resize-state.js

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
1-
import { useState } from "atomico";
1+
import { useHost, useState } from "atomico";
22
import { useResizeObserver } from "../use-resize-observer/use-resize-observer.js";
33
import media from "@uppercod/match-media";
44

5+
/**
6+
* @type {{[index:string]:ReturnType<media>}}
7+
*/
8+
const CACHE_TEMPLATE = {};
59
/**
610
*
711
* @param {import("atomico").Ref<Element>} ref
812
* @return {string}
913
*/
10-
export function useResizeState(ref, sizes) {
14+
export function useRefResizeState(ref, sizes) {
1115
/**
1216
* @type {ReturnType<media>}
1317
*/
@@ -25,3 +29,37 @@ export function useResizeState(ref, sizes) {
2529

2630
return state;
2731
}
32+
33+
/**
34+
*
35+
* @param {string|TemplateStringsArray} part
36+
* @param {...any} [args]
37+
* @returns
38+
*/
39+
export function useResizeState(part, ...args) {
40+
const ref = useHost();
41+
/**
42+
* @type {ReturnType<media>}
43+
*/
44+
let template;
45+
if (typeof part === "string") {
46+
if (!CACHE_TEMPLATE[part]) {
47+
CACHE_TEMPLATE[part] = media.call(null, { raw: [part] });
48+
}
49+
template = CACHE_TEMPLATE[part];
50+
} else {
51+
template = media.call(null, part, ...args);
52+
}
53+
54+
const [state, setState] = useState();
55+
56+
function getState() {
57+
const { clientWidth } = ref.current;
58+
59+
return template.match(({ size }) => size <= clientWidth);
60+
}
61+
62+
useResizeObserver(ref, () => setState(getState));
63+
64+
return state;
65+
}
Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,35 @@
11
import { expect } from "@esm-bundle/chai";
2-
import { compareSnapshot, setViewport } from "@web/test-runner-commands";
2+
import { setViewport } from "@web/test-runner-commands";
33
import { createHooks } from "atomico/test-hooks";
4-
import { useResizeState } from "./use-resize-state.js";
4+
import { useRefResizeState } from "./use-resize-state.js";
55

6-
it("useResponsiveState <= 320px", async () => {
7-
const current = document.createElement("div");
8-
const ref = { current };
9-
let step = 0;
10-
const results = [];
6+
describe("useResponsiveState", () => {
7+
it("useResponsiveState <= 320px", async () => {
8+
const current = document.createElement("div");
9+
const ref = { current };
10+
const results = [];
1111

12-
document.body.appendChild(current);
12+
document.body.appendChild(current);
1313

14-
const hooks = createHooks(() => hooks.load(load), current);
14+
const hooks = createHooks(() => hooks.load(load), current);
1515

16-
const load = () => {
17-
const value = useResizeState(ref, "no, yes 320px");
18-
results.push(value);
19-
};
16+
const load = () => {
17+
const value = useRefResizeState(ref, "no, yes 320px");
18+
results.push(value);
19+
};
2020

21-
hooks.load(load);
21+
hooks.load(load);
2222

23-
hooks.cleanEffects()();
23+
hooks.cleanEffects()();
2424

25-
await setViewport({ width: 360, height: 640 });
25+
await setViewport({ width: 360, height: 640 });
2626

27-
await new Promise((resolve) => setTimeout(resolve, 100));
27+
await new Promise((resolve) => setTimeout(resolve, 100));
2828

29-
await setViewport({ width: 200, height: 640 });
29+
await setViewport({ width: 200, height: 640 });
3030

31-
await new Promise((resolve) => setTimeout(resolve, 100));
31+
await new Promise((resolve) => setTimeout(resolve, 100));
3232

33-
expect(results).to.deep.equal([undefined, "yes", "no"]);
33+
expect(results).to.deep.equal([undefined, "yes", "no"]);
34+
});
3435
});

src/use-responsive-state/src/string-escape.js

Lines changed: 0 additions & 38 deletions
This file was deleted.

src/use-responsive-state/use-responsive-state.js

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,32 @@ import media from "@uppercod/match-media";
66
*/
77
const CACHE = {};
88

9+
/**
10+
* @type {{[index:string]:ReturnType<media>}}
11+
*/
12+
const CACHE_TEMPLATE = {};
13+
914
/**
1015
* @param {import("@uppercod/match-media").Result} result
1116
*/
1217
const getId = ({ size, unit }) => `(min-width: ${size}${unit})`;
1318

19+
/**
20+
*
21+
* @param {string|TemplateStringsArray} part
22+
* @param {...any} [args]
23+
* @returns
24+
*/
1425
export function useResponsiveState(part, ...args) {
1526
/**@type {ReturnType<typeof media>} */
1627
let template;
1728

1829
if (typeof part === "string") {
19-
if (!CACHE[part]) {
20-
CACHE[part] = media.call(null, { raw: [part] });
30+
if (!CACHE_TEMPLATE[part]) {
31+
CACHE_TEMPLATE[part] = media.call(null, { raw: [part] });
2132
}
22-
template = CACHE[part];
23-
} else if (part) {
33+
template = CACHE_TEMPLATE[part];
34+
} else {
2435
template = media.call(null, part, ...args);
2536
}
2637

0 commit comments

Comments
 (0)