Skip to content

Commit

Permalink
chore: add responsive module (#7716)
Browse files Browse the repository at this point in the history
**Related Issue:** #6670 

## Summary

Adds support module for component responsiveness. 

### Notes

* Spec test is skipped until the following JSDOM issues are addressed:
  * jsdom/jsdom#3563
  * jsdom/jsdom#2160.
* Moves existing custom matchers from the color-picker E2E test to the
test utils module for reuse.
  • Loading branch information
jcfranco authored Sep 8, 2023
1 parent f09fead commit 5dcde0f
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,14 @@ import { CSS, DEFAULT_COLOR, DEFAULT_STORAGE_KEY_PREFIX, DIMENSIONS, SCOPE_SIZE
import { E2EElement, E2EPage, EventSpy, newE2EPage } from "@stencil/core/testing";
import { ColorValue } from "./interfaces";
import SpyInstance = jest.SpyInstance;
import { GlobalTestProps, selectText, getElementXY, newProgrammaticE2EPage } from "../../tests/utils";
import {
GlobalTestProps,
selectText,
getElementXY,
newProgrammaticE2EPage,
toBeNumber,
toBeInteger,
} from "../../tests/utils";
import { html } from "../../../support/formatting";

describe("calcite-color-picker", () => {
Expand Down Expand Up @@ -787,31 +794,6 @@ describe("calcite-color-picker", () => {
});

describe("color inputs", () => {
// see https://jasmine.github.io/tutorials/custom_argument_matchers for more info
function toBeInteger(): any {
return {
asymmetricMatch(abc: string): boolean {
return Number.isInteger(abc);
},

jasmineToString(): string {
return `Expected value to be an integer.`;
},
};
}

function toBeNumber(): any {
return {
asymmetricMatch(expected: string): boolean {
return !isNaN(parseFloat(expected)) && isFinite(Number(expected));
},

jasmineToString(): string {
return `Expected value to be an number.`;
},
};
}

it("numbering system does not revert to latn when clamping RGB channels", async () => {
const page = await newE2EPage();
await page.setContent(
Expand Down
34 changes: 34 additions & 0 deletions packages/calcite-components/src/tests/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -354,3 +354,37 @@ export async function getFocusedElementProp(
options?.shadow
);
}

/**
* Custom integer matcher to use with object matchers.
*
* @see https://jasmine.github.io/tutorials/custom_argument_matchers
*/
export function toBeInteger(): any {
return {
asymmetricMatch(abc: string): boolean {
return Number.isInteger(abc);
},

jasmineToString(): string {
return `Expected value to be an integer.`;
},
};
}

/**
* Custom number matcher to use with object matchers.
*
* @see https://jasmine.github.io/tutorials/custom_argument_matchers
*/
export function toBeNumber(): any {
return {
asymmetricMatch(expected: string): boolean {
return !isNaN(parseFloat(expected)) && isFinite(Number(expected));
},

jasmineToString(): string {
return `Expected value to be an number.`;
},
};
}
28 changes: 28 additions & 0 deletions packages/calcite-components/src/utils/responsive.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { getBreakpoints } from "./responsive";
import { toBeInteger } from "../tests/utils";

describe("getBreakpoints()", () => {
// skipped due to JSDOM bugs with inheritance/getComputedStyle
// see https://github.com/jsdom/jsdom/issues/2160 and https://github.com/jsdom/jsdom/issues/3563
it.skip("returns breakpoints lookup object", async () => {
document.head.innerHTML = `
<style>
:root {
--calcite-app-breakpoint-width-lg: 1000px;
--calcite-app-breakpoint-width-md: 100px;
--calcite-app-breakpoint-width-sm: 10px;
--calcite-app-breakpoint-width-xs: 1px;
}
</style>
`;

expect(await getBreakpoints()).toMatchObject({
width: {
large: toBeInteger(),
medium: toBeInteger(),
small: toBeInteger(),
xsmall: toBeInteger(),
},
});
});
});
42 changes: 42 additions & 0 deletions packages/calcite-components/src/utils/responsive.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
interface Breakpoints {
width: {
large: number;
medium: number;
small: number;
xsmall: number;
};
}

let getBreakpointsPromise: Promise<Breakpoints>;

function breakpointTokenToNumericalValue(style: CSSStyleDeclaration, tokenName: string): number {
return parseInt(style.getPropertyValue(tokenName));
}

/**
* This util will return a breakpoints lookup object.
*
* Note that the breakpoints will be evaluated at the root and cached for reuse.
*/
export async function getBreakpoints(): Promise<Breakpoints> {
if (getBreakpointsPromise) {
return getBreakpointsPromise;
}

getBreakpointsPromise = new Promise<Breakpoints>((resolve) => {
requestAnimationFrame(() => {
const rootStyles = getComputedStyle(document.body);

resolve({
width: {
large: breakpointTokenToNumericalValue(rootStyles, "--calcite-app-breakpoint-width-lg"),
medium: breakpointTokenToNumericalValue(rootStyles, "--calcite-app-breakpoint-width-md"),
small: breakpointTokenToNumericalValue(rootStyles, "--calcite-app-breakpoint-width-sm"),
xsmall: breakpointTokenToNumericalValue(rootStyles, "--calcite-app-breakpoint-width-xs"),
},
});
});
});

return getBreakpointsPromise;
}

0 comments on commit 5dcde0f

Please sign in to comment.