cadrumo.entrypoints.tui.components.widgets module

Reusable, state-free Textual widgets for Cadrumo surfaces.

class ContentScroll(*children, name=None, id=None, classes=None, disabled=False, can_focus=None, can_focus_children=None, can_maximize=None)[source]

Bases: VerticalScroll

The scroll host every Cadrumo surface puts its content column in.

Parameters:
  • children (Widget)

  • name (str | None)

  • id (str | None)

  • classes (str | None)

  • disabled (bool)

  • can_focus (bool | None)

  • can_focus_children (bool | None)

  • can_maximize (bool | None)

can_focus: bool

Widget may receive focus.

can_focus_children: bool

Widget’s children may receive focus.

class ContentDataTable(*args, **kwargs)[source]

Bases: DataTable, Generic

A table that expands to its rows, and to the width it is given.

Textual’s own add_column offers a fixed cell count or shrink-to-fit and nothing between, so a table built from fixed widths keeps them however wide the terminal is: it clips its own headers and identifiers while the rest of the row sits empty. The height side of that problem was already solved here by watch_virtual_size; this is its missing counterpart.

The surplus goes to ONE column – fill_column, defaulting to the last – rather than being spread across all of them, because widening an identifier or a state word past its content buys nothing while a truncated description is exactly what the space is for.

Parameters:
  • args (Any)

  • kwargs (Any)

fill_column: int | None

Index of the column that absorbs surplus width; None disables it.

DEFAULT_CELL_PADDING: Final

The product’s one table density, so no call site names a number.

watch_virtual_size(size)[source]

Keep the layout box equal to the current rows and header.

Return type:

None

Parameters:

size (Size)

on_resize()[source]

Give the surplus width to the fill column.

Return type:

None

absorb_surplus_width()[source]

Re-apply the width policy after an owner rebuilds the columns.

A screen that rebuilds its column set (responsive tables do) replaces the columns this widget already corrected, and the resize that would correct them again has been and gone. Such an owner calls this itself.

Return type:

None

can_focus: bool

Widget may receive focus.

can_focus_children: bool

Widget’s children may receive focus.

class NoticeBand(notices, *, id=None)[source]

Bases: Vertical

Render already-resolved notices without adding interaction state.

Parameters:
compose()[source]

Called by Textual to create child widgets.

This method is called when a widget is mounted or by setting recompose=True when calling [refresh()][textual.widget.Widget.refresh].

Note that you don’t typically need to explicitly call this method.

Return type:

Iterable[Widget]

Example

def compose(self) -> ComposeResult:
    yield Header()
    yield Label("Press the button below:")
    yield Button()
    yield Footer()
can_focus: bool

Widget may receive focus.

can_focus_children: bool

Widget’s children may receive focus.

class DisclosureGroup(*children, title, collapsed=True, id=None)[source]

Bases: Collapsible

A titled, collapsible task section – the shared Show optional primitive.

A thin, named extension of Textual’s own Collapsible rather than a parallel reimplementation: every Cadrumo surface that needs a collapsed optional-detail or completed-group section (the Required stage’s task sections, Show optional, Show not applicable) composes this one widget instead of each host reaching for Collapsible under its own title and defaults.

Parameters:
  • children (Widget)

  • title (str)

  • collapsed (bool)

  • id (str | None)

DEFAULT_CSS: ClassVar[str]

Default TCSS.

can_focus: bool

Widget may receive focus.

can_focus_children: bool

Widget’s children may receive focus.

class RequirementStatus(*values)[source]

Bases: StrEnum

The non-colour-safe requirement states a badge can render.

Named for the reader, not the palette: two operators comparing a screenshot in greyscale and one in colour must reach the same conclusion, so every state carries its own glyph and label rather than only a colour class.

REQUIRED_MISSING
REQUIRED_PRESENT
NEEDS_APPLICABILITY
OPTIONAL
NOT_APPLICABLE
class RequirementBadge(label, status, *, id=None)[source]

Bases: Static

One field’s requirement state, rendered by glyph and label together.

Never colour alone: _REQUIREMENT_GLYPH gives every RequirementStatus its own distinguishing mark, so a non-colour terminal or a colour-blind operator reads the same state a sighted colour-terminal operator does.

Parameters:
property status: RequirementStatus

Return the settled requirement status this badge renders.

can_focus: bool

Widget may receive focus.

can_focus_children: bool

Widget’s children may receive focus.

class CredentialRequirement(label, status)[source]

Bases: object

One resolved credential-requirement fact, present or absent as a unit.

A label without a status, or a status without a label, is not a weaker fact – it is not a fact at all, and the card cannot render half of one. Carrying the pair in one record makes that state unexpressible instead of relying on callers to honour it: the previous shape was two independent optional fields whose dependency lived only in prose, so a half-populated descriptor silently rendered NO badge and raised nothing, dropping a resolved requirement on an operator-facing surface with no signal at all.

Parameters:
label: str
status: RequirementStatus
class SourceActionDescriptor(title, description, action_label, credential_requirement=None)[source]

Bases: object

One Get data source: what it is, and the action that starts it.

credential_requirement is an optional pre-resolved requirement fact; this widget classifies nothing itself. When present, the card renders it through the shared RequirementBadge, the same primitive Required uses, rather than inventing a second requirement presentation for sources.

Parameters:
title: str
description: str
action_label: str
credential_requirement: CredentialRequirement | None
class SourceActionCard(descriptor, *, id=None)[source]

Bases: Vertical

A focusable card for one disclosed data source and its start action.

Renders only; starting the described operation is the host screen’s concern; the card is not what dispatches. Composes a real Button so the card is reachable and actionable by keyboard alone, per this Wave’s focus-order proof.

Parameters:
DEFAULT_CSS: ClassVar[str]

Vertical’s own default height expands to fill a container’s share, which is fine standing alone but stretches a card to fill whatever space several 1fr siblings divide – overriding to auto sizes the card to its own three children instead.

can_focus: bool

Widget may receive focus.

can_focus_children: bool

Widget’s children may receive focus.

compose()[source]

Called by Textual to create child widgets.

This method is called when a widget is mounted or by setting recompose=True when calling [refresh()][textual.widget.Widget.refresh].

Note that you don’t typically need to explicitly call this method.

Return type:

Iterable[Widget]

Example

def compose(self) -> ComposeResult:
    yield Header()
    yield Label("Press the button below:")
    yield Button()
    yield Footer()