Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
a5da220
Update shiny deps to `main`
schloerke Oct 19, 2023
0801d5c
Update htmltools deps to `main`
schloerke Oct 19, 2023
96aad41
Update bslib dep files (includes bootstrap 5.3). Needs new htmldep ob…
schloerke Oct 19, 2023
61176c8
Use new bslib html dep files
schloerke Oct 19, 2023
ddeb8a7
htmldep followup; Drop sidebar css and make web component a JS module
schloerke Oct 23, 2023
ceb64f3
Updates from rstudio/bslib#798
schloerke Oct 23, 2023
2bfc397
Set `inverse=True` for navbar; Add classes to page methods; Updates f…
schloerke Oct 23, 2023
9868bc7
Add `page_bootstrap(**kwargs)` to support attrs on body tag. From rst…
schloerke Oct 23, 2023
a3a385d
Always try to init the sidebar; From rstudio/bslib#795
schloerke Oct 23, 2023
096b7cc
Use semantic elements in sidebar rstudio/bslib#580
schloerke Oct 23, 2023
52a7da2
Add .bslib-input-switch class rstudio/bslib#741
schloerke Oct 23, 2023
28f1d6f
Docs for tooltip / popover accessibility; rstudio/bslib#825
schloerke Oct 23, 2023
101c2ae
docs(navs): Improve examples for recommended usage; rstudio/bslib#848
schloerke Oct 23, 2023
8457a66
Fix bug where dropdown menu did not align right
schloerke Oct 25, 2023
5e4f3bc
Update navs card methods to have header/footer in the main body of th…
schloerke Oct 25, 2023
6a2f5de
Add `ui.navset_underline()`, `ui.navset_card_underline()`, `ui.page_n…
schloerke Oct 25, 2023
37ef3d7
Add title support for `navset_card_tab()`, `navset_card_pill()`, and …
schloerke Oct 25, 2023
14b3298
Do not have `navset_bar(title=)` be displayed as a link. Use `span`
schloerke Oct 25, 2023
69c0ebc
Add `See Also` entries for navset_underline, navset_card_underline, n…
schloerke Oct 25, 2023
04a5f8d
Docs, changelog, and quartodoc for `navset_underline()` and `navset_c…
schloerke Oct 25, 2023
735a6ab
Do not keep htmldep files that are not used
schloerke Oct 25, 2023
83e867c
Update r-shiny deps
schloerke Oct 25, 2023
1f23738
Update `layout_column_width(fixed_width)` param's min width.
schloerke Oct 25, 2023
d68adf2
Make `layout_column_wrap(*args, width=)`'s `width` come after `*args`
schloerke Oct 25, 2023
13db422
Update test_navs.py
schloerke Oct 25, 2023
09865d9
Update _page.py
schloerke Oct 25, 2023
7dd3121
First pass of Move X valuebox code over to main. Start new value_box …
schloerke Oct 25, 2023
c5ef9ae
Legacy type check change for python <= 3.9
schloerke Oct 25, 2023
9bb128a
Use array of options when building multiple TS files
schloerke Oct 26, 2023
286aa86
Implement new `value_box(showcase=,theme=)`
schloerke Oct 26, 2023
f4f7f82
Move and fix accordion and valubox e2e tests
schloerke Oct 27, 2023
a2a018d
Update CHANGELOG.md
schloerke Oct 27, 2023
3f5bb6b
Add navset underline methods to api-example
schloerke Oct 27, 2023
ac44ae3
Update width position
schloerke Oct 27, 2023
6ca74f6
Update Nav test
schloerke Oct 27, 2023
a19adbe
Fixes for finds from Karan
schloerke Oct 27, 2023
81699b4
Simplify example to supply only text
schloerke Oct 27, 2023
b2fd369
Use proper width location
schloerke Oct 27, 2023
9330df1
Move icons in example to external files
schloerke Oct 27, 2023
f658fe6
Remove legacy support as the error message is ok
schloerke Oct 27, 2023
65eb240
Code feedback
schloerke Oct 27, 2023
7726d91
lints
schloerke Oct 27, 2023
4d5e12b
Save metafile when bundle is made, not after all bundles are made
schloerke Oct 27, 2023
256f1b3
Update name / theme docs
schloerke Oct 27, 2023
2ec03aa
Merge branch 'main' into update_shinyverse
schloerke Oct 27, 2023
9a381b9
Better full screen icon support; Updated css vars from bslib
schloerke Oct 27, 2023
1261877
Update test_sidebar_colors.py
schloerke Oct 27, 2023
080fa8a
Update bootstrap web link
schloerke Oct 27, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 37 additions & 15 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,79 +8,101 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [UNRELEASED]

### 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).
* 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.2/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 `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`).

These named color themes aren't limited to value boxes: because they're powered by small utility classes, you can use them anywhere within your bslib-powered UI.

* Added `shiny.ui.showcase_bottom()`, a new `shiny.ui.value_box()` layout that places the showcase below the value box `title` and `value`, perfect for a full-bleed plot. (#772)

### API changes

* Added `shiny.ui.navset_underline()` and `shiny.ui.navset_card_underline()` whose navigation container is similar to `shiny.ui.navset_tab()` and `shiny.ui.navset_card_tab()` respectively, but its active/focused navigation links are styled with an underline. (#772)
* `shiny.ui.layout_column_wrap(width, *args)` was rearranged to `shiny.ui.layout_column_wrap(*args, width)`. Now, `width` will default to `200px` is no value is provided. (#772)
* `shiny.ui.showcase_left_center()` and `shiny.ui.showcase_top_right()` no longer take two values for the `width` argument. Instead, they now take a single value (e.g., `width = "30%"`) representing the width of the showcase are in the value box. Furthermore, they've both gained `width_full_screen` arguments that determine the width of the showcase area when the value box is expanded to fill the screen. (#772)


* TODO-barret-API; `shiny.ui.panel_main()` and `shiny.ui.panel_sidebar()` are deprecated in favor of new API for `shiny.ui.layout_sidebar()`. Please use `shiny.ui.sidebar()` to construct a sidebar and supply it (along with the main content) to `shiny.ui.layout_sidebar(*args, **kwargs)`. (#680)

#### API relocations

* `shiny.ui`'s `navset_pill_card()` and `navset_tab_card()` have been renamed to `.navset_card_pill()` and `navset_tab_card()` respectively (#492).
* `shiny.ui`'s `navset_pill_card()` and `navset_tab_card()` have been renamed to `navset_card_pill()` and `navset_card_tab()` respectively (#492).

The following methods have been moved from `shiny.experimental.ui` and integrated into `shiny.ui` (final locations under `shiny.ui` are displayed) (#680):

* Sidebar - Sidebar layout or manipulation
* `page_sidebar()`, `toggle_sidebar()`, `layout_sidebar()`
* `sidebar()`, `page_sidebar()`, `toggle_sidebar()`, `layout_sidebar()`, `Sidebar`
* Filling layout - Allow UI components to expand into the parent container and/or allow its content to expand
* `page_fillable()`, `fill.as_fillable_container()`, `fill.as_fill_item()`, `fill.is_fillable_container()`, `fill.is_fill_item()`, `fill.remove_all_fill()`
* `output_plot(fill=)`, `output_image(fill=)`, `output_ui(fill=, fillable=)`
* CSS units - CSS units and padding
* `css.as_css_unit()`, `css.as_css_padding()`, `css.as_width_unit()`, `css.CssUnit`
* `css.as_css_unit()`, `css.as_css_padding()`, `css.CssUnit`
* Tooltip - Hover-based context UI element
* `tooltip()`, `toggle_tooltip()`, `update_tooltip()`
* Popover - Click-based context UI element
* `popover()`, `toggle_popover()`, `update_popover()`
* Accordion - Vertically collapsible UI element
* `accordion()`, `accordion_panel()`, `accordion_panel_close()`, `accordion_panel_insert()`, `accordion_panel_open()`, `accordion_panel_remove()`, `accordion_panel_set()`, `Accordion`
* `accordion()`, `accordion_panel()`, `accordion_panel_close()`, `accordion_panel_insert()`, `accordion_panel_open()`, `accordion_panel_remove()`, `accordion_panel_set()`, `update_accordion_panel()`, `Accordion`, `AccordionPanel`
* Card - A general purpose container for grouping related UI elements together
* `card()`, `card_header()`, `card_footer()`, `CardItem`
* Valuebox - Opinionated container for displaying a value and title
* `valuebox()`
* `showcase_left_center()`
* `showcase_top_right()`
* Navs - Navigation within a page
* `navset_bar()`, `navset_tab_card()`, `navset_pill_card()`
* `page_navbar(sidebar=, fillable=, fillable_mobile=, gap=, padding=, inverse=True)`, `navset_card_tab(sidebar=)`, `navset_card_pill(sidebar=)`, `navset_bar(sidebar=, fillable=, gap=, padding=)`
* `page_navbar(sidebar=, fillable=, fillable_mobile=, gap=, padding=)`, `navset_card_tab(sidebar=)`, `navset_card_pill(sidebar=)`, `navset_bar(sidebar=, fillable=, gap=, padding=)`
* Layout - Layout of UI elements
* `layout_column_wrap()`
* Inputs - UI elements for user input
* `toggle_switch()`
* `input_text_area(autoresize=)`

If a ported method is called from `shiny.experimental.ui`, a deprecation warning will be displayed.

Methods still under consideration in `shiny.experimental.ui`:
* `value_box(showcase=)`
* `card(wrapper=)`, `card_body()`, `card_image()`, `card_header()`


### Bug fixes
* `shiny run` now respects the user provided `reload-dir` argument (#765).
* `card(wrapper=)`: A function (which returns a UI element) to call on unnamed arguments in `card(*args)` which are not already `shiny.ui.CardItem` objects.
* `card_body()`: A container for grouping related UI elements together
* `card_image()`: A general container for an image within a `shiny.ui.card`.
* `card_title()`: A general container for the "title" of a `shiny.ui.card`.

#### API removals

* `shiny.experimental.ui.FillingLayout` has been removed. (#481)
* `shiny.experimental.ui.as_width_unit()` has been made defunct. Please remove it from your code. (#772)
* Support for `min_height=`, `max_height=`, and `gap=` in `shiny.experimental.ui.as_fillable_container()` and `as_fill_item()` has been removed. (#481)
* `shiny.experimental.ui.TagCallable` has been deprecated. Its type is equivalent to `htmltools.TagFunction`. (#680)
* `shiny.eperimental.ui.as_fill_carrier()` and `shiny.eperimental.ui.is_fill_carrier()` have been deprecated. Please use `shiny.ui.fill.as_fill_item()` and `shiny.ui.fill.as_fillable_container()` or `shiny.ui.fill.is_fill_item()` and `shiny.ui.fill.is_fillable_container()` respectively in combination to achieve similar behavior. (#680)
* `shiny.experimental.ui.as_fill_carrier()` and `shiny.experimental.ui.is_fill_carrier()` have been deprecated. Please use `shiny.ui.fill.as_fill_item()` and `shiny.ui.fill.as_fillable_container()` or `shiny.ui.fill.is_fill_item()` and `shiny.ui.fill.is_fillable_container()` respectively in combination to achieve similar behavior. (#680)

### Bug fixes

* `shiny run` now respects the user provided `reload-dir` argument (#765).
* Fixed #646: Wrap bare value box value in `<p />` 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

### Breaking Changes
* `shiny.run` only allows positional arguments for `app`, `host`, and `port`, all other arguments must be specified with keywords.
* `layout_sidebar()` now uses an `<aside>` element for the sidebar's container and a `<header>` element for the sidebar title. The classes of each element remain the same, but the semantic meaning of the elements is now better reflected in the HTML markup. (#772)
* `layout_sidebar()` no longer gives the sidebar main content area the `role="main"` attribute. (#772)
* Improved the style and appearance of the button to enter full screen in `card()`s and `value_box()`es to better adapt to Bootstrap's dark mode. (#772)


## [0.5.1] - 2023-08-08
Expand Down
31 changes: 16 additions & 15 deletions docs/_quartodoc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ quartodoc:
- ui.page_fluid
- ui.page_fixed
- ui.page_bootstrap
- title: UI Layout
- title: UI Layouts
desc: Control the layout of multiple UI components.
contents:
- ui.sidebar
Expand All @@ -28,7 +28,6 @@ quartodoc:
- ui.card
- ui.card_header
- ui.card_footer
- ui.value_box
- ui.popover
- ui.tooltip
- ui.accordion
Expand All @@ -53,18 +52,30 @@ quartodoc:
- ui.input_password
- ui.input_action_button
- ui.input_action_link
- title: Value boxes
desc: Prominently display a value and label in a box that can be expanded to show more information.
contents:
- ui.value_box
- ui.value_box_theme
- ui.showcase_bottom
- ui.showcase_left_center
- ui.showcase_top_right
- ui.ValueBoxTheme
- ui.ShowcaseLayout
- title: Navigation (tab) panels
desc: Create segments of UI content.
contents:
- ui.nav
- ui.nav_control
- ui.nav_spacer
- ui.nav_menu
- ui.navset_tab
- ui.navset_bar
- ui.navset_card_tab
- ui.navset_tab
- ui.navset_pill
- ui.navset_underline
- ui.navset_card_tab
- ui.navset_card_pill
- ui.navset_card_underline
- ui.navset_pill_list
- ui.navset_hidden
- title: UI panels
Expand Down Expand Up @@ -277,21 +288,11 @@ quartodoc:
path: ExCard
summary:
name: "Card"
desc: "Cards are a common organizing unit for modern user interfaces (UI). At their core, theyre just rectangular containers with borders and padding. However, when utilized properly to group related information, they help users better digest, engage, and navigate through content."
desc: "Cards are a common organizing unit for modern user interfaces (UI). At their core, they're just rectangular containers with borders and padding. However, when utilized properly to group related information, they help users better digest, engage, and navigate through content."
flatten: true
contents:
- experimental.ui.card_body
- experimental.ui.card_title
- experimental.ui.card_image
- experimental.ui.ImgContainer
- experimental.ui.WrapperCallable
- kind: page
path: ExValueBoxes
summary:
name: "Value boxes"
desc: "Prominently display a value and label in a box that can be expanded to show more information."
flatten: true
contents:
- experimental.ui.value_box
- experimental.ui.showcase_left_center
- experimental.ui.showcase_top_right
75 changes: 40 additions & 35 deletions js/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,55 +4,60 @@ import * as fs from "node:fs/promises";

const outDir = "../shiny/www/shared/py-shiny";

// TODO-barret-future; Map over options and wait their build to finish

async function bundle_dataframe() {
async function bundle_helper(
options: BuildOptions
): Promise<ReturnType<typeof build>> {
try {
const options: BuildOptions = {
entryPoints: { dataframe: "dataframe/index.tsx" },
const result = await build({
format: "esm",
bundle: true,
outdir: outDir + "/dataframe",
minify: true,
sourcemap: true,
plugins: [sassPlugin({ type: "css-text", sourceMap: false })],
metafile: true,
};
metafile: false,
outdir: outDir,
...options,
});

const result = await build(options);
console.log("Building dataframe completed successfully!");
// console.log("Output:", result);
await fs.writeFile(
"esbuild-metadata.json",
JSON.stringify(result.metafile)
Object.entries(options.entryPoints as Record<string, string>).forEach(
([output_file_stub, input_path]) => {
console.log(
"Building " + output_file_stub + ".js completed successfully!"
);
}
);

if (options.metafile) {
// Save metafile
const dataframe_results = result;
await fs.writeFile(
"esbuild-metadata.json",
JSON.stringify(dataframe_results.metafile)
);
console.log("Metadata file written to esbuild-metadata.json");
}
return result;
} catch (error) {
console.error("Build failed:", error);
}
}

async function bundle_textarea() {
try {
const options: BuildOptions = {
entryPoints: {
"textarea-autoresize": "text-area/textarea-autoresize.ts",
},
format: "esm",
bundle: true,
outdir: outDir + "/text-area",
minify: false,
sourcemap: false,
metafile: false,
};
const result = await build(options);
console.log("Building textarea-autoresize completed successfully!");
} catch (error) {
console.error("Build failed for textarea-autoresize:", error);
}
}
const opts: Array<BuildOptions> = [
{
entryPoints: { "dataframe/dataframe": "dataframe/index.tsx" },
plugins: [sassPlugin({ type: "css-text", sourceMap: false })],
metafile: true,
},
{
entryPoints: {
"text-area/textarea-autoresize": "text-area/textarea-autoresize.ts",
},
minify: false,
sourcemap: false,
},
];

// Run function to avoid top level await
async function main(): Promise<void> {
await Promise.all([bundle_dataframe(), bundle_textarea()]);
await Promise.all(opts.map(bundle_helper));
}
main();
4 changes: 3 additions & 1 deletion js/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
"private": true,
"license": "MIT",
"scripts": {
"build": "tsc -noEmit && eslint . && tsx build.ts",
"lint": "tsc -noEmit && eslint .",
"bundle": "tsx build.ts",
"build": "npm run lint && npm run bundle",
"watch": "npx nodemon --exec 'npm run build' --ext '*' --ignore dist/ --ignore esbuild-metadata.json",
"build-fast": "tsx build.ts",
"watch-fast": "npx nodemon --exec 'npm run build-fast' --ext '*' --ignore dist/ --ignore esbuild-metadata.json"
Expand Down
33 changes: 29 additions & 4 deletions scripts/htmlDependencies.R
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ versions <- list()
message("Installing GitHub packages: bslib, shiny, htmltools")
withr::local_temp_libpaths()
ignore <- capture.output({
pak::pkg_install(c("rstudio/bslib@a076e72e78562d7f006889da4118cd781c66c84c", "rstudio/shiny@ab69d7292c51d8983174e0828496a7096f513673", "rstudio/htmltools@9338b7f3e2ed7b3fef8fd813904b9b05281344aa"))
pak::pkg_install(c("rstudio/bslib@main", "rstudio/shiny@main", "rstudio/htmltools@main"))
})
# pak::pkg_install(c("cran::bslib", "cran::shiny", "cran::htmltools"))

Expand Down Expand Up @@ -173,7 +173,12 @@ message("Save bootstrap bundle")
deps <- bslib::bs_theme_dependencies(shiny_theme)
withr::with_options(
list(htmltools.dir.version = FALSE),
ignore <- lapply(deps, copyDependencyToDir, www_shared)
ignore <- lapply(deps, function(dep) {
if (dep$name %in% c("bslib-component-css", "bslib-component-js")) {
return()
}
copyDependencyToDir(dep, www_shared)
})
)
bs_ver <- names(bslib::versions())[bslib::versions() == "5"]
versions["bootstrap"] <- bs_ver
Expand Down Expand Up @@ -203,10 +208,30 @@ message("Cleanup bootstrap bundle")
# This additional bs3compat HTMLDependency() only holds
# the JS shim for tab panel logic, which we don't need
# since we're generating BS5+ tab markup. Note, however,
# we still do have bs3compat's CSS on the page, which
# comes in via the bootstrap HTMLDependency()
# we still do have bs3compat's bundled CSS on the page, which
# comes in naturally via the bootstrap HTMLDependency()
fs::dir_delete(fs::path(www_shared, "bs3compat"))

# Remove non-minified or unused files
fs::file_delete(
fs::path(www_shared, c(
"datepicker/css/bootstrap-datepicker3.css",
"datepicker/js/bootstrap-datepicker.js",
"datepicker/scss",
"ionrangeslider/js/ion.rangeSlider.js",
"ionrangeslider/scss",
"jquery/jquery-3.6.0.js",
"jqueryui/jquery-ui.css",
"jqueryui/jquery-ui.js",
"jqueryui/jquery-ui.structure.css",
"jqueryui/jquery-ui.structure.min.css",
"jqueryui/jquery-ui.theme.css",
"jqueryui/jquery-ui.theme.min.css",
"selectize/accessibility/js/selectize-plugin-a11y.js",
"selectize/js/selectize.js"
))
)


# ------------------------------------------------------------------------------
message("Save requirejs")
Expand Down
8 changes: 4 additions & 4 deletions shiny/_versions.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
shiny_html_deps = "1.7.4.9003"
bslib = "0.5.0.9000"
htmltools = "0.5.5.9000"
bootstrap = "5.2.2"
shiny_html_deps = "1.7.5.9000"
bslib = "0.5.1.9000"
htmltools = "0.5.6.9001"
bootstrap = "5.3.1"
requirejs = "2.3.6"

__all__ = (
Expand Down
2 changes: 1 addition & 1 deletion shiny/api-examples/accordion/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ def _():
@output
@render.text
def acc_val():
return input.acc()
return "input.acc(): " + str(input.acc())


app = App(app_ui, server)
2 changes: 1 addition & 1 deletion shiny/api-examples/accordion_panel/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def _():
@output
@render.text
def acc_val():
return input.acc()
return "input.acc(): " + str(input.acc())


app = App(app_ui, server)
1 change: 1 addition & 0 deletions shiny/api-examples/accordion_panel_remove/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ def make_panel(letter: str) -> ui.AccordionPanel:
f"Remove Section {choices[-1]}",
class_="mt-3 mb-3",
),
" (Sections randomly picked at server start)",
ui.accordion(*items, id="acc", multiple=True),
)

Expand Down
Loading