Skip to content

Commit

Permalink
improve the useResizeState and useResponsiveState api
Browse files Browse the repository at this point in the history
  • Loading branch information
UpperCod committed May 19, 2022
1 parent c18f8a4 commit 137c5a6
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 65 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@atomico/hooks",
"description": "Series of utilities in hooks format to extend the operation of Atomico",
"version": "3.39.0",
"version": "3.40.0",
"type": "module",
"workspaces": [
"src/**/*"
Expand Down
42 changes: 40 additions & 2 deletions src/use-resize-state/use-resize-state.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
import { useState } from "atomico";
import { useHost, useState } from "atomico";
import { useResizeObserver } from "../use-resize-observer/use-resize-observer.js";
import media from "@uppercod/match-media";

/**
* @type {{[index:string]:ReturnType<media>}}
*/
const CACHE_TEMPLATE = {};
/**
*
* @param {import("atomico").Ref<Element>} ref
* @return {string}
*/
export function useResizeState(ref, sizes) {
export function useRefResizeState(ref, sizes) {
/**
* @type {ReturnType<media>}
*/
Expand All @@ -25,3 +29,37 @@ export function useResizeState(ref, sizes) {

return state;
}

/**
*
* @param {string|TemplateStringsArray} part
* @param {...any} [args]
* @returns
*/
export function useResizeState(part, ...args) {
const ref = useHost();
/**
* @type {ReturnType<media>}
*/
let template;
if (typeof part === "string") {
if (!CACHE_TEMPLATE[part]) {
CACHE_TEMPLATE[part] = media.call(null, { raw: [part] });
}
template = CACHE_TEMPLATE[part];
} else {
template = media.call(null, part, ...args);
}

const [state, setState] = useState();

function getState() {
const { clientWidth } = ref.current;

return template.match(({ size }) => size <= clientWidth);
}

useResizeObserver(ref, () => setState(getState));

return state;
}
41 changes: 21 additions & 20 deletions src/use-resize-state/use-resize-state.test.js
Original file line number Diff line number Diff line change
@@ -1,34 +1,35 @@
import { expect } from "@esm-bundle/chai";
import { compareSnapshot, setViewport } from "@web/test-runner-commands";
import { setViewport } from "@web/test-runner-commands";
import { createHooks } from "atomico/test-hooks";
import { useResizeState } from "./use-resize-state.js";
import { useRefResizeState } from "./use-resize-state.js";

it("useResponsiveState <= 320px", async () => {
const current = document.createElement("div");
const ref = { current };
let step = 0;
const results = [];
describe("useResponsiveState", () => {
it("useResponsiveState <= 320px", async () => {
const current = document.createElement("div");
const ref = { current };
const results = [];

document.body.appendChild(current);
document.body.appendChild(current);

const hooks = createHooks(() => hooks.load(load), current);
const hooks = createHooks(() => hooks.load(load), current);

const load = () => {
const value = useResizeState(ref, "no, yes 320px");
results.push(value);
};
const load = () => {
const value = useRefResizeState(ref, "no, yes 320px");
results.push(value);
};

hooks.load(load);
hooks.load(load);

hooks.cleanEffects()();
hooks.cleanEffects()();

await setViewport({ width: 360, height: 640 });
await setViewport({ width: 360, height: 640 });

await new Promise((resolve) => setTimeout(resolve, 100));
await new Promise((resolve) => setTimeout(resolve, 100));

await setViewport({ width: 200, height: 640 });
await setViewport({ width: 200, height: 640 });

await new Promise((resolve) => setTimeout(resolve, 100));
await new Promise((resolve) => setTimeout(resolve, 100));

expect(results).to.deep.equal([undefined, "yes", "no"]);
expect(results).to.deep.equal([undefined, "yes", "no"]);
});
});
38 changes: 0 additions & 38 deletions src/use-responsive-state/src/string-escape.js

This file was deleted.

19 changes: 15 additions & 4 deletions src/use-responsive-state/use-responsive-state.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,32 @@ import media from "@uppercod/match-media";
*/
const CACHE = {};

/**
* @type {{[index:string]:ReturnType<media>}}
*/
const CACHE_TEMPLATE = {};

/**
* @param {import("@uppercod/match-media").Result} result
*/
const getId = ({ size, unit }) => `(min-width: ${size}${unit})`;

/**
*
* @param {string|TemplateStringsArray} part
* @param {...any} [args]
* @returns
*/
export function useResponsiveState(part, ...args) {
/**@type {ReturnType<typeof media>} */
let template;

if (typeof part === "string") {
if (!CACHE[part]) {
CACHE[part] = media.call(null, { raw: [part] });
if (!CACHE_TEMPLATE[part]) {
CACHE_TEMPLATE[part] = media.call(null, { raw: [part] });
}
template = CACHE[part];
} else if (part) {
template = CACHE_TEMPLATE[part];
} else {
template = media.call(null, part, ...args);
}

Expand Down

0 comments on commit 137c5a6

Please sign in to comment.