Connection lost. Reconnecting… attempt 1 of 8
Paused. Your work is held on the server.
Could not reconnect.
This session has expired on the server.
An unhandled error has occurred.
Sedna.UI
v0.17.0 · main

Status bar

tier 1 — the frame

One strip across the bottom of the window that says the app is not working normally — the circuit dropped, the session expired, something threw. One class family for every case.

Status bar

All five modifiers are shown together here; in an app one shows at a time. The bar's own controls are .status-bar-action — filled, and never a .btn, whose tint disappears on a crimson bar — .status-bar-dismiss for the error bar's close button, and .status-bar-attempt for the retry counter, hidden until Blazor has put a number in it.

ModifierWhat it says
.status-bar--reconnectingthe circuit dropped and is being re-established — the only one that pulses
.status-bar--pausedthe server released the circuit and kept the state
.status-bar--failedreconnecting is over; only a reload helps
.status-bar--expiredthe session is gone from the server
.status-bar--erroran unhandled error reached the browser
Connection lost. Reconnecting… attempt 3 of 8
Paused. Your work is held on the server.
Could not reconnect.
This session has expired on the server.
An unhandled error has occurred.
<div class="status-bar status-bar--reconnecting">
    <i class="ri-wifi-off-line"></i>
    <span>
        Connection lost. Reconnecting…
        <span class="status-bar-attempt">attempt 3 of 8</span>
    </span>
</div>
<div class="status-bar status-bar--paused">
    <i class="ri-pause-circle-line"></i>
    <span>Paused. Your work is held on the server.</span>
</div>
<div class="status-bar status-bar--failed">
    <i class="ri-close-circle-line"></i><span>Could not reconnect.</span>
    <button class="status-bar-action" type="button"><i class="ri-refresh-line"></i> Retry</button>
</div>
<div class="status-bar status-bar--expired">
    <i class="ri-error-warning-line"></i><span>This session has expired on the server.</span>
    <button class="status-bar-action" type="button"><i class="ri-refresh-line"></i> Reload</button>
</div>
<div class="status-bar status-bar--error">
    <i class="ri-alert-line"></i><span>An unhandled error has occurred.</span>
    <button class="status-bar-action" type="button"><i class="ri-refresh-line"></i> Reload</button>
    <button class="status-bar-dismiss" type="button" aria-label="Dismiss this message"><i class="ri-close-line"></i></button>
</div>

The status bar in the host page

Paste this into App.razor, inside <body> and before the component that carries the render mode; supply it, or Blazor injects an unstyled box of its own. The bar is a child of the id, never the id itself#components-reconnect-modal is the container Blazor sets a state class on, and you write the rows while the framework sets those classes:

Blazor setsThe row that shows
components-reconnect-show.status-bar--reconnecting
components-reconnect-retrying.status-bar--reconnecting, with its counter revealed
components-reconnect-paused.status-bar--paused, or the reconnecting row if there is none
components-reconnect-failed.status-bar--failed
components-reconnect-resume-failed.status-bar--failed
components-reconnect-rejected.status-bar--expired
components-reconnect-hidenone — connected

retrying is added alongside show and only reveals the counter; .status-bar--paused is optional and falls back to the reconnecting row, but the other three are not — omit one and that state renders as an empty strip. The reload buttons are plain onclick handlers: the circuit is gone in those states, so a Blazor handler cannot run.

<div id="components-reconnect-modal">
    <div class="status-bar status-bar--reconnecting">
        <i class="ri-wifi-off-line"></i>
        <span>
            Connection lost. Reconnecting…
            <!-- Blazor fills these two by id, if they are there. -->
            <span class="status-bar-attempt">
                attempt <span id="components-reconnect-current-attempt">1</span>
                of <span id="components-reconnect-max-retries">8</span>
            </span>
        </span>
    </div>
    <div class="status-bar status-bar--paused">
        <i class="ri-pause-circle-line"></i>
        <span>Paused. Your work is held on the server.</span>
    </div>
    <div class="status-bar status-bar--failed">
        <i class="ri-close-circle-line"></i><span>Could not reconnect.</span>
        <button class="status-bar-action" type="button" onclick="location.reload()">
            <i class="ri-refresh-line"></i> Retry
        </button>
    </div>
    <div class="status-bar status-bar--expired">
        <i class="ri-error-warning-line"></i><span>This session has expired on the server.</span>
        <button class="status-bar-action" type="button" onclick="location.reload()">
            <i class="ri-refresh-line"></i> Reload
        </button>
    </div>
</div>

The unhandled-error bar

#blazor-error-ui is the second place the bar mounts, and the framework reveals it by setting display: block inline. Put .status-bar--error on the strip inside the id and never on the id itself: that inline declaration beats every rule in every layer, so this one bar would lay out as inline text while the reconnect rows stayed flex rows.

<!-- Blazor's own element, and the second place the status bar mounts. The framework
     reveals it by setting `display: block` inline on an unhandled circuit error.

     The id is the CONTAINER and `.status-bar` is the strip inside it. An inline
     `display: block` beats every rule in every layer, so a `.status-bar` on the id
     itself would lay this one bar out as inline text while the reconnect rows stayed
     flex rows.

     Both controls are plain `onclick` handlers, for the same reason the reconnect
     rows' are: the circuit is gone by the time this bar is visible, so a Blazor
     handler cannot run. The dismiss is a <button>, not the project template's <span>:
     it is a control, and it should be focusable and announced as one. -->
<div id="blazor-error-ui">
    <div class="status-bar status-bar--error">
        <i class="ri-alert-line"></i>
        <span>An unhandled error has occurred.</span>
        <button class="status-bar-action" type="button" onclick="location.reload()">
            <i class="ri-refresh-line"></i> Reload
        </button>
        <button class="status-bar-dismiss" type="button" aria-label="Dismiss this message"
                onclick="this.closest('#blazor-error-ui').style.display='none'">
            <i class="ri-close-line"></i>
        </button>
    </div>
</div>