Provide documentation and tests for the LoadingOverlay.

This commit is contained in:
Ken Sternberg
2024-05-17 15:01:59 -07:00
parent 934f778b97
commit 22a8ccfba6
4 changed files with 175 additions and 1 deletions

View File

@ -6,8 +6,26 @@ import { customElement, property } from "lit/decorators.js";
import PFBase from "@patternfly/patternfly/patternfly-base.css";
export interface ILoadingOverlay {
topMost?: boolean;
}
/**
* @class LoadingOverlay
* @element ak-loading-overlay
*
* The LoadingOverlay is meant to cover the container element completely, hiding the content behind
* a dimming filter, while content loads.
*
* @slot "body" - [Optional] message content to display while the overlay is visible.
*/
@customElement("ak-loading-overlay")
export class LoadingOverlay extends AKElement {
export class LoadingOverlay extends AKElement implements ILoadingOverlay {
/**
* When true, forces the overlay onto the top layer of the display stack.
*
* @attr
*/
@property({ type: Boolean })
topMost = false;
@ -38,3 +56,9 @@ export class LoadingOverlay extends AKElement {
</ak-empty-state>`;
}
}
declare global {
interface HTMLElementTagNameMap {
"ak-loading-overlay": LoadingOverlay;
}
}

View File

@ -0,0 +1,36 @@
import { Canvas, Description, Meta, Story, Title } from "@storybook/blocks";
import * as LoadingOverlayStories from "./LoadingOverlay.stories";
<Meta of={LoadingOverlayStories} />
# LoadingOverlay
The LoadingOverlay is meant to cover the container element completely, hiding the content behind a
dimming filter, while content loads.
It has a single named slot, "body" into which messages about the loading process can be included.
## Usage
```Typescript
import "@goauthentik/elements/LoadingOverlay.js";
```
Note that the content of an alert _must_ be a valid HTML component; plain text does not work here.
```html
<ak-loading-overlay topMost>
><span slot="body">This would display in the "body" slot</span></ak-loading-overlay
>
```
## Demo
### Default
<Story of={LoadingOverlayStories.DefaultStory} />
### With a message
<Story of={LoadingOverlayStories.WithAMessage} />

View File

@ -0,0 +1,73 @@
import type { Meta, StoryObj } from "@storybook/web-components";
import { LitElement, TemplateResult, css, html } from "lit";
import { customElement, property } from "lit/decorators.js";
import { type ILoadingOverlay, LoadingOverlay } from "../LoadingOverlay.js";
import "../LoadingOverlay.js";
const metadata: Meta<LoadingOverlay> = {
title: "Elements/<ak-loading-overlay>",
component: "ak-loading-overlay",
parameters: {
docs: {
description: "Our empty state spinner",
},
},
argTypes: {
topMost: { control: "boolean" },
message: { control: "text" },
},
};
export default metadata;
@customElement("ak-storybook-demo-container")
export class Container extends LitElement {
static get styles() {
return css`
:host {
display: block;
position: relative;
height: 25vh;
width: 75vw;
}
#main-container {
position: relative;
width: 100%;
height: 100%;
}
`;
}
@property({ type: Object, attribute: false })
content!: TemplateResult;
render() {
return html` <div id="main-container">${this.content}</div>`;
}
}
export const DefaultStory: StoryObj = {
args: {
topMost: undefined,
// @ts-ignore
message: undefined,
},
// @ts-ignore
render: ({ topMost, message }: ILoadingOverlay) => {
message = typeof message === "string" ? html`<span slot="body">${message}</span>` : message;
const content = html` <ak-loading-overlay ?topMost=${topMost}
>${message ?? ""}
</ak-loading-overlay>`;
return html`<ak-storybook-demo-container
.content=${content}
></ak-storybook-demo-container>`;
},
};
export const WithAMessage: StoryObj = {
...DefaultStory,
args: { ...DefaultStory.args, message: html`<p slot="body">Overlay with a message</p>` },
};

View File

@ -0,0 +1,41 @@
import { ensureCSSStyleSheet } from "@goauthentik/elements/utils/ensureCSSStyleSheet.js";
import { $, expect } from "@wdio/globals";
import { msg } from "@lit/localize";
import { TemplateResult, html, render as litRender } from "lit";
import AKGlobal from "@goauthentik/common/styles/authentik.css";
import PFBase from "@patternfly/patternfly/patternfly-base.css";
import "../LoadingOverlay.js";
const render = (body: TemplateResult) => {
document.adoptedStyleSheets = [
...document.adoptedStyleSheets,
ensureCSSStyleSheet(PFBase),
ensureCSSStyleSheet(AKGlobal),
];
return litRender(body, document.body);
};
describe("ak-loading-overlay", () => {
it("should render the default loader", async () => {
render(
html`<ak-loading-overlay></ak-loading-overlay>`,
);
const empty = await $("ak-loading-overlay");
await expect(empty).toExist();
});
it("should render a slotted message", async () => {
render(
html`<ak-loading-overlay>
<p slot="body">Try again with a different filter</p>
</ak-loading-overlay>`,
);
const message = await $("ak-loading-overlay").$(">>>p");
await expect(message).toHaveText("Try again with a different filter");
});
});