Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Jul 14, 2025

Problem

When using shiny.express.ui.accordion_panel() with insert_accordion_panel(), the app would throw an error:

Unhandled error: 'RecallContextManager' object has no attribute 'resolve'

This occurred because:

  • shiny.ui.accordion_panel() returns an AccordionPanel object directly
  • shiny.express.ui.accordion_panel() returns a RecallContextManager[AccordionPanel]
  • insert_accordion_panel() expected an AccordionPanel and called .resolve() on it
  • RecallContextManager doesn't have a .resolve() method

Solution

Modified insert_accordion_panel() to handle both types:

# Before the fix - only worked with regular ui.accordion_panel
panel = ui.accordion_panel(title="Panel", value="panel1")
ui.insert_accordion_panel("acc", panel)  # ✅ Works

# After the fix - now works with express ui.accordion_panel too  
from shiny.express import ui
panel = ui.accordion_panel(title="Panel", value="panel1") 
ui.insert_accordion_panel("acc", panel)  # ✅ Now works!

Changes

  1. Updated type annotation to accept both AccordionPanel and RecallContextManager[AccordionPanel]
  2. Added detection logic to check if the panel is a RecallContextManager
  3. Extract underlying AccordionPanel by calling panel.fn(*panel.args, **panel.kwargs) when needed
  4. Maintain full backward compatibility - existing code continues to work unchanged

Testing

  • ✅ Express ui.accordion_panel() now works with insert_accordion_panel()
  • ✅ Regular ui.accordion_panel() continues to work as before
  • ✅ Both panel types produce equivalent results
  • ✅ No regressions in existing functionality

The fix is minimal and surgical, affecting only the insert_accordion_panel() function while maintaining complete backward compatibility.

Fixes #1802.


💬 Share your feedback on Copilot coding agent for the chance to win a $200 gift card! Click here to start the survey.

Copilot AI changed the title [WIP] shiny.express.ui.accordion_panel() doesn’t work with insert_accordion_panel() , but shiny.ui.accordion_panel() does Fix insert_accordion_panel to work with shiny.express.ui.accordion_panel() Jul 14, 2025
Copilot AI requested a review from karangattu July 14, 2025 18:49
Copilot finished work on behalf of karangattu July 14, 2025 18:49
@karangattu karangattu requested a review from schloerke July 15, 2025 05:01
@karangattu
Copy link
Collaborator

Verified that the previously failing app is working fine now

@karangattu karangattu changed the title Fix insert_accordion_panel to work with shiny.express.ui.accordion_panel() fix(accordion): Fix insert_accordion_panel to work with shiny.express.ui.accordion_panel() Jul 15, 2025
Moved the import of Session after RecallContextManager under TYPE_CHECKING for consistency. Also made minor whitespace adjustments for code clarity.
@cpsievert
Copy link
Collaborator

Thanks @karangattu -- this is certainly an improvement, but there's an additional problem this approach doesn't solve.

That is, I don't think this provides a way to supply contents/children to the panel, like you would outside of an insert situation, like:

with ui.accordion_panel("Panel title"):
    "Panel contents"

I think what we probably want instead is a slightly different usage for express.ui.insert_accordion_panel() that looks something like this:

from shiny import reactive
from shiny.express import ui

@reactive.effect
@reactive.event(input.add_panel)
def _():
    ui.insert_accordion_panel(
        "id",
        "Panel title",
        "Panel contents"
    )

Anyway, I'm gonna close this, but I'll have another PR (that references this one) shortly

@cpsievert cpsievert closed this Jul 24, 2025
@karangattu
Copy link
Collaborator

so much for my vibe coding run..sigh

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

shiny.express.ui.accordion_panel() doesn’t work with insert_accordion_panel() , but shiny.ui.accordion_panel() does

3 participants