Releases: rstudio/shiny
shiny 1.11.1
This is a patch release primarily for addressing the bugs introduced in v1.11.0.
Bug fixes
shiny 1.11.0
Improvements
-
When auto-reload is enabled, Shiny now reloads the entire app when support files, like Shiny modules, additional script files, or web assets, change. To enable auto-reload, call
devmode(TRUE)to enable Shiny's developer mode, or setoptions(shiny.autoreload = TRUE)to specifically enable auto-reload. You can choose which files are watched for changes with theshiny.autoreload.patternoption. (#4184) -
When busy indicators are enabled (i.e.,
useBusyIndicators()), Shiny now: -
Shiny now uses
{cli}instead of{crayon}for rich log messages. (thanks @olivroy, #4170) -
renderPlot()was updated to accommodate changes in ggplot2 v4.0.0. (#4226) -
When adding the new tab via
insertTab()orbslib::nav_insert(), the underlying JavaScript no longer renders content twice. (#4179)
New features
-
textInput(),textAreaInput(),numericInput()andpasswordInput()all gain anupdateOnoption.updateOn = "change"is the default and previous behavior, where the input value updates immediately whenever the value changes. WithupdateOn = "blur", the input value will update only when the text input loses focus or when the user presses Enter (or Cmd/Ctrl + Enter fortextAreaInput()). (#4183) -
textAreaInput()gains aautoresizeoption, which automatically resizes the text area to fit its content. (#4210) -
The family of
update*Input()functions can now render HTML content passed to thelabelargument (e.g.,updateInputText(label = tags$b("New label"))). (#3996) -
ExtendedTasknow catches synchronous values and errors and returns them via$result(). Previously, the extended task function was required to always return a promise. This change makes it easier to useExtendedTaskwith a function that may return early or do some synchronous work before returning a promise. (#4225) -
The
callbackargument of Shiny.js'InputBinding.subscribe()method gains support for a value of"event". This makes it possible for an input binding to use event priority when updating the value (i.e., send immediately and always resend, even if the value hasn't changed). (#4211)
Changes
-
Shiny no longer suspends input changes when any
<input type="submit">or<button type="submit">is on the page. Instead, it now only suspends when asubmitButton()is present. If you have reason for creating a submit button from custom HTML, add a CSS class ofshiny-submit-buttonto the button. (#4209) -
Shiny's JavaScript assets are now compiled to ES2021 instead of ES5. (#4066)
-
Upgraded jQuery from 3.6.0 to 3.7.1. (#3969)
-
Updated jQuery UI from 1.13.2 to 1.14.1. (#4175)
Bug fixes
-
The Shiny Client Console (enabled with
shiny::devmode()) no longer displays duplicate warning or error message. (#4177) -
Synchronous errors that occur inside a
ExtendedTaskno longer stop the session. (#4225) -
Calling
removeModal()immediately aftershowModal()no longer fails to remove the modal (this would sometimes happen if the remove message was received while the modal was in the process of being revealed). (#4173) -
runExample("08_html")now (correctly) requests to 'shiny.min.css', eliminating a network request failure. (#4220) -
shiny::shinyAppTemplate()no longer errors without a call tolibrary(shiny). (#3870)
shiny 1.10.0
New features and improvements
-
When busy indicators are enabled (i.e.,
useBusyIndicators()is in the UI), Shiny now: -
Improve collection of deep stack traces (stack traces that are tracked across steps in an async promise chain) with
{coro}async generators such as{elmer}chat streams. Previously, Shiny treated each iteration of an async generator as a distinct deep stack, leading to pathologically long stack traces; now, Shiny only keeps/prints unique deep stack trace, discarding duplicates. (#4156) -
Added an example to the
ExtendedTaskdocumentation. (@daattali #4087)
Bug fixes
-
Fixed a bug in
conditionalPanel()that would cause the panel to repeatedly show/hide itself when the provided condition was not boolean. (@kamilzyla, #4127) -
Fixed a bug with
sliderInput()when used as a range slider that made it impossible to change the slider value when both handles were at the maximum value. (#4131) -
dateInput()anddateRangeInput()no longer send immediate updates to the server when the user is typing a date input. Instead, it waits until the user presses Enter or clicks out of the field to send the update, avoiding spurious and incorrect date values. Note that an update is still sent immediately when the field is cleared. (#3664) -
Fixed a bug in
onBookmark()hook that caused elements to not be excluded from URL bookmarking. (#3762) -
Fixed a bug with stack trace capturing that caused reactives with very long async promise chains (hundreds/thousands of steps) to become extremely slow. Chains this long are unlikely to be written by hand, but
{coro}async generators and{elmer}async streaming were easily creating problematically long chains. (#4155) -
Duplicate input and output IDs -- e.g. using
"debug"for two inputs or two outputs -- or shared IDs -- e.g. using"debug"as theinputIdfor an input and an output -- now result in a console warning message, but not an error. Whendevmode()is enabled, an informative message is shown in the Shiny Client Console. We recommend all Shiny devs enabledevmode()when developing Shiny apps locally. (#4101) -
Updating the choices of a
selectizeInput()viaupdateSelectizeInput()withserver = TRUEno longer retains the selected choice as a deselected option if the current value is not part of the new choices. (@dvg-p4 #4142) -
Fixed a bug where stack traces from
observeEvent()were being stripped of stack frames too aggressively. (#4163)
shiny 1.9.1
Bug fixes
- Fixed a bug introduced in v1.9.0 where the boundaries of hover/click/brush regions on plots were being incorrectly scaled when browser zoom was used. (#4111)
shiny 1.9.0
New busy indication feature
Add the new useBusyIndicators() function to any UI definition to:
- Add a spinner overlay on calculating/recalculating outputs.
- Show a page-level pulsing banner when Shiny is busy calculating something (e.g., a download, side-effect, etc), but no calculating/recalculating outputs are visible.
In a future version of Shiny, busy indication will be enabled by default, so we encourage you to try it out now, provide feedback, and report any issues.
In addition, various properties of the spinners and pulse can be customized with busyIndicatorOptions(). For more details, see ?busyIndicatorOptions. (#4040, #4104)
New features and improvements
-
The client-side TypeScript code for Shiny has been refactored so that the
Shinyobject is now an instance of classShinyClass. (#4063) -
In TypeScript, the
Shinyobject has a new propertyinitializedPromise, which is a Promise-like object that can beawaited or chained with.then(). This Promise-like object corresponds to theshiny:sessioninitializedJavaScript event, but is easier to use because it can be used both before and after the events have occurred. (#4063) -
Output bindings now include the
.recalculatingCSS class when they are first bound, up until the first render. This makes it possible/easier to show progress indication when the output is calculating for the first time. (#4039) -
A new
shiny.client_devmodeoption controls client-side devmode features, in particular the client-side error console introduced in shiny 1.8.1, independently of the R-side features ofshiny::devmode(). This usage is primarily intended for automatic use in Shinylive. (#4073) -
Added function
reactlogAddMark()to programmatically add _mark_ed locations in the reactlog log without the requirement of keyboard bindings during an idle reactive moment. (#4103)
Bug fixes
-
downloadButton()anddownloadLink()are now disabled up until they are fully initialized. This prevents the user from clicking the button/link before the download is ready. (#4041) -
Output bindings that are removed, invalidated, then inserted again (while invalidated) now correctly include the
.recalculatingCSS class. (#4039) -
Fixed a recent issue with
uiOutput()andconditionalPanel()not properly lower opacity when recalculation (in a Bootstrap 5 context). (#4027) -
Image outputs that were scaled by CSS had certain regions that were unresponsive to hover/click/brush handlers. (#3234)
shiny 1.8.1.1
In v1.8.1, shiny.js starting throwing an error when input/output bindings have duplicate IDs. This error is now only thrown when shiny::devmode(TRUE) is enabled, so the issue is still made discoverable through the JS error console, but avoids unnecessarily breaking apps that happen to work with duplicate IDs. (#4019)
shiny 1.8.1
New features and improvements
-
Added
ExtendedTask, a new simple way to launch long-running asynchronous tasks that are truly non-blocking. That is, even within a session, anExtendedTaskwon't block the main thread from flushing the reactive graph (i.e., UI updates won't be blocked).ExtendedTaskpairs nicely with newbslib::input_task_button()andbslib::bind_task_button()functions, which help give user feedback and prevent extra button clicks. (#3958) -
Added a JavaScript error dialog, reporting errors that previously were only discoverable by opening the browser's devtools open. Since this dialog is mainly useful for debugging and development, it must be enabled with
shiny::devmode(). (#3931) -
runExamples()now uses the{bslib}package to generate a better looking result. It also gains apackageargument so that other packages can leverage this same function to run Shiny app examples. For more, see?runExamples. (#3963, #4005) -
Added
onUnhandledError()to register a function that will be called when an unhandled error occurs in a Shiny app. Note that this handler doesn't stop the error or prevent the session from closing, but it can be used to log the error or to clean up session-specific resources. (thanks @JohnCoene, #3993)
Changes
-
renderDataTable()/dataTableOutput()are officially deprecated in favor of their{DT}equivalents. Migrating to{DT}, in most cases, just requires changingrenderDataTable()toDT::renderDT()anddataTableOutput()toDT::DTOutput(). Also, to promote migration, when a recent version of{DT}is available,renderDataTable()/dataTableOutput()now automatically use their{DT}equivalent (and provide a message that they are doing so). If this happens to degrade an existing app, setoptions(shiny.legacy.datatable = TRUE)to get the old (i.e., non-{DT}) implementation. (#3998) -
Both
conditionalPanel()anduiOutput()are now styled withdisplay: contentsby default in Shiny apps that use Bootstrap 5. This means that the elements they contain are positioned as if they were direct children of the parent container holding theconditionalPanel()oruiOutput(). This is probably what most users intend when they use these functions, but it may break apps that applied styles directly to the container elements created by these two functions. In that case, you may include CSS rules to setdisplay: blockfor the.shiny-panel-conditionalor.shiny-html-outputclasses. (#3957, #3960)
Bug fixes
-
Notifications are now constrained to the width of the viewport for window widths smaller the default notification panel size. (#3949)
-
Fixed #2392:
downloadButton()now visibly returns its HTML tag so that it renders correctly in R Markdown and Quarto output. (Thanks to @fennovj, #2672) -
Calling
updateSelectizeInput()withchoicesandselectednow clears the current selection before updating the choices and selected value. (#3967) -
Loading a Shiny app in a package-like directory will no longer warn if autoloading is disabled by the presence of an
R/_disable_autoload.Rfile. (Thanks to @krlmlr and @tanho63, #3513)
shiny 1.8.0
Breaking changes
- Closed #3899: The JS function
Shiny.bindAll()is now asynchronous. This change is driven by the recent push toward making dynamic UI rendering asynchronous, which is necessary for shinylive (and should've happened when it was first introduced in Shiny v1.7.5). The vast majority of existingShiny.bindAll()uses should continue to work as before, but some cases may break if downstream code relies on it being synchronous (i.e., blocking the main thread). In this case, consider placing any downstream code in a.then()callback (orawaitthe result in aasyncfunction). (#3929)- Since
renderContent()callsbindAll()(after it inserts content), it now returns aPromise<void>instead ofvoid, which can be useful if downstream code needs to wait for the binding to complete.
- Since
New features and improvements
-
Updated
selectizeInput()'s selectize.js dependency from v0.12.4 to v0.15.2. In addition to many bug fixes and improvements, this update also adds several new plugin options. (#3875) -
Shiny's CSS styling (for things like
showNotification(),withProgress(),inputPanel(), etc.), has been updated with{bslib}'s upcoming CSS-only dark mode feature in mind. (#3882, #3914) -
Default styles for
showNotification()were tweaked slightly to improve accessibility, sizing, and padding. (#3913) -
Shiny inputs and
{htmlwidgets}are no longer treated as draggable inside ofabsolutePanel()/fixedPanel()withdraggable = TRUE. As a result, interactions like zooming and panning now work as expected with widgets like{plotly}and{leaflet}when they appear in a draggable panel. (#3752, #3933) -
For
InputBindings, the.receiveMessage()method can now be asynchronous or synchronous (previously it could only be synchronous). (#3930)
Bug fixes
shiny 1.7.5.1
Bug fixes
- On r-devel (R > 4.3.1),
isTruthy(NULL)now returnsFALSE(as it does with older versions of R). (#3906)
shiny 1.7.5
Possibly breaking changes
-
For
reactiveValues()objects, whenever the$names()or$values()methods are called, the keys are now returned in the order that they were inserted. (#3774) -
The value provided to
options(shiny.json.digits)is now interpreted as number of digits after the decimal instead of significant digits. To treat the value as significant digits, wrap it inI()(e.g.,options(shiny.json.digits = I(4))). This new default behavior not only helps with reducing digits in testing snapshots, but is also more consistent with{jsonlite}'s default behavior. (#3819)
New features and improvements
-
Closed #789: Dynamic UI is now rendered asynchronously, thanks in part to the newly exported
Shiny.renderDependenciesAsync(),Shiny.renderHtmlAsync(), andShiny.renderContentAsync(). Importantly, this means<script>tags are now loaded asynchronously (the old way usedXMLHttpRequest, which is synchronous). In addition,Shinynow manages a queue of async tasks (exposed viaShiny.shinyapp.taskQueue) so that order of execution is preserved. (#3666) -
Fixes #3840:
updateSliderInput()now warns when attempting to set invalidmin,max, orvaluevalues. Sending an invalid update message to an input no longer causes other update messages to fail. (#3843) -
sliderInput()now has a larger target area for clicking or tapping on the slider handle or range. (#3859) -
Closed #2956: Component authors can now prevent Shiny from creating an input binding on specific elements by adding the
data-shiny-no-bind-inputattribute to the element. The attribute may have any or no value; its presence will prevent binding. This feature is primarily useful for input component authors who want to use standard HTML input elements without causing Shiny to create an input binding for them. Additionally, Shiny now adds custom classes to its inputs. For example,checkboxInput()now has ashiny-input-checkboxclass. These custom classes may be utilized in future updates to Shiny's input binding logic. (#3861) -
Mapobjects are now initialized at load time instead of build time. This avoids potential problems that could arise from storingfastmapobjects into the built Shiny package. (#3775)