UNPKG

@zeix/ui-element

Version:

UIElement - minimal reactive framework based on Web Components

165 lines (151 loc) 4.2 kB
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8" /> <title>Context Tests</title> </head> <body> <motion-context> <my-animation> <h1>Reduced Motion: <span>Unknown to Server</span></h1> </my-animation> </motion-context> <user-context display-name="Jane Doe"> <hello-world> <h1>Hello, <span>World</span>!</h1> </hello-world> </user-context> <script type="module"> import { runTests } from "@web/test-runner-mocha"; import { assert } from "@esm-bundle/chai"; import { RESET, component, state, first, provide, consume, asString, setText, } from "../index.dev.js"; const animationFrame = async () => new Promise(requestAnimationFrame); const normalizeText = (text) => text.replace(/\s+/g, " ").trim(); component( "motion-context", { "reduced-motion": () => { const mql = matchMedia("(prefers-reduced-motion)"); const reducedMotion = state(mql.matches); mql.onchange = (e) => reducedMotion.set(e.matches); return reducedMotion; }, }, () => [provide(["reduced-motion"])], ); component( "my-animation", { reducedMotion: consume("reduced-motion"), }, () => [first("span", setText("reducedMotion"))], ); component( "user-context", { "display-name": asString(RESET), }, () => [provide(["display-name"])], ); component( "hello-world", { displayName: consume("display-name"), }, () => [first("span", setText("displayName"))], ); runTests(() => { describe("Context provider", function () { it("should have motion-context signal from media query list", async function () { assert.equal( "reduced-motion" in document.querySelector("motion-context"), true, ); }); it("should have display-name signal from attribute", async function () { assert.equal( document.querySelector("user-context")[ "display-name" ], "Jane Doe", ); }); }); describe("Context consumer", function () { it("should have consumed context in properties", async function () { assert.equal( "reducedMotion" in document.querySelector("my-animation"), true, ); }); it("should update according to consumed context", async function () { const contextConsumer = document.querySelector("my-animation"); await animationFrame(); const textContent = normalizeText( contextConsumer.querySelector("h1").textContent, ); assert.equal( textContent, `Reduced Motion: ${matchMedia("(prefers-reduced-motion)").matches}`, "Should have updated heading from context", ); }); it("should update when context is set", async function () { const contextProvider = document.querySelector("user-context"); const contextConsumer = document.querySelector("hello-world"); await animationFrame(); let textContent = normalizeText( contextConsumer.querySelector("span").textContent, ); assert.equal( textContent, "Jane Doe", "Should update heading from initial display-name context", ); contextProvider["display-name"] = "Esther Brunner"; await animationFrame(); textContent = normalizeText( contextConsumer.querySelector("span").textContent, ); assert.equal( textContent, "Esther Brunner", "Should update heading from setting display-name context", ); }); it("should revert when context is removed", async function () { const contextProvider = document.querySelector("user-context"); const contextConsumer = document.querySelector("hello-world"); contextProvider.removeAttribute("display-name"); await animationFrame(); const textContent = normalizeText( contextConsumer.querySelector("span").textContent, ); assert.equal( textContent, "World", "Should revert heading from context", ); }); }); }); </script> </body> </html>