Skip to content

Releases: posit-dev/py-shiny

shiny 1.2.1

14 Nov 15:43
7d95565
Compare
Choose a tag to compare

Bug fixes

  • Branded theming via ui.Theme.from_brand() now correctly applies monospace inline and block font family choices. (#1762)

  • Compatibility with websockets>=14.0, which has changed its public APIs. Shiny now requires websockets 13 or later. (#1769)

shiny 1.2.0

29 Oct 21:19
Compare
Choose a tag to compare

Breaking changes

  • .expect_inverse() for Navset controllers in shiny.playwright.controllers now requires a bool value. To keep behavior the same, use .expect_inverse(False). (#1668)

  • .expect_layout() for Navset controllers in shiny.playwright.controllers is now renamed to .expect_fluid() and requires a bool value. To keep behavior the same, use .expect_fluid(True) (#1668)

  • .expect_icon() for Accordion controllers in shiny.playwright.controllers now requires a bool value instead of a str. (#1710)

New features

  • New features for @render.data_frame:

    • Added narwhals support for @render.data_frame. This allows for any eager data frame supported by narwhals to be returned from a @render.data_frame output method. All internal methods and helper methods now leverage the narwhals API to be data frame agnostic. (#1570)

    • Added .data_patched() reactive calculation that applies all .cell_patches() to .data(). (#1719)

    • Added .update_cell_value() method to programmatically update the contents of a data frame cell. (#1719)

    • Added .update_data() method to update the rendered data without resetting any user sort or filter. Note, all user edits will be forgotten. (#1719)

  • Added narwhals support for @render.table. This allows for any eager data frame supported by narwhals to be returned from a @render.table output method. (#1570)

  • Shiny now supports theming via brand.yml with a single _brand.yml file. Call ui.Theme.from_brand() with __file__ or the path to a _brand.yml file and pass the resulting theme to the theme argument of express.ui.page_opts() (Shiny Express) or ui.page_*() functions (Shiny Core) to apply the brand theme to the entire app. (#1743)

  • chat_ui() and Chat.ui() gain a messages parameter for providing starting messages. (#1736)

Other changes

  • Incorporated orjson for faster data serialization in @render.data_frame outputs. (#1570)

  • Added PageNavbar class to the list of shiny.playwright.controllers for testing ui.page_navbar(). (#1668)

  • Added .expect_widths() to NavsetPillList in shiny.playwright.controllers for testing ui.navset_pill_list(widths=). (#1668)

  • Added .expect_title() for Popover in shiny.playwright.controllers (#1683)

  • Added .expect_disabled() for InputActionButton in shiny.playwright.controllers (#1705)

  • Small improvements to the default pulse busy indicator to better blend with any background. It's also now slightly smaller by default.(#1707)

  • Added .expect_class(), .expect_gap(), .expect_bg_color(), .expect_desktop_state(), .expect_mobile_state(), .expect_mobile_max_height(), .expect_title(), and .expect_padding() for Sidebar in shiny.playwright.controllers (#1715)

  • Modified .expect_text() for Sidebar in shiny.playwright.controllers to use .loc_content instead of loc for text. Also modified .expect_width() to check the .loc_container's style instead of the .loc element. (#1715)

  • Modified .expect_text() and .expect_width() for Sidebar in shiny.playwright.controllers to use loc_content instead of loc for text. (#1715)

  • Added .expect_class() and .expect_multiple() for Accordion in shiny.playwright.controllers (#1710)

Bug fixes

  • A few fixes for ui.Chat(), including:

    • Fixed a bug with Chat() sometimes silently dropping errors. (#1672)
    • Fixed a bug with Chat() sometimes not removing it's loading icon (on error or a None transform). (#1679)
    • .messages(format="anthropic") correctly removes non-user starting messages (once again). (#1685)
  • shiny create now uses the template id rather than the directory name as the default directory. (#1666)

  • ui.Theme() now works correctly on Windows when the theme requires Sass compilation. (Thanks, @yuuuxt!) (#1684)

  • Fixed multiple input controllers (InputSlider, InputDate, InputDateRange, InputCheckbox, and InputCheckboxGroup) in shiny.playwright.controller to check the width property within the style attribute. (#1691, #1696, #1702)

  • Fixed multiple input controllers (InputSwitch, InputRadioButtons, InputNumeric, InputText, InputTextArea, InputPassword, InputActionButton, and InputActionLink) in shiny.playwright.controller to correctly validate the width style property in `.expect_width(). (#1705)

  • Fixed input controller InputTextArea in shiny.playwright.controller to correctly validate the resize style property in .expect_resize(). (#1705)

  • Fixed a bug in ui.conditional_panel() that would cause the panel to repeatedly show/hide itself when the provided condition did not evaluate to a boolean value. (#1707)

  • Fixed a bug with ui.input_slider() when used as a range slider that made it impossible to change the slider value when both handles were at the maximum value. (#1707)

  • Fixed bug in @render.data_frame where bool or object columns were not being rendered. (#1570)

  • Fixed output controller OutputDataFrame in shiny.playwright.controller to correctly assert the number of rows in .expect_nrow() as the total number of virtual rows, not the number of currently displaying rows. (#1719)

  • Fixed issue where @render.download did not respect the module namespacing. (Thanks, @nsiicm0!) (#1732)

  • Added workaround in Accordion in shiny.playwright.controller where .expect_open() and .expect_panels() would hang while resolving a playwright locator. (Thanks, @joesho112358!) (#1165)

Shiny 1.1.0

03 Sep 19:16
Compare
Choose a tag to compare

New features

  • ui.Chat() gains a new .update_user_input() method, which adds the ability to update the input placeholder message. As a result, .set_user_message() is now deprecated (since the new method can also be used to update the message). (#1594)

  • shiny create now supports a succinct format for specifying the GitHub repository via the --github flag, e.g. --github posit-dev/py-shiny-templates. You can now also use --github and --template together, in which case --github should point to a repository containing a directory matching the name provided in --template. (#1623)

  • shiny create now identifies templates in external repositories using a _template.json metadata file. This file should contain at an "id" and optionally a "title" and "description". When shiny create is called with the --github flag but without a --template flag, it will offer a menu listing all available templates in the repository. (#1631)

Other changes

  • A few changes for ui.Chat(), including:
    • The .messages() method no longer trims messages by default (i.e., the default value of token_limits is now None instead of the overly generic and conservative value of (4096, 1000)). See the new generative AI in production templates (via shiny create) for examples of setting token_limits based on the model being used. (#1657)
    • User input that contains markdown now renders the expected HTML. (#1607)
    • Busy indication is now visible/apparent during the entire lifecycle of response generation. (#1607)

Bug fixes

  • A few fixes for ui.Chat(), including:

    • A fix for use inside Shiny modules. (#1582)
    • .messages(format="google") now returns the correct role. (#1622)
    • ui.Chat(messages) are no longer dropped when dynamically rendered. (#1593)
    • transform_assistant_response can now return None and correctly handles change of content on the last chunk. (#1641)
  • An empty ui.input_date() value no longer crashes Shiny. (#1528)

  • Fixed bug where calling .update_filter(None) on a data frame renderer did not visually reset non-numeric column filters. (It did reset the column's filtering, just not the label). Now it resets filter's label. (#1557)

  • Require shinyswatch >= 0.7.0 and updated examples accordingly. (#1558)

  • ui.input_text_area(autoresize=True) now resizes properly even when it's not visible when initially rendered (e.g. in a closed accordion or a hidden tab). (#1560)

  • ui.notification_show(duration=None) now persists the notification until the app user closes it. (#1577)

  • Some copies of Windows 10 have registry entries mapping .js files to content type "text/plain", which was causing all sorts of problems for browsers. (#1624)

  • Added missing support for express.ui.navset_card_pill(placement:). (#1602)

  • Added .expect_sidebar() and .expect_title() methods for NavsetCardTab, NavsetCardPill, NavsetCardUnderline, and NavsetBar. (#1602)

  • Added .expect_placement() method for NavsetCardPill and NavsetCardUnderline. (#1602)

Shiny 1.0.0

18 Jul 16:20
@wch wch
Compare
Choose a tag to compare

New features

  • Added a new shiny.ui.Chat class for building conversational interfaces with fully customizable and performant response generation. (#1453)

  • Expose shiny.playwright, shiny.run, and shiny.pytest modules that allow users to testing their Shiny apps. (#1448, #1456, #1481)

    • shiny.playwright contains controller and expect submodules. controller will contain many classes to interact with (and verify!) your Shiny app using Playwright. expect contains expectation functions that enhance standard Playwright expectation methods.
    • shiny.run contains the run_shiny_app command and the return type ShinyAppProc. ShinyAppProc can be used to type the Shiny app pytest fixtures.
    • shiny.pytest contains pytest test fixtures. The local_app pytest fixture is automatically available and runs a sibling app.py file. Where as create_app_fixture(PATH_TO_APP) allows for a relative path to a Shiny app to be instantiated from a different folder.
  • Added CLI command shiny add test to add a test file to an existing Shiny app. (#1461)

  • @render.data_frame, render.DataGrid, and render.DataTable now support polars data frames (#1474).

  • @render.data_frame, render.DataGrid, and render.DataTable are now type aware. This means that the data frame renderer object's .data() and .data_view() methods will return the same type of data given the the renderer. E.g. If a DataGrid wrapping a polars data frame is returned to the renderer function, .data_view() will return polars data. (#1502)

  • @render.data_frame's render.DataGrid and render.DataTable added support for cell styling with the new styles= parameter. This parameter can receive a style info object (or a list of style info objects), or a function that accepts a data frame and returns a list of style info objects. Each style info object can contain the rows and cols locations where the inline style and/or CSS class should be applied. (#1475)

  • @render.data_frame has added a few new methods:

    • .data_view_rows() is a reactive value representing the sorted and filtered row numbers. This value wraps input.<ID>_data_view_rows()(#1374)
    • .sort() is a reactive value representing the sorted column information (dictionaries containing col: int and desc: bool). This value wraps input.<ID>_sort(). (#1374)
    • .filter() is a reactive value representing the filtered column information (dictionaries containing col: int and value which is either a string or a length 2 array of at least one non-None number). This value wraps input.<ID>_filter(). (#1374)
    • .update_sort(sort=) allows app authors to programmatically update the sorting of the data frame. (#1374)
    • .update_filter(filter=) allows app authors to programmatically update the filtering of the data frame. (#1374)
  • @render.data_frame now accepts both a non-"none" selection_mode value and editable=True. (#1454, #1534)

  • @render.data_frame's <ID>.cell_selection() no longer returns a None value and now always returns a dictionary containing both the rows and cols keys. This is done to achieve more consistent author code when working with cell selection. When the value's type="none", both rows and cols are empty tuples. When type="row", cols represents all column numbers of the data. In the future, when type="col", rows will represent all row numbers of the data. These extra values are not available in input.<ID>_cell_selection() as they are independent of cells being selected and are removed to reduce information being sent to and from the browser. (#1376)

  • Relative imports, like from . import utils, now can be used in Shiny Express apps. (#1464)

  • ui.Theme allows you to create custom themes for your Shiny app by recompiling Bootstrap and Shiny's Sass files with your own customizations. Themes created with ui.Theme can be passed directly to the theme argument of express.ui.page_opts() (Shiny Express) or ui.page_*() functions (Shiny Core) to apply the theme to the entire app. This feature requires the libsass package which can be installed with pip install libsass. (#1358)

  • ui.card_body() can be used to wrap the contents of elements in ui.card(), allowing you to change parameters like fillable or padding and gap for groups of elements in the card. (#1506)

Other changes

  • ui.input_action_button() and ui.update_action_button() gain a disabled argument. When the button is disabled, it appears grayed out and cannot be clicked. (#1465)

  • The main content area of ui.page_sidebar() and ui.page_navbar() with a page-level sidebar now have a minimum height and width to avoid squashed content in fillable layouts. The minimum height and width are controllable via --bslib-page-main-min-{width,height} CSS variables. (#1436)

  • Added a new option to place an always-open sidebar above the main content on mobile screens by providing open={"mobile": "always-above"} to ui.sidebar(). (#1436)

Bug fixes

  • Fixed #1440: When a Shiny Express app with a www/ subdirectory was deployed to shinyapps.io or a Connect server, it would not start correctly. (#1442)

  • Fixed #1498: Update table related TypeScript dependencies to their latest versions. This fixed an issue where the Row Virtualizer would scroll to the end when hidden. This would cause the DOM to update numerous times, locking up the browser tab for multiple seconds. (#1524, #1550)

  • The return type for the data frame patch function now returns a list of render.CellPatch objects (which support htmltools.TagNode for the value attribute). These values will be set inside the data frame's .data_view() result. This also means that .cell_patches() will be a list of render.CellPatch objects. (#1526)

  • Made sure all @render.data_frame cells that have been edited are now restored back to ready state to handle the off chance that the returned patches are at different locations the the original edit patches. (#1529)

  • remove_all_fill(tag) no longer modifies the original tag input and instead returns a modified copy of tag. (#1538)

Deprecations

  • The following deprecated functions have now been removed (#1546):

    • shiny.ui.panel_sidebar() was deprecated in v0.6.0; use shiny.ui.sidebar() instead.
    • shiny.ui.panel_main() was deprecated in v0.6.0; instead pass items directly to shiny.ui.layout_sidebar().
    • shiny.ui.navset_pill_card() was deprecated in v0.6.0; use shiny.ui.navset_card_pill() instead.
    • shiny.ui.navset_tab_card() was deprecated in v0.6.0; use shiny.ui.navset_card_tab() instead.
    • shiny.ui.nav() was deprecated in v0.6.1; use shiny.ui.nav_panel() instead.
  • @render.data_frame, render.DataGrid, and render.DataTable have deprecated support for data frame types that are pandas compatible. Please call .to_pandas() on your data before it is returned to the renderer (#1502). Currently, both polars and pandas data frames are supported (#1474). If you'd like to add support for a new data frame type, please open an issue or a pull request.

  • @render.data_frame's .cell_selection() will no longer return None when the selection mode is "none". In addition, missing rows or cols information will be populated with appropiate values. This allows for consistent handling of the cell selection object. (#1374)

  • @render.data_frame's input value input.<ID>_data_view_indices() has been deprecated. Please use <ID>.data_view_rows() to retrieve the same information. (#1377)

  • @render.data_frame's input value input.<ID>_column_sort() has been deprecated. Please use <ID>.sort() to retrieve the same information. (#1374)

  • @render.data_frame's input value input.<ID>_column_filter() has been deprecated. Please use <ID>.filter() to retrieve the same information. (#1374)

  • Deprecated functions in shiny.experimental have been removed. By and large, these functions are now available in the main shiny namespace. (#1540)

  • We've deprecated several card-related shiny.experimental.ui functions that were moved to the main shiny.ui namespace in v0.6.0. Both card() and card_body() are no longer experimental and can be called via shiny.ui.card() and shiny.ui.card_body() directly. shiny.experimental.ui.card_title() is now deprecated, but can be replaced with shiny.ui.tags.h5() or shiny.ui.card_header(). (#1543)

Shiny 0.10.2

28 May 21:17
Compare
Choose a tag to compare

Bug fixes

  • Fixed an issue with output spinners only showing for a split second. (#1429)

Shiny 0.10.1

23 May 19:51
@wch wch
Compare
Choose a tag to compare

Bug fixes

  • Fixed an issue with opacity dimming occurring too often/quickly when outputs are recalculating. (#1415)

Shiny 0.10.0

23 May 16:00
@wch wch
Compare
Choose a tag to compare

Deprecations

  • Restored @render.data_frame's (prematurely removed in v0.9.0) input value input.<ID>_selected_rows(). Please use <ID>.cell_selection()["rows"] and consider input.<ID>_selected_rows() deprecated. (#1345, #1377)

  • @render.data_frame's method .input_cell_selection() has been renamed to .cell_selection(). Please use .cell_selection() and consider .input_cell_selection() deprecated. (#1407)

  • @render.data_frame's input value input.<ID>_data_view_indices has been renamed to input.<ID>_data_view_rows for consistent naming. Please use input.<ID>_data_view_rows and consider input.<ID>_data_view_indices deprecated. (#1377)

New features

  • Added busy indicators to provide users with a visual cue when the server is busy calculating outputs or otherwise serving requests to the client. More specifically, a spinner is shown on each calculating/recalculating output, and a pulsing banner is shown at the top of the page when the app is otherwise busy. Use the new ui.busy_indicator.options() function to customize the appearance of the busy indicators and ui.busy_indicator.use() to disable/enable them. (#918)

  • Added support for creating modules using Shiny Express syntax, and using modules in Shiny Express apps. (#1220)

  • ui.page_*() functions gain a theme argument that allows you to replace the Bootstrap CSS file with a new CSS file. theme can be a local CSS file, a URL, or a shinyswatch theme. In Shiny Express apps, theme can be set via express.ui.page_opts(). (#1334)

Bug fixes

  • Fixed an issue that prevented Shiny from serving the font.css file referenced in Shiny's Bootstrap CSS file. (#1342)

  • Removed temporary state where a data frame renderer would try to subset to selected rows that did not exist. (#1351, #1377)

  • Fix an issue in the data frame output which caused the table to freeze when filters removed previously selected cells. (#1412)

Other changes

  • Session is now an abstract base class, and AppSession is a concrete subclass of it. Also, ExpressMockSession has been renamed ExpressStubSession and is a concrete subclass of Session. (#1331)

  • The Session class now has a method is_stub_session(). For ExpressStubSession, this method returns True for , and AppSession objects it returns False. (#1331)

  • Closed #1293: The error console would display error messages if an app was disconnected and the user changed an input. (#1339)

  • Fixed an issue where some CSS files were larger than necessary because they had source maps embedded in them. (#1339)

Shiny 0.9.0

16 Apr 15:19
@wch wch
Compare
Choose a tag to compare

Breaking Changes

  • @render.data_frame return values of DataTable and DataGrid had their parameter of row_selection: Literal["single", "multiple"] become deprecated. Please use selection_mode="row" or selection_mode="rows" instead. (#1198)

  • The col_widths argument of ui.layout_columns() now sets the sm breakpoint by default, rather than the md breakpoint. For example, col_widths=(12, 6, 6) is now equivalent to {"sm": (12, 6, 6)} rather than {"md": (12, 6, 6)}. (#1222)

New features

  • Session objects now have a set_message_handler(name, fn) method that allows you to register a message handler function that will be called when a request message with the given name is received from the client (via Shiny.shinyapp.makeRequest() (JS)). (#1253)

  • Experimental: @render.data_frame return values of DataTable and DataGrid support editable=True to enable editing of the data table cells. (#1198)

  • ui.card() and ui.value_box() now take an id argument that, when provided, is used to report the full screen state of the card or value box to the server. For example, when using ui.card(id = "my_card", full_screen = TRUE) you can determine if the card is currently in full screen mode by reading the boolean value of input.my_card_full_screen(). (#1215, #1266)

  • Added support for using shiny.express in Quarto Dashboards. (#1217)

  • ui.value_box(), ui.layout_columns() and ui.layout_column_wrap() now all have min_height and max_height arguments. These are useful in filling layouts, like ui.page_fillable(), ui.page_sidebar(fillable=True) or ui.page_navbar(fillable=True). For example, you can use ui.layout_columns(min_height=300, max_height=500) to ensure that a set of items (likely arranged in a row of columns) are always between 300 and 500 pixels tall. (#1223)

  • Added an error console which displays errors in the browser's UI. This is enabled by default when running applications locally, and can be disabled with shiny run --no-dev-mode. It is not enabled for applications that are deployed to a server. (#1060)

  • shiny create was updated to include some additional templates as well as an option to choose from the new templates website. (#1273, #1277, #1274)

  • shiny.express.ui.page_opts() now accepts additional keyword arguments that are passed to the underlying page layout chosen by shiny.ui.page_auto(). (#1314)

Bug fixes

  • On Windows, Shiny Express app files are now read in as UTF-8. (#1203)

  • input_dark_mode() now accepts a style argument that can be used to customize the appearance and position of the dark mode toggle switch. (#1207)

  • Calling ui.update_selectize() with choices and selected now clears the current selection before updating the choices and selected value. (#1221)

  • Fixed an issue that could happen with a ui.card() or ui.value_box() that is rendered dynamically via @render.ui when an updated card replaces a card that the user has expanded into full screen mode. Now the full screen state is reset for the new card or value box. If you want to update a card without potentially exiting the full-screen mode, update specific parts of the card using ui.output_ui() or ui.output_text(). (#1221)

  • ui.layout_columns() now correctly applies the row_heights at the xs breakpoint, if supplied. (#1222)

  • ui.panel_conditional() now adds the .shiny-panel-conditional class to the <div> element wrapping the conditional panel contents. (#1257)

  • ui.panel_conditional() no longer results in unwanted double padding when the parent container uses gap for spacing multiple elements (e.g., when used in ui.layout_columns(), ui.page_fillable(), etc). (#1266)

  • Error messages now use var(--bs-danger) instead of var(--bs-danger-text-emphasis) for the text color. (#1266)

Other changes

  • The fill CSS used by fillable containers (i.e. when fillable=True) now uses a CSS cascade layer named htmltools to reduce the precedence order of the fill CSS. (#1228)

Shiny 0.8.1

07 Mar 14:21
@wch wch
7d6a046
Compare
Choose a tag to compare

Breaking Changes

  • ui.page_sidebar() now places the title element in a .navbar container that matches the structure of page_navbar(). This ensures that the title elements of page_sidebar() and page_navbar() have consistent appearance. (#1176)

Bug fixes

  • Shiny now compiles the Bootstrap 5-based stylesheets for component styles imported from https://github.com/rstudio/shiny. (#1191)

  • Fixed the CSS for ui.output_ui() to avoid unwanted double padding when its parent container uses gap for spacing multiple elements (e.g., ui.layout_columns(), ui.page_fillable(), etc). (#1176)

Other changes

  • Closed #1178: Removed run-time dependency on asgiref. (#1183)

  • The uvicorn and click packages are no longer needed when running on Emscripten. (#1187)

  • We adjusted the shadows used for cards and popovers. Cards now use a slightly smaller shadow and the same shadow style is also now used by popovers. (#1176)

  • We increased the spacing between elements just slightly. This change is most noticeable in the layout_columns() or layout_column_wrap() component. In these and other components, you can use gap and padding arguments to choose your own values, or you can set the --bslib-spacer (CSS) variable. (#1176)

Shiny 0.8.0

04 Mar 16:55
@wch wch
Compare
Choose a tag to compare

Breaking Changes

  • Page-level sidebars used in ui.page_sidebar() and ui.page_navbar() will now default to being initially open but collapsible on desktop devices and always open on mobile devices. You can adjust this default choice by setting ui.sidebar(open=). (#1129)

  • ui.sidebar() is now a thin wrapper for the internal ui.Sidebar class. The ui.Sidebar class has been updated to store the sidebar's contents and settings and to delay rendering until the sidebar HTML is actually used. Because most users call ui.sidebar() instead of using the class directly, this change is not expected to affect many apps. (#1129)

New features

  • Added ui.input_dark_mode(), a toggle switch that allows users to switch between light and dark mode. By default, when ui.input_dark_mode() is added to an app, the app's color mode follows the users's system preferences, unless the app author sets the mode argument. When ui.input_dark_mode(id=) is set, the color mode is reported to the server, and server-side color mode updating is possible using ui.update_dark_mode(). (#1149)

  • ui.sidebar(open=) now accepts a dictionary with keys desktop and mobile, allowing you to independently control the initial state of the sidebar at desktop and mobile screen sizes. (#1129)

  • Closed #984: In Shiny Express apps, if there is a "www" subdirectory in the app's directory, Shiny will serve the files in that directory as static assets, mounted at /. (#1170)

  • For Shiny Express apps, added express.app_opts(), which allows setting application-level options, like static_assets and debug. (#1170)

  • Closed #1079: For Shiny Express apps, automatically run a globals.py file in the same directory as the app file, if it exists. The code in globals.py will be run with the session context set to None. (#1172)

Other changes

  • @render.data_frame now properly fills its container by default. (#1126)

  • We improved the accessibility of the full screen toggle button in cards created with ui.card(full_screen=True). Full-screen cards are now also supported on mobile devices. (#1129)

  • When entering and exiting full-screen card mode, Shiny now emits a client-side custom bslib.card event that JavaScript-oriented users can use to react to the full screen state change. (#1129)

  • The sidebar's collapse toggle now has a high z-index value to ensure it always appears above elements in the main content area of ui.layout_sidebar(). The sidebar overlay also now receives the same high z-index on mobile layouts. (#1129)

  • Updated example apps to use lower-case versions of reactive.Calc->reactive.calc, reactive.Effect->reactive.effect, and reactive.Value->reactive.value. (#1164)

  • Closed #1081: The @expressify() function now has an option has_docstring. This allows the decorator to be used with functions that contain a docstring. (#1163)

Bug fixes

  • Fixed input_task_button not working in a Shiny module. (#1108)

  • Fixed several issues with page_navbar() styling. (#1124)

  • Fixed Renderer.output_id to not contain the module namespace prefix, only the output id. (#1130)

  • Fixed gap-driven spacing between children in fillable nav_panel() containers. (#1152)

  • Fixed #1138: An empty value in a date or date range input would cause an error; now it is treated as None. (#1139)

Other changes

  • Replaced use of sys.stderr.write() with print(file=sys.stderr), because on some platforms sys.stderr can be None. (#1131)

  • Replaced soon-to-be deprecated datetime method calls when handling shiny.datetime inputs. (#1146)