BeClaude

general-ui-ux

New
Community RegistryDocumentationby Jrakru

UI/UX design principles: color theory, typography, accessibility, layout, WCAG compliance

Community PluginView Source

Overview

Table of Contents

  1. Overview
  2. Features
  3. Installation
  4. Quick Start Guide
  5. Helper Scripts
  6. Skills Guide
  7. Integration with Textual Ecosystem
  8. Best Practices
  9. Troubleshooting
  10. FAQ
  11. Resources

Overview

The Textual Plugin is a comprehensive collection of 12+ skills, helper scripts, templates, and examples designed to help AI agents and developers build professional Text-based User Interface (TUI) applications using the Textual framework.

This plugin provides everything you need to:

  • Learn Textual from scratch or deepen your expertise
  • Generate complete applications programmatically
  • Access pre-built templates for common patterns
  • Find relevant examples for your specific use case
  • Test and validate your TUI applications
  • Apply UI/UX best practices

What is Textual?

Textual is a Python framework for building rich text user interfaces (TUIs) - terminal applications with modern UI features like:

  • Interactive widgets (buttons, inputs, tables, lists)
  • CSS styling (colors, layouts, animations)
  • Reactive programming (auto-updating UI)
  • Multi-screen navigation (modals, dialogs, wizards)
  • Event-driven architecture (keyboard, mouse, focus events)

Features

✅ Complete Skills Catalog

Core Foundation (2 skills)

  • Getting Started with Textual - Basic app structure and async patterns
  • App Lifecycle & Structure - Initialization, configuration, CLI args

Widget Development (2 skills)

  • Built-in Widgets - All standard widgets with examples
  • Custom Widgets - Create reusable components

Layout & Design (2 skills)

  • Layout Systems - Vertical, Horizontal, Grid, Dock layouts
  • CSS Styling (TCSS) - Selectors, colors, themes, responsive design

Interactivity (1 skill)

  • Events and Messages - Event handlers, @on decorator, custom messages

Reactivity (1 skill)

  • Reactive Attributes - Auto-updating state, watch/compute methods

Navigation (1 skill)

  • Screens and Navigation - Multi-screen apps, modals, async handling

Testing (1 skill)

  • Snapshot Testing - Visual regression testing with pytest

UI/UX Design (2 skills)

  • CLI UX Principles - Human-first design, progressive discovery
  • General UI/UX - Color theory, typography, accessibility

✅ Helper Scripts

  • textual_generator.py - Generate complete apps programmatically
  • template_manager.py - Access 20+ pre-built code templates
  • skill_finder.py - Find relevant skills for your task
  • quick_reference.py - Fast syntax lookup and patterns
  • marimo_generator.py - Generate Marimo reactive notebooks (bonus!)

✅ Ready-to-Run Examples

  • Complete example applications demonstrating best practices
  • Each skill file is runnable and educational
  • Quick start demo showcasing key features

✅ Learning Resources

  • 4 structured learning paths (Beginner to Expert)
  • Task-based skill recommendations
  • Quick reference guides
  • Best practices documentation

Installation

Prerequisites

bash
# Ensure you have Python 3.8+ installed
python --version

# Install Textual and dependencies
pip install textual textual-dev

Install Plugin Dependencies

bash
# Install test dependencies (optional but recommended)
pip install pytest pytest-asyncio pytest-textual-snapshot

Verify Installation

bash
# Run the quick start example
cd examples
python quick_start.py

You should see a fully functional TUI application launching in your terminal.

For AI Agents

If using in Claude Code or similar AI environment:

python
from helpers.skill_finder import SkillFinder

# Verify plugin is loaded
finder = SkillFinder()
skills = finder.find_skills("getting started")
print(f"Found {len(skills)} skills")

Quick Start Guide

Method 1: Run Examples (Fastest)

bash
# Launch the comprehensive demo
cd examples
python quick_start.py

This runs a complete application demonstrating:

  • Widgets (buttons, inputs, tables)
  • Layout (grid, horizontal, vertical)
  • Reactivity (auto-updating values)
  • Navigation (modal dialogs)
  • CSS styling

Method 2: Learn by Doing

bash
# Start with the basics
cd skills/textual/core
python 01_getting_started.py

# Explore widgets
cd ../widgets
python 01_builtin_widgets.py

Each skill file is runnable and contains:

  1. Working examples
  2. Explanatory comments
  3. Progressive complexity
  4. Best practices

Method 3: Generate Code

python
from helpers.textual_generator import TextualGenerator, WidgetSpec

# Create a specification
widgets = [
    WidgetSpec("Button", id="submit", properties={"label": "Submit"}),
    WidgetSpec("Input", id="name", properties={"placeholder": "Name"}),
]

# Generate complete app
generator = TextualGenerator()
app_code = generator.generate_app(
    "MyFormApp",
    widgets=widgets,
    css="Button { margin: 1; }",
    bindings=[("q", "quit", "Quit")]
)

print(app_code)

Method 4: Use Templates

python
from helpers.template_manager import TemplateManager, TemplateType

manager = TemplateManager()

# Get an app template
app_code = manager.get_template(
    TemplateType.APP,
    "basic",
    app_name="MyApp"
)

# Get a reactive widget template
widget_code = manager.get_template(
    TemplateType.WIDGET,
    "reactive",
    widget_name="Counter",
    reactive_attr="count",
    default_value=0
)

Helper Scripts

1. textual_generator.py

Purpose: Generate complete Textual applications programmatically

Features:

  • Generate full apps from specifications
  • Create custom widgets with reactivity
  • Generate screens and modals
  • Create test files
  • Auto-import collection

Usage Examples:

python
from helpers.textual_generator import TextualGenerator, WidgetSpec

# Generate a complete app
generator = TextualGenerator()

widgets = [
    WidgetSpec("Header"),
    WidgetSpec("Static", id="title", properties={"content": "My App"}),
    WidgetSpec("Button", id="click", properties={"label": "Click Me"}),
    WidgetSpec("Footer"),
]

code = generator.generate_app(
    "HelloWorldApp",
    widgets=widgets,
    css="""
    Screen {
        align: center middle;
    }
    Button {
        margin: 1;
    }
    """,
    bindings=[
        ("q", "quit", "Quit"),
        ("r", "reload", "Reload"),
    ]
)

Output:

python
"""
Generated Textual Application: HelloWorldApp
"""
from textual.app import App, ComposeResult
from textual.widgets import Header, Footer, Static, Button

class HelloWorldApp(App):
    """A Textual application."""

    CSS = '''
    Screen {
        align: center middle;
    }
    Button {
        margin: 1;
    }
    '''

    BINDINGS = [
        ("q", "quit", "Quit"),
        ("r", "reload", "Reload"),
    ]

    def compose(self) -> ComposeResult:
        """Create child widgets."""
        yield Header()
        yield Static("My App", id="title")
        yield Button("Click Me", id="click")
        yield Footer()

    def on_button_pressed(self, event: Button.Pressed) -> None:
        """Handle button press."""

if __name__ == "__main__":
    app = HelloWorldApp()
    app.run()

2. template_manager.py

Purpose: Access pre-built templates for common patterns

Template Types:

TypeVariantsUse Case
APPbasic, with_css, multi_screen, with_configStarting points for applications
WIDGETbasic, reactive, with_message, containerCustom widget development
SCREENbasic, with_returnMulti-screen navigation
MODALconfirm, inputDialog boxes
TESTsnapshot, unitTesting patterns
CSSbasic, card, grid_layoutStyling examples
EVENT_HANDLERbutton, key, customEvent patterns
REACTIVEbasic, computed, validatedState management

Usage Examples:

python
from helpers.template_manager import TemplateManager, TemplateType

manager = TemplateManager()

# List all templates
templates = manager.list_templates()
print(templates)

# Get a specific template
app_template = manager.get_template(
    TemplateType.APP,
    "multi_screen",
    app_name="MyMultiScreenApp"
)

# Get a modal template
modal_template = manager.get_template(
    TemplateType.MODAL,
    "confirm",
    title="Confirm Action",
    message="Are you sure?"
)

Customizing Templates:

python
# Template with variables
widget_code = manager.get_template(
    TemplateType.WIDGET,
    "reactive",
    widget_name="CustomWidget",
    reactive_attr="value",
    default_value="default",
    widget_type="Static"  # The underlying widget
)

3. skill_finder.py

Purpose: Find relevant skills based on your task

Features:

  • Search skills by keyword
  • Get recommendations for specific tasks
  • List learning paths
  • Find examples by functionality

Usage Examples:

python
from helpers.skill_finder import SkillFinder

finder = SkillFinder()

# Search by keyword
skills = finder.find_skills("button events")
for skill in skills:
    print(f"{skill.name}: {skill.description}")

# Get task-based recommendations
task = "Create a data entry form with validation"
recommendations = finder.find_by_task(task)
print(f"Recommended skills: {[r.name for r in recommendations]}")

# Get learning path
path = finder.get_learning_path("beginner")
print(f"Learning path: {path}")

# Find by category
core_skills = finder.find_by_category("core")
widget_skills = finder.find_by_category("widgets")

Task Examples:

TaskRecommended Skills
"Create a counter"Reactive Attributes, Built-in Widgets
"Build a modal dialog"Screens and Navigation
"Style my app"CSS Styling, Layout Systems
"Test my application"Snapshot Testing
"Create custom widget"Custom Widgets, Reactive Attributes

4. quick_reference.py

Purpose: Fast lookup for syntax and patterns

Content:

  • Widget signatures
  • Event handler patterns
  • CSS snippets
  • Common patterns
  • Best practices

Usage:

python
from helpers.quick_reference import QUICK_REFERENCE, get_pattern

# Display full reference
print(QUICK_REFERENCE)

# Get specific pattern
counter_pattern = get_pattern("counter")
form_pattern = get_pattern("form")
modal_pattern = get_pattern("modal")
reactive_pattern = get_pattern("reactive")

Available Patterns:

  • counter - Reactive counter widget
  • form - Input form with validation
  • modal - Confirmation dialog
  • reactive - Reactive attributes
  • grid - Grid layout
  • event_handler - Event patterns
  • custom_widget - Custom widget structure
  • data_table - Table with data
  • tabs - Tabbed interface
  • navigation - Screen navigation

5. marimo_generator.py

Purpose: Generate Marimo reactive notebooks (bonus feature)

Features:

  • Create notebooks programmatically
  • Add cells with proper reactivity
  • Generate interactive dashboards
  • Support for widgets and layouts

Usage:

python
from helpers.marimo.marimo_generator import MarimoNotebookGenerator

gen = MarimoNotebookGenerator()

# Create basic notebook
gen.add_imports_cell(["import marimo as mo", "import pandas as pd"])
gen.add_markdown_cell("# My Analysis")
gen.add_widget_cell("slider", "threshold", start=0, stop=100)
gen.add_code_cell("filtered_data = df[df['value'] > threshold]")

gen.save("analysis.py")

Skills Guide

Navigation Structure

code
skills/
├── textual/
│   ├── core/
│   │   ├── 01_getting_started.py        # ⭐ Start here
│   │   └── 02_app_lifecycle.py
│   ├── widgets/
│   │   ├── 01_builtin_widgets.py        # Essential widgets
│   │   └── 02_custom_widgets.py
│   ├── layout/
│   │   ├── 01_layouts.py                # Layout systems
│   │   └── 02_css_styling.py            # CSS styling
│   ├── interactivity/
│   │   └── 01_events_messages.py        # Event handling
│   ├── reactivity/
│   │   └── 01_reactive_attributes.py    # State management
│   ├── navigation/
│   │   └── 01_screens.py                # Multi-screen apps
│   └── testing/
│       └── 01_snapshot_testing.py       # Testing patterns
├── marimo/
│   ├── 01_getting_started.py            # Reactive notebooks
│   ├── 02_widgets_ui.py
│   ├── 03_layouts.py
│   └── 04_working_with_marimo.py
└── design/
    ├── 01_cli_ux_principles.py          # CLI UX best practices
    └── 02_general_ui_ux.py              # General UX principles

Learning Paths

code
1. ⭐ skills/textual/core/01_getting_started.py
2. ⭐ skills/textual/widgets/01_builtin_widgets.py
3. ⭐ skills/textual/layout/01_layouts.py
4. ⭐ skills/textual/interactivity/01_events_messages.py
5. ⭐ skills/textual/layout/02_css_styling.py

Goal: Create simple, functional TUI applications

code
1. skills/textual/widgets/02_custom_widgets.py
2. skills/textual/reactivity/01_reactive_attributes.py
3. skills/textual/navigation/01_screens.py
4. skills/textual/testing/01_snapshot_testing.py

Goal: Build multi-screen, reactive applications

code
1. skills/textual/core/02_app_lifecycle.py
2. Advanced testing strategies
3. Performance optimization
4. Complex state management
5. Accessibility

Goal: Production-ready applications

code
1. ⭐ skills/design/01_cli_ux_principles.py
2. ⭐ skills/design/02_general_ui_ux.py
3. Apply to Textual apps
4. Apply to Marimo notebooks

Goal: Master UI/UX design principles

Skill Categories

File: skills/textual/core/01_getting_started.py

What you'll learn:

  • Basic app structure
  • Compose method
  • Widget basics
  • Running apps
  • Hot reload development

Key Example:

python
from textual.app import App, ComposeResult
from textual.widgets import Static

class BasicApp(App):
    def compose(self) -> ComposeResult:
        yield Static("Hello, Textual!")

if __name__ == "__main__":
    app = BasicApp()
    app.run()

File: skills/textual/widgets/01_builtin_widgets.py

What you'll learn:

  • Button (all variants)
  • Input (text, password, validation)
  • DataTable, Tree, ListView
  • Checkbox, RadioButton, Switch
  • ProgressBar, Tabs
  • Markdown, RichLog

Key Examples:

python
# Button
Button("Click Me", variant="success")

# Input
Input(placeholder="Enter name", id="name")

# DataTable
table = DataTable()
table.add_columns("Name", "Age", "City")
table.add_rows([["Alice", 30, "NYC"], ["Bob", 25, "LA"]])

File: skills/textual/layout/01_layouts.py

Layout types:

  • Vertical (default) - Stacks widgets top to bottom
  • Horizontal - Arranges widgets left to right
  • Grid - Places widgets in a grid
  • Dock - Sticks widgets to edges
  • Scrollable - Makes content scrollable

Key Example:

python
from textual.containers import Vertical, Horizontal, Container

# Vertical layout (default)
with Vertical():
    yield Button("Top")
    yield Button("Bottom")

# Horizontal layout
with Horizontal():
    yield Button("Left")
    yield Button("Right")

# Grid layout
with Container():
    # CSS will define grid
    pass

File: skills/textual/layout/02_css_styling.py

CSS features:

  • Selectors (type, ID, class)
  • Colors and palettes
  • Borders and spacing
  • Text styling
  • Responsive design
  • External stylesheets

Key Example:

python
CSS = '''
Screen {
    background: $primary;
}

Button {
    margin: 1;
    padding: 0 2;
}

#special-button {
    background: $success;
}
'''

File: skills/textual/interactivity/01_events_messages.py

Event patterns:

  • Button clicks
  • Keyboard events
  • Mouse events
  • Focus events
  • Custom messages

Key Example:

python
from textual.widgets import Button

def on_button_pressed(self, event: Button.Pressed) -> None:
    """Handle button clicks."""
    if event.button.id == "submit":
        self.process_form()

# Or using @on decorator
from textual.on import on

@on(Button.Pressed, "#submit")
def handle_submit(self) -> None:
    self.process_form()

File: skills/textual/reactivity/01_reactive_attributes.py

Reactivity features:

  • Auto-updating state
  • Watch methods
  • Compute methods
  • Validation
  • Init parameters

Key Example:

python
from textual.reactive import reactive

class CounterApp(App):
    count = reactive(0)

    def watch_count(self, new_count: int) -> None:
        """Called when count changes."""
        self.query_one("#display", Static).update(str(new_count))

    def on_button_pressed(self) -> None:
        self.count += 1

File: skills/textual/navigation/01_screens.py

Navigation patterns:

  • Define screens
  • Push/pop/switch
  • Modal screens
  • Return values
  • Async handling

Key Example:

python
from textual.screen import Screen

class SettingsScreen(Screen):
    """Settings screen."""

    def compose(self) -> ComposeResult:
        yield Button("Back", id="back")

class MainApp(App):
    async def on_button_pressed(self) -> None:
        """Show settings screen."""
        await self.push_screen_wait(SettingsScreen())

File: skills/textual/testing/01_snapshot_testing.py

Testing patterns:

  • Snapshot testing
  • User interaction simulation
  • Keyboard/mouse testing
  • Form testing

Key Example:

python
from textual.testing import press

def test_counter():
    """Test counter app."""
    app = CounterApp()
    async with app.run_test() as pilot:
        # Click increment button
        await pilot.click("#inc")
        # Check result
        assert app.query_one("#display").renderable == "1"

Common Use Cases

Skills Needed:

  1. layout/01_layouts.py - Grid layout for dashboard
  2. widgets/01_builtin_widgets.py - DataTable, ProgressBar
  3. reactivity/01_reactive_attributes.py - Auto-updates
  4. layout/02_css_styling.py - Professional styling

Approach:

python
# Use grid layout with CSS
CSS = '''
.grid-container {
    grid-size: 3 2;
    grid-gutter: 1;
}
'''

# Add widgets to grid
with Container(classes="grid-container"):
    yield DataTable(id="table")
    yield ProgressBar(id="progress")
    yield Static(id="stats")

Skills Needed:

  1. widgets/01_builtin_widgets.py - Input, Button, validation
  2. interactivity/01_events_messages.py - Form submission
  3. reactivity/01_reactive_attributes.py - Validation feedback
  4. navigation/01_screens.py - Confirmation modals

Approach:

python
# Create form widgets
yield Input(placeholder="Name", id="name")
yield Input(placeholder="Email", id="email")
yield Button("Submit", id="submit")

# Handle submission
def on_button_pressed(self, event: Button.Pressed) -> None:
    if event.button.id == "submit":
        self.submit_form()

def submit_form(self):
    name = self.query_one("#name", Input).value
    email = self.query_one("#email", Input).value
    # Validate and process

Skills Needed:

  1. widgets/01_builtin_widgets.py - Tree, ListView
  2. navigation/01_screens.py - Multi-screen navigation
  3. interactivity/01_events_messages.py - Keyboard navigation
  4. layout/01_layouts.py - Dock layout for sidebar

Integration with Textual Ecosystem

Official Textual Resources

  • Documentation: https://textual.textualize.io
  • Tutorial: https://textual.textualize.io/tutorial/
  • Widget Gallery: https://textual.textualize.io/widget_gallery/
  • GitHub: https://github.com/Textualize/textual
  • Discord: https://discord.gg/Enf6Z3qhVr

Plugin vs Official Docs

TopicThis PluginOfficial Docs
Learning PathStructured skill progressionTopic-based
ExamplesRunnable skills with explanations分散在docs中
Code GenerationBuilt-in generatorsManual coding
Templates20+ pre-built templatesCode snippets
TestingComplete testing patternsBasic examples
Best PracticesCurated patterns分散在docs中

Compatibility

This plugin is compatible with:

  • Textual 0.40+ (latest recommended)
  • Python 3.8+
  • All platforms (Linux, macOS, Windows)

Extending the Plugin

To add your own skills:

  1. Create a skill file in the appropriate category
  2. Follow the existing skill format
  3. Include runnable examples
  4. Add docstrings and comments
  5. Update SKILLS_INDEX.md

Best Practices

1. App Structure

DO:

python
from textual.app import App, ComposeResult
from textual.widgets import Static

class MyApp(App):
    """A well-structured app."""

    CSS = '''
    /* Keep CSS concise */
    '''

    def compose(self) -> ComposeResult:
        """Create child widgets."""
        yield Static("Content")

    def on_mount(self) -> None:
        """Initialize after mounting."""
        self.log("App mounted")

    def on_unmount(self) -> None:
        """Clean up before unmounting."""
        self.log("App unmounting")

DON'T:

python
# Don't put logic in compose()
def compose(self) -> ComposeResult:
    # This should only yield widgets!
    data = fetch_data()  # ❌
    yield create_widget_from_data(data)  # ❌

2. Widget IDs and Classes

DO:

python
# Use IDs for unique widgets
yield Button("Click", id="submit-button")

# Use classes for groups
yield Button("Cancel", classes="secondary-button")
yield Button("Save", classes="primary-button")

DON'T:

python
# Don't query by content
self.query("Button:disabled")  # ❌ Fragile

3. CSS Organization

DO:

python
# Use external CSS files for large projects
class MyApp(App):
    CSS_PATH = "styles.tcss"

# Or use a separate CSS constant
CSS = '''
/* Group related styles */
.header {
    background: $primary;
}

.content {
    padding: 1;
}
'''

DON'T:

python
# Don't inline styles in compose()
with Container(style="background: red;"):  # ❌
    pass

4. Event Handling

DO:

python
from textual.on import on

@on(Button.Pressed, "#submit")
def handle_submit(self, event: Button.Pressed) -> None:
    """Handle submit button."""
    self.process_form()

# Or use named methods
def on_button_pressed(self, event: Button.Pressed) -> None:
    """Handle any button press."""
    if event.button.id == "submit":
        self.process_form()

DON'T:

python
# Don't use complex conditionals
def on_key(self, event) -> None:
    if event.key == "a" and self.state == "editing":  # ❌
        pass

5. Reactive Attributes

DO:

python
from textual.reactive import reactive

class CounterApp(App):
    count = reactive(0)

    def watch_count(self, new_count: int) -> None:
        """Auto-update when count changes."""
        self.query_one("#display", Static).update(str(new_count))

DON'T:

python
# Don't manually update without reactivity
def increment(self):
    self.count += 1
    self.update_display()  # ❌ Manual update

6. Testing

DO:

python
from textual.testing import press, click

async def test_form_submission():
    app = FormApp()
    async with app.run_test() as pilot:
        # Simulate user interaction
        await pilot.click("#submit")
        # Verify state
        assert app.submitted

DON'T:

python
# Don't test without running the app
def test_form():
    app = FormApp()
    assert app.is_valid()  # ❌ No event loop

7. Error Handling

DO:

python
from textual.widgets import Static

def on_button_pressed(self) -> None:
    try:
        self.process_data()
    except ValueError as e:
        self.notify(f"Error: {e}", severity="error")
        self.query_one("#error", Static).update(str(e))

DON'T:

python
# Don't silently ignore errors
def on_button_pressed(self) -> None:
    self.process_data()  # ❌ No error handling

8. Performance

DO:

python
from textual.workers import worker

@worker
async def fetch_data(self):
    """Use workers for long operations."""
    data = await self.api.get_data()
    self.data = data

def on_mount(self):
    self.run_worker(self.fetch_data)

DON'T:

python
# Don't block the UI
def on_mount(self):
    # This will freeze the app!
    data = self.blocking_api.get_data()  # ❌
    self.data = data

Troubleshooting

Issue: Import Errors

Symptom:

code
ModuleNotFoundError: No module named 'textual'

Solution:

bash
# Install Textual
pip install textual textual-dev

# Verify installation
python -c "import textual; print(textual.__version__)"

Issue: Widget Not Updating

Symptom: UI doesn't reflect state changes

Solution:

  1. Check if you're using reactive attributes
python
# ✅ Use reactive attributes
count = reactive(0)

def watch_count(self, new_count):
    self.query_one("#display").update(str(new_count))
  1. Verify event handlers are firing
python
def on_button_pressed(self, event):
    self.log(f"Button pressed: {event.button.id}")  # Debug

Issue: Layout Broken

Symptom: Widgets not positioned correctly

Solution:

  1. Check CSS grid settings
python
CSS = '''
Container {
    grid-size: 2 2;  /* 2 columns, 2 rows */
}
'''
  1. Verify container hierarchy
python
# ✅ Correct nesting
with Container():
    with Vertical():
        yield Button("Top")

# ❌ Incorrect
yield Container(Vertical(Button("Top")))

Issue: Events Not Firing

Symptom: Event handlers not called

Solution:

  1. Check widget IDs
python
# Ensure IDs match
yield Button("Click", id="my-button")

def on_button_pressed(self, event: Button.Pressed):
    if event.button.id == "my-button":  # ✅ Match
        pass
  1. Use @on decorator for clarity
python
from textual.on import on

@on(Button.Pressed, "#my-button")
def handle_click(self) -> None:
    """Explicit event handler."""
    pass

Issue: Can't Run Examples

Symptom:

code
Permission denied: examples/quick_start.py

Solution:

bash
# Make executable (optional)
chmod +x examples/*.py

# Run with Python
python examples/quick_start.py

Issue: App Crashes on Exit

Symptom: App doesn't shut down gracefully

Solution:

  1. Add cleanup handlers
python
def on_unmount(self) -> None:
    """Clean up resources."""
    self.log("App closing")

# Or use exit hooks
def on_exit(self) -> None:
    """Handle exit."""
    pass

Issue: Slow Performance

Symptom: UI is sluggish or unresponsive

Solution:

  1. Use workers for long operations
python
from textual.workers import worker

@worker
async def long_task(self):
    result = await self.do_work()
    return result
  1. Batch DOM updates
python
def update_multiple_widgets(self):
    with self.batch_update():
        self.query_one("#w1").update("New 1")
        self.query_one("#w2").update("New 2")
        self.query_one("#w3").update("New 3")

Issue: CSS Not Loading

Symptom: Styles don't apply

Solution:

  1. Check CSS_PATH
python
class MyApp(App):
    CSS_PATH = "styles.tcss"  # File must exist
  1. Verify CSS syntax
python
CSS = '''
Button {  /* ✅ Correct */
    margin: 1;
}
'''

Issue: Type Errors

Symptom: Type checker reports errors

Solution:

  1. Add type hints
python
from textual.widgets import Button
from textual.app import ComposeResult

def compose(self) -> ComposeResult:
    """Return type hint."""
    yield Button("Click")

def on_button_pressed(self, event: Button.Pressed) -> None:
    """Event type hint."""
    pass

FAQ

Q: How is this plugin different from official Textual documentation?

A: This plugin provides:

  • Structured learning paths instead of topic-based browsing
  • Runnable examples embedded in each skill
  • Code generators for rapid prototyping
  • Pre-built templates for common patterns
  • Testing frameworks with ready-to-use examples
  • UI/UX best practices specific to TUIs

Q: Do I need to know Python async/await?

A: Basic understanding helps, but isn't required for simple apps. The plugin includes:

  • Sync examples for beginners
  • Async patterns in intermediate skills
  • Detailed explanations of async concepts

Q: Can I build web apps with this plugin?

A: No, this plugin is specifically for Textual TUI applications (terminal-based). For web apps, consider:

  • Textual Web - Run Textual in browsers
  • Traditional web frameworks (Flask, Django, FastAPI)

Q: Is this plugin suitable for production use?

A: Yes! Textual itself is production-ready and used by:

  • AWS CLI tools
  • Docker CLI
  • Poetry
  • And many more

This plugin includes production best practices for:

  • Error handling
  • Performance optimization
  • Testing strategies
  • Accessibility

Q: How do I contribute skills to this plugin?

A:

  1. Follow the existing skill format
  2. Create runnable examples
  3. Add comprehensive docstrings
  4. Include test cases (optional)
  5. Update SKILLS_INDEX.md
  6. Submit a pull request

Q: Can I use this with other terminal frameworks?

A: The skills are Textual-specific, but many concepts transfer:

  • Rich (text formatting)
  • Prompt Toolkit (CLI apps)
  • Urwid (TUI framework)

However, the code generators only produce Textual code.

Q: What's the learning curve?

A: Based on user feedback:

  • Beginner path: 2-4 hours (basic TUIs)
  • Intermediate path: 4-6 hours (multi-screen apps)
  • Advanced path: 6-10 hours (production apps)

Start with the examples to get immediate results!

Q: Does this work on Windows/macOS/Linux?

A: Yes! Textual works on all platforms:

  • Linux: Full support
  • macOS: Full support
  • Windows: Full support (requires Windows Terminal for best experience)

Q: How do I style my TUI?

A: Textual uses TCSS (Textual CSS):

python
CSS = '''
Button {
    background: $primary;
    color: $text;
    margin: 1;
}
'''

The plugin includes comprehensive CSS guides in skills/textual/layout/02_css_styling.py.

Q: Can I create animations?

A: Yes! Textual supports:

  • CSS transitions
  • Keyframe animations
  • Timer-based animations

See the CSS styling guide for examples.

Q: How do I handle multiple screens?

A: Use the Screen API:

python
from textual.screen import Screen

class SettingsScreen(Screen):
    pass

class MainApp(App):
    async def show_settings(self):
        await self.push_screen_wait(SettingsScreen())

Full examples in skills/textual/navigation/01_screens.py.

Q: What's the difference between Textual and curses?

A:

FeatureTextualPython Curses
APIModern, PythonicLow-level
StylingRich CSS supportLimited
WidgetsBuilt-in componentsManual coding
ReactivityBuilt-in reactive attributesManual updates
TestingSnapshot testingManual testing
DebuggingDevTools, consolePrint statements

Q: Can I integrate with databases?

A: Yes! Standard Python libraries work:

python
import sqlite3
import asyncpg
import sqlalchemy

# Use workers for DB operations
@worker
async def fetch_data(self):
    async with sqlite3.connect('data.db') as conn:
        cursor = conn.cursor()
        cursor.execute("SELECT * FROM users")
        return cursor.fetchall()

Q: How do I create custom widgets?

A:

python
from textual.widgets import Static
from textual.reactive import reactive

class CustomWidget(Static):
    """A custom widget."""

    DEFAULT_CSS = '''
    CustomWidget {
        background: $primary;
        color: $text;
    }
    '''

    value = reactive(0)

    def compose(self) -> ComposeResult:
        yield Static("Custom content")

    def watch_value(self, new_value):
        """Auto-update when value changes."""
        self.update(str(new_value))

Full guide in skills/textual/widgets/02_custom_widgets.py.


Resources

Official Textual

  • Documentation: https://textual.textualize.io
  • Tutorial: https://textual.textualize.io/tutorial/
  • Widget Gallery: https://textual.textualize.io/widget_gallery/
  • GitHub: https://github.com/Textualize/textual
  • Discord: https://discord.gg/Enf6Z3qhVr

Community

  • GitHub Discussions: https://github.com/Textualize/textual/discussions
  • Stack Overflow: Use "textual" tag
  • Reddit: r/Python (Textual posts)

Tools & Extensions

  • Textual Web: Run TUIs in browsers
  • Textual DevTools: Debug and inspect
  • Rich: Text formatting library (used by Textual)
  • Typing: Type annotations for Python

Example Projects

  • Textual Docs: https://github.com/Textualize/textual/tree/main/examples
  • Textual Apps: https://github.com/Textualize/textual-apps

Learning Resources

  • Real Python Textual Tutorial: https://realpython.com/python-textual-tutorial/
  • Textual Blog: https://www.textualize.io/blog/
  • YouTube: Search "Textual Python TUI"

Next Steps

  1. Run the examples

``bash cd examples python quick_start.py ``

  1. Choose your learning path

- Beginner: Start with skills/textual/core/01_getting_started.py - Intermediate: Try skills/textual/widgets/02_custom_widgets.py - Expert: Explore skills/textual/testing/01_snapshot_testing.py

  1. Use helper scripts

- Generate code: helpers/textual_generator.py - Get templates: helpers/template_manager.py - Find skills: helpers/skill_finder.py

  1. Join the community

- Discord: https://discord.gg/Enf6Z3qhVr - GitHub: https://github.com/Textualize/textual

  1. Build something amazing!

- Create your first TUI app - Share it with the community - Contribute back to Textual


Happy Building! 🎉

Create beautiful, interactive terminal applications with Textual and this comprehensive plugin!

Install & Usage

1
Create the skills directory
mkdir -p .claude/skills
2
Download the skill file
mkdir -p .claude/skills && curl -o .claude/skills/general-ui-ux.md https://raw.githubusercontent.com/Jrakru/marketplace_UI/main/SKILL.md
3
Invoke in Claude Code
/general-ui-ux
View source on GitHub
designuiuxaccessibilitywcagtypography

Frequently Asked Questions

What is general-ui-ux?

UI/UX design principles: color theory, typography, accessibility, layout, WCAG compliance

How to install general-ui-ux?

To install general-ui-ux, create the .claude/skills directory in your project, then run the curl command to download the skill file. Once installed, invoke it in Claude Code with /general-ui-ux.

What is general-ui-ux best for?

general-ui-ux is a community categorized under Documentation. It is designed for: design, ui, ux, accessibility, wcag, typography. Created by Jrakru.