Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(responsive): use JS module to create breakpoints lookup object #8051

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 3 additions & 6 deletions packages/calcite-components/src/components/alert/alert.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ import { KindIcons } from "../resources";
import { AlertMessages } from "./assets/alert/t9n";
import { AlertDuration, Sync, Unregister } from "./interfaces";
import { CSS, DURATIONS, SLOTS } from "./resources";
import { Breakpoints, getBreakpoints } from "../../utils/responsive";
import { createObserver } from "../../utils/observers";
import { breakpoints } from "../../utils/responsive";

/**
* Alerts are meant to provide a way to communicate urgent or important information to users, frequently as a result of an action they took in your app. Alerts are positioned
Expand Down Expand Up @@ -182,8 +182,7 @@ export class Alert implements OpenCloseComponent, LoadableComponent, T9nComponen

async componentWillLoad(): Promise<void> {
setUpLoadableComponent(this);
const [, breakpoints] = await Promise.all([setUpMessages(this), getBreakpoints()]);
this.breakpoints = breakpoints;
await setUpMessages(this);
if (this.open) {
onToggleOpenCloseComponent(this);
}
Expand Down Expand Up @@ -218,7 +217,7 @@ export class Alert implements OpenCloseComponent, LoadableComponent, T9nComponen
const { hasEndActions } = this;
const { open, autoClose, responsiveContainerWidth, label, placement, queued } = this;
const role = autoClose ? "alert" : "alertdialog";
const widthBreakpoints = this.breakpoints.width;
const widthBreakpoints = breakpoints.width;
const lessThanSmall = responsiveContainerWidth < widthBreakpoints.small;
const greaterOrEqualThanSmall = responsiveContainerWidth >= widthBreakpoints.small;
const hidden = !open;
Expand Down Expand Up @@ -439,8 +438,6 @@ export class Alert implements OpenCloseComponent, LoadableComponent, T9nComponen

private autoCloseTimeoutId: number = null;

private breakpoints: Breakpoints;

private closeButton: HTMLButtonElement;

private initialOpenTime: number;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import { Scale } from "../interfaces";
import { PaginationMessages } from "./assets/pagination/t9n";
import { CSS, ICONS } from "./resources";
import { createObserver } from "../../utils/observers";
import { Breakpoints, getBreakpoints } from "../../utils/responsive";
import { breakpoints } from "../../utils/responsive";
import { getIconScale } from "../../utils/component";

export interface PaginationDetail {
Expand Down Expand Up @@ -151,8 +151,6 @@ export class Pagination

@State() totalPages: number;

private breakpoints: Breakpoints;

private resizeObserver = createObserver("resize", (entries) =>
entries.forEach(this.resizeHandler)
);
Expand Down Expand Up @@ -181,8 +179,7 @@ export class Pagination
}

async componentWillLoad(): Promise<void> {
const [, breakpoints] = await Promise.all([setUpMessages(this), getBreakpoints()]);
this.breakpoints = breakpoints;
await setUpMessages(this);
setUpLoadableComponent(this);
this.handleTotalPages();
}
Expand Down Expand Up @@ -230,8 +227,6 @@ export class Pagination
// --------------------------------------------------------------------------

private setMaxItemsToBreakpoint(width: number): void {
const { breakpoints } = this;

if (!breakpoints || !width) {
return;
}
Expand Down
22 changes: 4 additions & 18 deletions packages/calcite-components/src/utils/responsive.spec.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,9 @@
import { getBreakpoints } from "./responsive";
import { breakpoints } 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: 10000px;
--calcite-app-breakpoint-width-md: 1000px;
--calcite-app-breakpoint-width-sm: 100px;
--calcite-app-breakpoint-width-xs: 10px;
--calcite-app-breakpoint-width-xxs: 1px;
}
</style>
`;

expect(await getBreakpoints()).toMatchObject({
describe("breakpoints", () => {
it("provides a breakpoints lookup object", async () => {
expect(breakpoints).toMatchObject({
width: {
large: toBeInteger(),
medium: toBeInteger(),
Expand Down
52 changes: 20 additions & 32 deletions packages/calcite-components/src/utils/responsive.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
import {
CoreBreakpointWidthDefaultLg,
CoreBreakpointWidthDefaultMd,
CoreBreakpointWidthDefaultSm,
CoreBreakpointWidthDefaultXs,
CoreBreakpointWidthDefaultXxs,
} from "@esri/calcite-design-tokens/dist/es6/calcite-headless";

export interface Breakpoints {
width: {
large: number;
Expand All @@ -8,39 +16,19 @@ export interface Breakpoints {
};
}

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.
*
* @returns {Promise<Breakpoints>} The Breakpoints object.
* A breakpoints lookup object.
*/
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"),
xxsmall: breakpointTokenToNumericalValue(rootStyles, "--calcite-app-breakpoint-width-xxs"),
},
});
});
});
export const breakpoints: Breakpoints = {
width: {
large: cssLengthToNumber(CoreBreakpointWidthDefaultLg),
medium: cssLengthToNumber(CoreBreakpointWidthDefaultMd),
small: cssLengthToNumber(CoreBreakpointWidthDefaultSm),
xsmall: cssLengthToNumber(CoreBreakpointWidthDefaultXs),
xxsmall: cssLengthToNumber(CoreBreakpointWidthDefaultXxs),
},
};

return getBreakpointsPromise;
function cssLengthToNumber(length: string): number {
return parseInt(length);
}
4 changes: 4 additions & 0 deletions packages/calcite-components/stencil.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,10 @@ export const create: () => Config = () => ({
"^lodash-es$": "lodash",
},
setupFilesAfterEnv: ["<rootDir>/src/tests/setupTests.ts"],
transform: {
"calcite-design-tokens/dist/es6/calcite-headless\\.js$":
"<rootDir>../../node_modules/@stencil/core/testing/jest-preprocessor.js",
},
},
hydratedFlag: {
selector: "attribute",
Expand Down
Loading