diff --git a/.github/workflows/deploy-docs.yml b/.github/workflows/deploy-docs.yml index 3a00dec9..241b39c4 100644 --- a/.github/workflows/deploy-docs.yml +++ b/.github/workflows/deploy-docs.yml @@ -4,7 +4,6 @@ on: push: branches: [main] pull_request: - branches: [main] jobs: build: @@ -50,7 +49,7 @@ jobs: # ===================================================== - uses: quarto-dev/quarto-actions/setup@v2 with: - version: 1.4.549 + version: 1.4.557 - name: Build site run: | diff --git a/_quarto.yml b/_quarto.yml index be2475cb..0484d6c0 100644 --- a/_quarto.yml +++ b/_quarto.yml @@ -62,6 +62,9 @@ website: image-height: 630 card-style: "summary_large_image" + repo-url: https://github.com/posit-dev/py-shiny-site + repo-actions: [issue, edit] + navbar: background: primary foreground: light diff --git a/components/_metadata.yml b/components/_metadata.yml index bd07e269..fda34ee3 100644 --- a/components/_metadata.yml +++ b/components/_metadata.yml @@ -10,3 +10,4 @@ filters: - quarto - line-highlight - shinylive +repo-actions: false diff --git a/components/outputs/data-grid/app-variation-select-rows-core.py b/components/outputs/data-grid/app-variation-select-rows-core.py index 41cc9584..10179d1a 100644 --- a/components/outputs/data-grid/app-variation-select-rows-core.py +++ b/components/outputs/data-grid/app-variation-select-rows-core.py @@ -17,7 +17,7 @@ def penguins_df(): @render.ui def rows(): - rows = penguins_df.input_cell_selection()["rows"] # << + rows = penguins_df.cell_selection()["rows"] # << selected = ", ".join(str(i) for i in sorted(rows)) if rows else "None" return f"Rows selected: {selected}" diff --git a/components/outputs/data-grid/app-variation-select-rows-express.py b/components/outputs/data-grid/app-variation-select-rows-express.py index 68cf1ade..5173593e 100644 --- a/components/outputs/data-grid/app-variation-select-rows-express.py +++ b/components/outputs/data-grid/app-variation-select-rows-express.py @@ -9,7 +9,7 @@ @render.ui() def rows(): - rows = penguins_df.input_cell_selection()["rows"] # << + rows = penguins_df.cell_selection()["rows"] # << selected = ", ".join(str(i) for i in sorted(rows)) if rows else "None" return f"Rows selected: {selected}" diff --git a/components/outputs/data-grid/index.qmd b/components/outputs/data-grid/index.qmd index d3210bba..e90be377 100644 --- a/components/outputs/data-grid/index.qmd +++ b/components/outputs/data-grid/index.qmd @@ -47,7 +47,7 @@ listing: - title: Select Rows description: Set `selection_mode` in `render.DataGrid()` to `"row"` to allow the user to select one row at a time. Set it to `"rows"` to allow the user to select - multiple rows at a time. Access the selection(s) as `.input_cell_selection()["rows"]`. + multiple rows at a time. Access the selection(s) as `.cell_selection()["rows"]`. apps: - title: Preview file: app-variation-select-rows-core.py @@ -130,9 +130,9 @@ To make a reactive Data Grid, follow three steps: A Data Grid can also collect input from the user. To allow this, set `render.DataGrid(selection_mode="row")` or `render.DataGrid(selection_mode="rows")` to allow the user to select one or more rows of the Data Grid. -The indices of the selected rows will be accessible within the server function as a reactive variable returned by `.input_cell_selection()["rows"]`, where is the name of the function decorated with `@render.data_frame`. +The indices of the selected rows will be accessible within the server function as a reactive variable returned by `.cell_selection()["rows"]`, where is the name of the function decorated with `@render.data_frame`. -The value returned will be an empty tuple if no rows are selected, or a tuple of integers representing the indices of the selected rows. To filter a pandas data frame down to the selected rows, use `df.iloc[list(.input_cell_selection()["rows"])]`. +The value returned will be an empty tuple if no rows are selected, or a tuple of integers representing the indices of the selected rows. To filter a pandas data frame down to the selected rows, use `df.iloc[list(.cell_selection()["rows"])]`. For more information about interacting with data frames, see the API documentation for [Express](../../../api/express/express.render.data_frame.qmd) or [Core](../../../api/core/render.data_frame.qmd) syntax. diff --git a/components/outputs/datatable/app-variation-select-rows-core.py b/components/outputs/datatable/app-variation-select-rows-core.py index a9625cb9..af0ef71d 100644 --- a/components/outputs/datatable/app-variation-select-rows-core.py +++ b/components/outputs/datatable/app-variation-select-rows-core.py @@ -17,7 +17,7 @@ def penguins_df(): @render.ui def rows(): - rows = penguins_df.input_cell_selection()["rows"] # << + rows = penguins_df.cell_selection()["rows"] # << selected = ", ".join(str(i) for i in sorted(rows)) if rows else "None" return f"Rows selected: {selected}" diff --git a/components/outputs/datatable/app-variation-select-rows-express.py b/components/outputs/datatable/app-variation-select-rows-express.py index 032e4772..9a8c0bae 100644 --- a/components/outputs/datatable/app-variation-select-rows-express.py +++ b/components/outputs/datatable/app-variation-select-rows-express.py @@ -9,7 +9,7 @@ @render.ui def rows(): - rows = penguins_df.input_cell_selection()["rows"] # << + rows = penguins_df.cell_selection()["rows"] # << selected = ", ".join(str(i) for i in sorted(rows)) if rows else "None" return f"Rows selected: {selected}" diff --git a/components/outputs/datatable/index.qmd b/components/outputs/datatable/index.qmd index baf1cab8..3d40410c 100644 --- a/components/outputs/datatable/index.qmd +++ b/components/outputs/datatable/index.qmd @@ -47,7 +47,7 @@ listing: - title: Select Rows description: Set `selection_mode` in `render.DataTable()` to `"row"` to allow the user to select one row at a time. Set it to `"rows"` to allow the user to - select multiple rows at a time. Access the selection(s) as `.input_cell_selection()["rows"]`. + select multiple rows at a time. Access the selection(s) as `.cell_selection()["rows"]`. apps: - title: Preview file: app-variation-select-rows-core.py @@ -130,9 +130,9 @@ To make a reactive Data Table, follow three steps: A Data Table can also collect input from the user. To allow this, set `render.DataTable(selection_mode="row")` or `render.DataTable(selection_mode="rows")` to allow the user to select one or more rows of the Data Table. -The indices of the selected rows will be accessible within the server function as a reactive variable returned by `.input_cell_selection()["rows"]`, where is the name of the function decorated with `@render.data_frame`. +The indices of the selected rows will be accessible within the server function as a reactive variable returned by `.cell_selection()["rows"]`, where is the name of the function decorated with `@render.data_frame`. -The value returned will be an empty tuple if no rows are selected, or a tuple of integers representing the indices of the selected rows. To filter a pandas data frame down to the selected rows, use `df.iloc[list(.input_cell_selection()["rows"])]`. +The value returned will be an empty tuple if no rows are selected, or a tuple of integers representing the indices of the selected rows. To filter a pandas data frame down to the selected rows, use `df.iloc[list(.cell_selection()["rows"])]`. For more information about interacting with data frames, see the API documentation for [Express](../../../api/express/express.render.data_frame.qmd) or [Core](../../../api/core/render.data_frame.qmd) syntax. diff --git a/docs/helpers.py b/docs/helpers.py index 9b5fee6f..f7f561fc 100644 --- a/docs/helpers.py +++ b/docs/helpers.py @@ -207,43 +207,57 @@ def shinylive_app_preview( def express_core_preview( - app_express: str | None = None, - app_core: str | None = None, - files: list[str] | str | None = None, - div_attrs=".shiny-mode-tabset", - group="shiny-app-mode", - language="py", - **kwargs, + app_express: str, + app_core: str, + div_attrs: str = '.shiny-mode-tabset group="shiny-app-mode"', ) -> None: - if app_express is None and app_core is None: - return - - if files is None: - files = [] - elif isinstance(files, str): - files = [files] + app_preview_code( + { + "Express": app_express, + "Core": app_core, + }, + div_attrs=div_attrs, + ) - header_attrs = ".panel-tabset" - header_attrs += " " + div_attrs if div_attrs else "" - header_attrs += f" group='{group}'" if group else "" - block = QuartoPrint(["::: {" + header_attrs + "}"]) +def app_preview_code( + app_files: str | dict[str, str], + files: list[str] | str | None = None, + language: Literal["auto", "py", "r"] = "auto", + div_attrs: str = "", +) -> None: - apps = zip([app_express, app_core], ["Express", "Core"]) + is_tabset = isinstance(app_files, dict) - for app_file, tab_name in apps: - if app_file is None: - continue + if is_tabset: + div_attrs = ".panel-tabset " + div_attrs - sl_app = ShinyliveApp.from_local(app_file, files, language) - lang = "python" if language == "py" else "r" + block = QuartoPrint(["::: {" + div_attrs + "}"]) - block.append("### " + tab_name) - block.append( - f'```{{.{lang} .code-overflow-scroll shinylive="{sl_app.to_url()}"}}' - ) - block.append_file(app_file) - block.extend(["```", ""]) + if not is_tabset: + _add_code_chunk(block, app_files, files, language) + else: + for x in app_files: + block.append(f"## {x}") + _add_code_chunk(block, app_files[x], files, language) block.append(":::") print(block) + + +def _add_code_chunk( + block: QuartoPrint, + file: str, + files: list[str] | str | None = None, + language: Literal["auto", "py", "r"] = "auto", +): + if language == "auto": + language = "py" if file.endswith(".py") else "r" + + sl_app = ShinyliveApp.from_local(file, files=files, language=language) + + lang = "python" if language == "py" else "r" + + block.append(f'```{{.{lang} .code-overflow-scroll shinylive="{sl_app.to_url()}"}}') + block.append_file(file) + block.append("```") diff --git a/docs/overview.qmd b/docs/overview.qmd index 424266c5..fc236a77 100644 --- a/docs/overview.qmd +++ b/docs/overview.qmd @@ -539,7 +539,7 @@ shiny create -t dashboard ## Development workflow See the [workflow](install-create-run.qmd) section for more information developing Shiny apps locally. -Also keep in mind you can develop apps in the browser using the [playground](/playground). +Also keep in mind you can develop apps in the browser using the [playground](https://shinylive.io/py/examples/). ::: diff --git a/docs/user-interfaces.qmd b/docs/user-interfaces.qmd index d04ec2fb..8d33d96b 100644 --- a/docs/user-interfaces.qmd +++ b/docs/user-interfaces.qmd @@ -9,7 +9,7 @@ With Shiny, you can create a wide variety of user interfaces (UI), including das Here, we'll use the following dashboard as motivation to learn about some important UI components (e.g., [cards](#cards), [value boxes](#value-boxes)) and layouts (e.g., [columns](#multi-column-layout)). -![A Shiny dashboard with visuals for exploring restaurant tips (see [here](#altogether-now) for the code).](assets/tipping-dashboard.png){class="img-shadow"} +![A Shiny dashboard with visuals for exploring restaurant tips (see [here](#all-together-now) for the code).](assets/tipping-dashboard.png){class="img-shadow"} ::: callout-tip ## More UI design inspiration @@ -207,7 +207,7 @@ Did you know the app viewer above is resizable? Try resizing it to see how the l Tooltips and popovers are a useful means for both displaying and interacting with additional information in a non-obtrusive way. Tooltips are shown on hover, whereas popovers are shown on click, making them more suitable for interactive content like inputs. -In the [actual dashboard](#altogether-now), we'll leverage a popover to effectively add a toolbar with additional inputs controls to card headers. +In the [actual dashboard](#all-together-now), we'll leverage a popover to effectively add a toolbar with additional inputs controls to card headers. ```{shinylive-python} #| standalone: true diff --git a/gallery/_metadata.yml b/gallery/_metadata.yml new file mode 100644 index 00000000..e21e9fa0 --- /dev/null +++ b/gallery/_metadata.yml @@ -0,0 +1 @@ +repo-actions: false diff --git a/index.qmd b/index.qmd index 51f227e6..c5552f59 100644 --- a/index.qmd +++ b/index.qmd @@ -11,6 +11,7 @@ format: smooth-scroll: true css: - index.css +repo-actions: false --- ::::{.column-screen .mx-auto .pt-0 .mt-0 .pt-xl-5 style="max-width: 1500px;"} diff --git a/layouts/_metadata.yml b/layouts/_metadata.yml index 46e13544..d67c8313 100644 --- a/layouts/_metadata.yml +++ b/layouts/_metadata.yml @@ -1,7 +1,7 @@ sidebar: layouts format: html: - css: + css: - /components/_partials/components.css - _partials/layouts-list.css toc: false @@ -10,5 +10,6 @@ format: filters: - quarto - line-highlight - - shinylive - \ No newline at end of file + - shinylive + +repo-actions: false diff --git a/py-shiny b/py-shiny index 21694ced..38607069 160000 --- a/py-shiny +++ b/py-shiny @@ -1 +1 @@ -Subproject commit 21694ceda197f46549d1f3ca74444b25bc8e257c +Subproject commit 38607069d01a96554281fcd3e57252e130589363 diff --git a/templates/_metadata.yml b/templates/_metadata.yml index e06076a5..40661728 100644 --- a/templates/_metadata.yml +++ b/templates/_metadata.yml @@ -3,12 +3,13 @@ format: html: template: _partials/gallery-article.template page-layout: article - css: + css: - /components/_partials/components.css - _partials/templates.css toc: false code-line-numbers: false include-after-body: ../components/_partials/componentsjs.html filters: - - shinylive - \ No newline at end of file + - shinylive + +repo-actions: false