Fix theming.

This commit is contained in:
Teffen Ellis
2026-03-04 22:50:21 +01:00
parent 3db9450651
commit d4a8703329
3 changed files with 97 additions and 30 deletions

View File

@@ -13,9 +13,9 @@ import { AdminApi, CapabilitiesEnum, LicenseSummaryStatusEnum } from "@goauthent
import { msg } from "@lit/localize";
import { css, html, TemplateResult } from "lit";
import { ref } from "lit-html/directives/ref.js";
import { styleMap } from "lit-html/directives/style-map.js";
import { customElement } from "lit/decorators.js";
import { until } from "lit/directives/until.js";
import { customElement, state } from "lit/decorators.js";
import PFAbout from "@patternfly/patternfly/components/AboutModalBox/about-modal-box.css";
@@ -62,8 +62,9 @@ async function fetchAboutDetails(): Promise<AboutEntry[]> {
export class AboutModal extends WithLicenseSummary(WithBrandConfig(AKModal)) {
static hostStyles = [
css`
:host {
.ak-c-modal:has(ak-about-modal) {
--ak-c-modal--BackgroundColor: var(--pf-global--palette--black-900);
--ak-c-modal--BorderColor: var(--pf-global--palette--black-600);
}
`,
];
@@ -91,6 +92,22 @@ export class AboutModal extends WithLicenseSummary(WithBrandConfig(AKModal)) {
public static open = asInvoker(AboutModal);
@state()
protected entries: AboutEntry[] | null = null;
public refresh() {
return fetchAboutDetails().then((entries) => {
this.entries = entries;
});
}
public connectedCallback(): void {
super.connectedCallback();
this.refresh();
}
//#region Renderers
protected override renderCloseButton() {
return null;
}
@@ -103,6 +120,7 @@ export class AboutModal extends WithLicenseSummary(WithBrandConfig(AKModal)) {
}
return html`<div
${ref(this.scrollContainerRef)}
class="pf-c-about-modal-box"
style=${styleMap({
"--pf-c-about-modal-box__hero--sm--BackgroundImage": `url(${DEFAULT_BRAND_IMAGE})`,
@@ -135,21 +153,26 @@ export class AboutModal extends WithLicenseSummary(WithBrandConfig(AKModal)) {
<div class="pf-c-about-modal-box__content">
<div class="pf-c-about-modal-box__body">
<div class="pf-c-content">
${until(
fetchAboutDetails().then((entries) => {
return html`<dl>
${entries.map(([label, value]) => {
return html`<dt>${label}</dt>
<dd>${value}</dd>`;
})}
</dl>`;
}),
html`<ak-empty-state loading></ak-empty-state>`,
)}
${this.entries
? html`<dl>
${this.entries.map(([label, value]) => {
return html`<dt>${label}</dt>
<dd>${value}</dd>`;
})}
</dl>`
: html`<ak-empty-state loading></ak-empty-state>`}
</div>
</div>
<p class="pf-c-about-modal-box__strapline"></p>
</div>
</div>`;
}
//#endregion
}
declare global {
interface HTMLElementTagNameMap {
"ak-about-modal": AboutModal;
}
}

View File

@@ -10,6 +10,7 @@ import { ConsoleLogger, Logger } from "#logger/browser";
import { msg } from "@lit/localize";
import { CSSResult, html, PropertyValues } from "lit";
import { createRef } from "lit-html/directives/ref.js";
import { customElement, property, state } from "lit/decorators.js";
import { guard } from "lit/directives/guard.js";
@@ -46,11 +47,18 @@ export class AKModal extends AKElement {
#hostResizeObserver: ResizeObserver;
//#region Protected Properties
protected logger: Logger;
/**
* An optional Lit ref which can automatically synchronize the modal's height with the element's height.
*/
protected scrollContainerRef = createRef<HTMLElement>();
declare parentElement: HTMLDialogElement | null;
//#region Properties
//#region Public Properties
@property({ type: String, useDefault: true })
public headline: string | null = null;
@@ -146,22 +154,29 @@ export class AKModal extends AKElement {
* A map of observed elements to their expected sizes,
* used to prevent unnecessary height synchronizations.
*/
#expectedSizes = new WeakMap();
#expectedSizes = new WeakMap<Element, number>();
protected lastScrollHeight = 0;
protected synchronizeHeight: ResizeObserverCallback = ([entry]) => {
this.#heightSyncFrameID = requestAnimationFrame(() => {
const dialogElement = this.parentElement;
if (!dialogElement || !dialogElement.open) {
return;
}
const expectedSize = this.#expectedSizes.get(entry.target);
const blockSize = Math.ceil(entry.borderBoxSize[0].blockSize);
const desiredSize = Math.max(entry.target.scrollHeight, blockSize);
if (entry.contentRect.height === expectedSize) {
if (desiredSize === expectedSize) {
return;
}
if (!this.parentElement) {
return;
}
dialogElement.style.height = desiredSize + "px";
this.parentElement.style.height = entry.contentRect.height + "px";
this.#expectedSizes.set(entry.target, entry.contentRect.height);
this.#expectedSizes.set(entry.target, desiredSize);
});
};
@@ -175,6 +190,13 @@ export class AKModal extends AKElement {
if (this.parentElement) {
this.parentElement.style.height = "";
}
this.#heightResetAnimationFrameID = requestAnimationFrame(() => {
const scrollContainer = this.scrollContainerRef.value || this;
const scrollHeight = scrollContainer.scrollHeight;
this.lastScrollHeight = scrollHeight;
});
});
};
@@ -194,7 +216,9 @@ export class AKModal extends AKElement {
dialogElement.style.height = dialogElement.clientHeight + "px";
this.#hostResizeObserver.observe(this);
const scrollContainer = this.scrollContainerRef.value || this;
this.#hostResizeObserver.observe(scrollContainer);
window.addEventListener("resize", this.resetHeight, {
passive: true,
@@ -341,6 +365,19 @@ export class AKModal extends AKElement {
this.form = form;
this.form.viewportCheck = false;
}
const dialogElement = this.parentElement;
if (dialogElement && dialogElement.open) {
requestAnimationFrame(() => {
const scrollContainer = this.scrollContainerRef.value || this;
const scrollHeight = scrollContainer.scrollHeight;
if (scrollHeight !== this.lastScrollHeight) {
this.resetHeight();
}
});
}
}
//#endregion

View File

@@ -2,12 +2,16 @@
.ak-c-modal {
--ak-c-modal--BackgroundColor: var(--pf-global--BackgroundColor--100);
--ak-c-modal__backdrop--BackgroundColor: transparent;
--ak-c-modal__backdrop--BackdropFilter: blur(0);
--ak-c-modal--BoxShadow: var(--pf-global--BoxShadow--xl);
--ak-c-modal--ZIndex: var(--pf-global--ZIndex--xl);
--ak-c-modal--Width: 100%;
--ak-c-modal--MaxWidth: calc(100% - var(--pf-global--spacer--xl));
--ak-c-modal--MarginBlockStart: 10dvh;
--ak-c-modal--BorderColor: var(--pf-global--BackgroundColor--150);
--ak-c-modal__backdrop--BackgroundColor: transparent;
--ak-c-modal__backdrop--BackdropFilter: blur(0);
--ak-c-modal__backdrop--active--BackgroundColor: hsla(0, 0%, 0%, 0.5);
--ak-c-modal__backdrop--active--BackdropFilter: blur(2px);
}
/* #endregion */
@@ -27,7 +31,7 @@
background-color: var(--ak-c-modal--BackgroundColor);
box-shadow: var(--ak-c-modal--BoxShadow);
border-color: var(--pf-global--BackgroundColor--150);
border-color: var(--ak-c-modal--BorderColor);
&:focus-visible {
outline: none;
@@ -39,8 +43,9 @@
/* #region Transitions */
.ak-c-modal {
--ak-c-modal--TransitionDuration--fast: 50ms;
--ak-c-modal--TransitionDuration--slow: 100ms;
--ak-c-modal--TransitionDuration--fast: 100ms;
--ak-c-modal--TransitionDuration--slow: 150ms;
margin-block-start: var(--ak-c-modal--MarginBlockStart);
interpolate-size: allow-keywords;
@@ -71,8 +76,10 @@
}
&.fade-in {
--ak-c-modal__backdrop--BackdropFilter: blur(2px);
--ak-c-modal__backdrop--BackgroundColor: hsla(0, 0%, 0%, 0.5);
--ak-c-modal__backdrop--BackdropFilter: var(--ak-c-modal__backdrop--active--BackdropFilter);
--ak-c-modal__backdrop--BackgroundColor: var(
--ak-c-modal__backdrop--active--BackgroundColor
);
opacity: 1;
height: calc-size(max-content, size);