diff --git a/packages/calcite-components/src/components/scrim/resources.ts b/packages/calcite-components/src/components/scrim/resources.ts
index 3b943747318..8e2ffbaa012 100644
--- a/packages/calcite-components/src/components/scrim/resources.ts
+++ b/packages/calcite-components/src/components/scrim/resources.ts
@@ -2,3 +2,9 @@ export const CSS = {
scrim: "scrim",
content: "content"
};
+
+export const BREAKPOINTS = {
+ s: 72, // Less than 72px.
+ // medium is assumed default.
+ l: 480 // Greater than or equal to 480px.
+};
diff --git a/packages/calcite-components/src/components/scrim/scrim.e2e.ts b/packages/calcite-components/src/components/scrim/scrim.e2e.ts
index 4d3c5509344..49513f4a494 100644
--- a/packages/calcite-components/src/components/scrim/scrim.e2e.ts
+++ b/packages/calcite-components/src/components/scrim/scrim.e2e.ts
@@ -1,6 +1,8 @@
import { newE2EPage } from "@stencil/core/testing";
import { accessible, defaults, hidden, renders, t9n } from "../../tests/commonTests";
-import { CSS } from "./resources";
+import { BREAKPOINTS, CSS } from "./resources";
+import { html } from "../../../support/formatting";
+import { Scale } from "../interfaces";
describe("calcite-scrim", () => {
describe("renders", () => {
@@ -107,6 +109,65 @@ describe("calcite-scrim", () => {
expect(contentNode).not.toBeNull();
});
+ describe("Responsive loading spinner", () => {
+ const testValues: { width: number; height: number; scale: Scale }[] = [
+ {
+ width: BREAKPOINTS.s - 1,
+ height: 800,
+ scale: "s"
+ },
+ {
+ width: 800,
+ height: BREAKPOINTS.s - 1,
+ scale: "s"
+ },
+ {
+ width: BREAKPOINTS.l - 1,
+ height: 800,
+ scale: "m"
+ },
+ {
+ width: 800,
+ height: BREAKPOINTS.l - 1,
+ scale: "m"
+ },
+ {
+ width: BREAKPOINTS.l,
+ height: 800,
+ scale: "l"
+ },
+ {
+ width: 800,
+ height: BREAKPOINTS.l,
+ scale: "l"
+ }
+ ];
+
+ testValues.forEach((scaleSize) => {
+ it(`should have a scale="${scaleSize.scale}" loading spinner`, async () => {
+ const page = await newE2EPage();
+ await page.setContent(html`
+
+
I'm a panel that is loading.
+
`);
+ await page.waitForChanges();
+
+ const loader = await page.find("calcite-scrim >>> calcite-loader");
+
+ expect(loader).toBeDefined();
+ expect(await loader.isVisible()).toBe(true);
+ expect(await loader.getProperty("scale")).toBe(scaleSize.scale);
+ });
+ });
+ });
+
describe("CSS properties for light/dark modes", () => {
const scrimSnippet = `
diff --git a/packages/calcite-components/src/components/scrim/scrim.tsx b/packages/calcite-components/src/components/scrim/scrim.tsx
index abcf440e63c..7e1b80bd823 100644
--- a/packages/calcite-components/src/components/scrim/scrim.tsx
+++ b/packages/calcite-components/src/components/scrim/scrim.tsx
@@ -8,7 +8,9 @@ import {
updateMessages
} from "../../utils/t9n";
import { ScrimMessages } from "./assets/scrim/t9n";
-import { CSS } from "./resources";
+import { CSS, BREAKPOINTS } from "./resources";
+import { createObserver } from "../../utils/observers";
+import { Scale } from "../interfaces";
/**
* @slot - A slot for adding custom content, primarily loading information.
@@ -58,11 +60,11 @@ export class Scrim implements LocalizedComponent, T9nComponent {
@Element() el: HTMLCalciteScrimElement;
- // --------------------------------------------------------------------------
- //
- // Private State / Properties
- //
- // --------------------------------------------------------------------------
+ resizeObserver = createObserver("resize", () => this.handleResize());
+
+ loaderEl: HTMLCalciteLoaderElement;
+
+ @State() loaderScale: Scale;
@State() defaultMessages: ScrimMessages;
@@ -102,7 +104,9 @@ export class Scrim implements LocalizedComponent, T9nComponent {
render(): VNode {
const { el, loading, messages } = this;
const hasContent = el.innerHTML.trim().length > 0;
- const loaderNode = loading ?
: null;
+ const loaderNode = loading ? (
+
+ ) : null;
const contentNode = hasContent ? (
@@ -116,4 +120,35 @@ export class Scrim implements LocalizedComponent, T9nComponent {
);
}
+
+ // --------------------------------------------------------------------------
+ //
+ // Private Methods
+ //
+ // --------------------------------------------------------------------------
+
+ private storeLoaderEl = (el: HTMLCalciteLoaderElement): void => {
+ this.loaderEl = el;
+ this.handleResize();
+ };
+
+ private getScale(size: number): Scale {
+ if (size < BREAKPOINTS.s) {
+ return "s";
+ } else if (size >= BREAKPOINTS.l) {
+ return "l";
+ } else {
+ return "m";
+ }
+ }
+
+ private handleResize(): void {
+ const { loaderEl, el } = this;
+
+ if (!loaderEl) {
+ return;
+ }
+
+ this.loaderScale = this.getScale(Math.min(el.clientHeight, el.clientWidth) ?? 0);
+ }
}