diff --git a/plugins/ui/docs/components/divider.md b/plugins/ui/docs/components/divider.md new file mode 100644 index 000000000..ada4f42ad --- /dev/null +++ b/plugins/ui/docs/components/divider.md @@ -0,0 +1,71 @@ +# Divider + +Dividers enhance layout clarity by grouping and separating nearby content, helping to establish structure and hierarchy. + +## Example + +```python +from deephaven import ui + + +@ui.component +def ui_divider_basic_example(): + return ["Content above", ui.divider(), "Content below"] + + +my_divider_basic_example = ui_divider_basic_example() +``` + + +## Orientation + +While aligned horizontally by default, the alignment of the divider can be set using the `orientation` prop. + +If aligned vertically, a height should also be provided. + +```python +from deephaven import ui + + +@ui.component +def ui_divider_orientation_example(): + return ui.flex( + "Content before", + ui.divider(orientation="vertical"), + "Content after", + flex_grow=0, + ) + + +my_checkbox_group_orientation_example = ui_divider_orientation_example() +``` + +## Sizing + +The thickness (height of the divider) can be set through the `size` property. + +```python +from deephaven import ui + + +@ui.component +def ui_divider_size_example(): + return ui.flex( + "Content below", + ui.divider(size="L"), + "Content above", + ui.divider(size="M"), + "More content above", + ui.divider(size="S"), + direction="column", + ) + + +my_divider_size_example = ui_divider_size_example() +``` + +## API reference + +```{eval-rst} +.. dhautofunction:: deephaven.ui.divider +``` \ No newline at end of file diff --git a/plugins/ui/docs/sidebar.json b/plugins/ui/docs/sidebar.json index 2bcf34c54..9c74ca853 100644 --- a/plugins/ui/docs/sidebar.json +++ b/plugins/ui/docs/sidebar.json @@ -93,6 +93,10 @@ "label": "dialog_trigger", "path": "components/dialog_trigger.md" }, + { + "label": "divider", + "path": "components/divider.md" + }, { "label": "flex", "path": "components/flex.md" diff --git a/plugins/ui/src/deephaven/ui/components/__init__.py b/plugins/ui/src/deephaven/ui/components/__init__.py index 4c73da134..4625cbf20 100644 --- a/plugins/ui/src/deephaven/ui/components/__init__.py +++ b/plugins/ui/src/deephaven/ui/components/__init__.py @@ -20,6 +20,7 @@ from .date_range_picker import date_range_picker from .dialog import dialog from .dialog_trigger import dialog_trigger +from .divider import divider from .flex import flex from .form import form from .fragment import fragment @@ -90,6 +91,7 @@ "date_range_picker", "dialog", "dialog_trigger", + "divider", "flex", "form", "fragment", diff --git a/plugins/ui/src/deephaven/ui/components/divider.py b/plugins/ui/src/deephaven/ui/components/divider.py new file mode 100644 index 000000000..9aed33017 --- /dev/null +++ b/plugins/ui/src/deephaven/ui/components/divider.py @@ -0,0 +1,151 @@ +from __future__ import annotations + +from .types import ( + Orientation, + AlignSelf, + CSSProperties, + DimensionValue, + JustifySelf, + LayoutFlex, + Position, +) +from ..types import DividerSize +from .basic import component_element +from ..elements import Element + + +def divider( + size: DividerSize | None = "L", + orientation: Orientation = "horizontal", + flex: LayoutFlex | None = None, + flex_grow: float | None = None, + flex_shrink: float | None = None, + flex_basis: DimensionValue | None = None, + align_self: AlignSelf | None = None, + justify_self: JustifySelf | None = None, + order: int | 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: int | None = None, + is_hidden: bool | None = None, + id: str | None = None, + UNSAFE_class_name: str | None = None, + UNSAFE_style: CSSProperties | None = None, +) -> Element: + """ + Dividers bring clarity to a layout by grouping and dividing content in close proximity. + Args: + size: How thick the Divider should be. + orientation: The axis the Divider should align with. + 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 the element will grow to fit the space available. + flex_shrink: When used in a flex layout, specifies how the element will shrink to fit the space available. + flex_basis: When used in a flex layout, specifies the initial main size of the element. + align_self: Overrides the alignItems property of a flex or grid container. + justify_self: Species 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: When used in a grid layout specifies, specifies the named grid area that the element should be placed in within the grid. + grid_row: When used in a grid layout, specifies the row the element should be placed in within the grid. + grid_column: When used in a grid layout, specifies the column the element should be placed in within the grid. + grid_row_start: When used in a grid layout, specifies the starting row to span within the grid. + grid_row_end: When used in a grid layout, specifies the ending row to span within the grid. + grid_column_start: When used in a grid layout, specifies the starting column to span within the grid. + grid_column_end: When used in a grid layout, specifies the ending column to span within the grid. + margin: The margin for all four sides of the element. + margin_top: The margin for the top side of the element. + margin_bottom: The margin for the bottom side of the element. + margin_start: The margin for the logical start side of the element, depending on layout direction. + margin_end: The margin for the logical end side of the element, depending on layout direction. + margin_x: The margin for the left and right sides of the element. + margin_y: The margin for the top and bottom sides of the element. + width: The width of the element. + min_width: The minimum width of the element. + max_width: The maximum width of the element. + height: The height of the element. + min_height: The minimum height of the element. + max_height: The maximum height of the element. + position: The position of the element. + top: The distance from the top of the containing element. + bottom: The distance from the bottom of the containing element. + left: The distance from the left of the containing element. + right: The distance from the right of the containing element. + start: The distance from the start of the containing element, depending on layout direction. + end: The distance from the end of the containing element, depending on layout direction. + z_index: The stack order of the element. + is_hidden: Whether the element is hidden. + id: The unique identifier of 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 divider element. + """ + return component_element( + "Divider", + size=size, + orientation=orientation, + flex=flex, + flex_grow=flex_grow, + flex_shrink=flex_shrink, + flex_basis=flex_basis, + align_self=align_self, + justify_self=justify_self, + order=order, + grid_area=grid_area, + grid_row=grid_row, + grid_row_start=grid_row_start, + grid_row_end=grid_row_end, + grid_column=grid_column, + grid_column_start=grid_column_start, + grid_column_end=grid_column_end, + margin=margin, + margin_top=margin_top, + margin_bottom=margin_bottom, + margin_start=margin_start, + margin_end=margin_end, + margin_x=margin_x, + margin_y=margin_y, + width=width, + height=height, + min_width=min_width, + min_height=min_height, + max_width=max_width, + max_height=max_height, + position=position, + top=top, + bottom=bottom, + start=start, + end=end, + left=left, + right=right, + z_index=z_index, + is_hidden=is_hidden, + id=id, + UNSAFE_class_name=UNSAFE_class_name, + UNSAFE_style=UNSAFE_style, + ) diff --git a/plugins/ui/src/deephaven/ui/types/types.py b/plugins/ui/src/deephaven/ui/types/types.py index 329e3797d..f33bc262c 100644 --- a/plugins/ui/src/deephaven/ui/types/types.py +++ b/plugins/ui/src/deephaven/ui/types/types.py @@ -503,6 +503,7 @@ class SliderChange(TypedDict): ] Granularity = Literal["DAY", "HOUR", "MINUTE", "SECOND"] ListViewDensity = Literal["COMPACT", "NORMAL", "SPACIOUS"] +DividerSize = Literal["S", "M", "L"] ListViewOverflowMode = Literal["truncate", "wrap"] ActionGroupDensity = Literal["compact", "regular"] TabDensity = Literal["compact", "regular"] diff --git a/plugins/ui/src/js/src/elements/model/ElementConstants.ts b/plugins/ui/src/js/src/elements/model/ElementConstants.ts index ece264d44..a98453e08 100644 --- a/plugins/ui/src/js/src/elements/model/ElementConstants.ts +++ b/plugins/ui/src/js/src/elements/model/ElementConstants.ts @@ -40,6 +40,7 @@ export const ELEMENT_NAME = { dateRangePicker: uiComponentName('DateRangePicker'), dialog: uiComponentName('Dialog'), dialogTrigger: uiComponentName('DialogTrigger'), + divider: uiComponentName('Divider'), flex: uiComponentName('Flex'), form: uiComponentName('Form'), fragment: uiComponentName('Fragment'), diff --git a/plugins/ui/src/js/src/widget/WidgetUtils.tsx b/plugins/ui/src/js/src/widget/WidgetUtils.tsx index 64529306f..ac628e7ed 100644 --- a/plugins/ui/src/js/src/widget/WidgetUtils.tsx +++ b/plugins/ui/src/js/src/widget/WidgetUtils.tsx @@ -11,6 +11,7 @@ import { CheckboxGroup, Content, DialogTrigger, + Divider, Heading, Item, Link, @@ -131,6 +132,7 @@ export const elementComponentMap = { [ELEMENT_NAME.dateRangePicker]: DateRangePicker, [ELEMENT_NAME.dialog]: Dialog, [ELEMENT_NAME.dialogTrigger]: DialogTrigger, + [ELEMENT_NAME.divider]: Divider, [ELEMENT_NAME.flex]: Flex, [ELEMENT_NAME.form]: Form, [ELEMENT_NAME.fragment]: React.Fragment, diff --git a/tests/app.d/ui_render_all.py b/tests/app.d/ui_render_all.py index 3b96ae6e4..6f582c6a2 100644 --- a/tests/app.d/ui_render_all.py +++ b/tests/app.d/ui_render_all.py @@ -62,6 +62,7 @@ def ui_components1(): label="Date Range Picker", value={"start": "2021-01-01", "end": "2021-01-02"}, ), + ui.flex("Content before", ui.divider(orientation="vertical"), "Content after"), ui.flex("Flex default child A", "Flex default child B"), ui.flex("Flex column child A", "Flex column child B", direction="column"), ui.form("Form"), diff --git a/tests/express.spec.ts-snapshots/Histogram-loads-1-webkit-linux.png b/tests/express.spec.ts-snapshots/Histogram-loads-1-webkit-linux.png index fbc109b04..42b79ecec 100644 Binary files a/tests/express.spec.ts-snapshots/Histogram-loads-1-webkit-linux.png and b/tests/express.spec.ts-snapshots/Histogram-loads-1-webkit-linux.png differ diff --git a/tests/ui.spec.ts-snapshots/UI-all-components-render-1-1-chromium-linux.png b/tests/ui.spec.ts-snapshots/UI-all-components-render-1-1-chromium-linux.png index 01eeab591..f08f62836 100644 Binary files a/tests/ui.spec.ts-snapshots/UI-all-components-render-1-1-chromium-linux.png and b/tests/ui.spec.ts-snapshots/UI-all-components-render-1-1-chromium-linux.png differ diff --git a/tests/ui.spec.ts-snapshots/UI-all-components-render-1-1-firefox-linux.png b/tests/ui.spec.ts-snapshots/UI-all-components-render-1-1-firefox-linux.png index 2b2ca3238..8337ff61c 100644 Binary files a/tests/ui.spec.ts-snapshots/UI-all-components-render-1-1-firefox-linux.png and b/tests/ui.spec.ts-snapshots/UI-all-components-render-1-1-firefox-linux.png differ diff --git a/tests/ui.spec.ts-snapshots/UI-all-components-render-1-1-webkit-linux.png b/tests/ui.spec.ts-snapshots/UI-all-components-render-1-1-webkit-linux.png index 50e60dbb2..06c1639df 100644 Binary files a/tests/ui.spec.ts-snapshots/UI-all-components-render-1-1-webkit-linux.png and b/tests/ui.spec.ts-snapshots/UI-all-components-render-1-1-webkit-linux.png differ diff --git a/tests/ui.spec.ts-snapshots/UI-all-components-render-2-1-chromium-linux.png b/tests/ui.spec.ts-snapshots/UI-all-components-render-2-1-chromium-linux.png index 92492a7d7..f32a39aa8 100644 Binary files a/tests/ui.spec.ts-snapshots/UI-all-components-render-2-1-chromium-linux.png and b/tests/ui.spec.ts-snapshots/UI-all-components-render-2-1-chromium-linux.png differ diff --git a/tests/ui.spec.ts-snapshots/UI-all-components-render-2-1-firefox-linux.png b/tests/ui.spec.ts-snapshots/UI-all-components-render-2-1-firefox-linux.png index 55e199088..083699b0a 100644 Binary files a/tests/ui.spec.ts-snapshots/UI-all-components-render-2-1-firefox-linux.png and b/tests/ui.spec.ts-snapshots/UI-all-components-render-2-1-firefox-linux.png differ diff --git a/tests/ui.spec.ts-snapshots/UI-all-components-render-2-1-webkit-linux.png b/tests/ui.spec.ts-snapshots/UI-all-components-render-2-1-webkit-linux.png index 14da881b1..a46551b34 100644 Binary files a/tests/ui.spec.ts-snapshots/UI-all-components-render-2-1-webkit-linux.png and b/tests/ui.spec.ts-snapshots/UI-all-components-render-2-1-webkit-linux.png differ