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: allow overflow by default on ui.panel #896

Merged
merged 9 commits into from
Sep 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 2 additions & 2 deletions plugins/ui/src/deephaven/ui/components/grid.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@ def grid(
justify_content: JustifyContent = "stretch",
align_content: AlignContent = "start",
align_items: AlignItems = "stretch",
gap: DimensionValue | None = None,
gap: DimensionValue | None = "size-100",
column_gap: DimensionValue | None = None,
row_gap: DimensionValue | None = None,
flex: LayoutFlex | None = None,
flex: LayoutFlex | None = "auto",
flex_grow: float | None = None,
flex_shrink: float | None = None,
flex_basis: DimensionValue | None = None,
Expand Down
2 changes: 2 additions & 0 deletions plugins/ui/src/deephaven/ui/components/panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
AlignContent,
AlignItems,
DimensionValue,
Overflow,
)


Expand All @@ -24,6 +25,7 @@ def panel(
gap: DimensionValue | None = "size-100",
column_gap: DimensionValue | None = None,
row_gap: DimensionValue | None = None,
overflow: Overflow | None = "auto",
padding: DimensionValue | None = "size-100",
padding_top: DimensionValue | None = None,
padding_bottom: DimensionValue | None = None,
Expand Down
3 changes: 3 additions & 0 deletions plugins/ui/src/deephaven/ui/components/types/layout.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,9 @@
"legacy center",
]


Overflow = Union[Literal["visible", "hidden", "clip", "scroll", "auto"], str]

OverflowMode = Literal["wrap", "collapse"]

Alignment = Literal["start", "end"]
Expand Down
22 changes: 22 additions & 0 deletions plugins/ui/src/js/src/elements/Flex.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import React from 'react';
import {
Flex as DHCFlex,
FlexProps as DHCFlexProps,
} from '@deephaven/components';

import classNames from 'classnames';

export function Flex({
UNSAFE_className,
...restProps
}: DHCFlexProps): JSX.Element {
return (
<DHCFlex
UNSAFE_className={classNames('dh-flex', UNSAFE_className)}
// eslint-disable-next-line react/jsx-props-no-spreading
{...restProps}
/>
);
}

export default Flex;
22 changes: 22 additions & 0 deletions plugins/ui/src/js/src/elements/Grid.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import React from 'react';
import {
Grid as DHCGrid,
GridProps as DHCGridProps,
} from '@deephaven/components';

import classNames from 'classnames';

export function Grid({
UNSAFE_className,
...restProps
}: DHCGridProps): JSX.Element {
return (
<DHCGrid
UNSAFE_className={classNames('dh-grid', UNSAFE_className)}
// eslint-disable-next-line react/jsx-props-no-spreading
{...restProps}
/>
);
}

export default Grid;
4 changes: 4 additions & 0 deletions plugins/ui/src/js/src/elements/Tabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
} from '@deephaven/components';
import { isElementOfType } from '@deephaven/react-hooks';
import { ensureArray } from '@deephaven/utils';
import classNames from 'classnames';
import { TabPanels } from './TabPanels';

type TabProps = {
Expand Down Expand Up @@ -81,6 +82,7 @@ export function Tabs(props: TabComponentProps): JSX.Element {
children,
onSelectionChange: onSelectionChangeProp,
onChange,
UNSAFE_className,
...otherTabProps
} = props;
const childrenArray = useMemo(() => ensureArray(children), [children]);
Expand Down Expand Up @@ -137,6 +139,7 @@ export function Tabs(props: TabComponentProps): JSX.Element {
return (
<DHCTabs
onSelectionChange={onSelectionChange}
UNSAFE_className={classNames('dh-tabs', UNSAFE_className)}
// eslint-disable-next-line react/jsx-props-no-spreading
{...otherTabProps}
>
Expand All @@ -148,6 +151,7 @@ export function Tabs(props: TabComponentProps): JSX.Element {
return (
<DHCTabs
onSelectionChange={onSelectionChange}
UNSAFE_className={classNames('dh-tabs', UNSAFE_className)}
// eslint-disable-next-line react/jsx-props-no-spreading
{...otherTabProps}
>
Expand Down
2 changes: 2 additions & 0 deletions plugins/ui/src/js/src/elements/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ export * from './ComboBox';
export * from './DateField';
export * from './DatePicker';
export * from './DateRangePicker';
export * from './Flex';
export * from './Form';
export * from './Grid';
export * from './hooks';
export * from './HTMLElementView';
export * from './IconElementView';
Expand Down
5 changes: 4 additions & 1 deletion plugins/ui/src/js/src/layout/ReactPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ interface Props
| 'paddingEnd'
| 'paddingX'
| 'paddingY'
| 'overflow'
| 'UNSAFE_style'
| 'UNSAFE_className'
>,
Expand Down Expand Up @@ -64,6 +65,7 @@ function ReactPanel({
backgroundColor,
direction = 'column',
wrap,
overflow = 'auto',
justifyContent,
alignContent,
alignItems = 'start',
Expand Down Expand Up @@ -182,6 +184,7 @@ function ReactPanel({
<ReactPanelContext.Provider value={panelId}>
<View
height="100%"
width="100%"
backgroundColor={backgroundColor}
padding={padding}
paddingTop={paddingTop}
Expand All @@ -190,6 +193,7 @@ function ReactPanel({
paddingEnd={paddingEnd}
paddingX={paddingX}
paddingY={paddingY}
overflow={overflow}
UNSAFE_style={UNSAFE_style}
UNSAFE_className={
UNSAFE_className == null
Expand All @@ -199,7 +203,6 @@ function ReactPanel({
>
<Flex
UNSAFE_className="dh-inner-react-panel"
height="100%"
wrap={wrap}
direction={direction}
justifyContent={justifyContent}
Expand Down
48 changes: 44 additions & 4 deletions plugins/ui/src/js/src/styles.scss
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
@import '@deephaven/components/scss/custom.scss';

.ui-portal-panel {
display: contents;
height: 100%;
width: 100%;
position: relative;
overflow: hidden;
}

.ui-object-container {
Expand All @@ -10,9 +13,46 @@
}

.dh-react-panel {
.dh-inner-react-panel .iris-grid {
border: 1px solid var(--dh-color-bg);
border-radius: $border-radius;
// using grid to allow the panel to grow to fill the container
// without having to set the width/height explicitly
// so that overflow will include it's padding
display: grid;

.dh-inner-react-panel {
// forces the panel to have an intrinsic size
// 100% width items shrink to fit the container
min-width: 0;

// todo out tuesday, devins thing, panels thing
// clem needs a thing as well
// import blog articles

// inner-panel is flex with align-start
// so that things like buttons don't stretch
// but we still want child flex/grid items to stretch
> .dh-flex,
> .dh-grid {
align-self: stretch;
}

.dh-tabs {
flex: auto;
height: 100%;
}

.iris-grid {
// we don't want the grid to ever collapse to 0 height, so we set a min-height
// let's users know that the grid is there
min-height: 70px;
border: 1px solid var(--dh-color-bg);
border-radius: $border-radius;

canvas {
// setting canvas t0 position absolute
// removes the canvas from the normal flow
position: absolute;
}
}
}

&:has(.dh-inner-react-panel > .iris-grid:only-child),
Expand Down
5 changes: 2 additions & 3 deletions plugins/ui/src/js/src/widget/WidgetUtils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ import {
SpectrumCheckbox as Checkbox,
Content,
ContextualHelp,
Flex,
Grid,
Heading,
Item,
ListActionGroup,
Expand Down Expand Up @@ -54,7 +52,9 @@ import {
DateField,
DatePicker,
DateRangePicker,
Flex,
Form,
Grid,
IllustratedMessage,
Image,
ListView,
Expand Down Expand Up @@ -177,7 +177,6 @@ export function getComponentForElement(element: ElementNode): React.ReactNode {
</ContextualHelp>
);
}

return <Component {...props} />;
}
}
Expand Down
3 changes: 2 additions & 1 deletion tests/app.d/tests.app
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ name=Plugins Test Application
file_0=express.py
file_1=matplotlib.py
file_2=ui.py
file_3=ui_render_all.py
file_3=ui_render_all.py
file_4=ui_flex.py
85 changes: 85 additions & 0 deletions tests/app.d/ui_flex.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
from deephaven import ui
from deephaven.plot import express as dx
from deephaven import empty_table

_t_flex = empty_table(100).update(["x = i", "y = sin(i)"])
_p_flex = dx.line(_t_flex, x="x", y="y")


@ui.component
def ui_flex_text_field_input_types_examples():
return [
ui.form(
ui.text_field(label="Name", type="text", is_required=True),
ui.text_field(label="Personal Website", type="url", is_required=True),
ui.text_field(label="Phone", type="tel", is_required=True),
ui.text_field(label="Email", type="email", is_required=True),
ui.text_field(label="Password", type="password", is_required=True),
ui.text_field(label="Search Bar", type="search"),
validation_behavior="native",
),
_t_flex,
]


@ui.component
def ui_flex_test_component():
return [ui.text_field(), _t_flex, _t_flex]


flex_0 = ui_flex_test_component()
flex_1 = ui_flex_text_field_input_types_examples()
flex_2 = ui.panel(_t_flex, _t_flex, background_color="red")
flex_3 = ui.button("test")
flex_4 = ui.text_field(label="test", label_position="side")
flex_5 = ui.panel(
ui.flex(_t_flex, _t_flex, direction="column"), background_color="blue"
)
flex_6 = ui.panel(ui.flex(_t_flex, _t_flex, direction="row"), background_color="green")
flex_7 = ui.panel(_t_flex, _p_flex, direction="row")
flex_8 = ui.panel(_t_flex, _p_flex)
flex_9 = ui.panel(ui.text_field(label="test"), _t_flex)
flex_10 = ui.panel(
ui.flex(ui.flex(_t_flex, _t_flex), ui.button("hello")), ui.text_field()
)
flex_11 = ui.panel(
ui.flex(ui.flex(_p_flex, _p_flex), ui.button("hello")), ui.text_field()
)
flex_12 = ui.panel(_p_flex, _p_flex, direction="row")
flex_13 = ui.panel(_p_flex, _p_flex)
flex_14 = ui.flex(
ui.button("hello flex"), align_items="center", justify_content="center"
)
flex_15 = ui.panel(
ui.button("hello panel"), align_items="center", justify_content="center"
)
flex_16 = ui.panel(ui.flex(ui.flex(_t_flex, _t_flex)))
flex_17 = ui.panel(
ui.flex(ui.button("test"), ui.action_button("test"), direction="column")
)
flex_18 = ui.panel(
ui.form(
ui.text_field(label="Name", label_position="side"),
ui.text_field(label="Name", label_position="side"),
ui.text_field(label="Name", label_position="side"),
ui.text_field(label="Name", label_position="side"),
),
)
flex_19 = ui.panel(
ui.grid(ui.button("test"), _t_flex, _p_flex, rows="min-content 1fr 1fr")
)
flex_20 = ui.panel(
ui.tabs(
ui.tab(_p_flex, title="Tab A"),
ui.tab(_t_flex, title="Tab B"),
)
)
flex_21 = ui.panel(
ui.button("Test"),
ui.tabs(
ui.tab(_p_flex, title="Tab A"),
ui.tab(_t_flex, title="Tab B"),
),
ui.button("Test"),
_t_flex,
)
45 changes: 45 additions & 0 deletions tests/ui.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,48 @@ test('UI all components render 2', async ({ page }) => {
await openPanel(page, 'ui_render_all2', selector.REACT_PANEL_VISIBLE);
await expect(page.locator(selector.REACT_PANEL_VISIBLE)).toHaveScreenshot();
});

// Tests flex components render as expected
test.describe('UI flex components', () => {
[
{ name: 'flex_0', traces: 0 },
{ name: 'flex_1', traces: 0 },
{ name: 'flex_2', traces: 0 },
{ name: 'flex_3', traces: 0 },
{ name: 'flex_4', traces: 0 },
{ name: 'flex_5', traces: 0 },
{ name: 'flex_6', traces: 0 },
{ name: 'flex_7', traces: 1 },
{ name: 'flex_8', traces: 1 },
{ name: 'flex_9', traces: 0 },
{ name: 'flex_10', traces: 0 },
{ name: 'flex_11', traces: 2 },
{ name: 'flex_12', traces: 2 },
{ name: 'flex_13', traces: 2 },
{ name: 'flex_14', traces: 0 },
{ name: 'flex_15', traces: 0 },
{ name: 'flex_16', traces: 0 },
{ name: 'flex_17', traces: 0 },
{ name: 'flex_18', traces: 0 },
{ name: 'flex_19', traces: 1 },
{ name: 'flex_20', traces: 1 },
{ name: 'flex_21', traces: 1 },
].forEach(i => {
test(i.name, async ({ page }) => {
await gotoPage(page, '');
await openPanel(page, i.name, selector.REACT_PANEL_VISIBLE);

// need to wait for plots to be loaded before taking screenshot
// easiest way to check that is if the traces are present
if (i.traces > 0) {
await expect(
await page.locator(selector.REACT_PANEL_VISIBLE).locator('.trace')
).toHaveCount(i.traces);
}

await expect(
page.locator(selector.REACT_PANEL_VISIBLE)
).toHaveScreenshot();
});
});
});
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified tests/ui.spec.ts-snapshots/UI-loads-1-chromium-linux.png
Binary file modified tests/ui.spec.ts-snapshots/UI-loads-1-firefox-linux.png
Binary file modified tests/ui.spec.ts-snapshots/UI-loads-1-webkit-linux.png
Loading
Loading