Skip to content

Commit

Permalink
kerosene-ui: Add measureCSSProperty function (#48)
Browse files Browse the repository at this point in the history
* kerosene-ui: Add measureCSSProperty function

* kerosene-ui: Bump version to 0.0.12
  • Loading branch information
nhardy authored and brycehanscomb committed Sep 20, 2019
1 parent a17adca commit 441e968
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 18 deletions.
2 changes: 1 addition & 1 deletion packages/kerosene-ui/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@kablamo/kerosene-ui",
"version": "0.0.11",
"version": "0.0.12",
"repository": {
"type": "git",
"url": "https://github.com/KablamoOSS/kerosene.git",
Expand Down
4 changes: 4 additions & 0 deletions packages/kerosene-ui/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ Returns whether or not the provided `element` is inside the viewport.

Returns whether or not the current page is being displayed in a Progressive Web App.

### `measureCSSProperty(element, property, value)`

Measures a CSS `property` at the provided `element` by injecting a `<noscript />` element and setting the style `property` to `value` and measuring with `window.getComputedStyle`.

### `mergeRefs(...refs)`

Returns a new callback ref that effectively merges all provided `refs`.
Expand Down
1 change: 1 addition & 0 deletions packages/kerosene-ui/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export type ViewportDimensions = _ViewportDimensions;
export { default as isInViewport } from "./utils/isInViewport";
export { default as isPwa } from "./utils/isPwa";
export * from "./utils/listeners";
export { default as measureCSSProperty } from "./utils/measureCSSProperty";
export { default as mergeRefs } from "./utils/mergeRefs";
export { default as rafThrottle } from "./utils/rafThrottle";
export { default as waitForRepaint } from "./utils/waitForRepaint";
54 changes: 54 additions & 0 deletions packages/kerosene-ui/src/utils/measureCSSProperty.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import createSandbox from "jest-sandbox";
import { when } from "jest-when";
import measureCSSProperty from "./measureCSSProperty";
import { JestMock } from "../../../kerosene-test/src";

describe("measureCSSProperty", () => {
let sandbox: JestSandbox;
let createElement: JestMock<Document["createElement"]>;
let getComputedStyle: JestMock<Window["getComputedStyle"]>;
beforeEach(() => {
sandbox = createSandbox();
createElement = jest.fn();
document.createElement = createElement;
getComputedStyle = jest.fn();
window.getComputedStyle = getComputedStyle;
});

afterEach(() => {
sandbox.restore();
});

it("should inject a noscript tag and return the computed style", () => {
const el = {
appendChild: jest.fn(),
removeChild: jest.fn(),
};

const noscript = { tagName: "NOSCRIPT", style: {} } as HTMLElement;
when(createElement)
.calledWith("noscript")
.mockReturnValue(noscript);

when(getComputedStyle)
.calledWith({
...noscript,
style: { ...noscript.style, paddingTop: "var(--header-height, 0px)" },
} as HTMLElement)
.mockReturnValue({ paddingTop: "48px" } as CSSStyleDeclaration);

expect(
measureCSSProperty(
(el as Partial<Element>) as Element,
"paddingTop",
"var(--header-height, 0px)",
),
).toBe("48px");
expect(el.appendChild).toBeCalledWith(noscript);
expect(noscript.style).toHaveProperty(
["paddingTop"],
"var(--header-height, 0px)",
);
expect(el.removeChild).toBeCalledWith(noscript);
});
});
38 changes: 38 additions & 0 deletions packages/kerosene-ui/src/utils/measureCSSProperty.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/**
* Measures a CSS `property` at the provided `element` by injecting a `<noscript />` element and setting the style
* `property` to `value` and measuring with `window.getComputedStyle`.
*
* Useful for measuring CSS Custom Properties that contain calc expressions, e.g.
*
* ```css
* :root {
* --header-height: 48px;
* }
*
* @media only screen and (min-width: 768px) {
* :root {
* --header-height: 72px;
* }
* }
* ```
*
* ```typescript
* const headerHeight = measureCSSProperty(document.body, "paddingTop", "var(--header-height, 0px)");
* ```
*
* @param element
* @param property
* @param value
*/
export default function measureCSSProperty<P extends keyof CSSStyleDeclaration>(
element: Element,
property: P,
value: CSSStyleDeclaration[P],
): CSSStyleDeclaration[P] {
const noscript = document.createElement("noscript");
noscript.style[property] = value;
element.appendChild(noscript);
const computed = window.getComputedStyle(noscript)[property];
element.removeChild(noscript);
return computed;
}
18 changes: 1 addition & 17 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -862,17 +862,6 @@
"@types/istanbul-reports" "^1.1.1"
"@types/yargs" "^13.0.0"

"@kablamo/kerosene@^0.0.11":
version "0.0.11"
resolved "https://registry.yarnpkg.com/@kablamo/kerosene/-/kerosene-0.0.11.tgz#39e4419b26bdcc52859a9fd5aef84c98bc912a8b"
integrity sha512-XuvubcyM/xi8UMEuhjelPR5ei6H4zWVF/gpvjfqmL7HlMlgwe1TaCAj/FpaTd7dwx3MeIxqSCxhFUUSRl4brOw==
dependencies:
"@types/lodash" "^4.14.121"
content-type "^1.0.4"
core-js-pure "^3.1.3"
date-fns "^2.0.0-alpha.32"
lodash "^4.17.13"

"@sinonjs/commons@^1", "@sinonjs/commons@^1.3.0", "@sinonjs/commons@^1.4.0":
version "1.6.0"
resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.6.0.tgz#ec7670432ae9c8eb710400d112c201a362d83393"
Expand Down Expand Up @@ -1021,7 +1010,7 @@
dependencies:
"@types/jest-diff" "*"

"@types/lodash@^4.14.121", "@types/lodash@^4.14.138":
"@types/lodash@^4.14.138":
version "4.14.138"
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.138.tgz#34f52640d7358230308344e579c15b378d91989e"
integrity sha512-A4uJgHz4hakwNBdHNPdxOTkYmXNgmUAKLbXZ7PKGslgeV0Mb8P3BlbYfPovExek1qnod4pDfRbxuzcVs3dlFLg==
Expand Down Expand Up @@ -1783,11 +1772,6 @@ data-urls@^1.0.0, data-urls@^1.1.0:
whatwg-mimetype "^2.2.0"
whatwg-url "^7.0.0"

date-fns@^2.0.0-alpha.32:
version "2.1.0"
resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.1.0.tgz#0d7e806c3cefe14a943532dbf968995ccfd46bd9"
integrity sha512-eKeLk3sLCnxB/0PN4t1+zqDtSs4jb4mXRSTZ2okmx/myfWyDqeO4r5nnmA5LClJiCwpuTMeK2v5UQPuE4uMaxA==

date-fns@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.0.1.tgz#c5f30e31d3294918e6b6a82753a4e719120e203d"
Expand Down

0 comments on commit 441e968

Please sign in to comment.