xnano
xnano
¶
xnano
Build terminal and web interfaces with grids, fields, components, hooks, actions, and runtimes.
Modules:
-
actions–xnano.actions
-
area–xnano.area
-
cli–xnano.cli
-
colors–xnano.colors
-
components–xnano.components
-
context–xnano.context
-
core–xnano.core
-
cursor–xnano.cursor
-
device–xnano.device
-
effects–xnano.effects
-
events–xnano.events
-
fields–xnano.fields
-
grids–xnano.grids
-
hooks–xnano.hooks
-
markdown–xnano.markdown
-
rendering–xnano.rendering
-
requests–xnano.requests
-
server–xnano.server
-
state–xnano.state
-
tailwind–xnano.tailwind
-
terminal–xnano.terminal
-
types–xnano.types
-
utils–xnano.utils
-
web–xnano.web
Classes:
-
Action–Declarative event trigger.
-
Command–A command or subcommand group.
-
Component–Base class for custom xnano components.
-
Context–Values and controls available inside an event hook.
-
Frame–Immutable snapshot of one painted native frame.
-
Runtime–Drive one application through an
xnano_coresession. -
BaseGrid–Declarative layout container for a terminal-based UI.
-
GridSettings–Rendering, layout, and frame settings for a
BaseGridsubclass. -
Style–Style derived from Tailwind utility classes.
-
Terminal–Paint and interact with an application in a terminal.
-
Web–Serve an application in a browser from an offscreen runtime.
Functions:
-
Field–Create a new grid field info instance.
-
on_action–Bind a prebuilt
Actionas a hook trigger. -
on_click–Register a click handler for a grid layout field, or a group.
-
on_clipboard–Register a hook fired on clipboard paste events.
-
on_event–Register an event hook that triggers on every detected event.
-
on_field–Fire the decorated handler based on this grid's own field values.
-
on_focus–Register a focus hook for the terminal window, a field, or a group.
-
on_keyboard–Register a keyboard event hook.
-
on_mouse–Register a mouse event hook.
-
on_poll–Register a poll hook that fires on idle event waits or every frame.
-
on_resize–Register a hook fired on terminal resize events.
-
on_state–Fire the decorated handler based on the application state.
-
on_tick–Register a tick hook, optionally at a fixed interval.
-
render–Display renderables as print-like terminal output.
Action
dataclass
¶
Bases: ABC
Declarative event trigger.
Examples:
save = Action.keyboard("ctrl+s")
@on_action(save)
def save_document(self) -> None:
...
terminal.actions.perform(save)
Methods:
-
keyboard–Match one or more keyboard bindings.
-
mouse–Match a mouse event.
-
click–Match a button press on a field.
-
focus–Match a focus transition.
-
clipboard–Match pasted text.
-
tick–Match a clock tick.
-
resize–Match a resize event.
-
request–Match an HTTP request.
-
matches–Return whether
eventsatisfies this action.
keyboard
classmethod
¶
keyboard(
*bindings: KeyboardBinding,
kind: KeyboardEventKind | None = None
) -> "KeyboardAction"
Match one or more keyboard bindings.
mouse
classmethod
¶
mouse(
*buttons: MouseButton,
kind: MouseEventKind | None = None
) -> "MouseAction"
click
classmethod
¶
click(
field: str | None = None, button: MouseButton = "left"
) -> "ClickAction"
focus
classmethod
¶
focus(
field: str | None = None,
kind: FocusEventKind | None = None,
) -> "FocusAction"
resize
classmethod
¶
request
classmethod
¶
Command
dataclass
¶
Command(
name: str | None = None,
description: str | None = None,
strict: bool = False,
show_help: bool = True,
help: bool = True,
)
A command or subcommand group.
Attributes:
-
name(str | None) –The name of the command.
-
description(str | None) –A description of the command.
-
strict(bool) –Whether to validate parameter types against annotations.
-
show_help(bool) –Whether
--help/-hare recognized. -
help(bool) –Compatibility alias for
show_help. -
parameters(list[_Parameter]) –Resolved command parameters.
-
subcommands(dict[str, 'Command']) –Registered subcommands.
Example
command = Command(name="hello") @command ... def greet(name: str) -> str: ... return f"Hello, {name}" command.run(["Ada"]) 'Hello, Ada'
Methods:
-
option–Attach option names and help text to a command parameter.
-
command–Decorator to register a subcommand.
-
register_callback–Register the main callback for this command.
-
add_subcommand–Add a subcommand programmatically.
-
parse_arguments–Parse arguments without exiting the process.
-
run–Parse arguments and run the command, exiting on errors/help.
-
get_help–Return plain help text for this command.
-
__call__–Register a callback or run with
sys.argv.
description
class-attribute
instance-attribute
¶
description: str | None = None
Command summary shown in help.
strict
class-attribute
instance-attribute
¶
strict: bool = False
Whether annotations are validated strictly.
show_help
class-attribute
instance-attribute
¶
show_help: bool = True
Whether -h and --help are enabled.
UNSET
class-attribute
instance-attribute
¶
UNSET: Any = dataclasses.field(
default=UNSET, init=False, repr=False
)
Sentinel used for parameters without defaults.
option
staticmethod
¶
option(
name_or_flags: str | list[str],
*,
default: Any = None,
help: str | None = None,
is_flag: bool | None = None
) -> Callable[[Callable[..., Any]], Callable[..., Any]]
Attach option names and help text to a command parameter.
Source code in xnano/cli/command.py
command
¶
command(
name: str | None = None,
*,
description: str | None = None
) -> Callable[[Callable[..., Any]], Callable[..., Any]]
Decorator to register a subcommand.
Source code in xnano/cli/command.py
register_callback
¶
Register the main callback for this command.
add_subcommand
¶
Add a subcommand programmatically.
Source code in xnano/cli/command.py
parse_arguments
¶
Parse arguments without exiting the process.
Raises:
-
HelpRequested–When help was requested.
-
CliError–On usage / validation failures.
Source code in xnano/cli/command.py
run
¶
Parse arguments and run the command, exiting on errors/help.
Source code in xnano/cli/command.py
__call__
¶
Register a callback or run with sys.argv.
Component
dataclass
¶
Base class for custom xnano components.
Component attributes are live state: changing an attribute changes the
next rendered frame. Implement compose() to return content. Interactive
components can also implement handle_keyboard() or handle_paste().
The framework updates the read-only focused property when the
component gains or loses field focus.
Example
Text(content="Ready", color="green")
Attributes:
-
visible(bool) –Whether the component is rendered.
-
z(int) –Paint order relative to sibling components.
-
fit_content(bool) –Whether layout should prefer the natural content size.
Methods:
-
component_post_init–Initialize subclass state after dataclass fields are assigned.
-
get_frame–Optional frame/panel chrome around composed content.
-
get_size–Return the preferred cell size of this component.
-
before_render–Called before rendering; returns the effective render area.
-
after_render–Called after rendering for optional post-paint work.
-
compose–Compose interface-neutral content for this component.
-
compose_extra_small–Compose content when the viewport is extra small (< 40 cols).
-
compose_small–Compose content when the viewport is small (40–79 cols).
-
compose_medium–Compose content when the viewport is medium (80–119 cols).
-
compose_large–Compose content when the viewport is large (120–159 cols).
-
compose_extra_large–Compose content when the viewport is extra large (>= 160 cols).
-
handle_keyboard–Optional keyboard handler while focused.
-
handle_paste–Optional paste handler while focused.
visible
class-attribute
instance-attribute
¶
visible: bool = dataclasses.field(
default=True, kw_only=True
)
Whether this component paints at all.
z
class-attribute
instance-attribute
¶
z: int = dataclasses.field(default=0, kw_only=True)
Stacking order among sibling content.
fit_content
class-attribute
instance-attribute
¶
fit_content: bool = dataclasses.field(
default=True, kw_only=True
)
When True, paint at natural size inside a larger slot.
component_post_init
¶
Initialize subclass state after dataclass fields are assigned.
Override this method instead of __post_init__.
get_size
¶
get_size(ctx: ComponentRenderContext[StateT]) -> Size
before_render
¶
before_render(
ctx: ComponentRenderContext[StateT], area: "Area"
) -> "Area"
after_render
¶
after_render(
ctx: ComponentRenderContext[StateT], area: "Area"
) -> None
compose
¶
compose(
ctx: ComponentRenderContext[StateT],
) -> Content | None
Compose interface-neutral content for this component.
Returns:
-
Content | None–A
Contenttree, orNonewhen nothing should paint.
compose_extra_small
¶
compose_extra_small(
ctx: ComponentRenderContext[StateT],
) -> Content | None
Compose content when the viewport is extra small (< 40 cols).
Optional responsive counterpart to :meth:compose. When
overridden, it is used instead of compose while the window
is in this size tier. Overriding any compose_* variant opts the
component into breakpoint dispatch; a component that overrides none
pays no per-frame cost.
Source code in xnano/components/component.py
compose_small
¶
compose_small(
ctx: ComponentRenderContext[StateT],
) -> Content | None
Compose content when the viewport is small (40–79 cols).
See :meth:compose_extra_small.
compose_medium
¶
compose_medium(
ctx: ComponentRenderContext[StateT],
) -> Content | None
Compose content when the viewport is medium (80–119 cols).
See :meth:compose_extra_small.
compose_large
¶
compose_large(
ctx: ComponentRenderContext[StateT],
) -> Content | None
Compose content when the viewport is large (120–159 cols).
See :meth:compose_extra_small.
compose_extra_large
¶
compose_extra_large(
ctx: ComponentRenderContext[StateT],
) -> Content | None
Compose content when the viewport is extra large (>= 160 cols).
See :meth:compose_extra_small.
Source code in xnano/components/component.py
handle_keyboard
¶
handle_keyboard(keyboard: 'KeyboardEventData') -> bool
Context
dataclass
¶
Context(
event: "Event",
terminal: "Runtime[StateT]",
state: StateT,
request: "Request | None" = None,
)
Bases: Generic[StateT]
Values and controls available inside an event hook.
Use the event-specific shortcuts such as keyboard_event and
mouse_event, read or update application state, move focus, or access
the current cursor, device, actions, and stage.
Attributes:
-
event('Event') –Event that triggered the hook.
-
terminal('Runtime[StateT]') –Terminal or runtime handling the event.
-
state(StateT) –Application state shared with the runtime.
-
host('Runtime[StateT]') –Session handling the event.
-
runtime('Runtime[StateT]') –Runtime handling the event.
-
surface(str) –Active presentation surface.
-
request('Request | None') –HTTP request that triggered the hook, if any.
-
tick_event('TickEventData | None') –Tick payload that triggered the hook, if any.
-
keyboard_event('KeyboardEventData | None') –Keyboard payload that triggered the hook, if any.
-
mouse_event('MouseEventData | None') –Mouse payload that triggered the hook, if any.
-
cursor('Cursor') –Cursor controls for the active runtime.
-
device('Device') –Device controls for the active runtime.
-
actions('Actions') –Synthetic action performer.
-
stage('Stage') –Current layout stage.
-
focused_group(str | None) –Name of the focused field group.
Example
def handle_key(ctx: Context[dict[str, int]]) -> None: ... if ctx.keyboard_event is not None: ... ctx.state["keys"] += 1
Methods:
-
get_state–Return the shared application state.
-
focus–Focus the field labeled
groupon any attached grid. -
blur–Clear field focus on the active runtime.
-
is_focused–Return whether the field labeled
groupcurrently holds focus. -
call_soon–Schedule
callbackto run on the UI thread before the next pump. -
field_area–Return the last painted area for field
name, if known. -
scroll–Return a scroll handle for
Field(scroll=...)labeledgroup. -
get_scroll–Return scroll state for
group, orNoneif it is unavailable. -
with_event–Return a copy carrying a different event.
-
with_scope–Return a shallow copy with the given fields replaced.
-
has_clipboard_event–Return whether this context contains a clipboard event.
-
has_focus_event–Return whether this is a focus event.
-
has_keyboard_event–Return whether this is a keyboard event.
-
has_mouse_event–Return whether this is a mouse event.
-
has_resize_event–Return whether this is a resize event.
terminal
instance-attribute
¶
Terminal or offscreen session handling the event.
request
class-attribute
instance-attribute
¶
HTTP request that triggered the hook, if any.
tick_event
property
¶
Tick payload when this context was triggered by a tick.
keyboard_event
property
¶
Keyboard sub-event when triggered by a keyboard event.
mouse_event
property
¶
Mouse sub-event when triggered by a mouse event.
render_size
property
¶
Current viewport breakpoint tier.
The same value grid_render_<size> / compose_<size> dispatch
on — one of "extra_small", "small", "medium",
"large", "extra_large" — derived from the live window
width. Read it from any hook to branch on size without declaring a
per-tier render method.
get_state
¶
Return the shared application state.
Raises:
-
RuntimeError–If no state was attached to this context.
Source code in xnano/context.py
focus
¶
Focus the field labeled group on any attached grid.
Source code in xnano/context.py
blur
¶
Clear field focus on the active runtime.
Source code in xnano/context.py
is_focused
¶
call_soon
¶
call_soon(
callback: "Callable[..., Any]", *args: Any
) -> None
Schedule callback to run on the UI thread before the next pump.
The thread-safe bridge for updating grid state from a worker thread: the callback runs on the runtime's own thread, so it can freely mutate components/fields without racing the renderer.
Source code in xnano/context.py
field_area
¶
field_area(name: str) -> 'Area | None'
Return the last painted area for field name, if known.
Reads the always-on layout map so viewports and chrome math can use measured slot sizes instead of guessing.
Source code in xnano/context.py
scroll
¶
scroll(group: str) -> 'ScrollHandle | None'
Return a scroll handle for Field(scroll=...) labeled group.
with_event
¶
Frame
dataclass
¶
Frame(
width: int,
height: int,
text: str = "",
ansi: str = "",
cursor_position: tuple[int, int] | None = None,
cursor_visible: bool = True,
cursor_style: str | None = None,
title: str | None = None,
commands: tuple[Mapping[str, Any], ...] = (),
revision: int = 0,
)
Immutable snapshot of one painted native frame.
Example
Frame(width=20, height=4, text="Ready")
Attributes:
-
width(int) –Frame width in cells.
-
height(int) –Frame height in cells.
-
text(str) –Plain-text rows joined by newlines.
-
ansi(str) –ANSI-styled serialization of the buffer.
-
cursor_position(tuple[int, int] | None) –(x, y)caret cell, when known. -
cursor_visible(bool) –Whether the caret is shown.
-
cursor_style(str | None) –Caret style name when known.
-
title(str | None) –Terminal / document title when set.
-
commands(tuple[Mapping[str, Any], ...]) –Device commands queued with this frame.
-
revision(int) –Monotonic revision for diff consumers.
Methods:
-
contains–Return whether plain text contains
needle.
cursor_position
class-attribute
instance-attribute
¶
Caret position in cells.
cursor_visible
class-attribute
instance-attribute
¶
cursor_visible: bool = True
Whether the caret is visible.
cursor_style
class-attribute
instance-attribute
¶
cursor_style: str | None = None
Caret shape and blink style.
commands
class-attribute
instance-attribute
¶
Device commands emitted with the frame.
Runtime
¶
Runtime(
session: CoreSession,
*,
live: bool,
state: StateT | None = None,
title: str | None = None,
surface: str = "terminal",
tick_interval: int = 16
)
Bases: Generic[StateT]
Drive one application through an xnano_core session.
Most applications use :class:xnano.terminal.Terminal; use
Runtime directly when you need explicit session ownership.
Attributes:
-
session(CoreSession) –Native session owned by the runtime.
-
terminal('Runtime[StateT]') –Compatibility name for this runtime.
-
surface(str) –Presentation surface name.
-
is_live(bool) –Whether the runtime owns the user's terminal.
-
state(StateT | None) –Application state shared with hooks.
-
device(Device) –Display controls for the session.
-
cursor(Cursor) –Cursor controls for the session.
-
actions(Actions) –Synthetic action performer.
-
stage(Stage) –Current layout stage, when available.
-
size(tuple[int, int]) –Viewport width and height in cells.
-
focused_group(str | None) –Name of the focused field group.
Example
runtime = Runtime.offscreen(24, 3) frame = runtime.render("Hello") frame.width, frame.height (24, 3) runtime.close()
Methods:
-
live–Create a runtime backed by the active terminal.
-
offscreen–Create an active in-memory runtime.
-
supports_live_terminal–Return whether this build can claim a live terminal.
-
enter–Bind this runtime to the current context.
-
close–Restore the native session and release the active binding.
-
set_root–Set the renderable used by subsequent empty renders.
-
render–Render one frame and return its immutable snapshot.
-
call_soon–Schedule
callbackto run on the UI thread before the next pump. -
pump–Poll and dispatch at most one event.
-
dispatch–Dispatch one event to the root grid or component.
-
play_effect–Play an effect over fields recorded by the latest render.
-
cancel_effect–Stop the effect registered under
key. -
is_animating–Whether any effect is currently running in this session.
-
perform–Perform a synthetic action through its event representation.
-
resize–Resize support is fixed at offscreen-session construction.
-
request_exit–Stop the run loop after the current dispatch.
-
focus–Focus a named field group.
-
blur–Clear field focus.
-
focus_next–Move focus through the root grid when supported.
-
focus_previous–Move focus backward through the root grid when supported.
-
get_output–Return the current buffer as plain text.
-
get_output_as_ansi–Return the current buffer with ANSI styling.
Source code in xnano/core/runtime.py
terminal
property
¶
Compatibility name for the runtime's terminal surface.
live
classmethod
¶
live(
*,
state: StateT | None = None,
title: str | None = None,
tick_interval: int = 16,
mouse_events: bool = False
) -> "Runtime[StateT]"
Create a runtime backed by the active terminal.
Source code in xnano/core/runtime.py
offscreen
classmethod
¶
offscreen(
width: int = 80,
height: int = 24,
*,
state: StateT | None = None,
title: str | None = None
) -> "Runtime[StateT]"
Create an active in-memory runtime.
Source code in xnano/core/runtime.py
enter
¶
Bind this runtime to the current context.
close
¶
Restore the native session and release the active binding.
Source code in xnano/core/runtime.py
render
¶
render(
*renderables: Any,
foreground: ColorLike | None = None,
background: ColorLike | None = None,
modifiers: Sequence[CharacterModifier] | None = None,
horizontal_align: Alignment | None = None,
vertical_align: VerticalAlignment | None = None,
border: Border | None = None,
border_sides: Sequence[Side] | None = None,
border_color: ColorLike | None = None,
title: str | None = None,
title_position: FrameTitlePosition | None = None,
padding: PaddingLike | None = None,
gap: int = 0,
direction: Direction = "vertical",
color: ColorLike | None = None,
align: Alignment | None = None
) -> Frame
Render one frame and return its immutable snapshot.
Source code in xnano/core/runtime.py
call_soon
¶
Schedule callback to run on the UI thread before the next pump.
Thread-safe: worker threads enqueue here and the runtime drains the queue on its own thread, so background work can mutate grid state without racing the renderer.
Source code in xnano/core/runtime.py
pump
¶
Poll and dispatch at most one event.
Source code in xnano/core/runtime.py
dispatch
¶
dispatch(event: Any) -> None
Dispatch one event to the root grid or component.
Source code in xnano/core/runtime.py
play_effect
¶
Play an effect over fields recorded by the latest render.
Parameters:
-
effect(Any) –Effect description.
-
fields(list[str] | None, default:None) –Field names whose rendered areas receive the effect.
-
repeat(bool, default:False) –Loop the effect until it is cancelled, instead of running once for its duration.
Returns:
-
list[str]–The session keys registered, one per field that had a
-
list[str]–rendered area. Empty when nothing was targeted.
Source code in xnano/core/runtime.py
perform
¶
perform(action: Any) -> None
Perform a synthetic action through its event representation.
Source code in xnano/core/runtime.py
776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 | |
resize
¶
Resize support is fixed at offscreen-session construction.
request_exit
¶
focus
¶
Focus a named field group.
Source code in xnano/core/runtime.py
blur
¶
BaseGrid
¶
Bases: AbstractInterface
Declarative layout container for a terminal-based UI.
BaseGrid-scoped settings may be declared on the class header
(class Dashboard(BaseGrid, direction="horizontal", gap=1): ...),
in a class-level grid_settings dict, or both — values in
grid_settings override matching header kwargs.
Attributes:
-
grid_settings(GridSettings) –Class-level layout and frame configuration.
-
visible(bool) –Whether the grid is rendered.
-
z(int) –Layering order for overlapping grids.
-
columns(int) –Columns available during the current frame.
-
rows(int) –Rows available during the current frame.
Examples:
Layout fields render content; state=True fields hold app data.
Nested BaseGrid subclasses compose larger layouts:
from xnano import BaseGrid, Field, Terminal
class Sidebar(BaseGrid, direction="vertical"):
nav: str = Field(default="Home", border="rounded", height="1fr")
class App(BaseGrid, direction="horizontal", gap=1):
sidebar: Sidebar = Field(default_factory=Sidebar, width="25%")
content: str = Field(default="Main area", width="1fr")
selected: int = Field(default=0, state=True)
Terminal().run(App())
Event hooks register handlers on the grid class. Use @on_click to
scope mouse handlers to a layout field's region:
from xnano import BaseGrid, Context, Field, Terminal, hooks
class Counter(BaseGrid, direction="vertical", gap=1):
label: str = Field(default="Count: 0", height=1)
body: str = Field(default="Click me", height="1fr")
count: int = Field(default=0, state=True)
@hooks.on_keyboard("up")
def increment(self) -> None:
self.count += 1
self.label = f"Count: {self.count}"
@hooks.on_keyboard("down")
def decrement(self) -> None:
self.count -= 1
self.label = f"Count: {self.count}"
@hooks.on_click("body")
def on_body(self, ctx: Context) -> None:
self.body = "Clicked!"
@hooks.on_tick(1000)
def reset_body(self) -> None:
self.body = "Click me"
Terminal().run(Counter())
Methods:
-
grid_get_field_state–Return tracked state for a field.
-
grid_mark_field_dirty–Mark a field as changed.
-
get_field_state–Deprecated alias for
grid_get_field_state. -
mark_field_dirty–Deprecated alias for
grid_mark_field_dirty. -
__post_init__–Called at the end of the generated
__init__. Override to run post-construction logic. -
grid_post_init–Called exactly once, when this grid is first attached to a live
-
grid_render–Called each frame before layout.
-
grid_render_extra_small–Refine layout when the viewport is extra small (< 40 cols).
-
grid_render_small–Refine layout when the viewport is small (40–79 cols).
-
grid_render_medium–Refine layout when the viewport is medium (80–119 cols).
-
grid_render_large–Refine layout when the viewport is large (120–159 cols).
-
grid_render_extra_large–Refine layout when the viewport is extra large (>= 160 cols).
-
grid_play_effect–Run a visual effect on one or more layout field areas.
-
grid_effect–Run a visual effect on one or more layout field areas.
-
grid_field_position–Return the parent-relative slide offset for a layout field.
-
grid_set_field–Set a layout field's runtime value and/or per-instance field metadata.
-
grid_update_field–Update a layout field's style/layout attributes, live, in-place.
-
grid_set_frame–Set this grid instance's outer frame (chrome + background fill).
-
grid_set_background–Fill this grid instance's whole area with
background. -
grid_schedule_update–Apply an update on the UI thread before the next frame.
-
set_frame–Deprecated alias for
grid_set_frame. -
set_background–Deprecated alias for
grid_set_background. -
schedule_update–Deprecated alias for
grid_schedule_update.
Source code in xnano/grids.py
grid_settings
class-attribute
¶
grid_settings: GridSettings = {}
Class-level grid configuration, like Pydantic's model_config.
__xnano_grid__
class-attribute
¶
__xnano_grid__: bool = True
Marks this class as a grid, for cheap identity checks.
Faster and clearer than duck-typing _grid_fields, and usable from
layers that must not import BaseGrid — see is_grid.
visible
class-attribute
instance-attribute
¶
visible: bool = True
Whether this grid is rendered in the live session.
columns
class-attribute
instance-attribute
¶
columns: int = 0
Terminal columns available to this grid — set by the session each frame.
rows
class-attribute
instance-attribute
¶
rows: int = 0
Terminal rows available to this grid — set by the session each frame.
grid_focused
property
¶
grid_focused: bool
Whether any of this grid's fields currently holds field focus.
Live alongside per-component focused: derived from the same
per-frame focus flags, so self.grid_focused in a hook and
@on_field("focused") both read the current state.
grid_get_field_state
¶
grid_get_field_state(name: str) -> FieldState | None
Return tracked state for a field.
Parameters:
-
name(str) –Field attribute name.
Returns:
-
FieldState | None–Its state, or
Nonefor an unknown field.
Source code in xnano/core/interface.py
grid_mark_field_dirty
¶
grid_mark_field_dirty(name: str) -> None
Mark a field as changed.
Parameters:
-
name(str) –Field attribute name.
Source code in xnano/core/interface.py
get_field_state
¶
get_field_state(name: str) -> FieldState | None
Deprecated alias for grid_get_field_state.
Source code in xnano/core/interface.py
mark_field_dirty
¶
mark_field_dirty(name: str) -> None
Deprecated alias for grid_mark_field_dirty.
Source code in xnano/core/interface.py
__post_init__
¶
grid_post_init
¶
Called exactly once, when this grid is first attached to a live terminal — after its own hooks are bound, before its first paint.
Unlike __post_init__ (construction time, no terminal attached
yet), ctx/ctx.state are live here. Override with either
signature — the extra parameter is optional, matching every other
@on_* hook, dispatched by arity at runtime (see _call_hook):
def grid_post_init(self) -> None: ...
def grid_post_init(self, ctx: Context[MyState]) -> None: ...
A static type checker sees the one-parameter form as an invalid
override (this base declares zero); that's a known false positive
for this flexible-arity hook pattern — add
# ty: ignore[invalid-method-override] on the override line.
Source code in xnano/grids.py
grid_render
¶
Called each frame before layout.
Override to refresh field values every frame. Initial values can be set
with Field(default=...), default_factory, or __post_init__.
Override with either signature — the extra Context parameter is
optional, dispatched by arity like grid_post_init:
def grid_render(self) -> None: ...
def grid_render(self, ctx: Context[MyState]) -> None: ...
A static type checker sees the one-parameter form as an invalid
override; add # ty: ignore[invalid-method-override] on the
override line.
Source code in xnano/grids.py
grid_render_extra_small
¶
Refine layout when the viewport is extra small (< 40 cols).
Optional responsive counterpart to :meth:grid_render. Runs when
the window enters this size tier — on the first render and on
later resizes that cross into it — not every frame, so a
per-frame @on_tick mutation is not overwritten by a size hook
resetting the same field. Keep shared per-frame logic in
grid_render and size-specific setup here. Overriding any
grid_render_* variant opts the class into breakpoint dispatch;
a class that overrides none pays no per-frame cost.
Source code in xnano/grids.py
grid_render_small
¶
Refine layout when the viewport is small (40–79 cols).
See :meth:grid_render_extra_small.
grid_render_medium
¶
Refine layout when the viewport is medium (80–119 cols).
See :meth:grid_render_extra_small.
grid_render_large
¶
Refine layout when the viewport is large (120–159 cols).
See :meth:grid_render_extra_small.
grid_render_extra_large
¶
Refine layout when the viewport is extra large (>= 160 cols).
See :meth:grid_render_extra_small.
grid_play_effect
¶
grid_play_effect(
effect: AbstractEffect,
*,
fields: list[str] | None = None
) -> bool
grid_play_effect(
effect: KnownEffectKind,
*,
duration_ms: int = 300,
color: ColorLike | None = None,
background: ColorLike | None = None,
direction: EffectMotion | None = None,
gradient_length: int | None = None,
randomness: int | None = None,
interpolation: EffectInterpolation | None = None,
effects: Sequence[AbstractEffect] | None = None,
child: AbstractEffect | None = None,
times: int | None = None,
fields: list[str] | None = None,
key: str | None = None
) -> bool
grid_play_effect(
effect: KnownEffectKind | AbstractEffect,
*,
duration_ms: int = 300,
color: ColorLike | None = None,
background: ColorLike | None = None,
direction: EffectMotion | None = None,
gradient_length: int | None = None,
randomness: int | None = None,
interpolation: EffectInterpolation | None = None,
effects: Sequence[AbstractEffect] | None = None,
child: AbstractEffect | None = None,
times: int | None = None,
fields: list[str] | None = None,
key: str | None = None
) -> bool
Run a visual effect on one or more layout field areas.
Each layout field is tagged with its name as an effect key during
rendering, so effects can target field content rects on the frame
after grid_render.
Pass a custom AbstractEffect subclass or
provide a known effect kind with typed keyword arguments.
Parameters:
-
effect(KnownEffectKind | AbstractEffect) –A built effect instance or a known effect kind string.
-
duration_ms(int, default:300) –Duration of the effect in milliseconds.
-
color(ColorLike | None, default:None) –Foreground or accent color for color-driven effects.
-
background(ColorLike | None, default:None) –Background color for two-color effects.
-
direction(EffectMotion | None, default:None) –Motion direction for slide and sweep effects.
-
gradient_length(int | None, default:None) –Gradient length for slide and sweep effects.
-
randomness(int | None, default:None) –Randomness for slide and sweep effects.
-
interpolation(EffectInterpolation | None, default:None) –Interpolation curve for the effect.
-
effects(Sequence[AbstractEffect] | None, default:None) –Child effects for sequence and parallel composition.
-
child(AbstractEffect | None, default:None) –Child effect for repeat and delay composition.
-
times(int | None, default:None) –Repeat count for repeat effects.
-
fields(list[str] | None, default:None) –Layout field names to target. When omitted or empty, no effect is started.
-
key(str | None, default:None) –Identity used to de-duplicate this effect per target field — see
AbstractEffect.key. Only meaningful wheneffectis a known-kind string; ignored wheneffectis already a builtAbstractEffectinstance (setkeyon the instance itself in that case).
Returns:
Source code in xnano/grids.py
1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 | |
grid_effect
¶
grid_effect(
effect: KnownEffectKind | AbstractEffect,
*,
duration_ms: int | None = None,
color: ColorLike | None = None,
background: ColorLike | None = None,
direction: EffectMotion | None = None,
gradient_length: int | None = None,
randomness: int | None = None,
interpolation: EffectInterpolation | None = None,
effects: Sequence[AbstractEffect] | None = None,
child: AbstractEffect | None = None,
times: int | None = None,
fields: list[str] | None = None,
key: str | None = None
) -> "EffectHandle"
Run a visual effect on one or more layout field areas.
Returns an EffectHandle: truthy when at least one field was
targeted, with .active and .cancel(), and usable as a
context manager that cancels the effect on exit.
Starting an effect never blocks. duration_ms is the animation
length handed to the renderer, not a sleep — the effect advances
one frame at a time, so hooks keep running while it plays. Omit it
inside a with block and the effect repeats until the block
exits.
Parameters:
-
effect(KnownEffectKind | AbstractEffect) –A built effect instance or a known effect kind string.
-
duration_ms(int | None, default:None) –Animation length in milliseconds. Defaults to 300; omitted inside a
withblock the effect repeats until exit. -
color(ColorLike | None, default:None) –Foreground or accent color for color-driven effects.
-
background(ColorLike | None, default:None) –Background color for two-color effects.
-
direction(EffectMotion | None, default:None) –Motion direction for slide and sweep effects.
-
gradient_length(int | None, default:None) –Gradient length for slide and sweep effects.
-
randomness(int | None, default:None) –Randomness for slide and sweep effects.
-
interpolation(EffectInterpolation | None, default:None) –Interpolation curve for the effect.
-
effects(Sequence[AbstractEffect] | None, default:None) –Child effects for sequence and parallel composition.
-
child(AbstractEffect | None, default:None) –Child effect for repeat and delay composition.
-
times(int | None, default:None) –Repeat count for repeat effects.
-
fields(list[str] | None, default:None) –Layout field names to target. When omitted or empty, no effect is started.
-
key(str | None, default:None) –Identity used to de-duplicate this effect per target field — see
AbstractEffect.key. Calling with the samekeyevery tick replaces the running effect rather than stacking new ones.
Returns:
-
'EffectHandle'–A handle for the started effect.
Examples:
self.grid_effect("fade", fields=["body"])
with self.grid_effect("pulse", fields=["body"]):
do_slow_work()
Source code in xnano/grids.py
1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 | |
grid_field_position
¶
grid_set_field
¶
grid_set_field(
name: str,
value: Any = UNSET,
*,
position: tuple[int, int] | None = None,
strict: bool = UNSET,
slide: Sequence[Axis] | None = UNSET,
visible: bool | None = UNSET,
wireframe: bool | None = UNSET,
foreground: ColorLike | None = UNSET,
background: ColorLike | None = UNSET,
fill: bool | None = UNSET,
width: SizingLike | None = UNSET,
height: SizingLike | None = UNSET,
gap: int | None = UNSET,
direction: Direction | None = UNSET,
horizontal_align: Alignment | None = UNSET,
vertical_align: VerticalAlignment | None = UNSET,
border: Border | None = UNSET,
border_sides: Sequence[Side] | None = UNSET,
border_color: ColorLike | None = UNSET,
title: str | None = UNSET,
title_position: FrameTitlePosition | None = UNSET,
padding: PaddingLike | None = UNSET,
margin: PaddingLike | None = UNSET,
z: int | None = UNSET,
modifiers: Sequence[CharacterModifier] | None = UNSET,
class_name: ClassNameLike | None = UNSET,
bold: bool = UNSET,
dim: bool = UNSET,
italic: bool = UNSET,
underline: bool = UNSET,
slow_blink: bool = UNSET,
rapid_blink: bool = UNSET,
reversed: bool = UNSET,
color: ColorLike | None = UNSET,
align: Alignment | None = UNSET
) -> None
Set a layout field's runtime value and/or per-instance field metadata.
Cannot be used on state fields. default, default_factory,
init, and state cannot be changed at runtime.
For frequent, value-free style ticks (e.g. from on_tick or an
effect callback), prefer grid_update_field — it skips the
value/position handling this method carries for the general case.
color is a deprecated alias for foreground.
Source code in xnano/grids.py
1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 | |
grid_update_field
¶
grid_update_field(
name: str,
*,
slide: Sequence[Axis] | None = UNSET,
visible: bool | None = UNSET,
wireframe: bool | None = UNSET,
foreground: ColorLike | None = UNSET,
background: ColorLike | None = UNSET,
fill: bool | None = UNSET,
width: SizingLike | None = UNSET,
height: SizingLike | None = UNSET,
gap: int | None = UNSET,
direction: Direction | None = UNSET,
horizontal_align: Alignment | None = UNSET,
vertical_align: VerticalAlignment | None = UNSET,
border: Border | None = UNSET,
border_sides: Sequence[Side] | None = UNSET,
border_color: ColorLike | None = UNSET,
title: str | None = UNSET,
title_position: FrameTitlePosition | None = UNSET,
padding: PaddingLike | None = UNSET,
margin: PaddingLike | None = UNSET,
z: int | None = UNSET,
modifiers: Sequence[CharacterModifier] | None = UNSET,
class_name: ClassNameLike | None = UNSET,
bold: bool = UNSET,
dim: bool = UNSET,
italic: bool = UNSET,
underline: bool = UNSET,
slow_blink: bool = UNSET,
rapid_blink: bool = UNSET,
reversed: bool = UNSET,
color: ColorLike | None = UNSET,
align: Alignment | None = UNSET
) -> None
Update a layout field's style/layout attributes, live, in-place.
A narrower sibling of grid_set_field for frequent, value-free
attribute changes — pulsing a border color from on_tick,
toggling a modifier from an effect callback. It has no value=
or position= parameters at all, so a per-frame style tick never
pays for that method's value-validation branch. Optional style
patches never raise: a missing or state-only name is a no-op
(no try/except needed), though unknown keyword arguments
still raise as a programming error.
color is a deprecated alias for foreground.
Source code in xnano/grids.py
1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 | |
grid_set_frame
¶
grid_set_frame(
frame: Frame | None = UNSET,
*,
background: ColorLike | None = UNSET,
border: Border | None = UNSET,
border_color: ColorLike | None = UNSET,
border_sides: Sequence[Side] | None = UNSET,
title: str | None = UNSET,
title_position: FrameTitlePosition | None = UNSET,
padding: PaddingLike | None = UNSET
) -> None
Set this grid instance's outer frame (chrome + background fill).
The public replacement for mutating the private _grid_frame.
Pass a whole frame to replace it outright, or individual keyword
arguments to patch the current frame in place — a bare
background fills the grid's whole area with no border required,
so nested grids can be themed without any chrome. Pass frame=None
to clear the frame.
Source code in xnano/grids.py
grid_set_background
¶
grid_set_background(background: ColorLike | None) -> None
Fill this grid instance's whole area with background.
Shorthand for grid_set_frame(background=...) — the path for
theming a nested grid, replacing private _grid_frame mutation.
Source code in xnano/grids.py
grid_schedule_update
¶
grid_schedule_update(
callback: Callable[[], Any] | None = None,
*,
field: str | None = None
) -> None
Apply an update on the UI thread before the next frame.
The thread-safe way to reflect background work in the UI: pass a
callback to run on the runtime thread (so it can mutate this grid
without racing the renderer), and/or a field to mark dirty. Safe
to call from any thread; a no-op when no runtime is active.
Source code in xnano/grids.py
set_frame
¶
set_background
¶
set_background(background: ColorLike | None) -> None
Deprecated alias for grid_set_background.
schedule_update
¶
Deprecated alias for grid_schedule_update.
Source code in xnano/grids.py
GridSettings
¶
Bases: TypedDict
Rendering, layout, and frame settings for a BaseGrid subclass.
Attributes:
-
foreground(NotRequired[ColorLike]) –Foreground color of rendered content.
-
background(NotRequired[ColorLike]) –Background color of the grid frame.
-
direction(NotRequired[Direction]) –Direction used to lay out fields.
-
gap(NotRequired[int]) –Cells between fields.
-
border(NotRequired[Border]) –Border style around the grid.
-
border_sides(NotRequired[list[Side]]) –Border sides to display.
-
border_color(NotRequired[ColorLike]) –Color of the border.
-
title(NotRequired[str]) –Text displayed in the grid frame.
-
title_position(NotRequired[FrameTitlePosition]) –Alignment of the frame title.
-
padding(NotRequired[PaddingLike]) –Space between the frame and its content.
-
bold(NotRequired[bool]) –Whether content is bold.
-
dim(NotRequired[bool]) –Whether content is dimmed.
-
italic(NotRequired[bool]) –Whether content is italic.
-
underline(NotRequired[bool]) –Whether content is underlined.
-
slow_blink(NotRequired[bool]) –Whether content blinks slowly.
-
rapid_blink(NotRequired[bool]) –Whether content blinks rapidly.
-
reversed(NotRequired[bool]) –Whether foreground and background are reversed.
-
strict(NotRequired[bool]) –Whether field assignments are validated.
foreground
instance-attribute
¶
foreground: NotRequired[ColorLike]
The foreground color of the grid's content.
background
instance-attribute
¶
background: NotRequired[ColorLike]
The background color of the grid's frame area.
direction
instance-attribute
¶
direction: NotRequired[Direction]
The direction in which content within this grid should be laid out.
border
instance-attribute
¶
border: NotRequired[Border]
The border style to be applied onto the outer frame of the grid.
border_sides
instance-attribute
¶
border_sides: NotRequired[list[Side]]
The sides of the border to be applied onto the outer frame of the grid.
title
instance-attribute
¶
title: NotRequired[str]
The title to be displayed around the outer frame of the grid.
title_position
instance-attribute
¶
title_position: NotRequired[FrameTitlePosition]
The position of the title within the outer frame of the grid.
padding
instance-attribute
¶
padding: NotRequired[PaddingLike]
The padding to be applied around the content area of the grid.
italic
instance-attribute
¶
italic: NotRequired[bool]
Whether the grid should be rendered in italic.
underline
instance-attribute
¶
underline: NotRequired[bool]
Whether the grid should be rendered in underline.
slow_blink
instance-attribute
¶
slow_blink: NotRequired[bool]
Whether the grid should be rendered in slow blink.
rapid_blink
instance-attribute
¶
rapid_blink: NotRequired[bool]
Whether the grid should be rendered in rapid blink.
reversed
instance-attribute
¶
reversed: NotRequired[bool]
Whether the grid should be rendered in reversed color.
strict
instance-attribute
¶
strict: NotRequired[bool]
When True (the default), all field values are validated against their
type annotations during grid construction.
Style
dataclass
¶
Style(
*,
foreground: ColorLike | None = None,
background: ColorLike | None = None,
border: Border | None = None,
border_color: ColorLike | None = None,
border_sides: tuple[Side, ...] | None = None,
padding: Padding | None = None,
margin: Padding | None = None,
gap: int | None = None,
width: Sizing | None = None,
height: Sizing | None = None,
modifiers: tuple[CharacterModifier, ...] = (),
horizontal_align: Alignment | None = None,
direction: Direction | None = None,
title: str | None = None,
title_position: str | None = None,
visible: bool | None = None,
cursor: str | None = None,
passthrough_classes: tuple[str, ...] = (),
classes: tuple[str, ...] = ()
)
Style derived from Tailwind utility classes.
Attributes:
-
color–Foreground color.
-
background(ColorLike | None) –Background color.
-
border(Border | None) –Border style.
-
border_color(ColorLike | None) –Border color.
-
border_sides(tuple[Side, ...] | None) –Visible border sides.
-
padding(Padding | None) –Inner spacing.
-
margin(Padding | None) –Outer spacing.
-
gap(int | None) –Spacing between children.
-
width(Sizing | None) –Horizontal size.
-
height(Sizing | None) –Vertical size.
-
modifiers(tuple[CharacterModifier, ...]) –Text modifiers.
-
horizontal_align(Alignment | None) –Horizontal alignment.
-
direction(Direction | None) –Child layout direction.
-
title(str | None) –Optional frame title.
-
title_position(str | None) –Alignment of the frame title.
-
visible(bool | None) –Visibility override.
-
cursor(str | None) –Browser cursor class.
-
passthrough_classes(tuple[str, ...]) –Classes retained for browser output.
-
classes(tuple[str, ...]) –Normalized source classes.
Examples:
foreground
class-attribute
instance-attribute
¶
foreground: ColorLike | None = None
Foreground color.
background
class-attribute
instance-attribute
¶
background: ColorLike | None = None
Background color.
border_color
class-attribute
instance-attribute
¶
border_color: ColorLike | None = None
Border color.
border_sides
class-attribute
instance-attribute
¶
Visible border sides.
modifiers
class-attribute
instance-attribute
¶
modifiers: tuple[CharacterModifier, ...] = ()
Character modifiers.
horizontal_align
class-attribute
instance-attribute
¶
horizontal_align: Alignment | None = None
Horizontal alignment.
direction
class-attribute
instance-attribute
¶
direction: Direction | None = None
Child layout direction.
title_position
class-attribute
instance-attribute
¶
title_position: str | None = None
Frame title alignment.
passthrough_classes
class-attribute
instance-attribute
¶
Classes retained for browser output.
Terminal
¶
Terminal(
*,
state: StateT | None = None,
title: str | None = None,
tick_interval: int = 16,
mouse_events: bool = False
)
Bases: Generic[StateT]
Paint and interact with an application in a terminal.
Terminal selects a live session when one is available and otherwise
uses an offscreen buffer. Use :meth:offscreen explicitly in tests.
Pass mouse_events=True to receive clicks, drags, hovers, and wheel
events — required for click-to-focus and @on_click/@on_mouse
hooks; it is off by default so a keyboard-only app pays nothing.
Attributes:
-
runtime(Runtime[StateT]) –Runtime owned by the terminal.
-
state(StateT | None) –Application state shared with event hooks.
-
device–Display controls for the active session.
-
cursor–Cursor controls for the active session.
-
actions–Synthetic action performer.
-
stage–Layout stage for the current root.
-
size(tuple[int, int]) –Viewport width and height in cells.
-
focused_group(str | None) –Name of the focused field group.
-
surface–Active presentation surface.
Example
terminal = Terminal.offscreen(cols=24, rows=3) frame = terminal.render("Hello, xnano") "Hello, xnano" in frame.text True terminal.close()
Methods:
-
offscreen–Create a terminal backed by an in-memory cell buffer.
-
supports_live_terminal–Return whether interactive terminal sessions are available.
-
attach_grid–Set the grid used by subsequent renders and dispatch.
-
render–Paint one frame and return its immutable snapshot.
-
run–Render and dispatch events until an exit is requested.
-
request_exit–Stop the active run loop.
-
focus–Focus a named field group.
-
blur–Clear field focus.
-
focus_next–Move focus forward.
-
focus_previous–Move focus backward.
-
get_output–Return the current cell buffer as plain text.
-
get_output_as_ansi–Return the current cell buffer with ANSI styling.
-
copy_to_clipboard–Copy text when the active platform supports clipboard writes.
-
close–Restore and release the owned runtime.
Source code in xnano/terminal.py
offscreen
classmethod
¶
offscreen(
*,
cols: int = 40,
rows: int = 12,
state: StateT | None = None,
title: str | None = None
) -> "Terminal[StateT]"
Create a terminal backed by an in-memory cell buffer.
Source code in xnano/terminal.py
render
¶
render(
*renderables: Any,
foreground: ColorLike | None = None,
background: ColorLike | None = None,
modifiers: Sequence[CharacterModifier] | None = None,
horizontal_align: Alignment | None = None,
vertical_align: VerticalAlignment | None = None,
border: Border | None = None,
border_sides: Sequence[Side] | None = None,
border_color: ColorLike | None = None,
title: str | None = None,
title_position: FrameTitlePosition | None = None,
padding: PaddingLike | None = None,
gap: int = 0,
direction: Direction = "vertical",
color: ColorLike | None = None,
align: Alignment | None = None
) -> Frame
Paint one frame and return its immutable snapshot.
Parameters:
-
*renderables(Any, default:()) –Grids, components, content primitives, or plain values to paint.
-
foreground(ColorLike | None, default:None) –Foreground color applied to plain values.
-
background(ColorLike | None, default:None) –Background color for the rendered area.
-
modifiers(Sequence[CharacterModifier] | None, default:None) –Character modifiers applied to plain values.
-
horizontal_align(Alignment | None, default:None) –Horizontal alignment applied to plain values.
vertical_align: Vertical alignment applied to plain values. border: Border style around the rendered area. border_sides: Border sides to draw. border_color: Border foreground color. title: Optional border title. title_position: Border edge that holds the title. padding: Space between the border and content. gap: Cells between multiple renderables. direction: Direction used to lay out multiple renderables.
Returns:
-
Frame–A snapshot of the rendered terminal frame.
Source code in xnano/terminal.py
run
¶
run(
*renderables: Any,
foreground: ColorLike | None = None,
background: ColorLike | None = None,
modifiers: Sequence[CharacterModifier] | None = None,
horizontal_align: Alignment | None = None,
vertical_align: VerticalAlignment | None = None,
border: Border | None = None,
border_sides: Sequence[Side] | None = None,
border_color: ColorLike | None = None,
title: str | None = None,
title_position: FrameTitlePosition | None = None,
padding: PaddingLike | None = None,
gap: int = 0,
direction: Direction = "vertical",
color: ColorLike | None = None,
align: Alignment | None = None
) -> None
Render and dispatch events until an exit is requested.
Parameters:
-
*renderables(Any, default:()) –Grids, components, content primitives, or plain values to paint.
-
foreground(ColorLike | None, default:None) –Foreground color applied to plain values.
-
background(ColorLike | None, default:None) –Background color for the rendered area.
-
modifiers(Sequence[CharacterModifier] | None, default:None) –Character modifiers applied to plain values.
-
horizontal_align(Alignment | None, default:None) –Horizontal alignment applied to plain values.
vertical_align: Vertical alignment applied to plain values. border: Border style around the rendered area. border_sides: Border sides to draw. border_color: Border foreground color. title: Optional border title. title_position: Border edge that holds the title. padding: Space between the border and content. gap: Cells between multiple renderables. direction: Direction used to lay out multiple renderables.
Source code in xnano/terminal.py
request_exit
¶
focus
¶
blur
¶
copy_to_clipboard
¶
Web
¶
Serve an application in a browser from an offscreen runtime.
Attributes:
-
state–Application state shared with event and request hooks.
-
title–Browser document title.
-
width–Offscreen viewport width in cells.
-
height–Offscreen viewport height in cells.
-
surface–Presentation surface name.
Example
from xnano.components import Text web = Web(title="Status")
web.run(Text("Ready"), host="127.0.0.1", port=8000)¶
Methods:
-
run–Serve an application until interrupted.
-
close–Stop a managed server when one has been attached.
Source code in xnano/web.py
run
¶
Serve an application until interrupted.
Parameters:
-
source(Any) –Grid/component instance, class, or factory.
-
host(str, default:'127.0.0.1') –Bind address.
-
port(int, default:8000) –Bind port.
Source code in xnano/web.py
close
¶
Field
¶
Field(
default: None,
*,
default_factory: None = None,
state: bool = False,
strict: bool = False,
init: bool = True,
visible: bool | None = None,
modifiers: Sequence[CharacterModifier] | None = None,
foreground: ColorLike | None = None,
color: ColorLike | None = _COLOR_UNSET,
background: ColorLike | None = None,
fill: bool | None = None,
width: SizingLike | None = None,
height: SizingLike | None = None,
gap: int | None = None,
direction: Direction | None = None,
horizontal_align: Alignment | None = None,
vertical_align: VerticalAlignment | None = None,
border: Border | None = None,
border_sides: Sequence[Side] | None = None,
border_color: ColorLike | None = None,
title: str | None = None,
title_position: FrameTitlePosition | None = None,
padding: PaddingLike | None = None,
margin: PaddingLike | None = None,
z: int | None = None,
overlay: bool = False,
slide: Sequence[Axis] | None = None,
group: str | None = None,
autofocus: bool | None = None,
scroll: ScrollLike | None = None,
wireframe: bool | None = None,
class_name: ClassNameLike | None = None,
align: Alignment | None = None
) -> Any
Field(
default: _T,
*,
default_factory: None = None,
state: bool = False,
strict: bool = False,
init: bool = True,
visible: bool | None = None,
modifiers: Sequence[CharacterModifier] | None = None,
foreground: ColorLike | None = None,
color: ColorLike | None = _COLOR_UNSET,
background: ColorLike | None = None,
fill: bool | None = None,
width: SizingLike | None = None,
height: SizingLike | None = None,
gap: int | None = None,
direction: Direction | None = None,
horizontal_align: Alignment | None = None,
vertical_align: VerticalAlignment | None = None,
border: Border | None = None,
border_sides: Sequence[Side] | None = None,
border_color: ColorLike | None = None,
title: str | None = None,
title_position: FrameTitlePosition | None = None,
padding: PaddingLike | None = None,
margin: PaddingLike | None = None,
z: int | None = None,
overlay: bool = False,
slide: Sequence[Axis] | None = None,
group: str | None = None,
autofocus: bool | None = None,
scroll: ScrollLike | None = None,
wireframe: bool | None = None,
class_name: ClassNameLike | None = None,
align: Alignment | None = None
) -> _T
Field(
*,
default_factory: Callable[[], _T],
state: bool = False,
strict: bool = False,
init: bool = True,
visible: bool | None = None,
modifiers: Sequence[CharacterModifier] | None = None,
foreground: ColorLike | None = None,
color: ColorLike | None = _COLOR_UNSET,
background: ColorLike | None = None,
fill: bool | None = None,
width: SizingLike | None = None,
height: SizingLike | None = None,
gap: int | None = None,
direction: Direction | None = None,
horizontal_align: Alignment | None = None,
vertical_align: VerticalAlignment | None = None,
border: Border | None = None,
border_sides: Sequence[Side] | None = None,
border_color: ColorLike | None = None,
title: str | None = None,
title_position: FrameTitlePosition | None = None,
padding: PaddingLike | None = None,
margin: PaddingLike | None = None,
z: int | None = None,
overlay: bool = False,
slide: Sequence[Axis] | None = None,
group: str | None = None,
autofocus: bool | None = None,
scroll: ScrollLike | None = None,
wireframe: bool | None = None,
class_name: ClassNameLike | None = None,
align: Alignment | None = None
) -> _T
Field(
*,
default: Any = UNSET,
default_factory: None = None,
state: bool = False,
strict: bool = False,
init: bool = True,
visible: bool | None = None,
modifiers: Sequence[CharacterModifier] | None = None,
foreground: ColorLike | None = None,
color: ColorLike | None = _COLOR_UNSET,
background: ColorLike | None = None,
fill: bool | None = None,
width: SizingLike | None = None,
height: SizingLike | None = None,
gap: int | None = None,
direction: Direction | None = None,
horizontal_align: Alignment | None = None,
vertical_align: VerticalAlignment | None = None,
border: Border | None = None,
border_sides: Sequence[Side] | None = None,
border_color: ColorLike | None = None,
title: str | None = None,
title_position: FrameTitlePosition | None = None,
padding: PaddingLike | None = None,
margin: PaddingLike | None = None,
z: int | None = None,
overlay: bool = False,
slide: Sequence[Axis] | None = None,
group: str | None = None,
autofocus: bool | None = None,
scroll: ScrollLike | None = None,
wireframe: bool | None = None,
class_name: ClassNameLike | None = None,
align: Alignment | None = None
) -> Any
Field(
default: Any = UNSET,
*,
default_factory: Callable[[], Any] | None = None,
state: bool = False,
strict: bool = False,
init: bool = True,
visible: bool | None = None,
modifiers: Sequence[CharacterModifier] | None = None,
foreground: ColorLike | None = None,
color: ColorLike | None = _COLOR_UNSET,
background: ColorLike | None = None,
fill: bool | None = None,
width: SizingLike | None = None,
height: SizingLike | None = None,
gap: int | None = None,
direction: Direction | None = None,
horizontal_align: Alignment | None = None,
vertical_align: VerticalAlignment | None = None,
border: Border | None = None,
border_sides: Sequence[Side] | None = None,
border_color: ColorLike | None = None,
title: str | None = None,
title_position: FrameTitlePosition | None = None,
padding: PaddingLike | None = None,
margin: PaddingLike | None = None,
z: int | None = None,
overlay: bool = False,
slide: Sequence[Axis] | None = None,
group: str | None = None,
autofocus: bool | None = None,
scroll: ScrollLike | None = None,
wireframe: bool | None = None,
class_name: ClassNameLike | None = None,
align: Alignment | None = None
) -> GridFieldInfo
Create a new grid field info instance.
Parameters:
-
default(Any, default:UNSET) –Static default value for this field.
-
default_factory(Callable[[], Any] | None, default:None) –Callable that produces the default value each time an instance is created.
-
state(bool, default:False) –Whether this field is a stateful field (does not ever represent renderable content).
-
strict(bool, default:False) –When
Trueand this field is a state field, assignments are validated against the field's type annotation usingpydantic_core. -
init(bool, default:True) –Whether this field should be included within the constructor of it's parent grid class.
-
visible(bool | None, default:None) –Whether this field is visible on the live terminal display.
-
modifiers(Sequence[CharacterModifier] | None, default:None) –Modifiers to apply to all characters within this field. This can be a list including "bold", "dim", "italic", "underline", "slow_blink", "rapid_blink", "reversed".
-
foreground(ColorLike | None, default:None) –The foreground color of content within this field.
-
color(ColorLike | None, default:_COLOR_UNSET) –Deprecated alias for
foreground; passing it emits aDeprecationWarningand sets the foreground. -
background(ColorLike | None, default:None) –The background color of this field. Fills the whole slot by default when set (see
fill); also fills the framed content area when the field defines border/title/padding chrome. -
fill(bool | None, default:None) –Whether
backgroundfills the whole slot.Nonefills when a background is set;Trueforces a full-slot fill;Falsepaints the color only behind text glyphs. -
width(SizingLike | None, default:None) –Horizontal extent sizing (
10,"50%","1fr","fit", or aSizing). Drives the split constraint in horizontal layouts; shrinks the slot along the cross axis otherwise. -
height(SizingLike | None, default:None) –Vertical extent sizing (
3,"50%","1fr","fit", or aSizing). Drives the split constraint in vertical layouts; shrinks the slot along the cross axis otherwise. -
gap(int | None, default:None) –The gap between fields in this field or area.
-
direction(Direction | None, default:None) –The direction in which content within this field or area should be laid out.
-
horizontal_align(Alignment | None, default:None) –The horizontal alignment of content within this field's area.
-
vertical_align(VerticalAlignment | None, default:None) –The vertical alignment of content within this field's area.
-
border(Border | None, default:None) –A border style to be applied onto the outer frame of the rectangular area this field occupies.
-
border_sides(Sequence[Side] | None, default:None) –The sides of the border to be applied onto the outer frame of the area this field occupies.
-
border_color(ColorLike | None, default:None) –The color of this field's border, if one is set.
-
title(str | None, default:None) –A title to be displayed around the outer frame of this field's area.
-
title_position(FrameTitlePosition | None, default:None) –The alignment of the title within the outer frame of this field's area.
-
padding(PaddingLike | None, default:None) –The padding to be applied around the content area of this field.
-
margin(PaddingLike | None, default:None) –The margin to be applied around the outer area of this field.
-
z(int | None, default:None) –Layering order for this field's slot relative to its grid.
Noneinherits the grid's ownz; an explicit value stacks the field's whole subtree (text, component, or nested grid) above or below its siblings and is additive with the grid'sz. -
overlay(bool, default:False) –Float this field over the grid's content area (centered, sized by
width/height) instead of giving it a layout slot. Pair with a higherzfor a popup or modal over the panels behind it. -
slide(Sequence[Axis] | None, default:None) –The axes along which this field may slide within its parent grid.
-
class_name(ClassNameLike | None, default:None) –Tailwind CSS classes styling this field — a space-separated string or a sequence of class tokens. Classes are lowered into the standard field attributes (see
xnano.tailwind); an explicit keyword argument always overrides a class-derived value. Classes with no terminal equivalent are ignored by the terminal backend and emitted verbatim by the web backend.
Returns:
-
GridFieldInfo–A new
GridFieldInfoinstance with all display/layout metadata, -
GridFieldInfo–including the normalized
class_nametokens.
Source code in xnano/fields.py
539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 | |
on_action
¶
Bind a prebuilt Action as a hook trigger.
User-facing sugar for storing an Action on a handler:
SAVE = Action.keyboard("ctrl+s")
@on_action(SAVE)
def save(self, ctx): ...
Source code in xnano/hooks.py
on_click
¶
on_click(
handler: EventHookFunction,
/,
*,
field: str,
button: MouseButton = "left",
kind: MouseEventKind = "press",
) -> EventHookFunction
on_click(
*,
group: str,
button: MouseButton = "left",
kind: MouseEventKind = "press"
) -> Callable[[EventHookFunction], EventHookFunction]
on_click(
field_or_handler: "str | EventHookFunction | None" = None,
/,
*,
field: str | None = None,
group: str | None = None,
button: MouseButton = "left",
kind: MouseEventKind = "press",
) -> "EventHookFunction | Callable[[EventHookFunction], EventHookFunction]"
Register a click handler for a grid layout field, or a group.
A field-scoped handler binds to one field on the declaring grid
class. A group-scoped handler fires whenever any field sharing
group is clicked, regardless of which grid it lives on — see
Field(group=...).
Example
@on_click("body") def highlight_body(self, ctx): ...
@on_click(group="composer") def focus_composer(self, ctx): ctx.focus("composer")
Source code in xnano/hooks.py
on_clipboard
¶
on_event
¶
Register an event hook that triggers on every detected event.
on_field
¶
Fire the decorated handler based on this grid's own field values.
Pass an expression ("count > 0") to fire each frame it is truthy
against the grid's fields. Pass a bare reference ("count",
"items[0]") to fire only when that field is mutated — once per
change rather than every frame.
Example
@on_field("count > 0") def _show_count(self): ...
@on_field("count") def _on_count_changed(self): ...
Source code in xnano/hooks.py
on_focus
¶
on_focus(
field: str, /, *, kind: FocusHookKind | None = None
) -> Callable[[EventHookFunction], EventHookFunction]
on_focus(
*,
field: str | None = None,
group: str | None = None,
kind: FocusHookKind | None = None
) -> Callable[[EventHookFunction], EventHookFunction]
on_focus(
handler_or_field: "EventHookFunction | str | None" = None,
/,
*,
field: str | None = None,
group: str | None = None,
kind: FocusHookKind | None = None,
) -> "EventHookFunction | Callable[[EventHookFunction], EventHookFunction]"
Register a focus hook for the terminal window, a field, or a group.
Bare @on_focus fires on OS-level terminal focus gained/lost.
Pass a field name for application field focus; pass group= to
listen across grids — see Field(group=...).
Source code in xnano/hooks.py
on_keyboard
¶
on_keyboard(
key: KeyboardBinding,
/,
*keys: KeyboardBinding,
kind: KeyboardEventKind | None = None,
) -> Callable[[EventHookFunction], EventHookFunction]
on_keyboard(
*,
key: KeyboardBinding,
kind: KeyboardEventKind | None = None
) -> Callable[[EventHookFunction], EventHookFunction]
on_keyboard(
handler: EventHookFunction,
/,
*,
key: KeyboardBinding | None = None,
kind: KeyboardEventKind | None = None,
) -> EventHookFunction
on_keyboard(
handler_or_key: "EventHookFunction | KeyboardBinding | None" = None,
/,
*keys: KeyboardBinding,
key: KeyboardBinding | None = None,
kind: KeyboardEventKind | None = None,
) -> "EventHookFunction | Callable[[EventHookFunction], EventHookFunction]"
Register a keyboard event hook.
Example
@on_keyboard("q") def quit(self, ctx): ...
@on_keyboard("enter", kind="press") def submit(self): ...
Source code in xnano/hooks.py
on_mouse
¶
on_mouse(
button: MouseButton,
/,
*,
field: str | None = None,
kind: MouseEventKind | None = None,
) -> Callable[[EventHookFunction], EventHookFunction]
on_mouse(
*,
button: MouseButton | None = None,
field: str | None = None,
kind: MouseEventKind | None = None
) -> Callable[[EventHookFunction], EventHookFunction]
on_mouse(
handler: EventHookFunction,
/,
*,
button: MouseButton | None = None,
field: str | None = None,
kind: MouseEventKind | None = None,
) -> EventHookFunction
on_mouse(
handler_or_button: "EventHookFunction | MouseButton | None" = None,
/,
*buttons: MouseButton,
button: MouseButton | None = None,
field: str | None = None,
kind: MouseEventKind | None = None,
) -> "EventHookFunction | Callable[[EventHookFunction], EventHookFunction]"
Register a mouse event hook.
Defaults to left-button press when button and kind are
omitted. Pass field to bind to a grid layout field's region.
Source code in xnano/hooks.py
on_poll
¶
on_poll(
handler_or_when: "EventHookFunction | PollWhen | None" = None,
/,
*,
when: PollWhen | None = None,
) -> "EventHookFunction | Callable[[EventHookFunction], EventHookFunction]"
Register a poll hook that fires on idle event waits or every frame.
Source code in xnano/hooks.py
on_resize
¶
on_state
¶
Fire the decorated handler based on the application state.
Pass an expression ("count > 0") to fire each frame it is truthy
against the state's attributes. Pass a bare reference ("count",
"user.name") to fire only when that value is mutated — once per
change rather than every frame.
Example
@on_state("count > 0") def _on_positive_count(self, ctx): ...
@on_state("count") def _on_count_changed(self, ctx): ...
Source code in xnano/hooks.py
on_tick
¶
on_tick(
handler_or_interval: "EventHookFunction | int | None" = None,
/,
*,
interval_milliseconds: int | None = None,
) -> "EventHookFunction | Callable[[EventHookFunction], EventHookFunction]"
Register a tick hook, optionally at a fixed interval.
Source code in xnano/hooks.py
render
¶
render(
*renderables: Any,
direction: Direction = "vertical",
foreground: ColorLike | None = None,
background: ColorLike | None = None,
modifiers: Sequence[CharacterModifier] | None = None,
horizontal_align: Alignment | None = None,
vertical_align: VerticalAlignment | None = None,
border: Border | None = None,
border_sides: Sequence[Side] | None = None,
border_color: ColorLike | None = None,
title: str | None = None,
title_position: FrameTitlePosition | None = None,
padding: PaddingLike | None = None,
gap: int = 0,
sep: str | None = " ",
end: str | None = "\n",
file: IO[str] | TextIO | None = None,
flush: bool = False,
stream: str | bool | None = None,
update: bool = False,
color: ColorLike | None = None,
align: Alignment | None = None
) -> None
Display renderables as print-like terminal output.
A live runtime paints the values into its current viewport. Otherwise
xnano uses an offscreen native terminal and writes the resulting cells to
file or standard output.
Parameters:
-
*renderables(Any, default:()) –Grids, components, content primitives, or plain values.
-
direction(Direction, default:'vertical') –Direction used to lay out multiple renderables.
-
foreground(ColorLike | None, default:None) –Foreground color applied to plain values.
-
background(ColorLike | None, default:None) –Background color for the rendered area.
-
modifiers(Sequence[CharacterModifier] | None, default:None) –Character modifiers applied to plain values.
-
horizontal_align(Alignment | None, default:None) –Horizontal alignment applied to plain values.
-
vertical_align(VerticalAlignment | None, default:None) –Vertical alignment applied to plain values.
-
border(Border | None, default:None) –Border style around the rendered area.
-
border_sides(Sequence[Side] | None, default:None) –Border sides to draw.
-
border_color(ColorLike | None, default:None) –Border foreground color.
-
title(str | None, default:None) –Optional border title.
-
title_position(FrameTitlePosition | None, default:None) –Border edge that holds the title.
-
padding(PaddingLike | None, default:None) –Space between the border and content.
-
gap(int, default:0) –Cells between multiple renderables.
-
sep(str | None, default:' ') –Separator used between horizontally arranged plain values.
-
end(str | None, default:'\n') –Text appended after the rendered output.
-
file(IO[str] | TextIO | None, default:None) –Text stream written outside a live runtime.
-
flush(bool, default:False) –Whether to flush the output stream after writing.
-
stream(str | bool | None, default:None) –Named append-or-replace output region.
-
update(bool, default:False) –Replace the named stream instead of appending to it.
Source code in xnano/rendering.py
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 | |