dialog with property
This commit is contained in:
@@ -10,6 +10,9 @@ class ConfirmDialog(AsyncColumn):
|
|||||||
|
|
||||||
async def build(self, message: str, title: str = "Confirm"):
|
async def build(self, message: str, title: str = "Confirm"):
|
||||||
"""Build the dialog content"""
|
"""Build the dialog content"""
|
||||||
|
# Set dialog size using the property
|
||||||
|
self.dialog_size = 'w-96'
|
||||||
|
|
||||||
ui.label(title).classes('text-h6')
|
ui.label(title).classes('text-h6')
|
||||||
ui.label(message)
|
ui.label(message)
|
||||||
ui.space()
|
ui.space()
|
||||||
@@ -24,6 +27,10 @@ class FormDialog(AsyncColumn):
|
|||||||
|
|
||||||
async def build(self, title: str = "Enter Information"):
|
async def build(self, title: str = "Enter Information"):
|
||||||
"""Build the form dialog"""
|
"""Build the form dialog"""
|
||||||
|
# Set a wider dialog size for the form
|
||||||
|
if hasattr(self, '_dialog'):
|
||||||
|
self.dialog_size = 'w-1/2'
|
||||||
|
|
||||||
ui.label(title).classes('text-h6')
|
ui.label(title).classes('text-h6')
|
||||||
|
|
||||||
# Create input fields
|
# Create input fields
|
||||||
@@ -93,6 +100,9 @@ async def main():
|
|||||||
async def show_inline_dialog():
|
async def show_inline_dialog():
|
||||||
class QuickDialog(AsyncColumn):
|
class QuickDialog(AsyncColumn):
|
||||||
async def build(self):
|
async def build(self):
|
||||||
|
# Smaller dialog size for simple questions
|
||||||
|
self.dialog_size = 'w-72'
|
||||||
|
|
||||||
ui.label('Quick Question').classes('text-h6')
|
ui.label('Quick Question').classes('text-h6')
|
||||||
ui.label('Do you like this feature?')
|
ui.label('Do you like this feature?')
|
||||||
|
|
||||||
@@ -106,6 +116,30 @@ async def main():
|
|||||||
|
|
||||||
ui.button('Show Quick Dialog', on_click=show_inline_dialog)
|
ui.button('Show Quick Dialog', on_click=show_inline_dialog)
|
||||||
|
|
||||||
|
# Example with dynamic sizing based on content
|
||||||
|
async def show_dynamic_dialog():
|
||||||
|
class DynamicDialog(AsyncColumn):
|
||||||
|
async def build(self, items_count: int = 3):
|
||||||
|
# Adjust size based on content
|
||||||
|
if items_count <= 3:
|
||||||
|
self.dialog_size = 'w-96'
|
||||||
|
else:
|
||||||
|
self.dialog_size = 'w-1/2'
|
||||||
|
|
||||||
|
ui.label(f'Dynamic Dialog with {items_count} items').classes('text-h6')
|
||||||
|
|
||||||
|
for i in range(items_count):
|
||||||
|
ui.label(f'Item {i + 1}: This is some content for item {i + 1}')
|
||||||
|
|
||||||
|
ui.space()
|
||||||
|
ui.button('Close', on_click=lambda: self._dialog.submit(f'Closed with {items_count} items'))
|
||||||
|
|
||||||
|
for count in [2, 5]:
|
||||||
|
result = await DynamicDialog.as_dialog(items_count=count)
|
||||||
|
ui.notify(f'Result: {result}')
|
||||||
|
|
||||||
|
ui.button('Show Dynamic Dialogs', on_click=show_dynamic_dialog)
|
||||||
|
|
||||||
|
|
||||||
if __name__ in {"__main__", "__mp_main__"}:
|
if __name__ in {"__main__", "__mp_main__"}:
|
||||||
ui.run(title='Async Dialog Example', port=8085)
|
ui.run(title='Async Dialog Example', port=8085)
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
from .base import AsyncElement
|
from .base import AsyncElement
|
||||||
from .elements import (AsyncColumn, AsyncRow, AsyncCard, AsyncScrollArea)
|
from .elements import (AsyncColumn, AsyncRow, AsyncCard)
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
'AsyncElement',
|
'AsyncElement',
|
||||||
'AsyncColumn',
|
'AsyncColumn',
|
||||||
'AsyncRow',
|
'AsyncRow',
|
||||||
'AsyncCard',
|
'AsyncCard',
|
||||||
'AsyncScrollArea'
|
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -85,4 +85,4 @@ class AsyncElement(ABC, Generic[T]):
|
|||||||
|
|
||||||
def __exit__(self, *args):
|
def __exit__(self, *args):
|
||||||
"""Support context manager protocol"""
|
"""Support context manager protocol"""
|
||||||
return self._element.__exit__(*args)
|
return self._element.__exit__(*args)
|
||||||
|
|||||||
@@ -1,19 +1,35 @@
|
|||||||
from abc import ABC, abstractmethod
|
from abc import ABC, abstractmethod
|
||||||
from typing import Self, Any
|
from typing import Self, Any, Optional
|
||||||
from nicegui import ui
|
from nicegui import ui
|
||||||
|
|
||||||
|
|
||||||
class AsyncColumn(ui.column, ABC):
|
class AsyncColumn(ui.column, ABC):
|
||||||
"""Async column that inherits from ui.column for perfect typing"""
|
"""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):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
self._dialog_size: str | None = None
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
async def build(self, *args, **kwargs) -> None:
|
async def build(self, *args, **kwargs) -> None:
|
||||||
"""Build/setup the element - must be implemented by subclasses"""
|
"""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
|
@classmethod
|
||||||
async def create(cls, *args, **kwargs) -> Self:
|
async def create(cls, *args, **kwargs) -> Self:
|
||||||
"""Factory method to create and build a column instance"""
|
"""Factory method to create and build a column instance"""
|
||||||
@@ -38,13 +54,19 @@ class AsyncColumn(ui.column, ABC):
|
|||||||
dialog.open()
|
dialog.open()
|
||||||
|
|
||||||
# Build the element inside the dialog with a card
|
# Build the element inside the dialog with a card
|
||||||
with dialog, ui.card():
|
with dialog:
|
||||||
instance = cls()
|
with ui.card().style('max-width: none;') as dialog_card:
|
||||||
|
instance = cls()
|
||||||
|
|
||||||
# Store dialog reference for potential use in build()
|
# Store dialog reference for potential use in build()
|
||||||
instance._dialog = dialog # pyright: ignore[reportAttributeAccessIssue]
|
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
|
# Await the dialog result
|
||||||
result = await dialog
|
result = await dialog
|
||||||
@@ -58,14 +80,30 @@ class AsyncColumn(ui.column, ABC):
|
|||||||
class AsyncRow(ui.row, ABC):
|
class AsyncRow(ui.row, ABC):
|
||||||
"""Async row that inherits from ui.row for perfect typing"""
|
"""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):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
self._dialog_size: str | None = None
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
async def build(self, *args, **kwargs) -> None:
|
async def build(self, *args, **kwargs) -> None:
|
||||||
"""Build/setup the element - must be implemented by subclasses"""
|
"""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
|
@classmethod
|
||||||
async def create(cls, *args, **kwargs) -> Self:
|
async def create(cls, *args, **kwargs) -> Self:
|
||||||
"""Factory method to create and build a column instance"""
|
"""Factory method to create and build a column instance"""
|
||||||
@@ -79,10 +117,16 @@ class AsyncRow(ui.row, ABC):
|
|||||||
dialog = ui.dialog()
|
dialog = ui.dialog()
|
||||||
dialog.open()
|
dialog.open()
|
||||||
|
|
||||||
with dialog, ui.card():
|
with dialog:
|
||||||
instance = cls()
|
with ui.card().style('max-width: none;') as dialog_card:
|
||||||
instance._dialog = dialog # pyright: ignore[reportAttributeAccessIssue]
|
instance = cls()
|
||||||
await instance.build(*args, **kwargs)
|
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
|
result = await dialog
|
||||||
dialog.clear()
|
dialog.clear()
|
||||||
@@ -92,14 +136,30 @@ class AsyncRow(ui.row, ABC):
|
|||||||
class AsyncCard(ui.card, ABC):
|
class AsyncCard(ui.card, ABC):
|
||||||
"""Async card that inherits from ui.card for perfect typing"""
|
"""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):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
self._dialog_size: str | None = None
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
async def build(self, *args, **kwargs) -> None:
|
async def build(self, *args, **kwargs) -> None:
|
||||||
"""Build/setup the element - must be implemented by subclasses"""
|
"""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
|
@classmethod
|
||||||
async def create(cls, *args, **kwargs) -> Self:
|
async def create(cls, *args, **kwargs) -> Self:
|
||||||
"""Factory method to create and build a card instance"""
|
"""Factory method to create and build a card instance"""
|
||||||
@@ -113,44 +173,16 @@ class AsyncCard(ui.card, ABC):
|
|||||||
dialog = ui.dialog()
|
dialog = ui.dialog()
|
||||||
dialog.open()
|
dialog.open()
|
||||||
|
|
||||||
with dialog, ui.card():
|
with dialog:
|
||||||
instance = cls()
|
with ui.card().style('max-width: none;') as dialog_card:
|
||||||
instance._dialog = dialog # pyright: ignore[reportAttributeAccessIssue]
|
instance = cls()
|
||||||
await instance.build(*args, **kwargs)
|
instance._dialog = dialog # pyright: ignore[reportAttributeAccessIssue]
|
||||||
|
instance._dialog_card = dialog_card
|
||||||
result = await dialog
|
await instance.build(*args, **kwargs)
|
||||||
dialog.clear()
|
|
||||||
return result
|
# Apply dialog size if set
|
||||||
|
if hasattr(instance, '_dialog_size') and instance._dialog_size:
|
||||||
|
dialog.classes(instance._dialog_size)
|
||||||
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)
|
|
||||||
|
|
||||||
result = await dialog
|
result = await dialog
|
||||||
dialog.clear()
|
dialog.clear()
|
||||||
|
|||||||
Reference in New Issue
Block a user