Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: UI Dialog and DialogTrigger Components #953

Merged
merged 43 commits into from
Nov 1, 2024
Merged
Show file tree
Hide file tree
Changes from 42 commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
cacc961
Initial dialog trigger python
dgodinez-dh Oct 14, 2024
b929784
fix merge
dgodinez-dh Oct 21, 2024
139dfd8
dialog trigger props
dgodinez-dh Oct 21, 2024
0c5d190
hook up dialog trigger
dgodinez-dh Oct 21, 2024
d987c49
dialog python
dgodinez-dh Oct 21, 2024
538c870
default mobile type
dgodinez-dh Oct 21, 2024
8854513
hook up js
dgodinez-dh Oct 21, 2024
85cd401
fix dialog children
dgodinez-dh Oct 21, 2024
911f78b
fix trigger children type
dgodinez-dh Oct 21, 2024
30c46e1
fix merge
dgodinez-dh Oct 22, 2024
7967900
use flag
dgodinez-dh Oct 22, 2024
3d18f15
test flag
dgodinez-dh Oct 22, 2024
928674b
use flag md
dgodinez-dh Oct 22, 2024
d07f491
dialog design
dgodinez-dh Oct 22, 2024
e072c0c
fix on_dismiss callback
dgodinez-dh Oct 22, 2024
3fbf387
remove target ref
dgodinez-dh Oct 22, 2024
a16f975
fix type names
dgodinez-dh Oct 22, 2024
86af53c
initial dialog trigger design
dgodinez-dh Oct 22, 2024
9ef1da3
design
dgodinez-dh Oct 22, 2024
e61ecfa
initial dialog md
dgodinez-dh Oct 22, 2024
e032323
merge latest
dgodinez-dh Oct 23, 2024
c1c2642
dialog md
dgodinez-dh Oct 23, 2024
1fa0dbf
dialog sidebar
dgodinez-dh Oct 23, 2024
bed2d79
initali dialog trigger md
dgodinez-dh Oct 23, 2024
4bc7eba
dialog trigger md
dgodinez-dh Oct 23, 2024
95a4f0b
sidebar
dgodinez-dh Oct 23, 2024
b0e8ea4
Apply suggestions from code review
dgodinez-dh Oct 24, 2024
bb4f1ea
Apply suggestions from code review
dgodinez-dh Oct 25, 2024
84d6372
fix capitaliztion
dgodinez-dh Oct 25, 2024
3e9dbd5
link
dgodinez-dh Oct 25, 2024
7542d52
Apply suggestions from code review
dgodinez-dh Oct 25, 2024
bf67a17
fix descriptions
dgodinez-dh Oct 25, 2024
13e27f3
use callback in use flag
dgodinez-dh Oct 25, 2024
bacdfb8
merge latest
dgodinez-dh Oct 28, 2024
a636e85
use_boolean
dgodinez-dh Oct 28, 2024
0bf8115
update for tox
dgodinez-dh Oct 28, 2024
99d7334
change to union
dgodinez-dh Oct 28, 2024
89678de
use from future
dgodinez-dh Oct 28, 2024
9eac153
fix example
dgodinez-dh Oct 28, 2024
44dcdcd
update docs for use_boolean
dgodinez-dh Oct 28, 2024
cd55e91
merge latest
dgodinez-dh Oct 31, 2024
819e3cf
Update plugins/ui/src/deephaven/ui/hooks/use_boolean.py
dgodinez-dh Oct 31, 2024
d021d43
Apply suggestions from code review
dgodinez-dh Nov 1, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
205 changes: 205 additions & 0 deletions plugins/ui/DESIGN.md
Original file line number Diff line number Diff line change
Expand Up @@ -1874,6 +1874,211 @@ date_range_picker7 = ui.date_range_picker(
)
```

###### ui.dialog

Dialogs are windows containing contextual information, tasks, or workflows that appear over the user interface. Depending on the kind of Dialog, further interactions may be blocked until the Dialog is acknowledged.

```py
import deephaven.ui as ui
ui.dialog(
*children: Any,
size: DialogSize | None = None,
is_dismissable: bool | None = None,
on_dismiss: Callable[[], None] | None = None,
**props: Any
) -> DialogElement
```

###### Content

The content can be populated by providing the following components to your `dialog` as children:

- `header` (optional)
- `heading` (title, required)
- `divider` (optional)
- `content` (body, required)
- `button_group` (optional)
- `footer` (optional)

###### Parameters

| Parameter | Type | Description |
| ---------------- | ---------------------------- | --------------------------------------------------------------------------------------- |
| `*children` | `Any` | The contents of the Dialog. |
| `size` | `DialogSize \| None` | The size of the Dialog. Either `S`, `M`, or `L` . Only applies to "modal" type Dialogs. |
| `is_dismissable` | `bool \| None` | Whether the Dialog is dismissable. |
| `on_dismiss` | `Callable[[], None] \| None` | Handler that is called when the 'x' button of a dismissable Dialog is clicked. |
| `**props` | `Any` | Any other [Dialog](https://react-spectrum.adobe.com/react-spectrum/Dialog.html) prop |

```py
from deephaven import ui

# Open and closed using flag (controlled)
@ui.component
def open_close_example():
is_open, set_open = ui.use_boolean()
return ui.dialog_trigger(
ui.action_button("Open dialog", on_press=set_open.on),
ui.dialog(ui.heading("Dialog"), ui.content("Close using the button."), ui.button_group(ui.button("close", on_press=set_open.off))),
is_open=is_open
)

my_open_close_example = open_close_example()

# Dismissable (uncontrolled)
my_dismissable = ui.dialog_trigger(
ui.action_button("Open dialog",),
ui.dialog(
ui.heading("Dialog"),
ui.content("Dismiss using the X button."),
is_dismissable=True,
),
)

# A small dialog
my_small = ui.dialog_trigger(
ui.action_button("Open dialog",),
ui.dialog(ui.heading("Dialog"), ui.content("Dismiss using the X button."), is_dismissable=True, size="S"),
)

from deephaven import ui

# Dismissable callback (controlled)
@ui.component
def dismissable_callback():
is_open, set_open = ui.use_boolean()
return ui.dialog_trigger(
ui.action_button("Open dialog", on_press=set_open.on),
ui.dialog(ui.heading("Dialog"),
ui.content("Dismiss using the X button."),
is_dismissable=True,
on_dismiss=set_open.off
),
is_open=is_open
)

my_dismissable_callback = dismissable_callback()
```

###### ui.dialog_trigger

`dialog_trigger` serves as a wrapper around a `dialog` and its associated trigger, linking the `dialog's` open state with the trigger's press state. Additionally, it allows you to customize the type and positioning of the `dialog`.

```py
import deephaven.ui as ui
ui.dialog_trigger(
*children: Element,
type: DialogTriggerType | None = "modal",
placement: Placement | None = "bottom",
is_open: bool | None = None,
default_open: bool | None = None,
container_padding: float | None = None,
offset: float | None = None,
cross_offset: float | None = None,
should_flip: bool | None = None,
hide_arrow: bool | None = None,
is_dismissable: bool | None = None,
is_keyboard_dismiss_disabled: bool | None = None,
on_open_change: Callable[[bool], None] | None = None,
**props: Any
) -> DialogTriggerElement
```

###### Dialog types

By providing a `type` prop, you can specify the type of `dialog` that is rendered by your `dialog_trigger`.

- `modal`
- `popover`
- `tray`
- `fullscreen`
- `fullscreenTakeover`

###### Parameters

| Parameter | Type | Description |
| ------------------------------ | -------------------------------- | ------------------------------------------------------------------------------------------------------------ |
| `*children` | `Element` | The Dialog and its trigger element. |
| `type` | `DialogTriggerType \| None` | The type of Dialog that should be rendered. |
| `placement` | `Placement \| None` | The placement of the popover relative to the action button. |
| `is_open` | `bool \| None` | Whether the popover is open by default (controlled). |
| `default_open` | `bool \| None` | Whether the popover is open by default (uncontrolled). |
| `container_padding` | `float \| None` | The placement padding that should be applied between the element and its surrounding container. |
| `offset` | `float \| None` | The additional offset applied along the main axis between the element and its anchor element. |
| `cross_offset` | `float \| None` | The additional offset applied along the cross axis between the element and its anchor element. |
| `should_flip` | `bool \| None` | Whether the element should flip its orientation when there is insufficient room for it to render completely. |
| `hide_arrow` | `bool \| None` | Whether a popover type Dialog's arrow should be hidden. |
| `is_dismissable` | `bool \| None` | Whether a modal type Dialog should be dismissable. |
| `is_keyboard_dismiss_disabled` | `bool \| None` | Whether pressing the escape key to close the dialog should be disabled. |
| `on_open_change` | `Callable[[bool], None] \| None` | Handler that is called when the overlay's open state changes. |
| `**props` | `Any` | Any other [Dialog](https://react-spectrum.adobe.com/react-spectrum/Dialog.html) prop |

```py
from deephaven import ui

# Open and closed using flag (controlled)
@ui.component
def open_close_example():
is_open, set_open = ui.use_boolean()
return ui.dialog_trigger(
ui.action_button("Open dialog", on_press=set_open.on),
ui.dialog(ui.heading("Dialog"), ui.content("Close using the button."), ui.button_group(ui.button("close", on_press=set_open.off))),
is_open=is_open
)

my_open_close_example = open_close_example()

# Dismissable (uncontrolled)
my_dismissable = ui.dialog_trigger(
ui.action_button("Open dialog",),
ui.dialog(
ui.heading("Dialog"),
ui.content("Dismiss using the X button."),
),
is_dismissable=True,
)

# popover
my_popover = ui.dialog_trigger(
ui.action_button("Open dialog",),
ui.dialog(
ui.heading("Dialog"),
ui.content("Popover."),
),
type="popover"
)

# tray
my_tray = ui.dialog_trigger(
ui.action_button("Open dialog",),
ui.dialog(
ui.heading("Dialog"),
ui.content("Tray."),
),
type="tray"
)

# fullscreen
my_fullscreen = ui.dialog_trigger(
ui.action_button("Open dialog",),
ui.dialog(
ui.heading("Dialog"),
ui.content("Fullscreen."),
),
type="fullscreen"
)

# takeover
my_takeover = ui.dialog_trigger(
ui.action_button("Open dialog",),
ui.dialog(
ui.heading("Dialog"),
ui.content("Fullscreen takeover."),
),
type="fullscreenTakeover"
)
```

##### ui.combo_box

A combo_box that can be used to search or select from a list. Children should be one of five types:
Expand Down
Loading
Loading