Adopt shinychat's page_chat(): replace commons_ui() with commons_theme() - #169
Conversation
page_chat() and other bslib pages accept a bs_theme, so the commons chat CSS and JS can ride the theme itself via bslib::bs_bundle(theme, sass::sass_layer(html_deps = ...)) instead of a UI wrapper that attaches an htmlDependency to chat_ui() output. Theme dependencies render before shinychat's own stylesheet, so the .shiny-chat-* overrides need strictly higher specificity than shinychat's selectors. User-message radius/padding move to shinychat's public theme variables (shiny-chat-user-message-border-radius, shiny-chat-user-message-padding), which shinychat's stylesheet consumes via var() fallbacks; the remaining overrides get a shiny-chat-container prefix. Includes a live example at inst/examples/page-chat/ verified in a browser: assets load through the theme, the chat JS initializes, tool rows and verified-answer pills render with commons styling.
With the commons chat CSS and JavaScript carried by commons_theme(), the UI wrapper no longer does anything shinychat's own UI functions don't do. Callers compose shinychat::page_chat() (full-window) or shinychat::chat_ui() (embedded in a bslib page) with theme = commons_theme() on the page, and commons_server() on the server. - commons_app() now builds a page_chat() page; the interactive close button moves into toolbar_global. - The trajectory reviewer's transcript uses shinychat::chat_ui() and its page sidebar takes theme = commons_theme(), replacing the manual commons-chat dependency attach (and the ordering pin it needed). - Examples, demo, test apps, vignette, and onboarding skill updated. - The old UI test is replaced with a test that commons_theme() resolves the commons-chat dependency (stylesheet + script) through bs_theme_dependencies().
shinychat's chat_ui() now defaults icon_assistant to NULL, which omits the assistant icon entirely, so the empty-HTML workaround is no longer needed.
Both default to NULL in chat_ui()/page_chat(), which defers to chat_server(); it enables cancellation and attachments automatically. The explicit TRUEs in commons_app() were redundant.
The icon SVGs move from inst/figs/ to inst/www/commons-chat/figs/, so the commons-chat HTML dependency (which serves its whole directory) carries them and register_commons_icon_resources() is no longer needed. Icon URLs are derived from commons_chat_dependency() so they pick up the mtime-stamped version segment; the dependency's mtime stamp is now recursive so icon edits bust the cache too.
commons_theme() calls bslib:: and sass:: directly, and shinychat (already in Imports) depends on bslib, which in turn imports sass, so this changes nothing about what gets installed. With all three guaranteed present, the check_installed() guard in commons_theme() is removed.
inst/app.R already demonstrates the page_chat() + commons_theme() pattern, so a second copy of the same biodiversity app under inst/examples/ is redundant.
The manifest pinned shinychat at d7235ea4, which predates page_chat(); the deployed biodiversity app now uses page_chat() and failed to start on Connect. Pin to ac99efe1 (current shinychat main, which also has the assistant-icon and chat_server() defaults this branch relies on).
The manifest pinned commons at c394313, a pre-monorepo sha installed from the repo root: the Connect preview has been deploying that old commons rather than the code under review, and it lacks commons_theme(), so the app now fails to start. Pin commons to this branch's head with RemoteSubdir/GithubSubdir = pkg-r. Note the pin is inherently stale for PR previews — every push moves the branch head — so the deploy workflow should eventually install commons from the checkout instead.
The manifest pinned bslib 0.10.0 from CRAN, but the pinned shinychat requires bslib >= 0.12.0 (and commons now requires >= 0.11.0), so the deployed app failed to start. Record spliced from CRAN's 0.12.0 DESCRIPTION.
|
Preview deployed to Connect ( Deployed from commit a1175fc. |
|
Preview deployed to Connect ( Deployed from commit a1175fc. |
There was a problem hiding this comment.
Nice! Broadly on board for the transition to commons_theme(). [EDIT: seeing that Garrick has some reservations there. Would defer to yall's concensus.]
I'm not big on the bolded, required page title. We can paper over this commons-side, but wanted to get this in front of yall first in case you're open to shinychat changes.
| title = "Biodiversity explorer", | ||
| commons_ui("chat", greeting = greeting) | ||
| ui <- page_chat( | ||
| "Biodiversity explorer", |
There was a problem hiding this comment.
Noting that this is bolded at the top of the page in the new default UI. For commons_app(), it is always "commons" that's bolded up there. (Fine that it's not able to be adjusted in commons_app()--we want to push people towards the 'real thing' sooner than later.)
Could title support an empty string? Or, in the cases that it's non-empty, could it not be bolded / be styled differently?
I think @skaltman found a nice feel (albeit with additional Posit branding) in the tiles agent, but as this currently is implemented, that bolded title makes the app feel more like "default Shiny" than it did before.
There was a problem hiding this comment.
I think this is more of a question for @gadenbuie
There was a problem hiding this comment.
Noting that this is bolded at the top of the page in the new default UI.
You can set the font weight via the theme with this Sass variable
page_chat_theme(
"shiny-chat-page-title-font-weight" = 300
)or via the CSS variable
:root {
--shiny-chat-page-title-font-weight: normal;
}Could
titlesupport an empty string?
This is possible but requires title = list(). It's not generally a great idea, especially if you have more than one page, so the API is intentionally rough. I'd recommend against removing the title in general.
There was a problem hiding this comment.
@simonpcouch if you prefer, we can have commons_theme() default to that font weight. Just lmk
…ates # Conflicts: # pkg-r/R/chat.R # pkg-r/inst/skills/commons/references/onboarding.md # pkg-r/man/commons_app.Rd
commons_app() is the simple complete helper; commons_server() and commons_theme() are always used together when assembling a custom app, so they now share a help page.
Co-authored-by: Garrick Aden-Buie <garrick@adenbuie.com>
|
@simonpcouch should be ready for another look. |
simonpcouch
left a comment
There was a problem hiding this comment.
Thank you!
Just bumped that font weight here.
Let's squash and merge. :) I can send some PRs out to early-adopting packages once this is in.
|
Cleaned up 7 preview bundle(s) on https://dogfood.team.pct.posit.it: 364656, 364983, 364988, 365003, 365016, 365049, 365052 |
|
Cleaned up 7 preview bundle(s) on https://connect.staging.pct.posit.it: 2227, 2252, 2255, 2256, 2258, 2264, 2266 |


shinychat's new
page_chat()owns page composition, which leftcommons_ui()— our thinchat_ui()wrapper that attached commons's CSS/JS — with no way to get those assets onto the page. This PR removescommons_ui()and moves asset delivery intocommons_theme(), an ordinary bslib theme that works withpage_chat()or any bslib page.commons_server()is unchanged.The encouraged pattern for a commons app is now plain shinychat UI plus the theme:
For an embedded chat, use
chat_ui()inside any bslib page with the sametheme = commons_theme();inst/app.Ris a complete example.One thing worth knowing when reviewing: theme dependencies render before shinychat's own stylesheet, so commons's
.shiny-chat-*overrides needed strictly higher specificity (or, where shinychat exposes a theme variable, moving to the variable instead). Caught via live browser testing; details are in the CSS andcommons_theme().Commit walkthrough:
commons_theme().commons_ui(); portcommons_app(), the trajectory reviewer, examples, tests, and docs.icon_assistant = HTML(""); shinychat now omits the icon by default (#345).enable_cancel/allow_attachments;NULLdefers tochat_server()(#264).commons-chatdependency instead of a registered resource path.inst/app.Rcovers the pattern.Verified: the four affected test files pass, and the example apps were exercised live in a browser with a real agent (assets load via the theme, pills/tool rows render with commons styling, icons serve 200). The full suite and shinytest2 tests were too slow locally — relying on CI for those.