Skip to content

Commit

Permalink
fix: ToggleButtons would get incorrect values
Browse files Browse the repository at this point in the history
We were finding values for whatever elements in the children of togglebuttons had a `value` or `label` prop.
Now we properly loop through children (and activators of tooltip/menu, etc), and only get values for Buttons.
  • Loading branch information
iisakkirotko committed Nov 25, 2024
1 parent 8ad06aa commit a9225e7
Showing 1 changed file with 46 additions and 7 deletions.
53 changes: 46 additions & 7 deletions solara/components/togglebuttons.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,31 @@ def _get_button_value(button: reacton.core.Element):
return value


def _get_real_children(element: reacton.core.Element) -> List[reacton.core.Element]:
# Some elements, like menus and tooltips have a v_slots attribute that contains the children
if "v_slots" in element.kwargs and element.kwargs["v_slots"]:
children = []
for slot in element.kwargs["v_slots"]:
if slot["name"] == "activator":
children.extend(slot["children"])
return children
else:
return element.kwargs.get(element.child_prop_name, [])


def _get_child_values(children: List[reacton.core.Element]):
values = []
for child in children:
child_widget = solara.get_widget(child)
if isinstance(child_widget, v.Btn):
values.append(_get_button_value(child))
else:
nested_children = _get_real_children(child)
if len(nested_children) > 0:
values.extend(_get_child_values(nested_children))
return values


@overload
@solara.value_component(None)
def ToggleButtonsSingle(
Expand Down Expand Up @@ -120,18 +145,25 @@ def Page():
# the typechecker
reactive_value = solara.use_reactive(value, on_value) # type: ignore
children = [solara.Button(label=str(value)) for value in values] + children
values = values + [_get_button_value(button) for button in children] # type: ignore
all_values: solara.Reactive[List[T]] = solara.use_reactive([])
# When mandatory = True, index should not be None, but we are letting the front-end take care of setting index to 0 because of a bug
# (see https://github.com/widgetti/solara/issues/282)
# TODO: set index to 0 on python side (after #282 is resolved)
index, set_index = solara.use_state_or_update(values.index(reactive_value.value) if reactive_value.value in values else None, key="index")
index, set_index = solara.use_state_or_update(
all_values.value.index(reactive_value.value) if reactive_value.value in all_values.value else None, key="index"
)

def update_values():
all_values.set(_get_child_values(children))

solara.use_effect(update_values, children)

def on_index(index):
set_index(index)
if mandatory:
value = values[index]
value = all_values.value[index]
else:
value = values[index] if index is not None else None
value = all_values.value[index] if index is not None else None
reactive_value.set(value)

return cast(
Expand Down Expand Up @@ -184,12 +216,19 @@ def Page():
# See comment regarding typing issue in ToggleButtonsSingle
reactive_value = solara.use_reactive(value, on_value) # type: ignore
children = [solara.Button(label=str(value)) for value in values] + children
allvalues = values + [_get_button_value(button) for button in children]
indices, set_indices = solara.use_state_or_update([allvalues.index(k) for k in reactive_value.value], key="index")
allvalues: solara.Reactive[List[T]] = solara.use_reactive([])
indices, set_indices = solara.use_state_or_update(cast(List[int], []), key="index")

def update_values():
values = _get_child_values(children)
allvalues.set(values)
set_indices([values.index(item) for item in reactive_value.value])

solara.use_effect(update_values, children)

def on_indices(indices):
set_indices(indices)
value = [allvalues[k] for k in indices]
value = [allvalues.value[k] for k in indices]
reactive_value.set(value)

return cast(
Expand Down

0 comments on commit a9225e7

Please sign in to comment.