Skip to content

Commit a9225e7

Browse files
committed
fix: ToggleButtons would get incorrect values
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.
1 parent 8ad06aa commit a9225e7

File tree

1 file changed

+46
-7
lines changed

1 file changed

+46
-7
lines changed

solara/components/togglebuttons.py

Lines changed: 46 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,31 @@ def _get_button_value(button: reacton.core.Element):
2121
return value
2222

2323

24+
def _get_real_children(element: reacton.core.Element) -> List[reacton.core.Element]:
25+
# Some elements, like menus and tooltips have a v_slots attribute that contains the children
26+
if "v_slots" in element.kwargs and element.kwargs["v_slots"]:
27+
children = []
28+
for slot in element.kwargs["v_slots"]:
29+
if slot["name"] == "activator":
30+
children.extend(slot["children"])
31+
return children
32+
else:
33+
return element.kwargs.get(element.child_prop_name, [])
34+
35+
36+
def _get_child_values(children: List[reacton.core.Element]):
37+
values = []
38+
for child in children:
39+
child_widget = solara.get_widget(child)
40+
if isinstance(child_widget, v.Btn):
41+
values.append(_get_button_value(child))
42+
else:
43+
nested_children = _get_real_children(child)
44+
if len(nested_children) > 0:
45+
values.extend(_get_child_values(nested_children))
46+
return values
47+
48+
2449
@overload
2550
@solara.value_component(None)
2651
def ToggleButtonsSingle(
@@ -120,18 +145,25 @@ def Page():
120145
# the typechecker
121146
reactive_value = solara.use_reactive(value, on_value) # type: ignore
122147
children = [solara.Button(label=str(value)) for value in values] + children
123-
values = values + [_get_button_value(button) for button in children] # type: ignore
148+
all_values: solara.Reactive[List[T]] = solara.use_reactive([])
124149
# 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
125150
# (see https://github.com/widgetti/solara/issues/282)
126151
# TODO: set index to 0 on python side (after #282 is resolved)
127-
index, set_index = solara.use_state_or_update(values.index(reactive_value.value) if reactive_value.value in values else None, key="index")
152+
index, set_index = solara.use_state_or_update(
153+
all_values.value.index(reactive_value.value) if reactive_value.value in all_values.value else None, key="index"
154+
)
155+
156+
def update_values():
157+
all_values.set(_get_child_values(children))
158+
159+
solara.use_effect(update_values, children)
128160

129161
def on_index(index):
130162
set_index(index)
131163
if mandatory:
132-
value = values[index]
164+
value = all_values.value[index]
133165
else:
134-
value = values[index] if index is not None else None
166+
value = all_values.value[index] if index is not None else None
135167
reactive_value.set(value)
136168

137169
return cast(
@@ -184,12 +216,19 @@ def Page():
184216
# See comment regarding typing issue in ToggleButtonsSingle
185217
reactive_value = solara.use_reactive(value, on_value) # type: ignore
186218
children = [solara.Button(label=str(value)) for value in values] + children
187-
allvalues = values + [_get_button_value(button) for button in children]
188-
indices, set_indices = solara.use_state_or_update([allvalues.index(k) for k in reactive_value.value], key="index")
219+
allvalues: solara.Reactive[List[T]] = solara.use_reactive([])
220+
indices, set_indices = solara.use_state_or_update(cast(List[int], []), key="index")
221+
222+
def update_values():
223+
values = _get_child_values(children)
224+
allvalues.set(values)
225+
set_indices([values.index(item) for item in reactive_value.value])
226+
227+
solara.use_effect(update_values, children)
189228

190229
def on_indices(indices):
191230
set_indices(indices)
192-
value = [allvalues[k] for k in indices]
231+
value = [allvalues.value[k] for k in indices]
193232
reactive_value.set(value)
194233

195234
return cast(

0 commit comments

Comments
 (0)