fixed dialog classmethod
This commit is contained in:
@@ -2,15 +2,14 @@
|
|||||||
"""Example demonstrating the AsyncElement.as_dialog() method"""
|
"""Example demonstrating the AsyncElement.as_dialog() method"""
|
||||||
|
|
||||||
from nicegui import ui
|
from nicegui import ui
|
||||||
from src.niceguiex.async_elements import AsyncElement
|
from src.niceguiex.async_elements import AsyncColumn
|
||||||
|
|
||||||
|
|
||||||
class ConfirmDialog(AsyncElement[ui.column]):
|
class ConfirmDialog(AsyncColumn):
|
||||||
"""A confirmation dialog that can be awaited for a result"""
|
"""A confirmation dialog that can be awaited for a result"""
|
||||||
|
|
||||||
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"""
|
||||||
with self._element:
|
|
||||||
ui.label(title).classes('text-h6')
|
ui.label(title).classes('text-h6')
|
||||||
ui.label(message)
|
ui.label(message)
|
||||||
ui.space()
|
ui.space()
|
||||||
@@ -20,11 +19,13 @@ class ConfirmDialog(AsyncElement[ui.column]):
|
|||||||
ui.button('OK', on_click=lambda: self._dialog.submit(True)).props('color=primary')
|
ui.button('OK', on_click=lambda: self._dialog.submit(True)).props('color=primary')
|
||||||
|
|
||||||
|
|
||||||
class FormDialog(AsyncElement[ui.column]):
|
class FormDialog(AsyncColumn):
|
||||||
"""A form dialog that collects user input"""
|
"""A form dialog that collects user input"""
|
||||||
|
|
||||||
async def build(self, title: str = "Enter Information"):
|
async def build(self, title: str = "Enter Information"):
|
||||||
"""Build the form dialog"""
|
"""Build the form dialog"""
|
||||||
|
ui.label(title).classes('text-h6')
|
||||||
|
|
||||||
# Create input fields
|
# Create input fields
|
||||||
name_input = ui.input('Name', placeholder='Enter your name')
|
name_input = ui.input('Name', placeholder='Enter your name')
|
||||||
email_input = ui.input('Email', placeholder='Enter your email')
|
email_input = ui.input('Email', placeholder='Enter your email')
|
||||||
@@ -32,11 +33,16 @@ class FormDialog(AsyncElement[ui.column]):
|
|||||||
ui.space()
|
ui.space()
|
||||||
|
|
||||||
with ui.row().classes('full-width justify-end'):
|
with ui.row().classes('full-width justify-end'):
|
||||||
|
# Check if we're in dialog mode (self._dialog exists)
|
||||||
|
if hasattr(self, '_dialog'):
|
||||||
ui.button('Cancel', on_click=lambda: self._dialog.submit(None))
|
ui.button('Cancel', on_click=lambda: self._dialog.submit(None))
|
||||||
ui.button('Submit', on_click=lambda: self._dialog.submit({
|
ui.button('Submit', on_click=lambda: self._dialog.submit({
|
||||||
'name': name_input.value,
|
'name': name_input.value,
|
||||||
'email': email_input.value
|
'email': email_input.value
|
||||||
})).props('color=primary')
|
})).props('color=primary')
|
||||||
|
else:
|
||||||
|
# Normal mode - just show submit button that displays the values
|
||||||
|
ui.button('Submit', on_click=lambda: ui.notify(f"Name: {name_input.value}, Email: {email_input.value}")).props('color=primary')
|
||||||
|
|
||||||
|
|
||||||
@ui.page('/')
|
@ui.page('/')
|
||||||
@@ -44,6 +50,27 @@ async def main():
|
|||||||
ui.label('AsyncElement Dialog Examples').classes('text-h4')
|
ui.label('AsyncElement Dialog Examples').classes('text-h4')
|
||||||
ui.separator()
|
ui.separator()
|
||||||
|
|
||||||
|
# Example: Same component used both normally and as dialog
|
||||||
|
with ui.row():
|
||||||
|
with ui.column():
|
||||||
|
ui.label('Normal usage (inline):').classes('text-subtitle1')
|
||||||
|
# Use FormDialog normally inline on the page
|
||||||
|
await FormDialog.create(title="Inline Form")
|
||||||
|
|
||||||
|
with ui.column():
|
||||||
|
ui.label('Dialog usage:').classes('text-subtitle1')
|
||||||
|
|
||||||
|
async def show_form_dialog():
|
||||||
|
result = await FormDialog.as_dialog(title="Dialog Form")
|
||||||
|
if result:
|
||||||
|
ui.notify(f'Form submitted: {result}', type='positive')
|
||||||
|
else:
|
||||||
|
ui.notify('Form cancelled', type='warning')
|
||||||
|
|
||||||
|
ui.button('Open as Dialog', on_click=show_form_dialog)
|
||||||
|
|
||||||
|
ui.separator()
|
||||||
|
|
||||||
async def show_confirm():
|
async def show_confirm():
|
||||||
result = await ConfirmDialog.as_dialog(
|
result = await ConfirmDialog.as_dialog(
|
||||||
message="Are you sure you want to proceed?",
|
message="Are you sure you want to proceed?",
|
||||||
@@ -62,9 +89,9 @@ async def main():
|
|||||||
ui.button('Show Confirmation Dialog', on_click=show_confirm)
|
ui.button('Show Confirmation Dialog', on_click=show_confirm)
|
||||||
ui.button('Show Form Dialog', on_click=show_form)
|
ui.button('Show Form Dialog', on_click=show_form)
|
||||||
|
|
||||||
# Example with inline async element
|
# Example with inline async element using AsyncColumn
|
||||||
async def show_inline_dialog():
|
async def show_inline_dialog():
|
||||||
class QuickDialog(AsyncElement[ui.column]):
|
class QuickDialog(AsyncColumn):
|
||||||
async def build(self):
|
async def build(self):
|
||||||
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?')
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
from abc import ABC, abstractmethod
|
from abc import ABC, abstractmethod
|
||||||
from typing import Self
|
from typing import Self, Any
|
||||||
from nicegui import ui
|
from nicegui import ui
|
||||||
|
|
||||||
|
|
||||||
@@ -21,6 +21,39 @@ class AsyncColumn(ui.column, ABC):
|
|||||||
await instance.build(*args, **kwargs)
|
await instance.build(*args, **kwargs)
|
||||||
return instance
|
return instance
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
async def as_dialog(cls, *args, **kwargs) -> Any:
|
||||||
|
"""Create element inside a dialog and await its result
|
||||||
|
|
||||||
|
Works like create() but wraps the element in a dialog with a card that opens automatically
|
||||||
|
and returns the dialog result when submitted.
|
||||||
|
|
||||||
|
The dialog can be submitted using dialog.submit(result) from within the build() method.
|
||||||
|
Access the dialog via self._dialog in your build() implementation.
|
||||||
|
|
||||||
|
Returns the value passed to dialog.submit() or None if dismissed.
|
||||||
|
"""
|
||||||
|
# Create the dialog
|
||||||
|
dialog = ui.dialog()
|
||||||
|
dialog.open()
|
||||||
|
|
||||||
|
# Build the element inside the dialog with a card
|
||||||
|
with dialog, ui.card():
|
||||||
|
instance = cls()
|
||||||
|
|
||||||
|
# Store dialog reference for potential use in build()
|
||||||
|
instance._dialog = dialog # pyright: ignore[reportAttributeAccessIssue]
|
||||||
|
|
||||||
|
await instance.build(*args, **kwargs)
|
||||||
|
|
||||||
|
# Await the dialog result
|
||||||
|
result = await dialog
|
||||||
|
|
||||||
|
# Clean up the dialog after it's closed
|
||||||
|
dialog.clear()
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
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"""
|
||||||
@@ -40,6 +73,21 @@ class AsyncRow(ui.row, ABC):
|
|||||||
await instance.build(*args, **kwargs)
|
await instance.build(*args, **kwargs)
|
||||||
return instance
|
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
|
||||||
|
dialog.clear()
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
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"""
|
||||||
@@ -59,6 +107,21 @@ class AsyncCard(ui.card, ABC):
|
|||||||
await instance.build(*args, **kwargs)
|
await instance.build(*args, **kwargs)
|
||||||
return instance
|
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
|
||||||
|
dialog.clear()
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
class AsyncScrollArea(ui.scroll_area, ABC):
|
class AsyncScrollArea(ui.scroll_area, ABC):
|
||||||
"""Async ScrollArea that inherits from ui.scrol_area for perfect typing"""
|
"""Async ScrollArea that inherits from ui.scrol_area for perfect typing"""
|
||||||
@@ -77,3 +140,18 @@ class AsyncScrollArea(ui.scroll_area, ABC):
|
|||||||
instance = cls()
|
instance = cls()
|
||||||
await instance.build(*args, **kwargs)
|
await instance.build(*args, **kwargs)
|
||||||
return instance
|
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
|
||||||
|
dialog.clear()
|
||||||
|
return result
|
||||||
|
|||||||
Reference in New Issue
Block a user