Skip to content

Adopt shinychat's page_chat(): replace commons_ui() with commons_theme() - #169

Merged
cpsievert merged 16 commits into
mainfrom
feat/shinychat-ui-updates
Aug 26, 2026
Merged

Adopt shinychat's page_chat(): replace commons_ui() with commons_theme()#169
cpsievert merged 16 commits into
mainfrom
feat/shinychat-ui-updates

Conversation

@cpsievert

@cpsievert cpsievert commented Aug 25, 2026

Copy link
Copy Markdown
Collaborator

shinychat's new page_chat() owns page composition, which left commons_ui() — our thin chat_ui() wrapper that attached commons's CSS/JS — with no way to get those assets onto the page. This PR removes commons_ui() and moves asset delivery into commons_theme(), an ordinary bslib theme that works with page_chat() or any bslib page. commons_server() is unchanged.

The encouraged pattern for a commons app is now plain shinychat UI plus the theme:

library(shiny)
library(shinychat)

ui <- page_chat("Assistant", id = "chat", theme = commons_theme())

server <- function(input, output, session) {
  agent <- commons(
    ellmer::chat_anthropic(),
    data_sources = data_source(sales = sales)
  )
  commons_server("chat", agent)
}

shinyApp(ui, server)

For an embedded chat, use chat_ui() inside any bslib page with the same theme = commons_theme(); inst/app.R is 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 and commons_theme().

Commit walkthrough:

  • e85af0b — add commons_theme().
  • 978b4f1 — remove commons_ui(); port commons_app(), the trajectory reviewer, examples, tests, and docs.
  • a1e566f — drop icon_assistant = HTML(""); shinychat now omits the icon by default (#345).
  • e934e97 — drop explicit enable_cancel/allow_attachments; NULL defers to chat_server() (#264).
  • 45bee16 — serve the icon SVGs from the commons-chat dependency instead of a registered resource path.
  • d20d254 — move bslib/htmltools/sass to Imports (already transitive via shinychat).
  • 9123484 — drop a redundant example app; inst/app.R covers 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.

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.
@github-actions

github-actions Bot commented Aug 25, 2026

Copy link
Copy Markdown

Preview deployed to Connect (dogfood.team.pct.posit.it): https://dogfood.team.pct.posit.it/connect/#/apps/d7a36cae-8f27-448b-a478-61b81fbe3942/draft/365052

Deployed from commit a1175fc.

@github-actions

github-actions Bot commented Aug 25, 2026

Copy link
Copy Markdown

Preview deployed to Connect (connect.staging.pct.posit.it): https://connect.staging.pct.posit.it/connect/#/apps/ad662e1b-5048-4acc-9ad7-f9478c92274e/draft/2266

Deployed from commit a1175fc.

@cpsievert
cpsievert marked this pull request as ready for review August 25, 2026 23:04
@cpsievert
cpsievert requested a review from simonpcouch August 26, 2026 14:08
Comment thread pkg-r/inst/www/commons-chat/commons-chat.css Outdated
Comment thread pkg-r/R/theme.R

@simonpcouch simonpcouch left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread pkg-r/R/theme.R
Comment thread pkg-r/inst/app.R
title = "Biodiversity explorer",
commons_ui("chat", greeting = greeting)
ui <- page_chat(
"Biodiversity explorer",

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.)

Image

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.

Image

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is more of a question for @gadenbuie

@gadenbuie gadenbuie Aug 26, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 title support 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.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@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.
Comment thread pkg-r/inst/www/commons-chat/commons-chat.css Outdated
Co-authored-by: Garrick Aden-Buie <garrick@adenbuie.com>
@cpsievert

Copy link
Copy Markdown
Collaborator Author

@simonpcouch should be ready for another look.

@simonpcouch simonpcouch left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread pkg-r/R/theme.R Outdated
@cpsievert
cpsievert merged commit 202badd into main Aug 26, 2026
4 checks passed
@github-actions

Copy link
Copy Markdown

Cleaned up 7 preview bundle(s) on https://dogfood.team.pct.posit.it: 364656, 364983, 364988, 365003, 365016, 365049, 365052

@github-actions

Copy link
Copy Markdown

Cleaned up 7 preview bundle(s) on https://connect.staging.pct.posit.it: 2227, 2252, 2255, 2256, 2258, 2264, 2266

simonpcouch added a commit to posit-dev/devrel-agent that referenced this pull request Aug 27, 2026
@simonpcouch
simonpcouch deleted the feat/shinychat-ui-updates branch August 27, 2026 00:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

3 participants