diff --git a/plugins/ui/docs/components/contextual_help.md b/plugins/ui/docs/components/contextual_help.md index 4538c7491..d2a45678c 100644 --- a/plugins/ui/docs/components/contextual_help.md +++ b/plugins/ui/docs/components/contextual_help.md @@ -4,7 +4,7 @@ Contextual help can be used to show extra information about the state of a compo ## Example -For the contextual help component, both the `heading` and `content` props are required. +For the contextual help component, both the `heading` and `content` props are required, while the `footer` prop is optional. ```python from deephaven import ui @@ -13,11 +13,11 @@ from deephaven import ui my_contextual_help_basic = ui.contextual_help( heading="Need Help", content="If you are having issues accessing your account, contact our customer support team for help.", + footer=ui.link("Download support logs"), variant="info", ) ``` - ## Placement The contextual help component supports different placement options for when the popover's positioning needs to be customized. @@ -52,7 +52,6 @@ def ui_contextual_help_placement_examples(): my_contextual_help_placement_examples = ui_contextual_help_placement_examples() ``` - ## Events The `on_open_change` prop is triggered when the popover opens or closes. @@ -80,7 +79,6 @@ def ui_contextual_help_events_example(): my_contextual_help_events_example = ui_contextual_help_events_example() ``` - ## Visual Options The `variant` prop can be set to either "info" or "help", depending on how the contextual help component is meant to help the user. @@ -108,10 +106,12 @@ def ui_contextual_help_variant_examples(): my_contextual_help_variant_examples = ui_contextual_help_variant_examples() ``` - ## API reference ```{eval-rst} .. dhautofunction:: deephaven.ui.contextual_help +.. dhautofunction:: deephaven.ui.content + :no-index: +.. dhautofunction:: deephaven.ui.footer + :no-index: ``` - diff --git a/plugins/ui/docs/components/dialog.md b/plugins/ui/docs/components/dialog.md index ccc7c210d..06e1596e1 100644 --- a/plugins/ui/docs/components/dialog.md +++ b/plugins/ui/docs/components/dialog.md @@ -55,6 +55,7 @@ def dialog_example1(): ui.dialog( ui.heading("Publish 3 pages"), ui.content("Confirm publish?"), + ui.footer("You can undo this action later."), ui.button_group( ui.button("Cancel", variant="secondary", on_press=set_open.off), ui.button( @@ -106,11 +107,11 @@ def dialog_example3(): ui.text_field(label="Last Name"), ui.text_field(label="Street Address"), ui.text_field(label="City"), - ui.checkbox( - "I want to receive updates for exclusive offers in my area." - ), ) ), + ui.footer( + ui.checkbox("I want to receive updates for exclusive offers."), + ), ui.button_group( ui.button("Cancel", variant="secondary", on_press=set_open.off), ui.button("Register", variant="accent", on_press=set_open.off), @@ -319,4 +320,6 @@ my_large_example = large_example() ```{eval-rst} .. dhautofunction:: deephaven.ui.dialog +.. dhautofunction:: deephaven.ui.content +.. dhautofunction:: deephaven.ui.footer ``` diff --git a/plugins/ui/docs/sidebar.json b/plugins/ui/docs/sidebar.json index 6f56bb6b7..8ccc25bf5 100644 --- a/plugins/ui/docs/sidebar.json +++ b/plugins/ui/docs/sidebar.json @@ -184,6 +184,10 @@ "label": "form", "path": "components/form.md" }, + { + "label": "footer", + "path": "components/footer.md" + }, { "label": "fragment", "path": "components/fragment.md" diff --git a/plugins/ui/src/deephaven/ui/components/__init__.py b/plugins/ui/src/deephaven/ui/components/__init__.py index feb0b1360..477508aa4 100644 --- a/plugins/ui/src/deephaven/ui/components/__init__.py +++ b/plugins/ui/src/deephaven/ui/components/__init__.py @@ -26,6 +26,7 @@ from .divider import divider from .flex import flex from .form import form +from .footer import footer from .fragment import fragment from .heading import heading from .grid import grid @@ -107,6 +108,7 @@ "divider", "flex", "form", + "footer", "fragment", "grid", "heading", diff --git a/plugins/ui/src/deephaven/ui/components/content.py b/plugins/ui/src/deephaven/ui/components/content.py index b3d4bc0c5..aca1c3c57 100644 --- a/plugins/ui/src/deephaven/ui/components/content.py +++ b/plugins/ui/src/deephaven/ui/components/content.py @@ -101,6 +101,9 @@ def content( UNSAFE_class_name: A CSS class to apply to the element. UNSAFE_style: A CSS style to apply to the element. key: A unique identifier used by React to render elements in a list. + + Returns: + The rendered content element. """ return component_element( "Content", diff --git a/plugins/ui/src/deephaven/ui/components/footer.py b/plugins/ui/src/deephaven/ui/components/footer.py new file mode 100644 index 000000000..1f2b57fb5 --- /dev/null +++ b/plugins/ui/src/deephaven/ui/components/footer.py @@ -0,0 +1,151 @@ +from __future__ import annotations + +from .basic import component_element +from ..elements import Element, NodeType +from .types import ( + AlignSelf, + CSSProperties, + DimensionValue, + JustifySelf, + LayoutFlex, + Position, +) + + +def footer( + *children: NodeType, + 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, + key: str | None = None, +) -> Element: + """ + A footer for a document or section. + + Args: + *children: The items to render within the footer. + 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. + UNSAFE_class_name: A CSS class to apply to the element. + UNSAFE_style: A CSS style to apply to the element. + key: A unique identifier used by React to render elements in a list. + + + Returns: + The rendered footer element. + """ + return component_element( + "Footer", + children=children, + 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_column=grid_column, + grid_row=grid_row, + grid_column_start=grid_column_start, + grid_column_end=grid_column_end, + grid_row_start=grid_row_start, + grid_row_end=grid_row_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, + min_width=min_width, + max_width=max_width, + height=height, + min_height=min_height, + max_height=max_height, + position=position, + top=top, + bottom=bottom, + left=left, + right=right, + start=start, + end=end, + z_index=z_index, + is_hidden=is_hidden, + id=id, + UNSAFE_class_name=UNSAFE_class_name, + UNSAFE_style=UNSAFE_style, + key=key, + ) diff --git a/plugins/ui/src/js/src/elements/model/ElementConstants.ts b/plugins/ui/src/js/src/elements/model/ElementConstants.ts index 79cdbb8b3..2e76a0664 100644 --- a/plugins/ui/src/js/src/elements/model/ElementConstants.ts +++ b/plugins/ui/src/js/src/elements/model/ElementConstants.ts @@ -46,6 +46,7 @@ export const ELEMENT_NAME = { divider: uiComponentName('Divider'), flex: uiComponentName('Flex'), form: uiComponentName('Form'), + footer: uiComponentName('Footer'), fragment: uiComponentName('Fragment'), grid: uiComponentName('Grid'), heading: uiComponentName('Heading'), diff --git a/plugins/ui/src/js/src/widget/WidgetUtils.tsx b/plugins/ui/src/js/src/widget/WidgetUtils.tsx index fd816e5ee..c94dfb9a8 100644 --- a/plugins/ui/src/js/src/widget/WidgetUtils.tsx +++ b/plugins/ui/src/js/src/widget/WidgetUtils.tsx @@ -15,6 +15,7 @@ import { ContextualHelpTrigger, DialogTrigger, Divider, + Footer, Heading, Item, Link, @@ -148,6 +149,7 @@ export const elementComponentMap: Record, unknown> = { [ELEMENT_NAME.divider]: Divider, [ELEMENT_NAME.flex]: Flex, [ELEMENT_NAME.form]: Form, + [ELEMENT_NAME.footer]: Footer, [ELEMENT_NAME.fragment]: React.Fragment, [ELEMENT_NAME.grid]: Grid, [ELEMENT_NAME.heading]: Heading, diff --git a/tests/app.d/ui_render_all.py b/tests/app.d/ui_render_all.py index 819f394a6..177f49a2e 100644 --- a/tests/app.d/ui_render_all.py +++ b/tests/app.d/ui_render_all.py @@ -77,6 +77,7 @@ def ui_components1(): @ui.component def ui_components2(): return ( + ui.footer("© All rights reserved."), ui.fragment("Fragment"), ui.grid("Grid A", "Grid B"), ui.heading("Heading"), 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 ccf926bb3..be1196193 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 ee99dc4d4..14cd62e40 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 4ced905b5..045beb3d7 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