DRYL COMPONENTS
Color mode: System — switch to light
3.16.0
Agents

Canvas Dock

AI-aware

DrylCanvasDock is the canvas's command bar: a floating card in the corner with one input, one line of live status — and the transcript only on demand.

Why it is not a chat

In a line-of-business app the artifact is the answer, not the text beside it. A chat column would spend half the surface on sentences nobody reads once the dashboard is up. So the dock shows exactly one status line from the run ("Building · 7 elements", "Ready", or the error) and keeps your eyes on the canvas.

Your app supplies the transcript. The <Log> slot takes your own DrylMessage elements — the dock brings no second message model. Unfolded, the area grows through the same 0fr → 1fr mechanic as DrylToolCallGroup, so nothing is ever squeezed.

It anchors to the viewport, not to the card. A position: fixed element measures itself against the nearest ancestor with transform or backdrop-filter — in a real app almost always some glass card. The dock is therefore lifted into the browser's top layer via popover="manual"; without JavaScript (prerender) it stays an ordinary fixed element.

razor
<DrylCanvasDock Run="_run" Busy="Busy" OnSend="Send"
                Corner="DockCorner.BottomRight" Title="Builder"
                Placeholder="Ask for a view…">
    <Log>
        @foreach (var turn in _turns)
        {
            <DrylMessage Role="MessageRole.User" Author="You">@turn.Text</DrylMessage>
        }
    </Log>
</DrylCanvasDock>

In your language, and one press to talk

Every label and status line of the dock is a parameter with the English wording as its default. A failure always outranks your own Status, so a translated line can never hide an error — word it with ErrorText. With a voice run, VoiceFirst makes the collapsed button start listening in one press, and the voice takeover carries a mute toggle beside the stop button: the session stays connected while the microphone is off, and the status line says so.

It stays reachable over a dialog. The dock floats above every dialog, so the pointer reaches it anyway — and while a dialog is open, F6 takes the keyboard into the dock and back to where it left the dialog. Tab stays inside whichever of the two you are in; Escape still closes the dialog.

razor
<DrylCanvasDock Run="_run" Voice="_voice" VoiceFirst OnSend="Send"
                Title="Santiago" VoiceLabel="Mit Santiago sprechen"
                VoiceStopLabel="Gespräch beenden"
                VoiceMuteLabel="Mikrofon stummschalten"
                VoiceUnmuteLabel="Mikrofon einschalten" VoiceMutedText="Stumm"
                ShowLogLabel="Verlauf zeigen" HideLogLabel="Verlauf verbergen"
                CollapseLabel="Einklappen" ClearContextLabel="Bezug entfernen"
                IdleText="Bereit" WorkingText="Arbeitet…"
                BuildingText="@(n => $"Baut · {n} Elemente")"
                ReadyText="@(n => $"Fertig · {n} Elemente")"
                VoiceStatusText="@((phase, activity) => phase == VoicePhase.Connecting ? "Verbinde…" : null)"
                ErrorText="@(e => "Fehler: " + e.Message)" />

The dock on a workspace

The same example as on the workspace page — here the dock in the bottom right is the lead: type a view (&quot;Overview&quot;, &quot;Order 4711&quot;, &quot;Returns&quot;) and watch the status line while the artifact streams. The arrow unfolds the transcript; the minimise button shrinks the dock down to a single button.

No view yet
Ask for a view below — &quot;Overview&quot;, for example.
Overview Order 4711 Returns — ask for one of these below; the previous view stays in the bar.
AI
Idle
An unhandled error has occurred. Reload x

Reconnecting to the server…

Attempt /

Next try in s