snehilvj / dash-mantine-components

Plotly Dash components based on Mantine React Components
https://www.dash-mantine-components.com
MIT License
583 stars 61 forks source link

SegmentedControl: Cannot read properties of null (reading 'getBoundingClientRect') #215

Closed dgmcrae closed 2 months ago

dgmcrae commented 1 year ago

I have a dmc.SegmentedControl in my layout using dash-mantine-components 0.12.1, with the data property populated by callback based on selection from a MultiSelect menu. I am experiencing a very similar issue to the one described in this issue log for SegmentedControl Mantine Components: https://github.com/mantinedev/mantine/issues/4122, whereby if the currently selected value in the dmc.SegmentedControl is 'A' and I delete 'A' from the MultiSelect, it causes a callback error with the error message: Cannot read properties of null (reading 'getBoundingClientRect'). The same error can also be triggered (less reliably but quite often) by clearing the selection of the MultiSelect altogether, and then making a new selection in the MultiSelect that was not in the selection when cleared (eg if 'A', 'B', 'C' were selected, then cleared, choose 'D' to trigger the same callback error).

The Mantine Component issue report lists the issue as resolved in version 7.0.1 - is it possible the fix is not reflected in dmc?

Thanks for all your work on what is a fantastic library!

AnnMarieW commented 2 months ago

Hi @dgmcrae I expect this has been fixed since dmc 14 uses Mantine 7.

I'm not sure I clearly understand the issue. Could you please make a minimal example that reproduces the issue?

dgmcrae commented 2 months ago

@AnnMarieW, Thanks for following up on this, and for your helpful response to the other issue I posted as well. I've pasted a minimal example below that demonstrates the issue in 0.12.1; I've run the same example in dmc 14 as well and can confirm that it is fixed in the newer version.

  from dash import Dash, html, dcc, callback, Output, Input
  import dash_mantine_components as dmc

  dropdown = html.Div(
      [
          dmc.MultiSelect(
              label="Select a letter",
              id="dropdown-selection",
              placeholder="Select all you like!",
              value=[],
              data=["a", "b", "c", "d"],
          )
      ]
  )

  segmented = html.Div(
      children=[
          dmc.Text(
              "Choose multiple letters in the MultiSelect, highlight one in the SegmentedControl, then de-select in the MultiSelect. Callback error."
          ),
          dmc.SegmentedControl(
              id="segmented-dynamic-data",
              value="",
              data=[],
              mt=10,
          ),
      ]
  )
  radio = html.Div(
      [
          dmc.Text(
              "Choose multiple letters in the MultiSelect, choose one in the RadioItems, then de-select in the MultiSelect. No problem."
          ),
          dcc.RadioItems(id="radio-dynamic-data", value="", options=[]),
      ]
  )

  if __name__ == "__main__":
      app = Dash(__name__)

      @app.callback(
          Output("segmented-dynamic-data", "data"),
          Output("radio-dynamic-data", "options"),
          Input("dropdown-selection", "value"),
      )
      def populate_dynamic_segmentedcontrol_and_radio(selection):
          return (selection, selection)

      app.layout = html.Div(
          children=[
              dropdown,
              radio,
              segmented,
          ]
      )

      app.run(debug=True)
AnnMarieW commented 2 months ago

@dgmcrae,

Thanks for the example and confirming it works in the latest version 🎉