dialog with property

This commit is contained in:
2025-09-23 05:26:18 +02:00
parent 1012cf3d73
commit 02d7513b77
4 changed files with 116 additions and 51 deletions

View File

@@ -1,10 +1,9 @@
from .base import AsyncElement
from .elements import (AsyncColumn, AsyncRow, AsyncCard, AsyncScrollArea)
from .elements import (AsyncColumn, AsyncRow, AsyncCard)
__all__ = [
'AsyncElement',
'AsyncColumn',
'AsyncRow',
'AsyncCard',
'AsyncScrollArea'
]

View File

@@ -85,4 +85,4 @@ class AsyncElement(ABC, Generic[T]):
def __exit__(self, *args):
"""Support context manager protocol"""
return self._element.__exit__(*args)
return self._element.__exit__(*args)

View File

@@ -1,19 +1,35 @@
from abc import ABC, abstractmethod
from typing import Self, Any
from typing import Self, Any, Optional
from nicegui import ui
class AsyncColumn(ui.column, ABC):
"""Async column that inherits from ui.column for perfect typing"""
_dialog: Optional[ui.dialog] = None
_dialog_card: Optional[ui.card] = None
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self._dialog_size: str | None = None
@abstractmethod
async def build(self, *args, **kwargs) -> None:
"""Build/setup the element - must be implemented by subclasses"""
...
@property
def dialog_size(self) -> str | None:
"""Get or set the dialog size (e.g., 'w-1/2', 'w-96', 'max-w-4xl')"""
return self._dialog_size
@dialog_size.setter
def dialog_size(self, value: str | None) -> None:
"""Set the dialog size - applies to the dialog if it exists"""
self._dialog_size = value
if self._dialog_card:
self._dialog_card.classes(value)
@classmethod
async def create(cls, *args, **kwargs) -> Self:
"""Factory method to create and build a column instance"""
@@ -38,13 +54,19 @@ class AsyncColumn(ui.column, ABC):
dialog.open()
# Build the element inside the dialog with a card
with dialog, ui.card():
instance = cls()
with dialog:
with ui.card().style('max-width: none;') as dialog_card:
instance = cls()
# Store dialog reference for potential use in build()
instance._dialog = dialog # pyright: ignore[reportAttributeAccessIssue]
# Store dialog reference for potential use in build()
instance._dialog = dialog # pyright: ignore[reportAttributeAccessIssue]
instance._dialog_card = dialog_card
await instance.build(*args, **kwargs)
await instance.build(*args, **kwargs)
# Apply dialog size if set
if hasattr(instance, '_dialog_size') and instance._dialog_size:
dialog.classes(add=instance._dialog_size)
# Await the dialog result
result = await dialog
@@ -58,14 +80,30 @@ class AsyncColumn(ui.column, ABC):
class AsyncRow(ui.row, ABC):
"""Async row that inherits from ui.row for perfect typing"""
_dialog: Optional[ui.dialog] = None
_dialog_card: Optional[ui.card] = None
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self._dialog_size: str | None = None
@abstractmethod
async def build(self, *args, **kwargs) -> None:
"""Build/setup the element - must be implemented by subclasses"""
...
@property
def dialog_size(self) -> str | None:
"""Get or set the dialog size (e.g., 'w-1/2', 'w-96', 'max-w-4xl')"""
return self._dialog_size
@dialog_size.setter
def dialog_size(self, value: str | None) -> None:
"""Set the dialog size - applies to the dialog if it exists"""
self._dialog_size = value
if self._dialog_card:
self._dialog_card.classes(value)
@classmethod
async def create(cls, *args, **kwargs) -> Self:
"""Factory method to create and build a column instance"""
@@ -79,10 +117,16 @@ class AsyncRow(ui.row, ABC):
dialog = ui.dialog()
dialog.open()
with dialog, ui.card():
instance = cls()
instance._dialog = dialog # pyright: ignore[reportAttributeAccessIssue]
await instance.build(*args, **kwargs)
with dialog:
with ui.card().style('max-width: none;') as dialog_card:
instance = cls()
instance._dialog = dialog # pyright: ignore[reportAttributeAccessIssue]
instance._dialog_card = dialog_card
await instance.build(*args, **kwargs)
# Apply dialog size if set
if hasattr(instance, '_dialog_size') and instance._dialog_size:
dialog.classes(instance._dialog_size)
result = await dialog
dialog.clear()
@@ -92,14 +136,30 @@ class AsyncRow(ui.row, ABC):
class AsyncCard(ui.card, ABC):
"""Async card that inherits from ui.card for perfect typing"""
_dialog: Optional[ui.dialog] = None
_dialog_card: Optional[ui.card] = None
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self._dialog_size: str | None = None
@abstractmethod
async def build(self, *args, **kwargs) -> None:
"""Build/setup the element - must be implemented by subclasses"""
...
@property
def dialog_size(self) -> str | None:
"""Get or set the dialog size (e.g., 'w-1/2', 'w-96', 'max-w-4xl')"""
return self._dialog_size
@dialog_size.setter
def dialog_size(self, value: str | None) -> None:
"""Set the dialog size - applies to the dialog if it exists"""
self._dialog_size = value
if self._dialog_card:
self._dialog_card.classes(value)
@classmethod
async def create(cls, *args, **kwargs) -> Self:
"""Factory method to create and build a card instance"""
@@ -113,44 +173,16 @@ class AsyncCard(ui.card, ABC):
dialog = ui.dialog()
dialog.open()
with dialog, ui.card():
instance = cls()
instance._dialog = dialog # pyright: ignore[reportAttributeAccessIssue]
await instance.build(*args, **kwargs)
result = await dialog
dialog.clear()
return result
class AsyncScrollArea(ui.scroll_area, ABC):
"""Async ScrollArea that inherits from ui.scrol_area for perfect typing"""
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
@abstractmethod
async def build(self, *args, **kwargs) -> None:
"""Build/setup the element - must be implemented by subclasses"""
...
@classmethod
async def create(cls, *args, **kwargs) -> Self:
"""Factory method to create and build a column instance"""
instance = cls()
await instance.build(*args, **kwargs)
return instance
@classmethod
async def as_dialog(cls, *args, **kwargs) -> Any:
"""Create element inside a dialog and await its result"""
dialog = ui.dialog()
dialog.open()
with dialog, ui.card():
instance = cls()
instance._dialog = dialog # pyright: ignore[reportAttributeAccessIssue]
await instance.build(*args, **kwargs)
with dialog:
with ui.card().style('max-width: none;') as dialog_card:
instance = cls()
instance._dialog = dialog # pyright: ignore[reportAttributeAccessIssue]
instance._dialog_card = dialog_card
await instance.build(*args, **kwargs)
# Apply dialog size if set
if hasattr(instance, '_dialog_size') and instance._dialog_size:
dialog.classes(instance._dialog_size)
result = await dialog
dialog.clear()