diff --git a/.github/py-shiny/setup/action.yaml b/.github/py-shiny/setup/action.yaml index 1fd5b6253..e96f99619 100644 --- a/.github/py-shiny/setup/action.yaml +++ b/.github/py-shiny/setup/action.yaml @@ -4,7 +4,7 @@ inputs: python-version: description: 'Python version to use' required: false - default: "3.11" + default: "3.12" runs: using: "composite" steps: @@ -25,7 +25,6 @@ runs: shell: bash run: | pip install https://github.com/rstudio/py-htmltools/tarball/main - pip install https://github.com/posit-dev/py-shinylive/tarball/main make install-deps - name: Install diff --git a/.github/workflows/build-docs.yaml b/.github/workflows/build-docs.yaml index 3da9dda42..c53dfd047 100644 --- a/.github/workflows/build-docs.yaml +++ b/.github/workflows/build-docs.yaml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.11"] + python-version: ["3.12"] fail-fast: false steps: @@ -34,7 +34,6 @@ jobs: run: | cd docs make ../venv - . ../venv/bin/activate && pip install https://github.com/posit-dev/py-htmltools/tarball/main https://github.com/posit-dev/py-shinylive/tarball/main make deps - name: Run quartodoc diff --git a/.github/workflows/pytest.yaml b/.github/workflows/pytest.yaml index 12fcbf61c..3bc396917 100644 --- a/.github/workflows/pytest.yaml +++ b/.github/workflows/pytest.yaml @@ -16,7 +16,7 @@ jobs: strategy: matrix: # "3.10" must be a string; otherwise it is interpreted as 3.1. - python-version: ["3.11", "3.10", "3.9", "3.8"] + python-version: ["3.12", "3.11", "3.10", "3.9", "3.8"] os: [ubuntu-latest, windows-latest, macOS-latest] fail-fast: false @@ -53,7 +53,7 @@ jobs: if: github.event_name != 'release' strategy: matrix: - python-version: ["3.11", "3.10", "3.9", "3.8"] + python-version: ["3.12", "3.11", "3.10", "3.9", "3.8"] os: [ubuntu-latest] fail-fast: false @@ -68,13 +68,19 @@ jobs: timeout-minutes: 20 run: | make playwright-shiny SUB_FILE=". -vv" + - uses: actions/upload-artifact@v4 + if: failure() + with: + name: "playright-shiny-${{ matrix.os }}-${{ matrix.python-version }}-results" + path: test-results/ + retention-days: 5 playwright-examples: runs-on: ${{ matrix.os }} if: github.event_name != 'release' strategy: matrix: - python-version: ["3.11", "3.10", "3.9", "3.8"] + python-version: ["3.12", "3.11", "3.10", "3.9", "3.8"] os: [ubuntu-latest] fail-fast: false @@ -100,9 +106,42 @@ jobs: timeout-minutes: 20 run: | make playwright-examples SUB_FILE=". -vv" + - uses: actions/upload-artifact@v4 + if: failure() + with: + name: "playright-examples-${{ matrix.os }}-${{ matrix.python-version }}-results" + path: test-results/ + retention-days: 5 + + playwright-deploys-precheck: + if: github.event_name != 'release' + runs-on: ${{ matrix.os }} + strategy: + matrix: + # Matches deploy server python version + python-version: ["3.10"] + os: [ubuntu-latest] + fail-fast: false + + steps: + - uses: actions/checkout@v3 + - name: Setup py-shiny + uses: ./.github/py-shiny/setup + with: + python-version: ${{ matrix.python-version }} + + - name: Test that deployable example apps work + timeout-minutes: 5 # ~10s locally + env: + DEPLOY_APPS: "false" + run: | + make playwright-deploys SUB_FILE=". -vv" playwright-deploys: + needs: [playwright-deploys-precheck] + if: github.event_name != 'release' && (github.event_name == 'push' || (github.event_name == 'pull_request' && startsWith(github.head_ref, 'deploy'))) # Only allow one `playwright-deploys` job to run at a time. (Independent of branch / PR) + # Only one is allowed to run at a time because it is deploying to the same server location. concurrency: playwright-deploys runs-on: ${{ matrix.os }} strategy: @@ -119,8 +158,8 @@ jobs: with: python-version: ${{ matrix.python-version }} - - name: Test deploys example apps locally - timeout-minutes: 5 + - name: Test that deployable example apps work + timeout-minutes: 5 # ~10s locally env: DEPLOY_APPS: "false" run: | @@ -141,6 +180,13 @@ jobs: run: | make playwright-deploys SUB_FILE=". -vv --numprocesses 12" + - uses: actions/upload-artifact@v4 + if: failure() + with: + name: "playright-deploys-${{ matrix.os }}-${{ matrix.python-version }}-results" + path: test-results/ + retention-days: 5 + pypi: name: "Deploy to PyPI" runs-on: ubuntu-latest @@ -185,6 +231,7 @@ jobs: strategy: matrix: python-version: + - "3.12" - "3.11" - "3.10" - "3.9" diff --git a/.gitignore b/.gitignore index 70749a9e4..6f46035ff 100644 --- a/.gitignore +++ b/.gitignore @@ -114,3 +114,4 @@ docs/source/reference/ # Developer scratch area _dev/ tests/playwright/deploys/**/requirements.txt +test-results/ diff --git a/CHANGELOG.md b/CHANGELOG.md index ee71d4635..f4bc13aac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,11 +5,34 @@ All notable changes to Shiny for Python will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - ## [UNRELEASED] - YYYY-MM-DD ### 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) + +### New features + +### 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` (Sass) or `--bslib-spacer` (CSS) variable. (#1176) + +## [0.8.0] - 2024-03-04 + +### 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) @@ -20,27 +43,40 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * `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) -### 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) +* 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) -* 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) +* For Shiny Express apps, added `express.app_opts()`, which allows setting application-level options, like `static_assets` and `debug`. (#1170) -* 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) +* 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) ### 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 +* `@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) + * 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) @@ -118,9 +154,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### New features * `shiny create` now allows you to select from a list of template apps. + * `shiny create` provides templates which help you build your own custom JavaScript components. + * Closed #814: The functions `reactive.Calc` and `reactive.Effect` have been changed to have lowercase names: `reactive.calc`, and `reactive.effect`. The old capitalized names are now aliases to the new lowercase names, so existing code will continue to work. Similarly, the class `reactive.Value` has a new alias, `reactive.value`, but in this case, since the original was a class, it keeps the original capitalized name as the primary name. The examples have not been changed yet, but will be changed in a future release. (#822) + * Added `ui.layout_columns()` for creating responsive column-forward layouts based on Bootstrap's 12-column CSS Grid. (#856) + * Added support for Shiny Express apps, which has a simpler, easier-to-use API than the existing API (Shiny Core). Please note that this API is still experimental and may change. (#767) ### Bug fixes @@ -130,27 +170,42 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Other changes * Closed #492: `shiny.ui.nav()` is now deprecated in favor of the more aptly named `shiny.ui.nav_panel()` (#876). + * Update penguins example to credit Allison Horst and drop usage of `shiny.experimental` (#798). + * `as_fillable_container()` and `as_fill_item()` no longer mutate the `Tag` object that was passed in. Instead, it returns a new `Tag` object. Also closed #856: these functions now put the `html-fill-container` and `html-fill-item` CSS classes last, instead of first. (#862) + * `App()` now accepts a server function with a single `input` parameter, or a server function with parameters `input`, `output` and `session`. Server functions with two or more than three parameters now raise an exception. (#920) ## [0.6.0] - 2023-10-30 ### Breaking Changes + * `shiny.run` only allows positional arguments for `app`, `host`, and `port`, all other arguments must be specified with keywords. ### New features + * `shiny run` now takes `reload-includes` and `reload-excludes` to allow you to define which files trigger a reload (#780). + * `shiny.run` now passes keyword arguments to `uvicorn.run` (#780). + * The `@output` decorator is no longer required for rendering functions; `@render.xxx` decorators now register themselves automatically. You can still use `@output` explicitly if you need to set specific output options (#747, #790). + * Added support for integration with Quarto (#746). + * Added `shiny.render.renderer_components` decorator to help create new output renderers (#621). + * Added `shiny.experimental.ui.popover()`, `update_popover()`, and `toggle_popover()` for easy creation (and server-side updating) of [Bootstrap popovers](https://getbootstrap.com/docs/5.3/components/popovers/). Popovers are similar to tooltips, but are more persistent, and should primarily be used with button-like UI elements (e.g. `input_action_button()` or icons) (#680). + * Added CSS classes to UI input methods (#680) . + * `Session` objects can now accept an asynchronous (or synchronous) function for `.on_flush(fn=)`, `.on_flushed(fn=)`, and `.on_ended(fn=)` (#686). + * `App()` now allows `static_assets` to represent multiple paths. To do this, pass in a dictionary instead of a string (#763). + * The `showcase_layout` argument of `value_box()` now accepts one of three character values: `"left center"`, `"top right"`, `"bottom"`. (#772) + * `value_box()` now supports many new themes and styles, or fully customizable themes using the new `value_box_theme()` function. To reflect the new capabilities, we've replaced `theme_color` with a new `theme` argument. The previous argument will continue work as expected, but with a deprecation warning. (#772) In addition to the Bootstrap theme names (`primary` ,`secondary`, etc.), you can now use the main Boostrap colors (`purple`, `blue`, `red`, etc.). You can also choose to apply the color to the background or foreground by prepending a `bg-` or `text-` prefix to the theme or color name. Finally, we've also added new gradient themes allowing you to pair any two color names as `bg-gradient-{from}-{to}` (e.g., `bg-gradient-purple-blue`). @@ -162,25 +217,37 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Bug fixes * `shiny run` now respects the user provided `reload-dir` argument (#765). + * Fixed #646: Wrap bare value box value in `

` tags. (#668) + * Fixed #676: The `render.data_frame` selection feature was underdocumented and buggy (sometimes returning `None` as a row identifier if the pandas data frame's index had gaps in it). With this release, the selection is consistently a tuple of the 0-based row numbers of the selected rows--or `None` if no rows are selected. (#677) + * Added tests to verify that ui input methods, ui labels, ui update (value) methods, and ui output methods work within modules (#696). + * Adjusted the `@render.plot` input type to be `object` to allow for any object (if any) to be returned (#712). + * In `layout_column_wrap()`, when `width` is a CSS unit -- e.g. `width = "400px"` or `width = "25%"` -- and `fixed_width = FALSE`, `layout_column_wrap()` will ensure that the columns are at least `width` wide, unless the parent container is narrower than `width`. (#772) ### Other changes * `input_action_button()` now defaults to having whitespace around it. (#758) + * `layout_sidebar()` now uses an `