UI Layer¶
Command-line interface and user interaction components.
CLI¶
Command-line interface for the Svalboard Keymap Image Maker tool.
This module provides the CLI entry points for the skim tool using Click. It defines the main command group and subcommands for generating keymap images and configuration files.
- Commands:
skim generate: Generate keymap visualization imagesskim configure: Generate or output configuration files
Example
Generate images from a keymap file:
$ skim generate --keymap layout.kbi --output-dir ./images
Generate with custom configuration:
$ skim -v INFO generate -k layout.vil -c config.yaml -f png
Create configuration from Keybard file:
$ skim configure -k layout.kbi -o skim-config.yaml
Read keymap from stdin:
$ qmk c2json -kb svalboard/trackball/pmw3389/right -km vial --no-cpp $QMK_ROOT/keyboards/svalboard/keymaps/vial/keymap.c | skim generate - -o ./out
- class skim.cli.AliasedGroup(name=None, commands=None, invoke_without_command=False, no_args_is_help=None, subcommand_metavar=None, chain=False, result_callback=None, **kwargs)[source]¶
Bases:
GroupClick Group that supports command name abbreviation.
Allows users to invoke commands using unique prefixes instead of full command names. For example,
skim genmatchesgenerateif no other command starts with “gen”.Example
$ skim gen –keymap foo.kbi # Matches ‘generate’ $ skim conf -k bar.kbi # Matches ‘configure’
- Parameters:
Logging Configuration¶
Logging configuration for Skim CLI output.
This module provides logging setup with colored output and emoji indicators for different log levels. The configuration is optimized for CLI usage with progress feedback and debug information.
- Log level formatting:
DEBUG: Green with bug emoji (🐞)
INFO: Normal with contextual emoji (from record.emoji)
WARNING: Yellow with warning emoji (⚠️)
ERROR/CRITICAL: Red with error emoji (🚨)
Example
>>> from skim.ui.logging_config import setup_logging
>>> setup_logging("INFO", quiet=False)
>>> import logging
>>> logger = logging.getLogger(__name__)
>>> logger.info("Processing...", extra={"emoji": "🔄"})
🔄 Processing...
- class skim.application.logging_config.ColoredFormatter(fmt=None, datefmt=None, style='%', validate=True, *, defaults=None)[source]¶
Bases:
FormatterCustom log formatter with ANSI colors and emoji support.
Applies color coding based on log level and prepends optional emoji indicators to log messages. The emoji can be specified per-record using the “emoji” extra field.
- ANSI color codes are used for terminal output:
DEBUG: Green
INFO: Default (reset)
WARNING: Yellow
ERROR+: Red
- GREY¶
ANSI code for gray text.
- GREEN¶
ANSI code for green text.
- YELLOW¶
ANSI code for yellow text.
- RED¶
ANSI code for red text.
- BOLD_RED¶
ANSI code for bold red text.
- BLUE¶
ANSI code for blue text.
- RESET¶
ANSI code to reset formatting.
Example
formatter = ColoredFormatter() handler.setFormatter(formatter)
- GREY = '\x1b[38;5;240m'¶
- GREEN = '\x1b[32m'¶
- YELLOW = '\x1b[33m'¶
- RED = '\x1b[31m'¶
- BOLD_RED = '\x1b[31;1m'¶
- BLUE = '\x1b[34m'¶
- RESET = '\x1b[0m'¶
- skim.application.logging_config.setup_logging(verbosity, quiet)[source]¶
Configure the logging system for CLI output.
Sets up the root logger with colored output to stderr. The verbosity level can be specified as a string matching standard logging levels.
- Parameters:
- Return type:
Example
>>> setup_logging("INFO", quiet=False) >>> logging.info("This will be shown")
>>> setup_logging("WARNING", quiet=False) >>> logging.info("This will NOT be shown")
>>> setup_logging("DEBUG", quiet=True) >>> logging.debug("This will NOT be shown (quiet=True)")
TUI Configurator¶
Main TUI application for skim configuration editing.
- class skim.tui.app.LayerAdded(index, source_tab)[source]¶
Bases:
MessagePosted when a layer is added in either tab.
- time¶
- bubble: ClassVar[bool] = True¶
- handler_name: ClassVar[str] = 'on_layer_added'¶
Name of the default message handler.
- no_dispatch: ClassVar[bool] = False¶
- verbose: ClassVar[bool] = False¶
- class skim.tui.app.LayerRemoved(index, source_tab)[source]¶
Bases:
MessagePosted when a layer is removed in either tab.
- time¶
- bubble: ClassVar[bool] = True¶
- handler_name: ClassVar[str] = 'on_layer_removed'¶
Name of the default message handler.
- no_dispatch: ClassVar[bool] = False¶
- verbose: ClassVar[bool] = False¶
- class skim.tui.app.LayerUpdated[source]¶
Bases:
MessagePosted when a layer’s metadata (name, label, etc.) is changed.
- time¶
- bubble: ClassVar[bool] = True¶
- handler_name: ClassVar[str] = 'on_layer_updated'¶
Name of the default message handler.
- no_dispatch: ClassVar[bool] = False¶
- verbose: ClassVar[bool] = False¶
- class skim.tui.app.QuitConfirmScreen(name=None, id=None, classes=None)[source]¶
Bases:
ModalScreen[str]Modal dialog for save-on-quit with unsaved changes.
Returns “save” to save and quit, “discard” to quit without saving, or None if dismissed.
- BINDINGS: ClassVar[list[BindingType]] = [Binding(key='s', action='save_quit', description='Save & Quit', show=False, key_display=None, priority=False, tooltip='', id=None, system=False, group=None), Binding(key='d', action='discard', description='Discard', show=False, key_display=None, priority=False, tooltip='', id=None, system=False, group=None)]¶
A list of key bindings.
- 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. :rtype:
Iterable[Widget]Example
```python def compose(self) -> ComposeResult:
yield Header() yield Label(“Press the button below:”) yield Button() yield Footer()
- Return type:
Iterable[Widget]
- can_focus: bool = False¶
Widget may receive focus.
- can_focus_children: bool = True¶
Widget’s children may receive focus.
- class skim.tui.app.SaveTargetScreen(config_path)[source]¶
Bases:
ModalScreen[str|None]Modal dialog to choose where to save when -c was used without -o.
Returns “overwrite” to save back to the config file, “default” to save to skim-config.yaml in cwd, or None if dismissed.
- Parameters:
config_path (Path)
- BINDINGS: ClassVar[list[BindingType]] = [Binding(key='escape', action='dismiss_dialog', description='Cancel', show=False, key_display=None, priority=False, tooltip='', id=None, system=False, group=None)]¶
A list of key bindings.
- __init__(config_path)[source]¶
Initialize the screen.
- Parameters:
name – The name of the screen.
id – The ID of the screen in the DOM.
classes – The CSS classes for the screen.
config_path (Path)
- Return type:
None
- 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. :rtype:
Iterable[Widget]Example
```python def compose(self) -> ComposeResult:
yield Header() yield Label(“Press the button below:”) yield Button() yield Footer()
- Return type:
Iterable[Widget]
- can_focus: bool = False¶
Widget may receive focus.
- can_focus_children: bool = True¶
Widget’s children may receive focus.
- class skim.tui.app.OverwriteConfirmScreen(path, display_name=None)[source]¶
Bases:
ModalScreen[bool]Modal dialog to confirm overwriting an existing file.
Returns True to overwrite, False to cancel.
- BINDINGS: ClassVar[list[BindingType]] = [Binding(key='escape', action='dismiss_dialog', description='Cancel', show=False, key_display=None, priority=False, tooltip='', id=None, system=False, group=None)]¶
A list of key bindings.
- 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. :rtype:
Iterable[Widget]Example
```python def compose(self) -> ComposeResult:
yield Header() yield Label(“Press the button below:”) yield Button() yield Footer()
- Return type:
Iterable[Widget]
- can_focus: bool = False¶
Widget may receive focus.
- can_focus_children: bool = True¶
Widget’s children may receive focus.
- class skim.tui.app.ErrorDialog(message)[source]¶
Bases:
ModalScreen[None]Modal dialog to show an error message.
- Parameters:
message (str)
- BINDINGS: ClassVar[list[BindingType]] = [Binding(key='escape', action='dismiss_dialog', description='OK', show=False, key_display=None, priority=False, tooltip='', id=None, system=False, group=None)]¶
A list of key bindings.
- __init__(message)[source]¶
Initialize the screen.
- Parameters:
name – The name of the screen.
id – The ID of the screen in the DOM.
classes – The CSS classes for the screen.
message (str)
- Return type:
None
- 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. :rtype:
Iterable[Widget]Example
```python def compose(self) -> ComposeResult:
yield Header() yield Label(“Press the button below:”) yield Button() yield Footer()
- Return type:
Iterable[Widget]
- can_focus: bool = False¶
Widget may receive focus.
- can_focus_children: bool = True¶
Widget’s children may receive focus.
- class skim.tui.app.HelpScreen(content)[source]¶
Bases:
ModalScreen[None]Modal dialog to show contextual help as rendered markdown.
- Parameters:
content (str)
- BINDINGS: ClassVar[list[BindingType]] = [Binding(key='escape', action='dismiss_help', description='Close', show=False, key_display=None, priority=False, tooltip='', id=None, system=False, group=None), Binding(key='q', action='dismiss_help', description='Close', show=False, key_display=None, priority=False, tooltip='', id=None, system=False, group=None)]¶
A list of key bindings.
- __init__(content)[source]¶
Initialize the screen.
- Parameters:
name – The name of the screen.
id – The ID of the screen in the DOM.
classes – The CSS classes for the screen.
content (str)
- Return type:
None
- 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. :rtype:
Iterable[Widget]Example
```python def compose(self) -> ComposeResult:
yield Header() yield Label(“Press the button below:”) yield Button() yield Footer()
- Return type:
Iterable[Widget]
- can_focus: bool = False¶
Widget may receive focus.
- can_focus_children: bool = True¶
Widget’s children may receive focus.
- class skim.tui.app.SkimConfigApp(config_data, output_path=None, config_path=None, force=False)[source]¶
Bases:
AppInteractive skim configuration editor.
- Parameters:
- ENABLE_COMMAND_PALETTE: ClassVar[bool] = False¶
Should the [command palette][textual.command.CommandPalette] be enabled for the application?
- TITLE: str | None = 'skim configure'¶
A class variable to set the default title for the application.
To update the title while the app is running, you can set the [title][textual.app.App.title] attribute. See also [the Screen.TITLE attribute][textual.screen.Screen.TITLE].
- CSS: ClassVar[str] = '\n QuitConfirmScreen, SaveTargetScreen, OverwriteConfirmScreen, ErrorDialog, HelpScreen {\n align: center middle;\n }\n #quit-dialog, #save-target-dialog, #error-dialog {\n padding: 1 2;\n width: 55;\n height: auto;\n border: thick $background 80%;\n background: $surface;\n }\n #overwrite-dialog {\n padding: 1 2;\n width: 82;\n height: auto;\n border: thick $background 80%;\n background: $surface;\n }\n #question {\n text-align: center;\n width: 100%;\n height: auto;\n margin-bottom: 1;\n }\n #error-message {\n text-align: center;\n width: 100%;\n height: auto;\n margin-bottom: 1;\n }\n #quit-buttons, #overwrite-buttons, #error-buttons {\n width: 100%;\n height: auto;\n align-horizontal: center;\n }\n #quit-buttons Button, #overwrite-buttons Button, #error-buttons Button {\n margin: 0 1;\n padding: 0 3;\n }\n #help-dialog {\n padding: 0;\n width: 70;\n height: auto;\n max-height: 80%;\n border: thick $background 80%;\n background: $surface;\n }\n #help-dialog _HelpMarkdown {\n padding: 1 3;\n overflow-y: auto;\n max-height: 100%;\n }\n #help-dialog MarkdownH1 {\n background: transparent;\n margin: 0 0 1 0;\n }\n #help-dialog MarkdownH2,\n #help-dialog MarkdownH3 {\n background: transparent;\n }\n #save-target-buttons {\n width: 100%;\n height: auto;\n align-horizontal: center;\n }\n #save-target-buttons Button {\n width: 100%;\n margin: 0 0 1 0;\n }\n /* Global compact styling */\n Input {\n height: 3;\n width: 1fr;\n margin: 0;\n }\n Switch {\n height: auto;\n min-height: 1;\n }\n Select {\n width: 1fr;\n max-width: 30;\n }\n .field-row {\n height: auto;\n margin: 0;\n padding: 0;\n }\n .field-label {\n width: 22;\n height: 3;\n padding: 1 0 0 0;\n }\n .section-title {\n text-style: bold;\n color: $accent;\n margin: 1 0 0 0;\n }\n .section-title-first {\n margin: 0;\n }\n AutoComplete {\n & AutoCompleteList {\n border-left: wide $accent;\n }\n }\n ListItem {\n layout: horizontal;\n }\n ListItem > Static {\n text-wrap: nowrap;\n text-overflow: ellipsis;\n width: 1fr;\n }\n ListItem.moving {\n background: $accent 30%;\n }\n ListItem.moving > Static {\n color: $accent;\n }\n ListItem > .lc-swatch {\n width: 4;\n }\n ListItem > .move-indicator {\n dock: right;\n width: 3;\n color: $accent;\n }\n .list-buttons {\n height: auto;\n }\n .list-buttons Button {\n min-width: 12;\n margin: 0 1 0 0;\n }\n '¶
Inline CSS, useful for quick scripts. This is loaded after CSS_PATH, and therefore takes priority in the event of a specificity clash.
- BINDINGS: ClassVar[list[BindingType]] = [Binding(key='ctrl+q', action='request_quit', description='Quit', show=True, key_display='⌃Q', priority=False, tooltip='', id=None, system=False, group=None), Binding(key='ctrl+s', action='save', description='Save', show=True, key_display='⌃S', priority=False, tooltip='', id=None, system=False, group=None), Binding(key='ctrl+p', action='previous_tab', description='Previous Tab', show=True, key_display='⌃P', priority=True, tooltip='', id=None, system=False, group=None), Binding(key='ctrl+n', action='next_tab', description='Next Tab', show=True, key_display='⌃N', priority=True, tooltip='', id=None, system=False, group=None), Binding(key='up', action="focus_direction('up')", description='', show=False, key_display=None, priority=True, tooltip='', id=None, system=False, group=None), Binding(key='down', action="focus_direction('down')", description='', show=False, key_display=None, priority=True, tooltip='', id=None, system=False, group=None), Binding(key='left', action="focus_direction('left')", description='', show=False, key_display=None, priority=True, tooltip='', id=None, system=False, group=None), Binding(key='right', action="focus_direction('right')", description='', show=False, key_display=None, priority=True, tooltip='', id=None, system=False, group=None), Binding(key='ctrl+e', action="scroll_view('down')", description='Scroll down', show=True, key_display='⌃E', priority=True, tooltip='', id=None, system=False, group=None), Binding(key='ctrl+y', action="scroll_view('up')", description='Scroll up', show=True, key_display='⌃Y', priority=True, tooltip='', id=None, system=False, group=None), Binding(key='f1', action='show_help', description='Help', show=True, key_display='F1,⌥H', priority=True, tooltip='', id=None, system=False, group=None), Binding(key='alt+h', action='show_help', description='', show=False, key_display=None, priority=True, tooltip='', id=None, system=False, group=None)]¶
The default key bindings.
- __init__(config_data, output_path=None, config_path=None, force=False)[source]¶
Create an instance of an app.
- Parameters:
driver_class – Driver class or None to auto-detect. This will be used by some Textual tools.
css_path – Path to CSS or None to use the CSS_PATH class variable. To load multiple CSS files, pass a list of strings or paths which will be loaded in order.
watch_css – Reload CSS if the files changed. This is set automatically if you are using textual run with the dev switch.
ansi_color – Allow ANSI colors if True, or convert ANSI colors to RGB if False.
output_path (Path | None)
config_path (Path | None)
force (bool)
- Raises:
CssPathError – When the supplied CSS path(s) are an unexpected type.
- Return type:
None
- compose()[source]¶
Yield child widgets for a container.
This method should be implemented in a subclass.
- Return type:
Iterable[Widget]
- on_layer_added(event)[source]¶
- Return type:
- Parameters:
event (LayerAdded)
- on_layer_updated(event)[source]¶
- Return type:
- Parameters:
event (LayerUpdated)
- on_layer_removed(event)[source]¶
- Return type:
- Parameters:
event (LayerRemoved)
- action_scroll_view(direction)[source]¶
Scroll the VerticalScroll in the active tab (skip ListViews).
TUI Widgets¶
Shared reusable TUI widgets for skim configuration editor.
Bases:
FooterFooter with controlled binding order and paired key display.
- Parameters:
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. :rtype:
Iterable[Widget]Example
```python def compose(self) -> ComposeResult:
yield Header() yield Label(“Press the button below:”) yield Button() yield Footer()
- Return type:
Iterable[Widget]
Widget may receive focus.
Widget’s children may receive focus.
- class skim.tui.widgets.SkimStandaloneInput(*args, help_key=None, **kwargs)[source]¶
Bases:
InputInput for standalone fields outside edit panes.
- Parameters:
args (Any)
help_key (str | None)
kwargs (Any)
- BINDINGS: ClassVar[list[BindingType]] = [Binding(key='tab', action='focus_next', description='Next field', show=True, key_display='↓,⇥', priority=False, tooltip='', id=None, system=False, group=None), Binding(key='shift+tab', action='focus_previous', description='Previous field', show=True, key_display='↑,⇤', priority=False, tooltip='', id=None, system=False, group=None)]¶
- Key(s) | Description |:- | :- |left | Move the cursor left. |shift+left | Move cursor left and select. |ctrl+left | Move the cursor one word to the left. |right | Move the cursor right or accept the completion suggestion. |ctrl+shift+left | Move cursor left a word and select. |shift+right | Move cursor right and select. |ctrl+right | Move the cursor one word to the right. |backspace | Delete the character to the left of the cursor. |ctrl+shift+right | Move cursor right a word and select. |ctrl+shift+a | Select all text in the input. |home,ctrl+a | Go to the beginning of the input. |end,ctrl+e | Go to the end of the input. |shift+home | Select up to the input start. |shift+end | Select up to the input end. |delete,ctrl+d | Delete the character to the right of the cursor. |enter | Submit the current value of the input. |ctrl+w | Delete the word to the left of the cursor. |ctrl+u | Delete everything to the left of the cursor. |ctrl+f | Delete the word to the right of the cursor. |ctrl+k | Delete everything to the right of the cursor. |ctrl+x | Cut selected text. |ctrl+c | Copy selected text. |ctrl+v | Paste text from the clipboard. |
- __init__(*args, help_key=None, **kwargs)[source]¶
Initialise the Input widget.
- Parameters:
value – An optional default value for the input.
placeholder – Optional placeholder text for the input.
highlighter – An optional highlighter for the input.
password – Flag to say if the field should obfuscate its content.
restrict – A regex to restrict character inputs.
type – The type of the input.
max_length – The maximum length of the input, or 0 for no maximum length.
suggester – [Suggester][textual.suggester.Suggester] associated with this input instance.
validators – An iterable of validators that the Input value will be checked against.
validate_on – Zero or more of the values “blur”, “changed”, and “submitted”, which determine when to do input validation. The default is to do validation for all messages.
valid_empty – Empty values are valid.
select_on_focus – Whether to select all text on focus.
name – Optional name for the input widget.
id – Optional ID for the widget.
classes – Optional initial classes for the widget.
disabled – Whether the input is disabled or not.
tooltip – Optional tooltip.
compact – Enable compact style (without borders).
args (Any)
help_key (str | None)
kwargs (Any)
- Return type:
None
- can_focus: bool = True¶
Widget may receive focus.
- can_focus_children: bool = True¶
Widget’s children may receive focus.
- class skim.tui.widgets.SkimInput(*args, help_key=None, **kwargs)[source]¶
Bases:
InputInput with footer bindings for edit-pane field navigation.
- Parameters:
args (Any)
help_key (str | None)
kwargs (Any)
- BINDINGS: ClassVar[list[BindingType]] = [Binding(key='tab', action='focus_next', description='Next field', show=True, key_display='↓,⇥', priority=False, tooltip='', id=None, system=False, group=None), Binding(key='shift+tab', action='focus_previous', description='Previous field', show=True, key_display='↑,⇤', priority=False, tooltip='', id=None, system=False, group=None), Binding(key='enter', action='submit', description='Confirm changes', show=True, key_display='⏎', priority=False, tooltip='', id=None, system=False, group=None), Binding(key='escape', action='cancel_edit', description='Discard changes', show=True, key_display='\U000f12b7', priority=False, tooltip='', id=None, system=False, group=None)]¶
- Key(s) | Description |:- | :- |left | Move the cursor left. |shift+left | Move cursor left and select. |ctrl+left | Move the cursor one word to the left. |right | Move the cursor right or accept the completion suggestion. |ctrl+shift+left | Move cursor left a word and select. |shift+right | Move cursor right and select. |ctrl+right | Move the cursor one word to the right. |backspace | Delete the character to the left of the cursor. |ctrl+shift+right | Move cursor right a word and select. |ctrl+shift+a | Select all text in the input. |home,ctrl+a | Go to the beginning of the input. |end,ctrl+e | Go to the end of the input. |shift+home | Select up to the input start. |shift+end | Select up to the input end. |delete,ctrl+d | Delete the character to the right of the cursor. |enter | Submit the current value of the input. |ctrl+w | Delete the word to the left of the cursor. |ctrl+u | Delete everything to the left of the cursor. |ctrl+f | Delete the word to the right of the cursor. |ctrl+k | Delete everything to the right of the cursor. |ctrl+x | Cut selected text. |ctrl+c | Copy selected text. |ctrl+v | Paste text from the clipboard. |
- __init__(*args, help_key=None, **kwargs)[source]¶
Initialise the Input widget.
- Parameters:
value – An optional default value for the input.
placeholder – Optional placeholder text for the input.
highlighter – An optional highlighter for the input.
password – Flag to say if the field should obfuscate its content.
restrict – A regex to restrict character inputs.
type – The type of the input.
max_length – The maximum length of the input, or 0 for no maximum length.
suggester – [Suggester][textual.suggester.Suggester] associated with this input instance.
validators – An iterable of validators that the Input value will be checked against.
validate_on – Zero or more of the values “blur”, “changed”, and “submitted”, which determine when to do input validation. The default is to do validation for all messages.
valid_empty – Empty values are valid.
select_on_focus – Whether to select all text on focus.
name – Optional name for the input widget.
id – Optional ID for the widget.
classes – Optional initial classes for the widget.
disabled – Whether the input is disabled or not.
tooltip – Optional tooltip.
compact – Enable compact style (without borders).
args (Any)
help_key (str | None)
kwargs (Any)
- Return type:
None
- action_cancel_edit()[source]¶
No-op — handled by ListDetailPane.on_key via event bubbling.
- Return type:
- can_focus: bool = True¶
Widget may receive focus.
- can_focus_children: bool = True¶
Widget’s children may receive focus.
- class skim.tui.widgets.SkimListView(*args, help_key=None, **kwargs)[source]¶
Bases:
ListViewListView with footer bindings for navigation and edit.
- Parameters:
args (Any)
help_key (str | None)
kwargs (Any)
- BINDINGS: ClassVar[list[BindingType]] = [Binding(key='up', action='cursor_up', description='Prev item', show=True, key_display=None, priority=False, tooltip='', id=None, system=False, group=None), Binding(key='down', action='cursor_down', description='Next item', show=True, key_display=None, priority=False, tooltip='', id=None, system=False, group=None), Binding(key='enter', action='select_cursor', description='Edit', show=True, key_display='⏎', priority=False, tooltip='', id=None, system=False, group=None), Binding(key='m', action='move_mode', description='Move', show=True, key_display=None, priority=False, tooltip='', id=None, system=False, group=None), Binding(key='up', action='move_up', description='Move up', show=True, key_display=None, priority=False, tooltip='', id=None, system=False, group=None), Binding(key='down', action='move_down', description='Move down', show=True, key_display=None, priority=False, tooltip='', id=None, system=False, group=None), Binding(key='enter', action='confirm_move', description='Confirm position', show=True, key_display='⏎', priority=False, tooltip='', id=None, system=False, group=None), Binding(key='escape', action='cancel_move', description='Discard changes', show=True, key_display='\U000f12b7', priority=False, tooltip='', id=None, system=False, group=None)]¶
- Key(s) | Description |:- | :- |enter | Select the current item. |up | Move the cursor up. |down | Move the cursor down. |
- __init__(*args, help_key=None, **kwargs)[source]¶
Initialize a ListView.
- Parameters:
*children – The ListItems to display in the list.
initial_index – The index that should be highlighted when the list is first mounted.
name – The name of the widget.
id – The unique ID of the widget used in CSS/query selection.
classes – The CSS classes of the widget.
disabled – Whether the ListView is disabled or not.
args (Any)
help_key (str | None)
kwargs (Any)
- Return type:
None
- check_action(action, parameters)[source]¶
Check whether an action is enabled.
Implement this method to add logic for [dynamic actions](/guide/actions#dynamic-actions) / bindings.
- action_move_mode()[source]¶
No-op — handled by LayerListPane.on_key via event bubbling.
- Return type:
- action_move_down()[source]¶
No-op — handled by LayerListPane.on_key via event bubbling.
- Return type:
- action_confirm_move()[source]¶
No-op — handled by LayerListPane.on_key via event bubbling.
- Return type:
- action_cancel_move()[source]¶
No-op — handled by LayerListPane.on_key via event bubbling.
- Return type:
- can_focus: bool = True¶
Widget may receive focus.
- can_focus_children: bool = False¶
Widget’s children may receive focus.
- class skim.tui.widgets.SkimButton(*args, help_key=None, **kwargs)[source]¶
Bases:
ButtonButton that responds to both Enter and Space.
- Parameters:
args (Any)
help_key (str | None)
kwargs (Any)
- BINDINGS: ClassVar[list[BindingType]] = [Binding(key='enter', action='press', description='Activate', show=True, key_display='⏎,␣', priority=False, tooltip='', id=None, system=False, group=None), Binding(key='space', action='press', description='Activate', show=False, key_display=None, priority=False, tooltip='', id=None, system=False, group=None)]¶
A list of key bindings.
- __init__(*args, help_key=None, **kwargs)[source]¶
Create a Button widget.
- Parameters:
label – The text that appears within the button.
variant – The variant of the button.
name – The name of the button.
id – The ID of the button in the DOM.
classes – The CSS classes of the button.
disabled – Whether the button is disabled or not.
tooltip – Optional tooltip.
action – Optional action to run when clicked.
compact – Enable compact button style.
flat – Enable alternative flat look buttons.
args (Any)
help_key (str | None)
kwargs (Any)
- Return type:
None
- can_focus: bool = True¶
Widget may receive focus.
- can_focus_children: bool = True¶
Widget’s children may receive focus.
- class skim.tui.widgets.SkimSwitch(*args, help_key=None, **kwargs)[source]¶
Bases:
SwitchSwitch with footer binding for toggle action.
- Parameters:
args (Any)
help_key (str | None)
kwargs (Any)
- BINDINGS: ClassVar[list[BindingType]] = [Binding(key='enter', action='toggle_switch', description='Toggle', show=True, key_display='⏎,␣', priority=False, tooltip='', id=None, system=False, group=None), Binding(key='space', action='toggle_switch', description='Toggle', show=False, key_display=None, priority=False, tooltip='', id=None, system=False, group=None)]¶
- Key(s) | Description |:- | :- |enter,space | Toggle the switch state. |
- __init__(*args, help_key=None, **kwargs)[source]¶
Initialise the switch.
- Parameters:
value – The initial value of the switch.
animate – True if the switch should animate when toggled.
name – The name of the switch.
id – The ID of the switch in the DOM.
classes – The CSS classes of the switch.
disabled – Whether the switch is disabled or not.
tooltip – Optional tooltip.
args (Any)
help_key (str | None)
kwargs (Any)
- Return type:
None
- can_focus: bool = True¶
Widget may receive focus.
- can_focus_children: bool = True¶
Widget’s children may receive focus.
- class skim.tui.widgets.SkimSelect(*args, help_key=None, **kwargs)[source]¶
Bases:
SelectSelect with footer binding for menu action.
- Parameters:
args (Any)
help_key (str | None)
kwargs (Any)
- BINDINGS: ClassVar[list[BindingType]] = [Binding(key='enter', action='show_overlay', description='Show options', show=True, key_display='⏎,␣', priority=False, tooltip='', id=None, system=False, group=None), Binding(key='space', action='show_overlay', description='Show options', show=False, key_display=None, priority=False, tooltip='', id=None, system=False, group=None), Binding(key='tab', action='focus_next', description='Next field', show=True, key_display='↓,⇥', priority=False, tooltip='', id=None, system=False, group=None), Binding(key='shift+tab', action='focus_previous', description='Previous field', show=True, key_display='↑,⇤', priority=False, tooltip='', id=None, system=False, group=None), Binding(key='escape', action='cancel_edit', description='Discard changes', show=True, key_display='\U000f12b7', priority=False, tooltip='', id=None, system=False, group=None), Binding(key='up', action='skip_arrow', description='', show=False, key_display=None, priority=False, tooltip='', id=None, system=False, group=None), Binding(key='down', action='skip_arrow', description='', show=False, key_display=None, priority=False, tooltip='', id=None, system=False, group=None)]¶
- Key(s) | Description |:- | :- |enter,down,space,up | Activate the overlay |
- __init__(*args, help_key=None, **kwargs)[source]¶
Initialize the Select control.
- Parameters:
options – Options to select from. If no options are provided then allow_blank must be set to True.
prompt – Text to show in the control when no option is selected.
allow_blank – Enables or disables the ability to have the widget in a state with no selection made, in which case its value is set to the constant [Select.NULL][textual.widgets.Select.NULL].
value – Initial value selected. Should be one of the values in options. If no initial value is set and allow_blank is False, the widget will auto-select the first available option.
type_to_search – If True, typing will search for options.
name – The name of the select control.
id – The ID of the control in the DOM.
classes – The CSS classes of the control.
disabled – Whether the control is disabled or not.
tooltip – Optional tooltip.
compact – Enable compact select (without borders).
args (Any)
help_key (str | None)
kwargs (Any)
- Raises:
EmptySelectError – If no options are provided and allow_blank is False.
- Return type:
None
- action_cancel_edit()[source]¶
No-op — handled by ListDetailPane.on_key via event bubbling.
- Return type:
- can_focus: bool = True¶
Widget may receive focus.
- can_focus_children: bool = True¶
Widget’s children may receive focus.
- class skim.tui.widgets.SkimVerticalScroll(*children, name=None, id=None, classes=None, disabled=False, can_focus=None, can_focus_children=None, can_maximize=None)[source]¶
Bases:
VerticalScrollVerticalScroll that yields arrow keys for spatial focus navigation.
Arrow keys raise SkipAction so the app-level directional focus handler receives them. Page Up/Down and Home/End still scroll normally.
- Parameters:
- can_focus: bool = True¶
Widget may receive focus.
- can_focus_children: bool = True¶
Widget’s children may receive focus.
List Detail Pane¶
Reusable list/detail pane base class for the skim TUI.
- class skim.tui.list_detail_pane.ListDetailPane(pane_id, list_help_key=None, **kwargs)[source]¶
Bases:
WidgetBase class for a list/detail split pane.
Provides: horizontal layout with a list column (35%) and a detail pane, edit mode lifecycle (enter/exit/commit/cancel), snapshot/rollback, focus-out commit, and key handling (Enter/Escape/a/d).
Subclasses implement the abstract methods to supply data and fields.
- DEFAULT_CSS: ClassVar[str] = '\n ListDetailPane {\n height: auto;\n }\n ListDetailPane .ldp-container {\n height: auto;\n }\n ListDetailPane .ldp-list-col {\n width: 35%;\n min-width: 25;\n height: 100%;\n }\n ListDetailPane .ldp-list {\n height: 1fr;\n border: solid $accent 50%;\n }\n ListDetailPane .ldp-buttons {\n height: auto;\n width: 100%;\n }\n ListDetailPane .ldp-buttons Button {\n width: 50%;\n }\n ListDetailPane .ldp-detail {\n padding: 0 1;\n height: auto;\n overflow-x: hidden;\n border: solid $accent 30%;\n }\n ListDetailPane .ldp-detail:focus-within {\n border: solid $accent;\n }\n '¶
Default TCSS.
- class EntryAdded(index)[source]¶
Bases:
MessagePosted after an entry is added.
- Parameters:
index (int)
- time¶
- bubble: ClassVar[bool] = True¶
- handler_name: ClassVar[str] = 'on_list_detail_pane_entry_added'¶
Name of the default message handler.
- no_dispatch: ClassVar[bool] = False¶
- verbose: ClassVar[bool] = False¶
- class EntryRemoved(index)[source]¶
Bases:
MessagePosted after an entry is removed.
- Parameters:
index (int)
- time¶
- bubble: ClassVar[bool] = True¶
- handler_name: ClassVar[str] = 'on_list_detail_pane_entry_removed'¶
Name of the default message handler.
- no_dispatch: ClassVar[bool] = False¶
- verbose: ClassVar[bool] = False¶
- class EntryUpdated[source]¶
Bases:
MessagePosted after a successful commit.
- time¶
- bubble: ClassVar[bool] = True¶
- handler_name: ClassVar[str] = 'on_list_detail_pane_entry_updated'¶
Name of the default message handler.
- no_dispatch: ClassVar[bool] = False¶
- verbose: ClassVar[bool] = False¶
- __init__(pane_id, list_help_key=None, **kwargs)[source]¶
Initialize a Widget.
- Parameters:
- Return type:
None
- 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. :rtype:
Iterable[Widget]Example
```python def compose(self) -> ComposeResult:
yield Header() yield Label(“Press the button below:”) yield Button() yield Footer()
- Return type:
Iterable[Widget]
- abstract compose_detail_fields()[source]¶
Yield the detail field widgets.
- Return type:
Iterable[Widget]
- validate_and_apply(entry)[source]¶
Validate the edit, apply field values to the entry dict.
Return True if valid, False to revert and show error. Default implementation is a no-op that returns True.
- move_paired_lists()[source]¶
Return additional lists that must be swapped in sync with entries.
Subclasses override this to return lists (e.g. palette layers, keyboard layers) that are paired 1:1 with
get_entries().
- on_move_swap(entries, pos, target, direction)[source]¶
Hook called before swapping entries at pos and target.
Subclasses override this to adjust entry data (e.g. QMK indices) before the positional swap happens.
- on_key(event)[source]¶
Handle move mode, Enter/Escape in edit mode, a/d/m shortcuts on list.
- Return type:
- on_descendant_blur(event)[source]¶
Commit edit when focus leaves the editing pane.
- Return type:
- Parameters:
event (DescendantBlur)
- can_focus: bool = False¶
Widget may receive focus.
- can_focus_children: bool = True¶
Widget’s children may receive focus.
Keyboard Tab¶
Keyboard tab widget for the skim TUI configuration editor.
- class skim.tui.keyboard_tab.LayerListPane(config_data, **kwargs)[source]¶
Bases:
ListDetailPaneList/detail pane for keyboard layers.
- DEFAULT_CSS: ClassVar[str] = '\n LayerListPane {\n height: auto;\n }\n '¶
Default TCSS.
- move_paired_lists()[source]¶
Return additional lists that must be swapped in sync with entries.
Subclasses override this to return lists (e.g. palette layers, keyboard layers) that are paired 1:1 with
get_entries().
- on_move_swap(entries, pos, target, direction)[source]¶
Hook called before swapping entries at pos and target.
Subclasses override this to adjust entry data (e.g. QMK indices) before the positional swap happens.
- can_focus: bool = False¶
Widget may receive focus.
- can_focus_children: bool = True¶
Widget’s children may receive focus.
- class skim.tui.keyboard_tab.KeyboardTab(config_data, **kwargs)[source]¶
Bases:
WidgetKeyboard configuration tab.
Shows an Information section, a Features section, and a Layers section with a LayerListPane for editing individual layer metadata.
- DEFAULT_CSS: ClassVar[str] = '\n KeyboardTab {\n height: 1fr;\n padding: 0 1;\n }\n KeyboardTab #info-section {\n height: auto;\n }\n KeyboardTab #features-section {\n height: auto;\n }\n KeyboardTab #features-row {\n height: auto;\n }\n KeyboardTab #layers-section {\n height: auto;\n }\n '¶
Default TCSS.
- 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. :rtype:
Iterable[Widget]Example
```python def compose(self) -> ComposeResult:
yield Header() yield Label(“Press the button below:”) yield Button() yield Footer()
- Return type:
Iterable[Widget]
- on_list_detail_pane_entry_added(event)[source]¶
- Return type:
- Parameters:
event (EntryAdded)
- on_list_detail_pane_entry_removed(event)[source]¶
- Return type:
- Parameters:
event (EntryRemoved)
- on_list_detail_pane_entry_updated(event)[source]¶
- Return type:
- Parameters:
event (EntryUpdated)
- can_focus: bool = False¶
Widget may receive focus.
- can_focus_children: bool = True¶
Widget’s children may receive focus.
Keycodes Tab¶
Keycodes tab widget for the skim TUI configuration editor.
- class skim.tui.keycodes_tab.KeycodeAutoComplete(*args, **kwargs)[source]¶
Bases:
AutoCompleteToken-aware autocomplete for keycode/macro fields.
Splits input on separator characters so autocomplete works inside macro arguments (e.g.
LSFT(KC_SPC)). Macro completions likeLSFT()are inserted asLSFT(so the user can continue filling in the argument.- __init__(*args, **kwargs)[source]¶
An autocomplete widget.
- Parameters:
target – An Input instance or a selector string used to query an Input instance. If a selector is used, remember that widgets are not available until the widget has been mounted (don’t use the selector in compose - use it in on_mount instead).
candidates – The candidates to match on, or a function which returns the candidates to match on. If set to None, the candidates will be fetched by directly calling the get_candidates method, which is what you’ll probably want to do if you’re subclassing AutoComplete and supplying your own custom get_candidates method.
prevent_default_enter – Prevent the default enter behavior. If True, when you select a dropdown option using the enter key, the default behavior (e.g. submitting an Input) will be prevented.
prevent_default_tab – Prevent the default tab behavior. If True, when you select a dropdown option using the tab key, the default behavior (e.g. moving focus to the next widget) will be prevented.
args (Any)
kwargs (Any)
- Return type:
None
- get_search_string(target_state)[source]¶
This value will be passed to the match function.
This could be, for example, the text in the target widget, or a substring of that text.
- Return type:
- Returns:
The search string that will be used to filter the dropdown options.
- Parameters:
target_state (TargetState)
- apply_completion(value, state)[source]¶
Apply the completion to the target widget.
This method updates the state of the target widget to the reflect the value the user has chosen from the dropdown list.
- should_show_dropdown(search_string)[source]¶
Determine whether to show or hide the dropdown based on the current state.
This method can be overridden to customize the visibility behavior.
- post_completion()[source]¶
This method is called after a completion is applied. By default, it simply hides the dropdown.
- Return type:
- can_focus: bool = False¶
Widget may receive focus.
- can_focus_children: bool = True¶
Widget’s children may receive focus.
- class skim.tui.keycodes_tab.OverrideTargetAutoComplete(target, config_data, **kwargs)[source]¶
Bases:
AutoCompleteContext-aware autocomplete for the Override Target field.
Detects
@@(keycode reference) and%%(NerdFont glyph) prefixes at the cursor position and provides appropriate candidates. On completion, inserts the value with a trailing;.- __init__(target, config_data, **kwargs)[source]¶
An autocomplete widget.
- Parameters:
target (
Input) – An Input instance or a selector string used to query an Input instance. If a selector is used, remember that widgets are not available until the widget has been mounted (don’t use the selector in compose - use it in on_mount instead).candidates – The candidates to match on, or a function which returns the candidates to match on. If set to None, the candidates will be fetched by directly calling the get_candidates method, which is what you’ll probably want to do if you’re subclassing AutoComplete and supplying your own custom get_candidates method.
prevent_default_enter – Prevent the default enter behavior. If True, when you select a dropdown option using the enter key, the default behavior (e.g. submitting an Input) will be prevented.
prevent_default_tab – Prevent the default tab behavior. If True, when you select a dropdown option using the tab key, the default behavior (e.g. moving focus to the next widget) will be prevented.
kwargs (Any)
- Return type:
None
- get_search_string(target_state)[source]¶
This value will be passed to the match function.
This could be, for example, the text in the target widget, or a substring of that text.
- Return type:
- Returns:
The search string that will be used to filter the dropdown options.
- Parameters:
target_state (TargetState)
- get_candidates(target_state)[source]¶
Get the candidates to match against.
- Return type:
list[DropdownItem]- Parameters:
target_state (TargetState)
- apply_completion(value, state)[source]¶
Apply the completion to the target widget.
This method updates the state of the target widget to the reflect the value the user has chosen from the dropdown list.
- should_show_dropdown(search_string)[source]¶
Determine whether to show or hide the dropdown based on the current state.
This method can be overridden to customize the visibility behavior.
- post_completion()[source]¶
This method is called after a completion is applied. By default, it simply hides the dropdown.
- Return type:
- can_focus: bool = False¶
Widget may receive focus.
- can_focus_children: bool = True¶
Widget’s children may receive focus.
- class skim.tui.keycodes_tab.PreProcessListPane(config_data, **kwargs)[source]¶
Bases:
ListDetailPaneList/detail pane for pre-process keycode entries.
- can_focus: bool = False¶
Widget may receive focus.
- can_focus_children: bool = True¶
Widget’s children may receive focus.
- class skim.tui.keycodes_tab.OverrideListPane(config_data, **kwargs)[source]¶
Bases:
ListDetailPaneList/detail pane for override keycode entries.
- can_focus: bool = False¶
Widget may receive focus.
- can_focus_children: bool = True¶
Widget’s children may receive focus.
- class skim.tui.keycodes_tab.KeycodesTab(config_data, **kwargs)[source]¶
Bases:
WidgetKeycodes configuration tab.
Shows two sections – Pre-process and Overrides – each using a ListDetailPane subclass for editing individual keycode mapping entries.
- DEFAULT_CSS: ClassVar[str] = '\n KeycodesTab {\n height: 1fr;\n padding: 0 1;\n }\n KeycodesTab .keycodes-section {\n height: 1fr;\n }\n KeycodesTab .keycodes-section ListDetailPane {\n height: 1fr;\n }\n KeycodesTab .keycodes-section ListDetailPane .ldp-container {\n height: 100%;\n }\n KeycodesTab .keycodes-section ListDetailPane .ldp-list-col {\n width: 35%;\n min-width: 25;\n }\n KeycodesTab .keycodes-section ListDetailPane .ldp-list {\n height: 1fr;\n border: solid $accent 50%;\n }\n KeycodesTab .keycodes-section ListDetailPane .ldp-detail {\n padding: 0 1;\n height: auto;\n overflow-x: hidden;\n border: solid $accent 30%;\n }\n KeycodesTab .keycodes-section ListDetailPane .ldp-detail:focus-within {\n border: solid $accent;\n }\n '¶
Default TCSS.
- 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. :rtype:
Iterable[Widget]Example
```python def compose(self) -> ComposeResult:
yield Header() yield Label(“Press the button below:”) yield Button() yield Footer()
- Return type:
Iterable[Widget]
- can_focus: bool = False¶
Widget may receive focus.
- can_focus_children: bool = True¶
Widget’s children may receive focus.
Style Tab¶
Output tab widget for the skim TUI configuration editor.
- class skim.tui.output_tab.ColorAutoComplete(*args, **kwargs)[source]¶
Bases:
AutoCompleteAutoComplete that re-posts Input.Changed after dropdown selection.
The base AutoComplete suppresses Input.Changed during completion via
self.prevent(Input.Changed). This subclass re-fires the event so that parent widgets (e.g. swatch updates) react to the new value.- __init__(*args, **kwargs)[source]¶
An autocomplete widget.
- Parameters:
target – An Input instance or a selector string used to query an Input instance. If a selector is used, remember that widgets are not available until the widget has been mounted (don’t use the selector in compose - use it in on_mount instead).
candidates – The candidates to match on, or a function which returns the candidates to match on. If set to None, the candidates will be fetched by directly calling the get_candidates method, which is what you’ll probably want to do if you’re subclassing AutoComplete and supplying your own custom get_candidates method.
prevent_default_enter – Prevent the default enter behavior. If True, when you select a dropdown option using the enter key, the default behavior (e.g. submitting an Input) will be prevented.
prevent_default_tab – Prevent the default tab behavior. If True, when you select a dropdown option using the tab key, the default behavior (e.g. moving focus to the next widget) will be prevented.
args (Any)
kwargs (Any)
- Return type:
None
- should_show_dropdown(search_string)[source]¶
Determine whether to show or hide the dropdown based on the current state.
This method can be overridden to customize the visibility behavior.
- apply_completion(value, state)[source]¶
Apply the completion to the target widget.
This method updates the state of the target widget to the reflect the value the user has chosen from the dropdown list.
- post_completion()[source]¶
This method is called after a completion is applied. By default, it simply hides the dropdown.
- Return type:
- can_focus: bool = False¶
Widget may receive focus.
- can_focus_children: bool = True¶
Widget’s children may receive focus.
- class skim.tui.output_tab.LayerColorListPane(config_data, **kwargs)[source]¶
Bases:
ListDetailPaneList/detail pane for layer colors.
- DEFAULT_CSS: ClassVar[str] = '\n LayerColorListPane {\n height: auto;\n }\n LayerColorListPane .lc-swatch {\n width: 4;\n height: 1;\n dock: right;\n margin: 0 0 0 1;\n }\n LayerColorListPane .color-swatch {\n width: 4;\n height: 1;\n margin: 1 1 0 0;\n content-align: center middle;\n }\n LayerColorListPane .swatch-spacer {\n width: 4;\n height: 1;\n margin: 1 1 0 0;\n }\n LayerColorListPane .gradient-swatch {\n width: 4;\n height: 3;\n content-align: center middle;\n }\n LayerColorListPane .gradient-preview {\n height: 3;\n width: auto;\n layout: horizontal;\n padding: 0 2;\n }\n LayerColorListPane .gradient-dark {\n background: #1b1b1b;\n margin: 0 0 0 2;\n }\n LayerColorListPane .gradient-light {\n background: #ffffff;\n margin: 0 0 0 1;\n }\n LayerColorListPane .lc-manual-step {\n display: none;\n }\n LayerColorListPane.manual-mode .lc-manual-step {\n display: block;\n }\n LayerColorListPane.manual-mode #lc-dynamic-color {\n display: none;\n }\n LayerColorListPane.manual-mode #lc-dynamic-preview {\n display: none;\n }\n '¶
Default TCSS.
- move_paired_lists()[source]¶
Return additional lists that must be swapped in sync with entries.
Subclasses override this to return lists (e.g. palette layers, keyboard layers) that are paired 1:1 with
get_entries().
- on_move_swap(entries, pos, target, direction)[source]¶
Hook called before swapping entries at pos and target.
Subclasses override this to adjust entry data (e.g. QMK indices) before the positional swap happens.
- on_key(event)[source]¶
Override to let Select handle keys normally.
Textual’s on_key fires during event bubbling BEFORE the App-level binding system runs. We must stop the event (to prevent other handlers from interfering) and manually trigger binding checks.
- Return type:
- on_descendant_blur(event)[source]¶
Suppress focus-out commit while Select overlay is open.
- Return type:
- Parameters:
event (DescendantBlur)
- can_focus: bool = False¶
Widget may receive focus.
- can_focus_children: bool = True¶
Widget’s children may receive focus.
- class skim.tui.output_tab.OutputTab(config_data, **kwargs)[source]¶
Bases:
WidgetOutput configuration tab.
Has sections for layout, style, palette, and layer colors.
- DEFAULT_CSS: ClassVar[str] = '\n OutputTab {\n height: 1fr;\n padding: 0 1;\n }\n OutputTab .section {\n height: auto;\n border-bottom: solid $accent 20%;\n }\n OutputTab .color-swatch {\n width: 5;\n height: 1;\n margin: 1 1 0 0;\n content-align: center middle;\n }\n OutputTab .swatch-spacer {\n width: 4;\n height: 1;\n margin: 1 1 0 0;\n }\n '¶
Default TCSS.
- 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. :rtype:
Iterable[Widget]Example
```python def compose(self) -> ComposeResult:
yield Header() yield Label(“Press the button below:”) yield Button() yield Footer()
- Return type:
Iterable[Widget]
- on_list_detail_pane_entry_added(event)[source]¶
- Return type:
- Parameters:
event (EntryAdded)
- on_list_detail_pane_entry_removed(event)[source]¶
- Return type:
- Parameters:
event (EntryRemoved)
- on_input_changed(event)[source]¶
Route input changes to the correct config path.
- Return type:
- Parameters:
event (Changed)
- can_focus: bool = False¶
Widget may receive focus.
- can_focus_children: bool = True¶
Widget’s children may receive focus.