Skip to content

Commit

Permalink
feat: Python combo box implementation (#460)
Browse files Browse the repository at this point in the history
Fixes #412 
Adds python side of combo box implementation
  • Loading branch information
jnumainville authored May 15, 2024
1 parent 910a57c commit b87a5c6
Show file tree
Hide file tree
Showing 4 changed files with 254 additions and 0 deletions.
2 changes: 2 additions & 0 deletions plugins/ui/src/deephaven/ui/components/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from .list_action_menu import list_action_menu
from .item_table_source import item_table_source
from .date_picker import date_picker
from .combo_box import combo_box

from . import html

Expand All @@ -26,6 +27,7 @@
"button_group",
"checkbox",
"column",
"combo_box",
"component",
"content",
"contextual_help",
Expand Down
242 changes: 242 additions & 0 deletions plugins/ui/src/deephaven/ui/components/combo_box.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,242 @@
from __future__ import annotations

from typing import Callable

from .spectrum import (
FocusEventCallable,
KeyboardEventCallable,
LayoutFlex,
Number,
DimensionValue,
AlignSelf,
JustifySelf,
Position,
CSSProperties,
LabelPosition,
Alignment,
ValidationBehavior,
NecessityIndicator,
ValidationState,
MenuTriggerAction,
Align,
Direction,
LoadingState,
FormValue,
)

from deephaven.table import Table, PartitionedTable
from .section import SectionElement
from .item import Item
from .item_table_source import ItemTableSource
from ..elements import BaseElement, Element
from .._internal.utils import create_props, unpack_item_table_source
from ..types import Key

ComboBoxElement = BaseElement

SUPPORTED_SOURCE_ARGS = {
"key_column",
"label_column",
"description_column",
"icon_column",
"title_column",
}


def combo_box(
*children: Item | SectionElement | Table | PartitionedTable | ItemTableSource,
menu_trigger: MenuTriggerAction | None = "input",
is_quiet: bool | None = None,
align: Align | None = "end",
direction: Direction | None = "bottom",
loading_state: LoadingState | None = None,
should_flip: bool = True,
menu_width: DimensionValue | None = None,
form_value: FormValue | None = "text",
should_focus_wrap: bool | None = None,
input_value: str | None = None,
default_input_value: str | None = None,
allows_custom_value: bool | None = None,
disabled_keys: list[Key] | None = None,
selected_key: Key | None = None,
default_selected_key: Key | None = None,
is_disabled: bool | None = None,
is_read_only: bool | None = None,
is_required: bool | None = None,
validation_behavior: ValidationBehavior = "aria",
auto_focus: bool | None = None,
label: Element | None = None,
description: Element | None = None,
error_message: Element | None = None,
name: str | None = None,
validation_state: ValidationState | None = None,
label_position: LabelPosition = "top",
label_align: Alignment = "start",
necessity_indicator: NecessityIndicator | None = "icon",
contextual_help: Element | None = None,
on_open_change: Callable[[bool, MenuTriggerAction], None] | None = None,
on_selection_change: Callable[[Key], None] | None = None,
on_change: Callable[[Key], None] | None = None,
on_input_change: Callable[[str], None] | None = None,
on_focus: Callable[[FocusEventCallable], None] | None = None,
on_blur: Callable[[FocusEventCallable], None] | None = None,
on_focus_change: Callable[[bool], None] | None = None,
on_key_down: Callable[[KeyboardEventCallable], None] | None = None,
on_key_up: Callable[[KeyboardEventCallable], None] | None = None,
flex: LayoutFlex | None = None,
flex_grow: Number | None = None,
flex_shrink: Number | None = None,
flex_basis: DimensionValue | None = None,
align_self: AlignSelf | None = None,
justify_self: JustifySelf | None = None,
order: Number | None = None,
grid_area: str | None = None,
grid_row: str | None = None,
grid_row_start: str | None = None,
grid_row_end: str | None = None,
grid_column: str | None = None,
grid_column_start: str | None = None,
grid_column_end: str | None = None,
margin: DimensionValue | None = None,
margin_top: DimensionValue | None = None,
margin_bottom: DimensionValue | None = None,
margin_start: DimensionValue | None = None,
margin_end: DimensionValue | None = None,
margin_x: DimensionValue | None = None,
margin_y: DimensionValue | None = None,
width: DimensionValue | None = None,
height: DimensionValue | None = None,
min_width: DimensionValue | None = None,
min_height: DimensionValue | None = None,
max_width: DimensionValue | None = None,
max_height: DimensionValue | None = None,
position: Position | None = None,
top: DimensionValue | None = None,
bottom: DimensionValue | None = None,
start: DimensionValue | None = None,
end: DimensionValue | None = None,
left: DimensionValue | None = None,
right: DimensionValue | None = None,
z_index: Number | None = None,
is_hidden: bool | None = None,
id: str | None = None,
aria_label: str | None = None,
aria_labelledby: str | None = None,
aria_describedby: str | None = None,
aria_details: str | None = None,
UNSAFE_class_name: str | None = None,
UNSAFE_style: CSSProperties | None = None,
) -> ComboBoxElement:
"""
A combo box that can be used to search or select from a list. Children should be one of five types:
1. If children are of type `Item`, they are the dropdown options.
2. If children are of type `SectionElement`, they are the dropdown sections.
3. If children are of type `Table`, the values in the table are the dropdown options.
There can only be one child, the `Table`.
The first column is used as the key and label by default.
4. If children are of type `PartitionedTable`, the values in the table are the dropdown options
and the partitions create multiple sections. There can only be one child, the `PartitionedTable`.
The first column is used as the key and label by default.
5. If children are of type `ItemTableSource`, complex items are created from the source.
There can only be one child, the `ItemTableSource`.
Supported ItemTableSource arguments are `key_column`, `label_column`, `description_column`,
`icon_column`, and `title_column`.
Args:
*children: The options to render within the combo box.
menu_trigger: The interaction required to display the ComboBox menu.
is_quiet: Whether the ComboBox should be displayed with a quiet style.
align: Alignment of the menu relative to the input target.
direction: Direction the menu will render relative to the ComboBox.
loading_state: The current loading state of the ComboBox.
Determines whether or not the progress circle should be shown.
should_flip: Whether the menu should automatically flip direction when space is limited.
menu_width: Width of the menu. By default, matches width of the combobox.
Note that the minimum width of the dropdown is always equal to the combobox's width.
form_value: Whether the text or key of the selected item is submitted as part of an HTML form.
When allowsCustomValue is true, this option does not apply and the text is always submitted.
should_focus_wrap: Whether keyboard navigation is circular.
input_value: The value of the search input (controlled).
default_input_value: The default value of the search input (uncontrolled).
allows_custom_value: Whether the ComboBox allows a non-item matching input value to be set.
disabled_keys: The item keys that are disabled.
These items cannot be selected, focused, or otherwise interacted with.
selected_key: The currently selected key in the collection (controlled).
default_selected_key: The initial selected key in the collection (uncontrolled).
is_disabled: Whether the input is disabled.
is_read_only: Whether the input can be selected but not changed by the user.
is_required: Whether user input is required on the input before form submission.
validation_behavior: Whether to use native HTML form validation to prevent
form submission when the value is missing or invalid, or mark the field as required or invalid via ARIA.
auto_focus: Whether the element should receive focus on render.
label: The content to display as the label.
description: A description for the field. Provides a hint such as specific requirements for what to choose.
error_message: An error message for the field.
name: The name of the input element, used when submitting an HTML form.
validation_state: Whether the input should display its "valid" or "invalid" visual styling.
label_position: The label's overall position relative to the element it is labeling.
label_align: The label's horizontal alignment relative to the element it is labeling.
necessity_indicator: Whether the required state should be shown as an icon or text.
contextual_help: A ContextualHelp element to place next to the label.
on_open_change: Method that is called when the open state of the menu changes.
Returns the new open state and the action that caused the opening of the menu.
on_selection_change: Handler that is called when the selection changes.
on_change: Alias of `on_selection_change`. Handler that is called when the selection changes.
on_input_change: Handler that is called when the ComboBox input value changes.
on_focus: Handler that is called when the element receives focus.
on_blur: Handler that is called when the element loses focus.
on_focus_change: Handler that is called when the element's focus status changes.
on_key_down: Handler that is called when a key is pressed.
on_key_up: Handler that is called when a key is released.
flex: When used in a flex layout, specifies how the element will grow or shrink to fit the space available.
flex_grow: When used in a flex layout, specifies how much the element will grow to fit the space available.
flex_shrink: When used in a flex layout, specifies how much the element will shrink to fit the space available.
flex_basis: When used in a flex layout, specifies the initial size of the element.
align_self: Overrides the align_items property of a flex or grid container.
justify_self: Specifies how the element is justified inside a flex or grid container.
order: The layout order for the element within a flex or grid container.
grid_area: The name of the grid area to place the element in.
grid_row: The name of the grid row to place the element in.
grid_row_start: The name of the grid row to start the element in.
grid_row_end: The name of the grid row to end the element in.
grid_column: The name of the grid column to place the element in.
grid_column_start: The name of the grid column to start the element in.
grid_column_end: The name of the grid column to end the element in.
margin: The margin to apply around the element.
margin_top: The margin to apply above the element.
margin_bottom: The margin to apply below the element.
margin_start: The margin to apply before the element.
margin_end: The margin to apply after the element.
margin_x: The margin to apply to the left and right of the element.
margin_y: The margin to apply to the top and bottom of the element.
width: The width of the element.
height: The height of the element.
min_width: The minimum width of the element.
min_height: The minimum height of the element.
max_width: The maximum width of the element.
max_height: The maximum height of the element.
position: Specifies how the element is positioned.
top: The distance from the top of the containing element.
bottom: The distance from the bottom of the containing element.
start: The distance from the start of the containing element.
end: The distance from the end of the containing element.
left: The distance from the left of the containing element.
right: The distance from the right of the containing element.
z_index: The stack order of the element.
is_hidden: Whether the element is hidden.
id: A unique identifier for the element.
aria_label: The label for the element.
aria_labelledby: The id of the element that labels the element.
aria_describedby: The id of the element that describes the element.
aria_details: The details for the element.
UNSAFE_class_name: A CSS class to apply to the element.
UNSAFE_style: A CSS style to apply to the element.
Returns:
The rendered ComboBox.
"""
children, props = create_props(locals())

children, props = unpack_item_table_source(children, props, SUPPORTED_SOURCE_ARGS)

return BaseElement("deephaven.ui.components.ComboBox", *children, **props)
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@
from .toggle_button import *
from .flex import *
from .date_picker import *
from .combo_box import *
9 changes: 9 additions & 0 deletions plugins/ui/src/deephaven/ui/components/spectrum/combo_box.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from typing import Literal

MenuTriggerAction = Literal["focus", "input", "manual"]
Align = Literal["start", "end"]
Direction = Literal["bottom", "top"]
LoadingState = Literal[
"loading", "sorting", "loadingMore", "error", "idle", "filtering"
]
FormValue = Literal["key", "text"]

0 comments on commit b87a5c6

Please sign in to comment.