Load Panel
oge-load-panel — DevExtreme's LoadPanel: a shade over a container (or the viewport) with the suite's load indicator and a message, shown while visible is true.
While shown, the covered container is aria-busy="true" (and gets its previous value back after), the message is announced once through the shared live announcer, and pointer input is swallowed by the shade. The panel never takes or traps focus and does not make the container inert — that would blur a focused field and drop focus to the page.
Covering a container
Placed inside a container, the panel covers that parent (a statically positioned parent is made position: relative while shown). The parent is aria-busy for exactly as long as the panel is up, the message is announced through the shared live region, and clicks on the shade never reach the buttons underneath.
Orders
Clicks while loading: 0
import { ChangeDetectionStrategy, Component, signal } from '@angular/core';
import { OgeLoadPanel } from '@oge-ui/layout';
@Component({
selector: 'demo-root',
imports: [OgeLoadPanel],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<!-- The panel covers its own parent by default. While shown the parent
is aria-busy="true" (its previous value comes back after), the message
is announced once through the shared live announcer, and the shade
swallows pointer input. Focus is never taken or trapped. -->
<section class="orders">
<oge-load-panel [visible]="loading()" />
<h3>Orders</h3>
<button type="button" (click)="reload()">Reload</button>
</section>
`,
})
export class Demo {
protected readonly loading = signal(false);
protected reload(): void {
this.loading.set(true);
setTimeout(() => this.loading.set(false), 2000);
}
}Delay & minimum time
showDelay (300 ms here) keeps a fast load from flashing a panel at all; minDisplayTime (800 ms) keeps a panel that did appear on screen long enough to read. shown and hidden report what actually painted — the fast load fires neither.
Events: none
import { ChangeDetectionStrategy, Component, signal } from '@angular/core';
import { OgeLoadPanel } from '@oge-ui/layout';
@Component({
selector: 'demo-root',
imports: [OgeLoadPanel],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<!-- showDelay: a load that ends sooner never flashes a panel.
minDisplayTime: once shown, the panel stays long enough to read.
(shown) / (hidden) fire when it actually appears / disappears. -->
<section>
<oge-load-panel
[visible]="loading()"
[showDelay]="300"
[minDisplayTime]="800"
(shown)="log('shown')"
(hidden)="log('hidden')"
/>
<button type="button" (click)="load(100)">Fast load (100 ms)</button>
<button type="button" (click)="load(1500)">Slow load (1.5 s)</button>
</section>
`,
})
export class Demo {
protected readonly loading = signal(false);
protected load(ms: number): void {
this.loading.set(true);
setTimeout(() => this.loading.set(false), ms);
}
protected log(what: string): void {
console.log(what);
}
}Target & full screen
target takes an element or a selector anywhere on the page — the panel moves into it while shown. fullScreen covers the viewport (fixed, above everything); without a target it marks nothing busy, because aria-busy on the body would also mute the live region its own message goes to.
Chart area (the panel's target)
import { ChangeDetectionStrategy, Component, signal } from '@angular/core';
import { OgeLoadPanel } from '@oge-ui/layout';
@Component({
selector: 'demo-root',
imports: [OgeLoadPanel],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<!-- target: an element or a selector anywhere on the page. fullScreen
covers the viewport instead; without a target it marks nothing busy
(aria-busy on <body> would mute the live regions too). -->
<div id="report-chart">…</div>
<oge-load-panel target="#report-chart" [visible]="chartLoading()" message="Rendering chart…" />
<oge-load-panel [fullScreen]="true" [visible]="saving()" message="Saving the report…" />
`,
})
export class Demo {
protected readonly chartLoading = signal(false);
protected readonly saving = signal(false);
}Appearance
showPane: false drops the raised card, shading: false the dim layer, and position moves the pane to the top or bottom. Without the indicator the message itself is the readable text. The default message is the localized loadPanelMessage of the load-indicator config.
Plain, unshaded, top
Message only
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { OgeLoadPanel } from '@oge-ui/layout';
@Component({
selector: 'demo-root',
imports: [OgeLoadPanel],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<!-- showPane drops the raised card, shading the dim layer, position
moves the pane; showIndicator: false leaves only the message (which is
then the readable text). The default message is the localized
loadPanelMessage of the load-indicator config. -->
<oge-load-panel
[visible]="true"
[showPane]="false"
[shading]="false"
position="top"
message="Refreshing…"
/>
<oge-load-panel [visible]="true" [showIndicator]="false" message="Waiting for the server…" />
`,
})
export class Demo {}