#!/usr/bin/env python3 """Example demonstrating the AsyncElement.as_dialog() method""" from nicegui import ui from src.niceguiex.async_elements import AsyncColumn class ConfirmDialog(AsyncColumn): """A confirmation dialog that can be awaited for a result""" async def build(self, message: str, title: str = "Confirm"): """Build the dialog content""" # Set dialog size using the property self.dialog_size = 'w-96' ui.label(title).classes('text-h6') ui.label(message) ui.space() with ui.row().classes('full-width justify-end'): ui.button('Cancel', on_click=lambda: self._dialog.submit(False)) ui.button('OK', on_click=lambda: self._dialog.submit(True)).props('color=primary') class FormDialog(AsyncColumn): """A form dialog that collects user input""" async def build(self, title: str = "Enter Information"): """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') # Create input fields name_input = ui.input('Name', placeholder='Enter your name') email_input = ui.input('Email', placeholder='Enter your email') ui.space() 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('Submit', on_click=lambda: self._dialog.submit({ 'name': name_input.value, 'email': email_input.value })).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('/') async def main(): ui.label('AsyncElement Dialog Examples').classes('text-h4') 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(): result = await ConfirmDialog.as_dialog( message="Are you sure you want to proceed?", title="Confirmation Required" ) ui.notify(f'Confirmation result: {result}', type='positive' if result else 'negative') async def show_form(): result = await FormDialog.as_dialog(title="User Registration") if result: ui.notify(f'Form submitted: {result}', type='positive') else: ui.notify('Form cancelled', type='warning') with ui.row(): ui.button('Show Confirmation Dialog', on_click=show_confirm) ui.button('Show Form Dialog', on_click=show_form) # Example with inline async element using AsyncColumn async def show_inline_dialog(): class QuickDialog(AsyncColumn): async def build(self): # Smaller dialog size for simple questions self.dialog_size = 'w-72' ui.label('Quick Question').classes('text-h6') ui.label('Do you like this feature?') with ui.row(): ui.button('Yes!', on_click=lambda: self._dialog.submit('yes')) ui.button('No', on_click=lambda: self._dialog.submit('no')) ui.button('Maybe', on_click=lambda: self._dialog.submit('maybe')) result = await QuickDialog.as_dialog() ui.notify(f'Your answer: {result}') 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__"}: ui.run(title='Async Dialog Example', port=8085)