186 lines
4.7 KiB
Markdown
186 lines
4.7 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 customizable styling:
|
|
|
|
```python
|
|
from niceguiex.components import FileDrop
|
|
|
|
def handle_files(files: List[Dict[str, Any]]):
|
|
# For multiple files
|
|
for file in files:
|
|
print(f"File: {file['name']}, Size: {file['size']}")
|
|
# Access content with file['content']
|
|
|
|
def handle_single_file(file: Dict[str, Any]):
|
|
# For single file mode, returns dict directly
|
|
print(f"Uploaded: {file['name']}")
|
|
# Use file['path'] if return_content=False for large files
|
|
|
|
# Multiple files
|
|
FileDrop(
|
|
on_upload=handle_files,
|
|
multiple=True,
|
|
accept='.pdf,.txt,.docx',
|
|
max_size=5 # 5MB limit
|
|
)
|
|
|
|
# Single file with temp path (for large files)
|
|
FileDrop(
|
|
on_upload=handle_single_file,
|
|
multiple=False,
|
|
return_content=False # Returns temp file path instead of content
|
|
)
|
|
```
|
|
|
|
#### 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 |