Expand description
CollapsibleBody — a toast body that clamps to a few lines and offers to unfold.
§Why a toast body needs a ceiling
A title is one line by construction (ToastSurface
builds it .single_line()), but a body is whatever the app hands over — and apps hand
over error text. A formatted anyhow chain carries every context frame and every
absolute path in it; rendered at toast width that is easily eight or ten lines, and a
toast that tall stops being a notification and becomes a dialog nobody agreed to open.
So the body clamps to TOAST_BODY_COLLAPSED_LINES and, only when there is more to
see, grows a thin disclosure row. Short bodies — the overwhelming majority — are
untouched and gain no chrome.
§How “is there more to see” is answered
By measuring, in [Widget::layout_response], at the width the body will actually be
given. That is the only place the real content width is known: it is the proposal this
widget receives, already net of the glyph, the close button, the padding and the gaps.
Deriving it any other way would mean re-deriving the chrome’s arithmetic somewhere
else and keeping the two in step forever.
The measured verdict lands in a Signal, which is what drives the disclosure row’s
visibility — and writing a signal from layout is the thing to be careful about, since
it schedules another pass. Two properties make it safe:
- Transition-guarded. The signal is written only when the verdict changes,
tracked in a
Cell. A steady state writes nothing, so there is no loop. This is the same disciplineBuildContext::activation_signaldocuments for itself. - No feedback. The disclosure row sits below the text in a
VStack, so showing it changes the body’s height but never its width — and width is the only input to the measurement. The verdict therefore cannot flip as a result of acting on it.
Constants§
- TOAST_
BODY_ COLLAPSED_ LINES - How many lines of body text a toast shows before offering to unfold.
- TOAST_
BODY_ DISCLOSURE_ GAP - Vertical gap between the body text and its disclosure row.
- TOAST_
DISCLOSURE_ ACTION_ GAP - Horizontal gap between the disclosure row’s actions.