Setting up widgets with a param can be confusing

I did not know whether to create an issue or just report here.
I noticed there are many ways to set up a widgets using a param, but they are not equal in terms of interactivity and layout. This can be confusing specially for people new to the ecosystem.

Let’s take a switch as an example, and create it in various ways.

import panel as pn
import param
pn.extension()

class Params(param.Parameterized):
    enabled = param.Boolean(default=False)
    
p = Params()
pn.Column(pn.widgets.Switch(value=p.enabled),     # 1. read once (makes sense, since we are setting a value)
          pn.widgets.Switch(value=pn.bind(lambda v: v, p.param.enabled)), # 2. read but can not write
          pn.widgets.Switch.from_param(p.param.enabled),       # 3. read/write
          pn.widgets.Switch(value=p.param.enabled),            # 4. read but can not write?!
          pn.Param(p.param.enabled, widgets={'enabled': {'widget_type': pn.widgets.Switch}}),  # 5. read/write
         )

Of these, I think 4 is the most surprising. I believe, however, that it is expected behavior and may actually change with Implement support for allowing Parameter references by philippjfr · Pull Request #843 · holoviz/param · GitHub , after which it will potentially become a read/write setup.

Second, it is a bit weird that the indentation is different for the last option.
2023-10-19 13.00.12

I don’t have a specific ask other than a suggestion to maybe improve the docs, but I thought it may be helpful to share this as it may save someone some time.

1 Like

That’s a useful list!

I’d guess that the last option is creating a container that then has one item in it, which is why it’s different in indentation. That may be something that could be fixed, but it’s a good reason why it would differ; a block of widgets isn’t necessarily the same as a single widget.