widgetti / solara

A Pure Python, React-style Framework for Scaling Your Jupyter and Web Apps
https://solara.dev
MIT License
1.9k stars 141 forks source link

Radio Input Component #166

Open RaviNaik opened 1 year ago

RaviNaik commented 1 year ago

Hi,

It would be great to have a Radio Button component for input selection. I can see Radio and RadioGroup components in reacton.ipyvuetify. But there are no examples about the state updates. Can anyone please let me know how can I modify the below snippet to have the radio input value in state?

import solara
import reacton.ipyvuetify as rv

region, set_region = solara.use_state("Africa")
with rv.RadioGroup(label="Region", value=region):
    rv.Radio(label="Africa", value="Africa")
    rv.Radio(label="Americas", value="Americas")
    rv.Radio(label="Asia", value="Asia")
    rv.Radio(label="Europe", value="Europe")
    rv.Radio(label="Oceania", value="Oceania")
    rv.Radio(label="All", value="All")

print(region)

Thanks

Jhsmit commented 1 year ago

You can update the state via rv.RadioGroup's v_model and on_v_model:

REGIONS = [
    "Africa",
    "Americas",
    "Asia",
    "Europe",
    "Oceania",
    "All",
]

@solara.component
def RegionSelector(value, regions: list[str]):
    region = solara.use_reactive(value)

    with rv.RadioGroup(label="Region", v_model=region.value, on_v_model=region.set)):
        for _region in regions:
            rv.Radio(label=_region, value=_region)

@solara.component
def Page():
    region = solara.use_reactive("Africa")
    RegionSelector(region, REGIONS)

    text = solara.Text(f"Current region: {region.value}")
    rnd_btn = solara.Button("Randomize", on_click=lambda: region.set(random.choice(REGIONS)))
maartenbreddels commented 1 year ago

Nice @Jhsmit

Small tweak, you can drop the lambda:

with rv.RadioGroup(label="Region", v_model=region.value, on_v_model=region.set):
RaviNaik commented 1 year ago

Thanks @Jhsmit. Your solution works. I have modified the code a bit to be more generic and the ability to use solara.use_state. @maartenbreddels it would be great if we can add Radio to solara components rather than using it via reacton.

A generic code for Radio:

import solara
import reacton.ipyvuetify as rv

@solara.component
def Radio(label, value, values, on_value):
    value_ = solara.use_reactive(value, on_value)
    del value, on_value
    with rv.RadioGroup(label=label, v_model=value_.value, on_v_model=value_.set):
        for _value in values:
            rv.Radio(label=_value, value=_value)

REGIONS = ["Africa",
           "Americas",
           "Asia",
           "Europe",
           "Oceania",
           "All"]

@solara.component
def Page():
    region, set_region = solara.use_state("Asia")
    Radio(label="Select A Region", value=region, 
          on_value=set_region,values=REGIONS)
    solara.Markdown(f"current region is {region}")

Thanks

maartenbreddels commented 1 year ago

Does it make sense to have something like that? I wonder if we lose the flexibility of layout?

If we should add it, we can use https://github.com/widgetti/solara/pull/185 by @lp9052 as a template on how to add a new component