posit-dev / py-shinywidgets

Render ipywidgets inside a PyShiny app
MIT License
41 stars 2 forks source link

`render_widget` now attaches it's return value to the decorated function #119

Closed cpsievert closed 5 months ago

cpsievert commented 7 months ago

This PR helps solve the problem of needing a widget object in scope if you want to set/get attribute values, and thus, effectively eliminates any need for register_widget()

TODO

Example/testing app

import ipyleaflet as ipyl
from shiny import reactive, render, ui
from shiny.express import input

from shinywidgets import reactive_read, render_widget

print("A")

@render.text
def center():
    print("@render.text")
    cntr = reactive_read(map.widget, 'center')
    return f"Current center: {cntr}"

print("B")

@render_widget
def map():
    print("@render_widget")
    return ipyl.Map(zoom=input.zoom(), center=(0, 0))

print("C")
print("Widget value:", map.widget)

ui.input_slider("zoom", "Zoom", min=1, max=7, value=2, step=0.5)
schloerke commented 5 months ago
  • Can we provide typing/autocomplete on render_func.widget/render_func.value?

We currently have support for render_func.value, but not for render_func.widget. To get render_func.widget, we'd need to have special methods like @render_plotly as the widget class is not provided by the user but could be provided by the renderer's typing.

I've added a commented render_plotly method as a working prof-of-concept

schloerke commented 5 months ago
  • Deprecate register_widget()?

See #127 . This can be done in a followup PR

schloerke commented 5 months ago

I am strongly against doing render_fn.value or render_fn.widget and have it call any reactivity.

py-shiny did not implement reactive values for clarity. I'm going to continue with that approach and make helper methods for reactive_read() / reactive_depend() on the render_widget class.