web: unit tests for the simple things, with fixes that the tests revealed (#11633)

* Added tests and refinements as tests indicate.

* Building out the test suite.

* web: test the simple things. Fix what the tests revealed.

- Move `EmptyState.test.ts` into the `./tests` folder.
- Provide unit tests for:
  - Alert
  - Divider
  - Expand
  - Label
  - LoadingOverlay
- Give all tested items an Interface and a functional variant for rendering
- Give Label an alternative syntax for declaring alert levels
- Remove the slot name in LoadingOverlay
  - Change the slot call in `./enterprise/rac/index.ts` to not need the slot name as well
- Change the attribute names `topMost`, `textOpen`, and `textClosed` to `topmost`, `text-open`, and
  `text-closed`, respectively.
  - Change locations in the code where those are used to correspond

** Why interfaces: **

Provides another check on the input/output boundaries of our elements, gives Storybook and
WebdriverIO another validation to check, and guarantees any rendering functions cannot be passed
invalid property names.

** Why functions for rendering: **

Providing functions for rendering gets us one step closer to dynamically defining our forms-in-code
at runtime without losing any type safety.

** Why rename the attributes: **

A *very* subtle bug:
[Element:setAttribute()](https://developer.mozilla.org/en-US/docs/Web/API/Element/setAttribute)
automatically "converts an attribute name to all lower-case when called on an HTML element in an
HTML document." The three attributes renamed are all treated *as* attributes, either classic boolean
or stringly-typed attributes, and attempting to manipulate them with `setAttribute()` will fail.

All of these attributes are presentational; none of them end up in a transaction with the back-end,
so kebab-to-camel conversions are not a concern.

Also, ["topmost" is one word](https://www.merriam-webster.com/dictionary/topmost).

** Why remove the slot name: **

Because there was only one slot.  A name is not needed.

* Fix minor spelling error.
This commit is contained in:
Ken Sternberg
2024-10-10 15:14:29 -07:00
committed by GitHub
parent 795e0ff100
commit 058a388518
16 changed files with 495 additions and 65 deletions

View File

@ -1,17 +1,24 @@
import { AKElement } from "@goauthentik/elements/Base";
import "@goauthentik/elements/EmptyState";
import { type SlottedTemplateResult, type Spread } from "@goauthentik/elements/types";
import { spread } from "@open-wc/lit-helpers";
import { CSSResult, TemplateResult, css, html } from "lit";
import { css, html, nothing } from "lit";
import { customElement, property } from "lit/decorators.js";
import PFBase from "@patternfly/patternfly/patternfly-base.css";
@customElement("ak-loading-overlay")
export class LoadingOverlay extends AKElement {
@property({ type: Boolean })
topMost = false;
interface ILoadingOverlay {
topmost?: boolean;
}
static get styles(): CSSResult[] {
@customElement("ak-loading-overlay")
export class LoadingOverlay extends AKElement implements ILoadingOverlay {
// Do not camelize: https://www.merriam-webster.com/dictionary/topmost
@property({ type: Boolean, attribute: "topmost" })
topmost = false;
static get styles() {
return [
PFBase,
css`
@ -25,20 +32,30 @@ export class LoadingOverlay extends AKElement {
background-color: var(--pf-global--BackgroundColor--dark-transparent-200);
z-index: 1;
}
:host([topMost]) {
:host([topmost]) {
z-index: 999;
}
`,
];
}
render(): TemplateResult {
render() {
return html`<ak-empty-state loading header="">
<slot name="body" slot="body"></slot>
<slot></slot>
</ak-empty-state>`;
}
}
export function akLoadingOverlay(
properties: ILoadingOverlay,
content: SlottedTemplateResult = nothing,
) {
const message = typeof content === "string" ? html`<span>${content}</span>` : content;
return html`<ak-loading-overlay ${spread(properties as Spread)}
>${message}</ak-loading-overlay
>`;
}
declare global {
interface HTMLElementTagNameMap {
"ak-loading-overlay": LoadingOverlay;