# 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