[go: up one dir, main page]

Skip to content

Commit

Permalink
dialog bugfixes & documentation improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
mad-moo committed Aug 14, 2024
1 parent 1a24c6a commit 3d53ec8
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 10 deletions.
1 change: 0 additions & 1 deletion frontend/code/components/dialog_container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ export class DialogContainerComponent extends ComponentBase {

// Yes! Close it. First, inform the server.
callRemoteMethodDiscardResponse('dialogClosed', {
owningComponentId: this.state.owning_component_id,
dialogRootComponentId: this.id,
});

Expand Down
55 changes: 46 additions & 9 deletions rio/components/component.py
Original file line number Diff line number Diff line change
Expand Up @@ -674,8 +674,31 @@ async def show_custom_dialog(
"""
Displays a custom dialog.
This function displays a dialog to the user. This will call the `build`
function and use its result as the content of the dialog. The content
will be assigned the full size of the screen. This allows you to
position the dialog yourself, using the align and margin properties of
your component.
Note: Dialogs are useful if you need to show components without
returning them from the `build` method. A good example is asking for
confirmation from an event handler, without having to rebuild the
component. **If you can return components from the `build` method,
`rio.Popup` is often an easier choice** (set `position` to
`"fullscreen"` to get a similar look to dialogs).
Note: If spawning many dialogs (for example when creating one for each
item inside of a CRUD application) dialogs can be faster than
`rio.Popup`, because dialogs only have to build their children when
they're opened, while `rio.Popup` has its children built
immediately, for every single item in the list.
## Example
TODO
## Parameters
`build`: A function which creates the component to be displayed in the
Expand All @@ -693,6 +716,11 @@ async def show_custom_dialog(
`on_close`: An event handler which is called when the dialog is closed.
This will not be called if you explicitly remove the dialog by
calling `dialog.close()`.
## Metadata
`experimental`: True
"""
# TODO: Verify that the passed build function is indeed a function, and
# not already a component
Expand Down Expand Up @@ -754,6 +782,9 @@ async def show_simple_dialog(
"""
Display a simple dialog with a list of options.
This function is highly experimental and **will change in the future.**
Only use it if you feel adventurous.
This is a convenience function which displays a simple dialog to the
user, with a list of options to choose from. The user can select one of
the options, and the function will return the value of the selected
Expand Down Expand Up @@ -938,13 +969,15 @@ async def show_yes_no_dialog(
no_text: str = "No",
yes_color: rio.ColorSet = "keep",
no_color: rio.ColorSet = "keep",
) -> bool:
) -> bool | None:
"""
Display a simple dialog with a yes and no button.
Displays a simple dialog with a yes and no button.
This is a convenience function which displays a simple dialog to the
user, with a "Yes" and "No" button. The user can select one of the
options, and the function will return `True` or `False` respectively.
options, and the function will return `True` or `False` respectively. If
the user closes the dialog without selecting an option, `None` is
returned instead.
The button texts and colors can be customized.
Expand Down Expand Up @@ -996,19 +1029,22 @@ def build(self) -> rio.Component:
rio.Text(f"You've selected: {self.value}"),
)
```
## Metadata
`experimental`: True
"""
# Prepare a future. This will complete when the user selects an option
future: asyncio.Future[bool] = asyncio.Future()
future: asyncio.Future[bool | None] = asyncio.Future()

def set_result(value: bool) -> None:
def set_result(value: bool | None) -> None:
"""
Sets the future, but only if it hasn't been set already.
"""
if not future.done():
future.set_result(value)

# TODO: What if the dialog gets closed by some other way?

# Prepare a build function
#
# TODO: Display the buttons below each other on small displays
Expand Down Expand Up @@ -1102,11 +1138,12 @@ def build_content() -> rio.Component:
# Display the dialog
dialog = await self.show_custom_dialog(
build=build_content,
modal=True,
user_closeable=True,
on_close=lambda: set_result(None),
)

# Wait for the user to select an option
#
# TODO: What to do here if the dialog gets closed while waiting?
result = await future

# Remove the dialog
Expand Down

0 comments on commit 3d53ec8

Please sign in to comment.