Files
NiceGUIEx/README.md
2025-09-27 13:07:15 +02:00

187 lines
4.6 KiB
Markdown

# NiceGUI Extensions (niceguiex)
Extensions for NiceGUI including async elements with proper typing support and more. Create powerful UI components while maintaining full type hints and IDE support.
## Installation
Install directly from GitHub using uv or pip:
### Using uv
```bash
uv add git+https://git.project-insanity.de/gmarth/NiceGUIEx.git
```
#### Using pip
```
pip install git+https://git.project-insanity.de/gmarth/NiceGUIEx.git
```
## Usage
### Basic Example
```python
from nicegui import ui
from niceguiex.async_elements import AsyncElement, AsyncColumn, AsyncCard
# Create an async element that fetches data
class UserCard(AsyncElement[ui.column]):
async def build(self, user_id: int) -> None:
# Simulate async data fetching
user_data = await fetch_user(user_id)
with self:
with ui.card():
ui.label(user_data['name'])
ui.label(user_data['email'])
# Use in your NiceGUI app
@ui.page('/')
async def main():
# Creates the element and returns a properly typed ui.column
user_card = await UserCard.create(user_id=123)
user_card.classes('w-full') # Full IDE support!
```
### Using Inheritance
For even better typing, inherit from specific element types:
```python
class DataTable(AsyncColumn):
async def build(self, api_endpoint: str) -> None:
# Fetch data asynchronously
data = await fetch_data(api_endpoint)
with self:
ui.table(columns=data['columns'], rows=data['rows'])
# Usage
data_table = await DataTable.create(api_endpoint="/api/users")
# data_table is fully typed as DataTable/AsyncColumn
```
## Features
### Async Elements Module (`niceguiex.async_elements`)
- **Async Initialization**: Build UI elements that require async operations (API calls, database queries, etc.)
- **Full Type Support**: Maintains complete typing for IDE autocomplete and type checking
- **Context Manager Support**: Works seamlessly with NiceGUI's context manager pattern
- **Multiple Approaches**: Choose between generic `AsyncElement` or inherit from specific element types
- **Pre-built Async Components**: `AsyncColumn`, `AsyncRow`, `AsyncCard`, `AsyncDialog`, `AsyncTabs`, `AsyncScrollArea`, and more
### Additional Components
#### FileDrop
Drag-and-drop file upload component with visual feedback:
```python
from niceguiex.components import FileDrop
async def handle_upload(name: str, file_type: str, content: bytes):
"""Handle uploaded file"""
print(f"File: {name}, Type: {file_type}, Size: {len(content)} bytes")
# Process the file content
with open(f'uploads/{name}', 'wb') as f:
f.write(content)
# Basic usage
FileDrop(
on_upload=handle_upload,
multiple=False,
accept='.pdf,.txt,.docx'
)
# Multiple files
FileDrop(
on_upload=handle_upload,
multiple=True,
accept='image/*'
)
```
Features:
- Visual drag-over feedback
- Click to browse or drag & drop
- Customizable file type filtering
- Async callback support
#### ImageDrop
Specialized file drop for images that returns PIL Image objects:
```python
from niceguiex.components import ImageDrop
from PIL import Image
def handle_image(img: Image.Image):
# Receives PIL Image object directly
print(f"Image size: {img.size}")
print(f"Image format: {img.format}")
# Process image with PIL methods
img.thumbnail((200, 200))
img.save('thumbnail.jpg')
def handle_multiple_images(images: List[Image.Image]):
# For multiple images, receives list of PIL Images
for img in images:
print(f"Processing {img.size[0]}x{img.size[1]} image")
ImageDrop(
on_upload=handle_image,
multiple=False,
max_size=15 # 15MB limit
)
```
#### AutoScrollArea
Automatically scrolling area that follows content as it's added:
```python
from niceguiex.async_elements import AsyncScrollArea
class AutoScrollArea(AsyncScrollArea):
async def build(self) -> None:
# Automatically scrolls to bottom when content is added
pass
# Usage
auto_scroll = await AutoScrollArea.create()
with auto_scroll:
for message in messages:
ui.label(message)
```
#### ChatInput
Enhanced textarea for chat interfaces with Enter to send, Shift+Enter for new line:
```python
from niceguiex.components import ChatInput
async def handle_message(message: str):
print(f"User sent: {message}")
chat = ChatInput(
placeholder='Type your message...',
on_enter=handle_message
).classes('w-full')
```
### Coming Soon
- Additional UI component extensions
- Helper utilities for common patterns
- Enhanced form handling
- And more!
## Development
Run the example:
```bash
python example.py
```
## License
MIT