Skip to content

Commit

Permalink
Merge pull request #353 from AnnMarieW/controlled-popover
Browse files Browse the repository at this point in the history
controlled popover
  • Loading branch information
AnnMarieW authored Oct 14, 2024
2 parents afc5951 + cd9542e commit 9526983
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 4 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,13 @@ Note: `Chip` was available before but not documented. If you used `Chip` in dmc<
- Added new and missing props to the charts #349 by @AnnMarieW



### Fixed

- Excluded the `loading_state` prop from being passed to the DOM. Added `data-dash-is-loading` attribute to
components during callback execution, allowing custom CSS styling for loading states. #325 by @AnnMarieW
- Enabled the `opened` prop to trigger callback #353 by @AnnMarieW


### Changed

Expand Down
19 changes: 15 additions & 4 deletions src/ts/components/core/popover/Popover.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,34 @@ import React from "react";

interface Props extends PopoverProps, DashBaseProps {}

/** Popover */
/** Popover Component */
const Popover = (props: Props) => {
const { children, setProps, loading_state, ...others } = props;
const { children, opened, setProps, loading_state, ...others } = props;

return (
<MantinePopover
data-dash-is-loading={
(loading_state && loading_state.is_loading) || undefined
}
opened={opened}
onClose={() => setProps({ opened: false })}
{...others}
>
{React.Children.map(children, (child: any, index) => {
const childType = child.props._dashprivate_layout.type;

if (childType === "PopoverTarget") {
const { boxWrapperProps } = child.props;
const boxProps = { w: "fit-content", ...boxWrapperProps };

return (
<MantinePopover.Target key={index}>
<Box {...boxProps}>{child}</Box>
<Box
onClick={() => setProps({ opened: !opened })}
{...boxProps}
>
{child}
</Box>
</MantinePopover.Target>
);
}
Expand All @@ -33,6 +42,8 @@ const Popover = (props: Props) => {
);
};

Popover.defaultProps = {};
Popover.defaultProps = {
opened: false,
};

export default Popover;
42 changes: 42 additions & 0 deletions tests/test_popover.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
from dash import Dash, html, Output, Input, _dash_renderer
import dash_mantine_components as dmc

_dash_renderer._set_react_version("18.2.0")

def test_001po_popover(dash_duo):
app = Dash(__name__)

app.layout = dmc.MantineProvider(
html.Div([
dmc.Popover(
[dmc.PopoverTarget(dmc.Button("Toggle Popover", id="btn")),
dmc.PopoverDropdown(dmc.Text("This popover is opened"))],
id='popover',
opened=False
),
html.Div(id='output')
])
)

@app.callback(
Output('output', 'children'),
Input('popover', 'opened')
)
def update_output(opened):
return str(opened)

dash_duo.start_server(app)

# Wait for the app to load
dash_duo.wait_for_text_to_equal("#output", "False")

popover_btn = dash_duo.find_element("#btn")
popover_btn.click()

# Verify the output
dash_duo.wait_for_text_to_equal("#output", "True")

popover_btn.click()
dash_duo.wait_for_text_to_equal("#output", "False")

assert dash_duo.get_logs() == []

0 comments on commit 9526983

Please sign in to comment.