From df4c3031a3b2f892f5cb7da388ab44451eea23bc Mon Sep 17 00:00:00 2001 From: Garrick Aden-Buie Date: Tue, 16 Jan 2024 16:11:28 -0500 Subject: [PATCH 01/33] commit existing intermediate qmd files --- docs/api/App.qmd | 99 + docs/api/ContextManagerComponents.qmd | 1697 ++++++++ docs/api/ExCard.qmd | 345 ++ docs/api/ExceptionTypes.qmd | 155 + docs/api/Inputs.qmd | 10 + docs/api/MiscTypes.qmd | 396 ++ docs/api/OutputRender.qmd | 318 ++ docs/api/Outputs.qmd | 5 + docs/api/PageFunctions.qmd | 43 + docs/api/Session.qmd | 616 +++ docs/api/TagTypes.qmd | 427 ++ docs/api/_sidebar.yml | 203 + docs/api/index.qmd | 298 ++ docs/api/input_handler.input_handlers.qmd | 60 + docs/api/module.server.qmd | 4 + docs/api/module.ui.qmd | 4 + docs/api/reactive.calc.qmd | 54 + docs/api/reactive.effect.qmd | 33 + docs/api/reactive.event.qmd | 143 + docs/api/reactive.file_reader.qmd | 137 + docs/api/reactive.flush.qmd | 12 + docs/api/reactive.get_current_context.qmd | 17 + docs/api/reactive.invalidate_later.qmd | 56 + docs/api/reactive.isolate.qmd | 67 + docs/api/reactive.lock.qmd | 9 + docs/api/reactive.poll.qmd | 222 + docs/api/reactive.value.qmd | 183 + docs/api/render.DataGrid.qmd | 58 + docs/api/render.DataTable.qmd | 58 + docs/api/render.data_frame.qmd | 184 + docs/api/render.image.qmd | 31 + docs/api/render.plot.qmd | 55 + docs/api/render.table.qmd | 50 + docs/api/render.text.qmd | 23 + .../render.transformer.resolve_value_fn.qmd | 38 + docs/api/render.ui.qmd | 23 + docs/api/req.qmd | 90 + docs/api/run_app.qmd | 99 + docs/api/session.get_current_session.qmd | 23 + docs/api/session.require_active_session.qmd | 34 + docs/api/session.session_context.qmd | 12 + docs/api/ui.HTML.qmd | 16 + docs/api/ui.Progress.qmd | 195 + docs/api/ui.ShowcaseLayout.qmd | 28 + docs/api/ui.TagList.qmd | 137 + docs/api/ui.ValueBoxTheme.qmd | 4 + docs/api/ui.accordion.qmd | 135 + docs/api/ui.accordion_panel.qmd | 91 + docs/api/ui.card.qmd | 76 + docs/api/ui.card_footer.qmd | 59 + docs/api/ui.card_header.qmd | 63 + docs/api/ui.column.qmd | 35 + docs/api/ui.css.as_css_padding.qmd | 17 + docs/api/ui.css.as_css_unit.qmd | 17 + docs/api/ui.download_button.qmd | 109 + docs/api/ui.fill.as_fill_item.qmd | 109 + docs/api/ui.fill.as_fillable_container.qmd | 83 + docs/api/ui.fill.remove_all_fill.qmd | 33 + docs/api/ui.help_text.qmd | 24 + docs/api/ui.include_css.qmd | 103 + docs/api/ui.include_js.qmd | 67 + docs/api/ui.input_action_button.qmd | 108 + docs/api/ui.input_action_link.qmd | 82 + docs/api/ui.input_checkbox.qmd | 72 + docs/api/ui.input_checkbox_group.qmd | 91 + docs/api/ui.input_date.qmd | 156 + docs/api/ui.input_date_range.qmd | 162 + docs/api/ui.input_file.qmd | 143 + docs/api/ui.input_numeric.qmd | 81 + docs/api/ui.input_password.qmd | 75 + docs/api/ui.input_radio_buttons.qmd | 88 + docs/api/ui.input_select.qmd | 106 + docs/api/ui.input_selectize.qmd | 94 + docs/api/ui.input_slider.qmd | 134 + docs/api/ui.input_switch.qmd | 74 + docs/api/ui.input_text.qmd | 87 + docs/api/ui.input_text_area.qmd | 130 + docs/api/ui.insert_accordion_panel.qmd | 83 + docs/api/ui.insert_ui.qmd | 96 + docs/api/ui.layout_column_wrap.qmd | 115 + docs/api/ui.layout_columns.qmd | 198 + docs/api/ui.layout_sidebar.qmd | 117 + docs/api/ui.markdown.qmd | 74 + docs/api/ui.modal.qmd | 90 + docs/api/ui.modal_button.qmd | 39 + docs/api/ui.modal_remove.qmd | 27 + docs/api/ui.modal_show.qmd | 30 + docs/api/ui.nav.qmd | 5 + docs/api/ui.nav_control.qmd | 32 + docs/api/ui.nav_menu.qmd | 61 + docs/api/ui.nav_panel.qmd | 150 + docs/api/ui.nav_spacer.qmd | 28 + docs/api/ui.navset_bar.qmd | 106 + docs/api/ui.navset_card_pill.qmd | 58 + docs/api/ui.navset_card_tab.qmd | 54 + docs/api/ui.navset_card_underline.qmd | 58 + docs/api/ui.navset_hidden.qmd | 86 + docs/api/ui.navset_pill.qmd | 50 + docs/api/ui.navset_pill_list.qmd | 58 + docs/api/ui.navset_tab.qmd | 53 + docs/api/ui.navset_underline.qmd | 50 + docs/api/ui.notification_remove.qmd | 37 + docs/api/ui.notification_show.qmd | 104 + docs/api/ui.output_data_frame.qmd | 22 + docs/api/ui.output_image.qmd | 109 + docs/api/ui.output_plot.qmd | 117 + docs/api/ui.output_table.qmd | 136 + docs/api/ui.output_text.qmd | 87 + docs/api/ui.output_text_verbatim.qmd | 38 + docs/api/ui.output_ui.qmd | 76 + docs/api/ui.page_auto.qmd | 58 + docs/api/ui.page_bootstrap.qmd | 37 + docs/api/ui.page_fillable.qmd | 48 + docs/api/ui.page_fixed.qmd | 80 + docs/api/ui.page_fluid.qmd | 80 + docs/api/ui.page_navbar.qmd | 101 + docs/api/ui.page_output.qmd | 17 + docs/api/ui.page_sidebar.qmd | 90 + docs/api/ui.panel_absolute.qmd | 122 + docs/api/ui.panel_conditional.qmd | 91 + docs/api/ui.panel_fixed.qmd | 29 + docs/api/ui.panel_main.qmd | 5 + docs/api/ui.panel_sidebar.qmd | 5 + docs/api/ui.panel_title.qmd | 51 + docs/api/ui.panel_well.qmd | 29 + docs/api/ui.popover.qmd | 172 + docs/api/ui.remove_accordion_panel.qmd | 94 + docs/api/ui.remove_ui.qmd | 67 + docs/api/ui.row.qmd | 71 + docs/api/ui.showcase_bottom.qmd | 83 + docs/api/ui.showcase_left_center.qmd | 81 + docs/api/ui.showcase_top_right.qmd | 81 + docs/api/ui.sidebar.qmd | 164 + docs/api/ui.tags.qmd | 3819 +++++++++++++++++ docs/api/ui.tooltip.qmd | 150 + docs/api/ui.update_accordion.qmd | 74 + docs/api/ui.update_accordion_panel.qmd | 106 + docs/api/ui.update_checkbox.qmd | 80 + docs/api/ui.update_checkbox_group.qmd | 101 + docs/api/ui.update_date.qmd | 80 + docs/api/ui.update_date_range.qmd | 104 + docs/api/ui.update_navs.qmd | 87 + docs/api/ui.update_numeric.qmd | 99 + docs/api/ui.update_popover.qmd | 79 + docs/api/ui.update_radio_buttons.qmd | 101 + docs/api/ui.update_select.qmd | 103 + docs/api/ui.update_selectize.qmd | 96 + docs/api/ui.update_sidebar.qmd | 69 + docs/api/ui.update_slider.qmd | 119 + docs/api/ui.update_switch.qmd | 50 + docs/api/ui.update_text.qmd | 87 + docs/api/ui.update_text_area.qmd | 54 + docs/api/ui.update_tooltip.qmd | 84 + docs/api/ui.value_box.qmd | 153 + docs/api/ui.value_box_theme.qmd | 40 + 155 files changed, 19310 insertions(+) create mode 100644 docs/api/App.qmd create mode 100644 docs/api/ContextManagerComponents.qmd create mode 100644 docs/api/ExCard.qmd create mode 100644 docs/api/ExceptionTypes.qmd create mode 100644 docs/api/Inputs.qmd create mode 100644 docs/api/MiscTypes.qmd create mode 100644 docs/api/OutputRender.qmd create mode 100644 docs/api/Outputs.qmd create mode 100644 docs/api/PageFunctions.qmd create mode 100644 docs/api/Session.qmd create mode 100644 docs/api/TagTypes.qmd create mode 100644 docs/api/_sidebar.yml create mode 100644 docs/api/index.qmd create mode 100644 docs/api/input_handler.input_handlers.qmd create mode 100644 docs/api/module.server.qmd create mode 100644 docs/api/module.ui.qmd create mode 100644 docs/api/reactive.calc.qmd create mode 100644 docs/api/reactive.effect.qmd create mode 100644 docs/api/reactive.event.qmd create mode 100644 docs/api/reactive.file_reader.qmd create mode 100644 docs/api/reactive.flush.qmd create mode 100644 docs/api/reactive.get_current_context.qmd create mode 100644 docs/api/reactive.invalidate_later.qmd create mode 100644 docs/api/reactive.isolate.qmd create mode 100644 docs/api/reactive.lock.qmd create mode 100644 docs/api/reactive.poll.qmd create mode 100644 docs/api/reactive.value.qmd create mode 100644 docs/api/render.DataGrid.qmd create mode 100644 docs/api/render.DataTable.qmd create mode 100644 docs/api/render.data_frame.qmd create mode 100644 docs/api/render.image.qmd create mode 100644 docs/api/render.plot.qmd create mode 100644 docs/api/render.table.qmd create mode 100644 docs/api/render.text.qmd create mode 100644 docs/api/render.transformer.resolve_value_fn.qmd create mode 100644 docs/api/render.ui.qmd create mode 100644 docs/api/req.qmd create mode 100644 docs/api/run_app.qmd create mode 100644 docs/api/session.get_current_session.qmd create mode 100644 docs/api/session.require_active_session.qmd create mode 100644 docs/api/session.session_context.qmd create mode 100644 docs/api/ui.HTML.qmd create mode 100644 docs/api/ui.Progress.qmd create mode 100644 docs/api/ui.ShowcaseLayout.qmd create mode 100644 docs/api/ui.TagList.qmd create mode 100644 docs/api/ui.ValueBoxTheme.qmd create mode 100644 docs/api/ui.accordion.qmd create mode 100644 docs/api/ui.accordion_panel.qmd create mode 100644 docs/api/ui.card.qmd create mode 100644 docs/api/ui.card_footer.qmd create mode 100644 docs/api/ui.card_header.qmd create mode 100644 docs/api/ui.column.qmd create mode 100644 docs/api/ui.css.as_css_padding.qmd create mode 100644 docs/api/ui.css.as_css_unit.qmd create mode 100644 docs/api/ui.download_button.qmd create mode 100644 docs/api/ui.fill.as_fill_item.qmd create mode 100644 docs/api/ui.fill.as_fillable_container.qmd create mode 100644 docs/api/ui.fill.remove_all_fill.qmd create mode 100644 docs/api/ui.help_text.qmd create mode 100644 docs/api/ui.include_css.qmd create mode 100644 docs/api/ui.include_js.qmd create mode 100644 docs/api/ui.input_action_button.qmd create mode 100644 docs/api/ui.input_action_link.qmd create mode 100644 docs/api/ui.input_checkbox.qmd create mode 100644 docs/api/ui.input_checkbox_group.qmd create mode 100644 docs/api/ui.input_date.qmd create mode 100644 docs/api/ui.input_date_range.qmd create mode 100644 docs/api/ui.input_file.qmd create mode 100644 docs/api/ui.input_numeric.qmd create mode 100644 docs/api/ui.input_password.qmd create mode 100644 docs/api/ui.input_radio_buttons.qmd create mode 100644 docs/api/ui.input_select.qmd create mode 100644 docs/api/ui.input_selectize.qmd create mode 100644 docs/api/ui.input_slider.qmd create mode 100644 docs/api/ui.input_switch.qmd create mode 100644 docs/api/ui.input_text.qmd create mode 100644 docs/api/ui.input_text_area.qmd create mode 100644 docs/api/ui.insert_accordion_panel.qmd create mode 100644 docs/api/ui.insert_ui.qmd create mode 100644 docs/api/ui.layout_column_wrap.qmd create mode 100644 docs/api/ui.layout_columns.qmd create mode 100644 docs/api/ui.layout_sidebar.qmd create mode 100644 docs/api/ui.markdown.qmd create mode 100644 docs/api/ui.modal.qmd create mode 100644 docs/api/ui.modal_button.qmd create mode 100644 docs/api/ui.modal_remove.qmd create mode 100644 docs/api/ui.modal_show.qmd create mode 100644 docs/api/ui.nav.qmd create mode 100644 docs/api/ui.nav_control.qmd create mode 100644 docs/api/ui.nav_menu.qmd create mode 100644 docs/api/ui.nav_panel.qmd create mode 100644 docs/api/ui.nav_spacer.qmd create mode 100644 docs/api/ui.navset_bar.qmd create mode 100644 docs/api/ui.navset_card_pill.qmd create mode 100644 docs/api/ui.navset_card_tab.qmd create mode 100644 docs/api/ui.navset_card_underline.qmd create mode 100644 docs/api/ui.navset_hidden.qmd create mode 100644 docs/api/ui.navset_pill.qmd create mode 100644 docs/api/ui.navset_pill_list.qmd create mode 100644 docs/api/ui.navset_tab.qmd create mode 100644 docs/api/ui.navset_underline.qmd create mode 100644 docs/api/ui.notification_remove.qmd create mode 100644 docs/api/ui.notification_show.qmd create mode 100644 docs/api/ui.output_data_frame.qmd create mode 100644 docs/api/ui.output_image.qmd create mode 100644 docs/api/ui.output_plot.qmd create mode 100644 docs/api/ui.output_table.qmd create mode 100644 docs/api/ui.output_text.qmd create mode 100644 docs/api/ui.output_text_verbatim.qmd create mode 100644 docs/api/ui.output_ui.qmd create mode 100644 docs/api/ui.page_auto.qmd create mode 100644 docs/api/ui.page_bootstrap.qmd create mode 100644 docs/api/ui.page_fillable.qmd create mode 100644 docs/api/ui.page_fixed.qmd create mode 100644 docs/api/ui.page_fluid.qmd create mode 100644 docs/api/ui.page_navbar.qmd create mode 100644 docs/api/ui.page_output.qmd create mode 100644 docs/api/ui.page_sidebar.qmd create mode 100644 docs/api/ui.panel_absolute.qmd create mode 100644 docs/api/ui.panel_conditional.qmd create mode 100644 docs/api/ui.panel_fixed.qmd create mode 100644 docs/api/ui.panel_main.qmd create mode 100644 docs/api/ui.panel_sidebar.qmd create mode 100644 docs/api/ui.panel_title.qmd create mode 100644 docs/api/ui.panel_well.qmd create mode 100644 docs/api/ui.popover.qmd create mode 100644 docs/api/ui.remove_accordion_panel.qmd create mode 100644 docs/api/ui.remove_ui.qmd create mode 100644 docs/api/ui.row.qmd create mode 100644 docs/api/ui.showcase_bottom.qmd create mode 100644 docs/api/ui.showcase_left_center.qmd create mode 100644 docs/api/ui.showcase_top_right.qmd create mode 100644 docs/api/ui.sidebar.qmd create mode 100644 docs/api/ui.tags.qmd create mode 100644 docs/api/ui.tooltip.qmd create mode 100644 docs/api/ui.update_accordion.qmd create mode 100644 docs/api/ui.update_accordion_panel.qmd create mode 100644 docs/api/ui.update_checkbox.qmd create mode 100644 docs/api/ui.update_checkbox_group.qmd create mode 100644 docs/api/ui.update_date.qmd create mode 100644 docs/api/ui.update_date_range.qmd create mode 100644 docs/api/ui.update_navs.qmd create mode 100644 docs/api/ui.update_numeric.qmd create mode 100644 docs/api/ui.update_popover.qmd create mode 100644 docs/api/ui.update_radio_buttons.qmd create mode 100644 docs/api/ui.update_select.qmd create mode 100644 docs/api/ui.update_selectize.qmd create mode 100644 docs/api/ui.update_sidebar.qmd create mode 100644 docs/api/ui.update_slider.qmd create mode 100644 docs/api/ui.update_switch.qmd create mode 100644 docs/api/ui.update_text.qmd create mode 100644 docs/api/ui.update_text_area.qmd create mode 100644 docs/api/ui.update_tooltip.qmd create mode 100644 docs/api/ui.value_box.qmd create mode 100644 docs/api/ui.value_box_theme.qmd diff --git a/docs/api/App.qmd b/docs/api/App.qmd new file mode 100644 index 000000000..cb48139bf --- /dev/null +++ b/docs/api/App.qmd @@ -0,0 +1,99 @@ +# App { #shiny.App } + +`App(self, ui, server, *, static_assets=None, debug=False)` + +Create a Shiny app instance. + +## Parameters + +ui: [Tag](`htmltools.Tag`) \| [TagList](`htmltools.TagList`) \| [Callable](`typing.Callable`)\[\[[Request](`starlette.requests.Request`)\], [Tag](`htmltools.Tag`) \| [TagList](`htmltools.TagList`)\] \| [Path](`pathlib.Path`) + +: The UI definition for the app (e.g., a call to [](:func:`~shiny.ui.page_fluid`) or + similar, with layouts and controls nested inside). You can + also pass a function that takes a [](:class:`~starlette.requests.Request`) and + returns a UI definition, if you need the UI definition to be created dynamically + for each pageview. + +server: [Callable](`typing.Callable`)\[\[[Inputs](`shiny.session.Inputs`)\], None\] \| [Callable](`typing.Callable`)\[\[[Inputs](`shiny.session.Inputs`), [Outputs](`shiny.session.Outputs`), [Session](`shiny.session.Session`)\], None\] \| None + +: A function which is called once for each session, ensuring that each session is + independent. + +static_assets: [Optional](`typing.Optional`)\['str' \| 'os.PathLike\[str\]' \| [dict](`dict`)\[[str](`str`), [Path](`pathlib.Path`)\]\] = None + +: Static files to be served by the app. If this is a string or Path object, it + must be a directory, and it will be mounted at `/`. If this is a dictionary, + each key is a mount point and each value is a file or directory to be served at + that mount point. + +debug: [bool](`bool`) = False + +: Whether to enable debug mode. + +## Example + + +```{python} +#| eval: false +from shiny import App, Inputs, Outputs, Session, ui + +app_ui = ui.page_fluid("Hello Shiny!") + +def server(input: Inputs, output: Outputs, session: Session): + pass + +app = App(app_ui, server) +``` + +## Attributes + +| Name | Description | +| --- | --- | +| [lib_prefix](#shiny.App.lib_prefix) | A path prefix to place before all HTML dependencies processed by ``register_web_dependency()``. | +| [sanitize_error_msg](#shiny.App.sanitize_error_msg) | The message to show when an error occurs and ``SANITIZE_ERRORS=True``. | +| [sanitize_errors](#shiny.App.sanitize_errors) | Whether or not to show a generic message (``SANITIZE_ERRORS=True``) or the actual message (``SANITIZE_ERRORS=False``) in the app UI when an error occurs. This flag may default to ``True`` in some production environments (e.g., Posit Connect). | + +## Methods + +| Name | Description | +| --- | --- | +| [call_pyodide](#shiny.App.call_pyodide) | Communicate with pyodide. Warning ------- This method is not intended for public usage. It's exported for use by shinylive. | +| [run](#shiny.App.run) | Run the app. | +| [stop](#shiny.App.stop) | Stop the app (i.e., close all sessions). See Also -------- ~shiny.Session.close | + +### call_pyodide { #shiny.App.call_pyodide } + +`App.call_pyodide(scope, receive, send)` + +Communicate with pyodide. + + + +#### Warning + +This method is not intended for public usage. It's exported for use by +shinylive. + +### run { #shiny.App.run } + +`App.run(**kwargs)` + +Run the app. + +#### Parameters + +**kwargs: [object](`object`) = {} + +: Keyword arguments passed to [](:func:`~shiny.run_app`). + +### stop { #shiny.App.stop } + +`App.stop()` + +Stop the app (i.e., close all sessions). + + + +#### See Also + +[](:func:`~shiny.Session.close`) \ No newline at end of file diff --git a/docs/api/ContextManagerComponents.qmd b/docs/api/ContextManagerComponents.qmd new file mode 100644 index 000000000..348317749 --- /dev/null +++ b/docs/api/ContextManagerComponents.qmd @@ -0,0 +1,1697 @@ +# Context manager components + + + +# express.ui.sidebar { #shiny.express.ui.sidebar } + +`express.ui.sidebar(width=250, position='left', open='always', id=None, title=None, bg=None, fg=None, class_=None, max_height_mobile='auto', gap=None, padding=None)` + +Context manager for sidebar element + +This function wraps [](:func:`~shiny.ui.sidebar`). + +## Parameters + +width: [CssUnit](`shiny.ui.css.CssUnit`) = 250 + +: A valid CSS unit used for the width of the sidebar. + +position: [Literal](`typing.Literal`)\['left', 'right'\] = 'left' + +: Where the sidebar should appear relative to the main content. + +open: [Literal](`typing.Literal`)\['desktop', 'open', 'closed', 'always'\] = 'always' + +: The initial state of the sidebar. + + * `"desktop"`: the sidebar starts open on desktop screen, closed on mobile + * `"open"` or `True`: the sidebar starts open + * `"closed"` or `False`: the sidebar starts closed + * `"always"` or `None`: the sidebar is always open and cannot be closed + + In [](:func:`~shiny.ui.update_sidebar`), `open` indicates the desired state of the + sidebar. Note that [](:func:`~shiny.ui.update_sidebar`) can only open or close the + sidebar, so it does not support the `"desktop"` and `"always"` options. + +id: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: A character string. Required if wanting to re-actively read (or update) the + `collapsible` state in a Shiny app. + +title: [TagChild](`htmltools.TagChild`) \| [str](`str`) = None + +: A character title to be used as the sidebar title, which will be wrapped in a + `
` element with class `sidebar-title`. You can also provide a custom + [](:class:`~htmltools.Tag`) for the title element, in which case you'll + likely want to give this element `class = "sidebar-title"`. + +bg: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: A background or foreground color. + +class_: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: CSS classes for the sidebar container element, in addition to the fixed + `.sidebar` class. + +max_height_mobile: [Optional](`typing.Optional`)\[[str](`str`) \| [float](`float`)\] = 'auto' + +: A CSS length unit (passed through [](:func:`~shiny.ui.css.as_css_unit`)) defining + the maximum height of the horizontal sidebar when viewed on mobile devices. Only + applies to always-open sidebars that use `open = "always"`, where by default the + sidebar container is placed below the main content container on mobile devices. + +gap: [Optional](`typing.Optional`)\[[CssUnit](`shiny.ui.css.CssUnit`)\] = None + +: A CSS length unit defining the vertical `gap` (i.e., spacing) between elements + provided to `*args`. + +padding: [Optional](`typing.Optional`)\[[CssUnit](`shiny.ui.css.CssUnit`) \| [list](`list`)\[[CssUnit](`shiny.ui.css.CssUnit`)\]\] = None + +: Padding within the sidebar itself. This can be a numeric vector (which will be + interpreted as pixels) or a character vector with valid CSS lengths. `padding` + may be one to four values. + + * If a single value, then that value will be used for all four sides. + * If two, then the first value will be used for the top and bottom, while + the second value will be used for left and right. + * If three values, then the first will be used for top, the second will be left + and right, and the third will be bottom. + * If four, then the values will be interpreted as top, right, bottom, and left + respectively. + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +from shiny import App, Inputs, Outputs, Session, render, ui + +app_ui = ui.page_fluid( + ui.card( + ui.layout_sidebar( + ui.sidebar("Left sidebar content", id="sidebar_left"), + ui.output_text_verbatim("state_left"), + ) + ), + ui.card( + ui.layout_sidebar( + ui.sidebar("Right sidebar content", id="sidebar_right", position="right"), + ui.output_text_verbatim("state_right"), + ), + ), + ui.card( + ui.layout_sidebar( + ui.sidebar("Closed sidebar content", id="sidebar_closed", open="closed"), + ui.output_text_verbatim("state_closed"), + ) + ), + ui.card( + ui.layout_sidebar( + ui.sidebar("Always sidebar content", id="sidebar_always", open="always"), + ui.output_text_verbatim("state_always"), + ) + ), +) + + +def server(input: Inputs, output: Outputs, session: Session): + @render.text + def state_left(): + return f"input.sidebar_left(): {input.sidebar_left()}" + + @render.text + def state_right(): + return f"input.sidebar_right(): {input.sidebar_right()}" + + @render.text + def state_closed(): + return f"input.sidebar_closed(): {input.sidebar_closed()}" + + @render.text + def state_always(): + return f"input.sidebar_always(): {input.sidebar_always()}" + + +app = App(app_ui, server) + +``` + + + +# express.ui.layout_sidebar { #shiny.express.ui.layout_sidebar } + +`express.ui.layout_sidebar(fillable=True, fill=True, bg=None, fg=None, border=None, border_radius=None, border_color=None, gap=None, padding=None, height=None, **kwargs)` + +Context manager for sidebar layout + +This function wraps [](:func:`~shiny.ui.layout_sidebar`). + +Create a sidebar layout component which can be dropped inside any Shiny UI page +method (e.g. [](:func:`~shiny.shiny.ui.page_fillable`)) or [](:func:`~shiny.ui.card`) +context. + +The first child needs to be of class [](:class:`~shiny.ui.Sidebar`) object created by +[](:func:`~shiny.express.ui.sidebar`). The remaining arguments will contain the contents +to the main content area. Or tag attributes that are supplied to the resolved +[](:class:`~htmltools.Tag`) object. + +## Parameters + +fillable: [bool](`bool`) = True + +: Whether or not the main content area should be wrapped in a fillable container. + See [](:func:`~shiny.ui.as_fillable_container`) for details. + +fill: [bool](`bool`) = True + +: Whether or not the sidebar layout should be wrapped in a fillable container. See + [](:func:`~shiny.ui.as_fill_item`) for details. + +bg: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: A background or foreground color. + +border: [Optional](`typing.Optional`)\[[bool](`bool`)\] = None + +: Whether or not to show a border around the sidebar layout. + +border_radius: [Optional](`typing.Optional`)\[[bool](`bool`)\] = None + +: Whether or not to round the corners of the sidebar layout. + +border_color: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: A border color. + +gap: [Optional](`typing.Optional`)\[[CssUnit](`shiny.ui.css.CssUnit`)\] = None + +: A CSS length unit defining the vertical `gap` (i.e., spacing) between elements + provided to `*args`. This value will only be used if `fillable` is `True`. + +padding: [Optional](`typing.Optional`)\[[CssUnit](`shiny.ui.css.CssUnit`) \| [list](`list`)\[[CssUnit](`shiny.ui.css.CssUnit`)\]\] = None + +: Padding within the sidebar itself. This can be a numeric vector (which will be + interpreted as pixels) or a character vector with valid CSS lengths. `padding` + may be one to four values. If one, then that value will be used for all four + sides. If two, then the first value will be used for the top and bottom, while + the second value will be used for left and right. If three, then the first will + be used for top, the second will be left and right, and the third will be + bottom. If four, then the values will be interpreted as top, right, bottom, and + left respectively. + +height: [Optional](`typing.Optional`)\[[CssUnit](`shiny.ui.css.CssUnit`)\] = None + +: Any valid CSS unit to use for the height. + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +import matplotlib.pyplot as plt +import numpy as np + +from shiny import App, Inputs, Outputs, Session, render, ui + +app_ui = ui.page_fluid( + ui.layout_sidebar( + ui.sidebar( + ui.input_slider("n", "N", min=0, max=100, value=20), + ), + ui.output_plot("plot"), + ), +) + + +def server(input: Inputs, output: Outputs, session: Session): + @render.plot(alt="A histogram") + def plot() -> object: + np.random.seed(19680801) + x = 100 + 15 * np.random.randn(437) + + fig, ax = plt.subplots() + ax.hist(x, input.n(), density=True) + return fig + + +app = App(app_ui, server) + +``` + + + +# express.ui.layout_column_wrap { #shiny.express.ui.layout_column_wrap } + +`express.ui.layout_column_wrap(width=MISSING, fixed_width=False, heights_equal='all', fill=True, fillable=True, height=None, height_mobile=None, gap=None, class_=None, **kwargs)` + +Context manager for a grid-like, column-first layout + +This function wraps [](:func:`~shiny.ui.layout_column_wrap`). + +Wraps a 1d sequence of UI elements into a 2d grid. The number of columns (and rows) +in the grid dependent on the column `width` as well as the size of the display. + +## Parameters + +width: [CssUnit](`shiny.ui.css.CssUnit`) \| None \| [MISSING_TYPE](`shiny.types.MISSING_TYPE`) = MISSING + +: The desired width of each card. It can be one of the following: + + * A (unit-less) number between 0 and 1, specified as `1/num`, where `num` + represents the number of desired columns. + * A CSS length unit representing either the minimum (when `fixed_width=False`) + or fixed width (`fixed_width=True`). + * `None`, which allows power users to set the `grid-template-columns` CSS + property manually, either via a `style` attribute or a CSS stylesheet. + * If missing, a value of `200px` will be used. + +fixed_width: [bool](`bool`) = False + +: When `width` is greater than 1 or is a CSS length unit, e.g. `"200px"`, + `fixed_width` indicates whether that `width` value represents the absolute size + of each column (`fixed_width=TRUE`) or the minimum size of a column + (`fixed_width=FALSE`). + + When `fixed_width=FALSE`, new columns are added to a row when `width` space is + available and columns will never exceed the container or viewport size. + + When `fixed_width=TRUE`, all columns will be exactly `width` wide, which may + result in columns overflowing the parent container. + +heights_equal: [Literal](`typing.Literal`)\['all', 'row'\] = 'all' + +: If `"all"` (the default), every card in every row of the grid will have the same + height. If `"row"`, then every card in _each_ row of the grid will have the same + height, but heights may vary between rows. + +fill: [bool](`bool`) = True + +: Whether or not to allow the layout to grow/shrink to fit a fillable container + with an opinionated height (e.g., [](:func:`~shiny.ui.page_fillable`)). + +fillable: [bool](`bool`) = True + +: Whether or not each element is wrapped in a fillable container. + +height: [Optional](`typing.Optional`)\[[CssUnit](`shiny.ui.css.CssUnit`)\] = None + +: Any valid CSS unit to use for the height. + +height_mobile: [Optional](`typing.Optional`)\[[CssUnit](`shiny.ui.css.CssUnit`)\] = None + +: Any valid CSS unit to use for the height when on mobile devices (or narrow + windows). + +gap: [Optional](`typing.Optional`)\[[CssUnit](`shiny.ui.css.CssUnit`)\] = None + +: Any valid CSS unit to use for the gap between columns. + +class_: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: A CSS class to apply to the containing element. + +**kwargs: [TagAttrValue](`htmltools.TagAttrValue`) = {} + +: Additional attributes to apply to the containing element. + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +from shiny import App, ui + +y = ui.card("A simple card") + +app_ui = ui.page_fluid( + # Always has 2 columns (on non-mobile) + ui.layout_column_wrap(y, y, y, width=1 / 2), + ui.hr(), + # Has three columns when viewport is wider than 750px + ui.layout_column_wrap(y, y, y, width="250px"), +) + + +app = App(app_ui, server=None) + +``` + + + +# express.ui.layout_columns { #shiny.express.ui.layout_columns } + +`express.ui.layout_columns(col_widths=None, row_heights=None, fill=True, fillable=True, gap=None, class_=None, height=None, **kwargs)` + +Context manager for responsive, column-based grid layouts, based on a 12-column +grid. + +This function wraps [](:func:`~shiny.ui.layout_columns`). + +## Parameters + +col_widths: [BreakpointsUser](`shiny.ui._layout_columns.BreakpointsUser`)\[[int](`int`)\] = None + +: The widths of the columns, possibly at different breakpoints. Can be one of the + following: + + * `None` (the default): Automatically determines a sensible number of columns + based on the number of children given to the layout. + * A list or tuple of integers between 1 and 12, where each element represents + the number of columns for the relevant UI element. Column widths are recycled + to extend the values in `col_widths` to match the actual number of items in + the layout, and children are wrapped onto the next row when a row exceeds 12 + column units. For example, `col_widths=(4, 8, 12)` allocates 4 columns to the + first element, 8 columns to the second element, and 12 columns to the third + element (which wraps to the next row). Negative values are also allowed, and + are treated as empty columns. For example, `col_widths=(-2, 8, -2)` would + allocate 8 columns to an element (with 2 empty columns on either side). + * A dictionary of column widths at different breakpoints. The keys should be one + of `"xs"`, `"sm"`, `"md"`, `"lg"`, `"xl"`, or `"xxl"`, and the values are + either of the above. For example, `col_widths={"sm": (3, 3, 6), "lg": (4)}`. + +row_heights: [BreakpointsUser](`shiny.ui._layout_columns.BreakpointsUser`)\[[CssUnit](`shiny.ui.css.CssUnit`)\] = None + +: The heights of the rows, possibly at different breakpoints. Can be one of the + following: + + * A numeric vector, where each value represents the [fractional + unit](https://css-tricks.com/introduction-fr-css-unit/) (`fr`) height of the + relevant row. If there are more rows than values provided, the pattern will be + repeated. For example, `row_heights=(1, 2)` allows even rows to take up twice + as much space as odd rows. + * A list of numeric or CSS length units, where each value represents the height + of the relevant row. If more rows are needed than values provided, the pattern + will repeat. For example, `row_heights=["auto", 1]` allows the height of odd + rows to be driven my it's contents and even rows to be + [`1fr`](https://css-tricks.com/introduction-fr-css-unit/). + * A single string containing CSS length units. In this case, the value is + supplied directly to `grid-auto-rows`. + * A dictionary of row heights at different breakpoints, where each key is a + breakpoint name (one of `"xs"`, `"sm"`, `"md"`, `"lg"`, `"xl"`, or `"xxl"`) + and where the values may be any of the above options. + +fill: [bool](`bool`) = True + +: Whether or not to allow the layout to grow/shrink to fit a fillable container + with an opinionated height (e.g., [](:func:`~shiny.ui.page_fillable`)). + +fillable: [bool](`bool`) = True + +: Whether or not each element is wrapped in a fillable container. + +gap: [Optional](`typing.Optional`)\[[CssUnit](`shiny.ui.css.CssUnit`)\] = None + +: Any valid CSS unit to use for the gap between columns. + +class_: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: CSS class(es) to apply to the containing element. + +height: [Optional](`typing.Optional`)\[[CssUnit](`shiny.ui.css.CssUnit`)\] = None + +: Any valid CSS unit to use for the height. + +**kwargs: [TagAttrValue](`htmltools.TagAttrValue`) = {} + +: Additional attributes to apply to the containing element. + +## Returns + +| Type | Description | +|--------------------------------------------------------------------------------------------------------|-------------------------------------| +| [RecallContextManager](`shiny.express._recall_context.RecallContextManager`)\[[Tag](`htmltools.Tag`)\] | An [](:class:`~htmltools.Tag`) element. | + +## See Also + +* [](:func:`~shiny.express.layout.layout_column_wrap`) for laying out elements into a + uniform grid. + + + +## Reference + +* [Bootstrap CSS Grid](https://getbootstrap.com/docs/5.3/layout/grid/) +* [Bootstrap Breakpoints](https://getbootstrap.com/docs/5.3/layout/breakpoints/) + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +from model_plots import * # model plots and cards + +from shiny import App, Inputs, Outputs, Session, render, ui + +app_ui = ui.page_fluid( + ui.panel_title(ui.h2("Model Dashboard")), + ui.markdown("Using `ui.layout_columns()` for the layout."), + ui.layout_columns( + card_loss, + card_acc, + card_feat, + col_widths={"sm": (5, 7, 12)}, + # row_heights=(2, 3), + # height="700px", + ), +) + + +def server(input: Inputs, output: Outputs, session: Session): + @render.plot + def loss_over_time(): + return plot_loss_over_time() + + @render.plot + def accuracy_over_time(): + return plot_accuracy_over_time() + + @render.plot + def feature_importance(): + return plot_feature_importance() + + +app = App(app_ui, server) + +## file: model_plots.py +import matplotlib.pyplot as plt +import numpy as np + +from shiny import ui + + +def plot_loss_over_time(): + epochs = np.arange(1, 101) + loss = 1000 / np.sqrt(epochs) + np.random.rand(100) * 25 + + fig = plt.figure(figsize=(10, 6)) + plt.plot(epochs, loss) + plt.xlabel("Epochs") + plt.ylabel("Loss") + return fig + + +def plot_accuracy_over_time(): + epochs = np.arange(1, 101) + accuracy = np.sqrt(epochs) / 12 + np.random.rand(100) * 0.15 + accuracy = [np.min([np.max(accuracy[:i]), 1]) for i in range(1, 101)] + + fig = plt.figure(figsize=(10, 6)) + plt.plot(epochs, accuracy) + plt.xlabel("Epochs") + plt.ylabel("Accuracy") + return fig + + +def plot_feature_importance(): + features = ["Product Category", "Price", "Brand", "Rating", "Number of Reviews"] + importance = np.random.rand(5) + + fig = plt.figure(figsize=(10, 6)) + plt.barh(features, importance) + plt.xlabel("Importance") + return fig + + +card_loss = ui.card( + ui.card_header("Loss Over Time"), + ui.output_plot("loss_over_time"), + full_screen=True, +) + +card_acc = ui.card( + ui.card_header("Accuracy Over Time"), + ui.output_plot("accuracy_over_time"), + full_screen=True, +) + +card_feat = ui.card( + ui.card_header("Feature Importance"), + ui.output_plot("feature_importance"), + full_screen=True, +) + +``` + + + +# express.ui.card { #shiny.express.ui.card } + +`express.ui.card(full_screen=False, height=None, max_height=None, min_height=None, fill=True, class_=None, **kwargs)` + +Context manager for Bootstrap card component + +This function wraps [](:func:`~shiny.ui.card`). + +A general purpose container for grouping related UI elements together with a border +and optional padding. To learn more about `card()`s, see [this +article](https://rstudio.github.io/bslib/articles/cards.html). + +## Parameters + +full_screen: [bool](`bool`) = False + +: If `True`, an icon will appear when hovering over the card body. Clicking the + icon expands the card to fit viewport size. + +height: [Optional](`typing.Optional`)\[[CssUnit](`shiny.ui.css.CssUnit`)\] = None + +: Any valid CSS unit (e.g., `height="200px"`). Doesn't apply when a card is made + `full_screen` (in this case, consider setting a `height` in + [](:func:`~shiny.experimental.ui.card_body`)). + +fill: [bool](`bool`) = True + +: Whether or not to allow the card to grow/shrink to fit a fillable container with + an opinionated height (e.g., [](:func:`~shiny.ui.page_fillable`)). + +class_: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: Additional CSS classes for the returned Tag. + +**kwargs: [TagAttrValue](`htmltools.TagAttrValue`) = {} + +: HTML attributes on the returned Tag. + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +from shiny import App, ui + +app_ui = ui.page_fluid( + ui.card( + ui.card_header("This is the header"), + ui.p("This is the body."), + ui.p("This is still the body."), + ui.card_footer("This is the footer"), + full_screen=True, + ), +) + + +app = App(app_ui, server=None) + +``` + + + +# express.ui.accordion { #shiny.express.ui.accordion } + +`express.ui.accordion(id=None, open=None, multiple=True, class_=None, width=None, height=None, **kwargs)` + +Context manager for a vertically collapsing accordion. + +This function wraps [](:func:`~shiny.ui.accordion`). + +## Parameters + +id: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: If provided, you can use `input.id()` in your server logic to determine which of + the [](:func:`~shiny.ui.accordion_panel`)s are currently active. The + value will correspond to the [](:func:`~shiny.ui.accordion_panel`)'s + `value` argument. + +open: [Optional](`typing.Optional`)\[[bool](`bool`) \| [str](`str`) \| [list](`list`)\[[str](`str`)\]\] = None + +: A list of [](:func:`~shiny.ui.accordion_panel`) values to open (i.e., + show) by default. The default value of `None` will open the first + [](:func:`~shiny.ui.accordion_panel`). Use a value of `True` to open + all (or `False` to open none) of the items. It's only possible to open more than + one panel when `multiple=True`. + +multiple: [bool](`bool`) = True + +: Whether multiple [](:func:`~shiny.ui.accordion_panel`) can be open at + once. + +class_: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: Additional CSS classes to include on the accordion div. + +width: [Optional](`typing.Optional`)\[[CssUnit](`shiny.ui.css.CssUnit`)\] = None + +: Any valid CSS unit; for example, height="100%". + +height: [Optional](`typing.Optional`)\[[CssUnit](`shiny.ui.css.CssUnit`)\] = None + +: Any valid CSS unit; for example, height="100%". + +**kwargs: [TagAttrValue](`htmltools.TagAttrValue`) = {} + +: Attributes to this tag. + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +from shiny import App, Inputs, Outputs, Session, reactive, render, ui + + +def make_items(): + return [ + ui.accordion_panel(f"Section {letter}", f"Some narrative for section {letter}") + for letter in "ABCDE" + ] + + +# # First shown by default +# ui.accordion(*make_items()) + +# # Nothing shown by default +# ui.accordion(*make_items(), open=False) +# # Everything shown by default +# ui.accordion(*make_items(), open=True) + +# # Show particular sections +# ui.accordion(*make_items(), open="Section B") +# ui.accordion(*make_items(), open=["Section A", "Section B"]) + + +app_ui = ui.page_fluid( + ui.markdown("#### Accordion: (`multiple=False`)"), + # Provide an id to create a shiny input binding + ui.accordion(*make_items(), id="acc_single", multiple=False), + ui.output_text_verbatim("acc_single_val", placeholder=True), + ui.tags.br(), + ui.markdown("#### Accordion: (`multiple=True`)"), + ui.accordion(*make_items(), id="acc_multiple"), + ui.output_text_verbatim("acc_multiple_val", placeholder=True), +) + + +def server(input: Inputs, output: Outputs, session: Session): + @reactive.Effect + def _(): + print(input.acc()) + + @render.text + def acc_multiple_val(): + return "input.acc_multiple(): " + str(input.acc_multiple()) + + @render.text + def acc_single_val(): + return "input.acc_single(): " + str(input.acc_single()) + + +app = App(app_ui, server) + +``` + + + +# express.ui.accordion_panel { #shiny.express.ui.accordion_panel } + +`express.ui.accordion_panel(title, *, value=MISSING, icon=None, **kwargs)` + +Context manager for single accordion panel. + +This function wraps [](:func:`~shiny.ui.accordion_panel`). + +## Parameters + +title: [TagChild](`htmltools.TagChild`) + +: A title to appear in the [](:func:`~shiny.ui.accordion_panel`)'s header. + +value: [Optional](`typing.Optional`)\[[str](`str`)\] \| [MISSING_TYPE](`shiny.types.MISSING_TYPE`) = MISSING + +: A character string that uniquely identifies this panel. If `MISSING`, the + `title` will be used. + +icon: [Optional](`typing.Optional`)\[[TagChild](`htmltools.TagChild`)\] = None + +: A [](:class:`~htmltools.Tag`) which is positioned just before the `title`. + +**kwargs: [TagAttrValue](`htmltools.TagAttrValue`) = {} + +: Tag attributes to the `accordion-body` div Tag. + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +from shiny import App, Inputs, Outputs, Session, reactive, render, ui + +items = [ + ui.accordion_panel(f"Section {letter}", f"Some narrative for section {letter}") + for letter in "ABCDE" +] + +app_ui = ui.page_fluid( + # Provide an id to create a shiny input binding + ui.accordion(*items, id="acc"), + ui.h4("Accordion:"), + ui.output_text_verbatim("acc_val", placeholder=True), +) + + +def server(input: Inputs, output: Outputs, session: Session): + @reactive.Effect + def _(): + print(input.acc()) + + @render.text + def acc_val(): + return "input.acc(): " + str(input.acc()) + + +app = App(app_ui, server) + +``` + + + +# express.ui.nav_panel { #shiny.express.ui.nav_panel } + +`express.ui.nav_panel(title, *, value=None, icon=None)` + +Context manager for nav item pointing to some internal content. + +This function wraps [](:func:`~shiny.ui.nav`). + +## Parameters + +title: [TagChild](`htmltools.TagChild`) + +: A title to display. Can be a character string or UI elements (i.e., tags). + +value: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: The value of the item. This is used to determine whether the item is active + (when an ``id`` is provided to the nav container), programmatically select the + item (e.g., [](:func:`~shiny.ui.update_navs`)), and/or be provided to the + ``selected`` argument of the navigation container (e.g., + [](:func:`~shiny.ui.navset_tab`)). + +icon: [TagChild](`htmltools.TagChild`) = None + +: An icon to appear inline with the button/link. + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +from typing import List + +from shiny import App, Inputs, Outputs, Session, reactive, ui +from shiny.types import NavSetArg + + +def nav_controls(prefix: str) -> List[NavSetArg]: + return [ + ui.nav_panel("a", prefix + ": tab a content"), + ui.nav_panel("b", prefix + ": tab b content"), + ui.nav_panel("c", prefix + ": tab c content"), + ui.nav_spacer(), + ui.nav_menu( + "Links", + ui.nav_control( + ui.a( + "Shiny", + href="https://shiny.posit.co/py/", + target="_blank", + ) + ), + "----", + "Plain text", + "----", + ui.nav_control( + ui.a( + "Posit", + href="https://posit.co", + target="_blank", + ) + ), + align="right", + ), + ] + + +app_ui = ui.page_navbar( + *nav_controls("page_navbar"), + title="page_navbar()", + id="navbar_id", + footer=ui.div( + {"style": "width:80%;margin: 0 auto"}, + ui.tags.style( + """ + h4 { + margin-top: 3em; + } + """ + ), + ui.h4("navset_tab()"), + ui.navset_tab(*nav_controls("navset_tab()")), + ui.h4("navset_pill()"), + ui.navset_pill(*nav_controls("navset_pill()")), + ui.h4("navset_underline()"), + ui.navset_underline(*nav_controls("navset_underline()")), + ui.h4("navset_card_tab()"), + ui.navset_card_tab(*nav_controls("navset_card_tab()")), + ui.h4("navset_card_pill()"), + ui.navset_card_pill(*nav_controls("navset_card_pill()")), + ui.h4("navset_card_underline()"), + ui.navset_card_underline(*nav_controls("navset_card_underline()")), + ui.h4("navset_pill_list()"), + ui.navset_pill_list(*nav_controls("navset_pill_list()")), + ) +) + + +def server(input: Inputs, output: Outputs, session: Session): + @reactive.Effect + def _(): + print("Current navbar page: ", input.navbar_id()) + + +app = App(app_ui, server) + +## file: __pycache__/app-basic.cpython-311.pyc +## type: binary +pw0NCgAAAAB74qZlKQEAAOMAAAAAAAAAAAAAAAAKAAAAAAAAAPPWAAAAlwBkAGQBbABtAVoBbQJaAm0DWgMBAAIAZQNqBAAAAAAAAAAAAgBlA2oFAAAAAAAAAABkAqYBAACrAQAAAAAAAAAAAgBlA2oGAAAAAAAAAAACAGUDagcAAAAAAAAAAGQDZASmAgAAqwIAAAAAAAAAAAIAZQNqBwAAAAAAAAAAZAVkBqYCAACrAgAAAAAAAAAApgIAAKsCAAAAAAAAAACmAgAAqwIAAAAAAAAAAFoIZAdlAmYCZAiEBFoJAgBlAWUIZQmmAgAAqwIAAAAAAAAAAFoKZAlTACkK6QAAAAApA9oDQXBw2gZJbnB1dHPaAnVpehFCYXNpYyBOYXYgRXhhbXBsZdoDT25lehJGaXJzdCB0YWIgY29udGVudC7aA1R3b3oTU2Vjb25kIHRhYiBjb250ZW50LtoFaW5wdXRjAQAAAAAAAAAAAAAAAQAAAAMAAADzBgAAAJcAZABTACkBTqkAKQFyCAAAAHMBAAAAIPpuL1VzZXJzL2dhcnJpY2svd29yay9wb3NpdC1kZXYvcHktc2hpbnkud29ya3RyZWVzL2V4cHJlc3MvcGFuZWwtdGl0bGUvc2hpbnkvYXBpLWV4YW1wbGVzL25hdl9wYW5lbC9hcHAtYmFzaWMucHnaBnNlcnZlcnIMAAAADAAAAHMHAAAAgADYBAiARPMAAAAATikL2gVzaGlueXIDAAAAcgQAAAByBQAAANoKcGFnZV9maXhlZNoLcGFuZWxfdGl0bGXaCm5hdnNldF90YWLaCW5hdl9wYW5lbNoGYXBwX3VpcgwAAADaA2FwcHIKAAAAcg0AAAByCwAAAPoIPG1vZHVsZT5yFQAAAAEAAABzrQAAAPADAQEB2AAh0AAh0AAh0AAh0AAh0AAh0AAh0AAh0AAh0AAh4AkWiBKMHdgEEoBChE7QEybRBCfUBCfYBBGAQoRN2AgUiAKMDJBV0Bww0Qgx1Agx2AgUiAKMDJBV0Bwx0Qgy1Agy8QUDBQb0AAMFBvEFBgoC9AAGCgKABvASAQEJkCbwAAEBCfAAAQEJ8AABAQnwAAEBCfAIAAcKgGOIJpAm0QYZ1AYZgAOAA4ADcg0AAAA= +## file: app-basic.py +from shiny import App, Inputs, ui + +app_ui = ui.page_fixed( + ui.panel_title("Basic Nav Example"), + ui.navset_tab( + ui.nav_panel("One", "First tab content."), + ui.nav_panel("Two", "Second tab content."), + ), +) + + +def server(input: Inputs): + pass + + +app = App(app_ui, server) + +``` + + + +# express.ui.nav_control { #shiny.express.ui.nav_control } + +`express.ui.nav_control()` + +Context manager for a control in the navigation container. + +This function wraps [](:func:`~shiny.ui.nav_control`). + +# express.ui.nav_menu { #shiny.express.ui.nav_menu } + +`express.ui.nav_menu(title, *, value=None, icon=None, align='left')` + +Context manager for a menu of nav items. + +This function wraps [](:func:`~shiny.ui.nav_menu`). + +## Parameters + +title: [TagChild](`htmltools.TagChild`) + +: A title to display. Can be a character string or UI elements (i.e., tags). + +value: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: The value of the item. This is used to determine whether the item is active + (when an ``id`` is provided to the nav container), programmatically select the + item (e.g., [](:func:`~shiny.ui.update_navs`)), and/or be provided to the + ``selected`` argument of the navigation container (e.g., + [](:func:`~shiny.ui.navset_tab`)). + +icon: [TagChild](`htmltools.TagChild`) = None + +: An icon to appear inline with the button/link. + +align: [Literal](`typing.Literal`)\['left', 'right'\] = 'left' + +: Horizontal alignment of the dropdown menu relative to dropdown toggle. + +# express.ui.navset_bar { #shiny.express.ui.navset_bar } + +`express.ui.navset_bar(title, id=None, selected=None, sidebar=None, fillable=True, gap=None, padding=None, position='static-top', header=None, footer=None, bg=None, inverse=False, underline=True, collapsible=True, fluid=True)` + +Context manager for a set of nav items as a tabset inside a card container. + +This function wraps [](:func:`~shiny.ui.navset_bar`). + +## Parameters + +title: [TagChild](`htmltools.TagChild`) + +: Title to display in the navbar. + +id: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: If provided, will create an input value that holds the currently selected nav + item. + +selected: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: Choose a particular nav item to select by default value (should match it's + ``value``). + +sidebar: [Optional](`typing.Optional`)\[[ui](`shiny.ui`).[Sidebar](`shiny.ui.Sidebar`)\] = None + +: A [](:class:`~shiny.ui.Sidebar`) component to display on every + [](:func:`~shiny.ui.nav_panel`) page. + +fillable: [bool](`bool`) \| [list](`list`)\[[str](`str`)\] = True + +: Whether or not to allow fill items to grow/shrink to fit the browser window. If + `True`, all `nav()` pages are fillable. A character vector, matching the value + of `nav()`s to be filled, may also be provided. Note that, if a `sidebar` is + provided, `fillable` makes the main content portion fillable. + +gap: [Optional](`typing.Optional`)\[[CssUnit](`shiny.ui.css.CssUnit`)\] = None + +: A CSS length unit defining the gap (i.e., spacing) between elements provided to + `*args`. + +padding: [Optional](`typing.Optional`)\[[CssUnit](`shiny.ui.css.CssUnit`) \| [list](`list`)\[[CssUnit](`shiny.ui.css.CssUnit`)\]\] = None + +: Padding to use for the body. This can be a numeric vector (which will be + interpreted as pixels) or a character vector with valid CSS lengths. The length + can be between one and four. If one, then that value will be used for all four + sides. If two, then the first value will be used for the top and bottom, while + the second value will be used for left and right. If three, then the first will + be used for top, the second will be left and right, and the third will be + bottom. If four, then the values will be interpreted as top, right, bottom, and + left respectively. + +position: [Literal](`typing.Literal`)\['static-top', 'fixed-top', 'fixed-bottom', 'sticky-top'\] = 'static-top' + +: Determines whether the navbar should be displayed at the top of the page with + normal scrolling behavior ("static-top"), pinned at the top ("fixed-top"), or + pinned at the bottom ("fixed-bottom"). Note that using "fixed-top" or + "fixed-bottom" will cause the navbar to overlay your body content, unless you + add padding (e.g., ``tags.style("body {padding-top: 70px;}")``). + +header: [TagChild](`htmltools.TagChild`) = None + +: UI to display above the selected content. + +footer: [TagChild](`htmltools.TagChild`) = None + +: UI to display below the selected content. + +bg: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: Background color of the navbar (a CSS color). + +inverse: [bool](`bool`) = False + +: Either ``True`` for a light text color or ``False`` for a dark text color. + +collapsible: [bool](`bool`) = True + +: ``True`` to automatically collapse the navigation elements into an expandable + menu on mobile devices or narrow window widths. + +fluid: [bool](`bool`) = True + +: ``True`` to use fluid layout; ``False`` to use fixed layout. + +# express.ui.navset_card_pill { #shiny.express.ui.navset_card_pill } + +`express.ui.navset_card_pill(id=None, selected=None, title=None, sidebar=None, header=None, footer=None)` + +Context manager for a set of nav items as a tabset inside a card container. + +This function wraps [](:func:`~shiny.ui.navset_card_pill`). + +## Parameters + +id: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: If provided, will create an input value that holds the currently selected nav + item. + +selected: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: Choose a particular nav item to select by default value (should match it's + ``value``). + +sidebar: [Optional](`typing.Optional`)\[[ui](`shiny.ui`).[Sidebar](`shiny.ui.Sidebar`)\] = None + +: A [](:class:`shiny.ui.Sidebar`) component to display on every [](:func:`~shiny.ui.nav`) page. + +header: [TagChild](`htmltools.TagChild`) = None + +: UI to display above the selected content. + +footer: [TagChild](`htmltools.TagChild`) = None + +: UI to display below the selected content. + +# express.ui.navset_card_tab { #shiny.express.ui.navset_card_tab } + +`express.ui.navset_card_tab(id=None, selected=None, title=None, sidebar=None, header=None, footer=None)` + +Context manager for a set of nav items as a tabset inside a card container. + +This function wraps [](:func:`~shiny.ui.navset_card_tab`). + +## Parameters + +id: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: If provided, will create an input value that holds the currently selected nav + item. + +selected: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: Choose a particular nav item to select by default value (should match it's + ``value``). + +sidebar: [Optional](`typing.Optional`)\[[ui](`shiny.ui`).[Sidebar](`shiny.ui.Sidebar`)\] = None + +: A [](:class:`shiny.ui.Sidebar`) component to display on every [](:func:`~shiny.ui.nav`) page. + +header: [TagChild](`htmltools.TagChild`) = None + +: UI to display above the selected content. + +footer: [TagChild](`htmltools.TagChild`) = None + +: UI to display below the selected content. + +# express.ui.navset_card_underline { #shiny.express.ui.navset_card_underline } + +`express.ui.navset_card_underline(id=None, selected=None, title=None, sidebar=None, header=None, footer=None, placement='above')` + +Context manager for a set of nav items as a tabset inside a card container. + +This function wraps [](:func:`~shiny.ui.navset_card_underline`). + +## Parameters + +id: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: If provided, will create an input value that holds the currently selected nav + item. + +selected: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: Choose a particular nav item to select by default value (should match it's + ``value``). + +sidebar: [Optional](`typing.Optional`)\[[ui](`shiny.ui`).[Sidebar](`shiny.ui.Sidebar`)\] = None + +: A [](:class:`shiny.ui.Sidebar`) component to display on every [](:func:`~shiny.ui.nav`) page. + +header: [TagChild](`htmltools.TagChild`) = None + +: UI to display above the selected content. + +footer: [TagChild](`htmltools.TagChild`) = None + +: UI to display below the selected content. + +placement: [Literal](`typing.Literal`)\['above', 'below'\] = 'above' + +: Placement of the nav items relative to the content. + +# express.ui.navset_hidden { #shiny.express.ui.navset_hidden } + +`express.ui.navset_hidden(id=None, selected=None, header=None, footer=None)` + +Context manager for nav contents without the nav items. + +This function wraps [](:func:`~shiny.ui.navset_hidden`). + +## Parameters + +id: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: If provided, will create an input value that holds the currently selected nav + item. + +selected: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: Choose a particular nav item to select by default value (should match it's + ``value``). + +header: [TagChild](`htmltools.TagChild`) = None + +: UI to display above the selected content. + +footer: [TagChild](`htmltools.TagChild`) = None + +: UI to display below the selected content. + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +from shiny import App, Inputs, Outputs, Session, reactive, ui + +app_ui = ui.page_fluid( + ui.layout_sidebar( + ui.panel_sidebar( + ui.input_radio_buttons( + "controller", "Controller", ["1", "2", "3"], selected="1" + ) + ), + ui.panel_main( + ui.navset_hidden( + ui.nav_panel(None, "Panel 1 content", value="panel1"), + ui.nav_panel(None, "Panel 2 content", value="panel2"), + ui.nav_panel(None, "Panel 3 content", value="panel3"), + id="hidden_tabs", + ), + ), + ) +) + + +def server(input: Inputs, output: Outputs, session: Session): + @reactive.Effect + @reactive.event(input.controller) + def _(): + ui.update_navs("hidden_tabs", selected="panel" + str(input.controller())) + + +app = App(app_ui, server) + +``` + + + +# express.ui.navset_pill { #shiny.express.ui.navset_pill } + +`express.ui.navset_pill(id=None, selected=None, header=None, footer=None)` + +Context manager for a set of nav items as a pillset. + +This function wraps [](:func:`~shiny.ui.navset_pill`). + +## Parameters + +id: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: If provided, will create an input value that holds the currently selected nav + item. + +selected: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: Choose a particular nav item to select by default value (should match it's + ``value``). + +header: [TagChild](`htmltools.TagChild`) = None + +: UI to display above the selected content. + +footer: [TagChild](`htmltools.TagChild`) = None + +: UI to display below the selected content. + +# express.ui.navset_pill_list { #shiny.express.ui.navset_pill_list } + +`express.ui.navset_pill_list(id=None, selected=None, header=None, footer=None, well=True, widths=(4, 8))` + +Context manager for a set of nav items as a tabset inside a card container. + +This function wraps [](:func:`~shiny.ui.navset_pill_list`). + +## Parameters + +id: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: If provided, will create an input value that holds the currently selected nav + item. + +selected: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: Choose a particular nav item to select by default value (should match its + ``value``). + +header: [TagChild](`htmltools.TagChild`) = None + +: UI to display above the selected content. + +footer: [TagChild](`htmltools.TagChild`) = None + +: UI to display below the selected content. + +well: [bool](`bool`) = True + +: ``True`` to place a well (gray rounded rectangle) around the navigation list. + +widths: [tuple](`tuple`)\[[int](`int`), [int](`int`)\] = (4, 8) + +: Column widths of the navigation list and tabset content areas respectively. + +# express.ui.navset_tab { #shiny.express.ui.navset_tab } + +`express.ui.navset_tab(id=None, selected=None, header=None, footer=None)` + +Context manager for a set of nav items as a tabset. + +This function wraps [](:func:`~shiny.ui.navset_tab`). + +## Parameters + +id: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: If provided, will create an input value that holds the currently selected nav + item. + +selected: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: Choose a particular nav item to select by default value (should match it's + ``value``). + +header: [TagChild](`htmltools.TagChild`) = None + +: UI to display above the selected content. + +footer: [TagChild](`htmltools.TagChild`) = None + +: UI to display below the selected content. + +# express.ui.navset_underline { #shiny.express.ui.navset_underline } + +`express.ui.navset_underline(id=None, selected=None, header=None, footer=None)` + +Context manager for a set of nav items whose active/focused navigation links are +styled with an underline. + +This function wraps [](:func:`~shiny.ui.navset_underline`). + +## Parameters + +id: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: If provided, will create an input value that holds the currently selected nav + item. + +selected: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: Choose a particular nav item to select by default value (should match it's + ``value``). + +header: [TagChild](`htmltools.TagChild`) = None + +: UI to display above the selected content. + +footer: [TagChild](`htmltools.TagChild`) = None + +: UI to display below the selected content. + +# express.ui.value_box { #shiny.express.ui.value_box } + +`express.ui.value_box(showcase=None, showcase_layout='left center', full_screen=False, theme=None, height=None, max_height=None, fill=True, class_=None, **kwargs)` + +Context manager for a value box + +This function wraps [](:func:`~shiny.ui.value_box`). + +An opinionated ([](:func:`~shiny.ui.card`)-powered) box, designed for displaying a title +(the 1st child), value (the 2nd child), and other explanation text (other children, +if any). Optionally, a `showcase` can provide for context for what the `value` +represents (for example, it could hold an icon, or even a +[](:func:`~shiny.ui.output_plot`)). + +## Parameters + +showcase: [Optional](`typing.Optional`)\[[TagChild](`htmltools.TagChild`)\] = None + +: A [](:class:`~htmltools.Tag`) child to showcase (e.g., an icon, a + [](:func:`~shiny.ui.output_plot`), etc). + +showcase_layout: [ui](`shiny.ui`).[_valuebox](`shiny.ui._valuebox`).[SHOWCASE_LAYOUTS_STR](`shiny.ui._valuebox.SHOWCASE_LAYOUTS_STR`) \| [ui](`shiny.ui`).[ShowcaseLayout](`shiny.ui.ShowcaseLayout`) = 'left center' + +: One of `"left center"` (default), `"top right"` or `"bottom"`. Alternatively, + you can customize the showcase layout options with the + [](:func:`~shiny.ui.showcase_left_center`), :func:`~shiny.ui.showcase_top_right()`, + or :func:`~shiny.ui.showcase_bottom()` functions. Use the options functions when + you want to control the height or width of the showcase area. + +theme: [Optional](`typing.Optional`)\[[str](`str`) \| [ui](`shiny.ui`).[ValueBoxTheme](`shiny.ui.ValueBoxTheme`)\] = None + +: The name of a theme (e.g. `"primary"`, `"danger"`, `"purple"`, `"bg-green"`, + `"text-red"`) for the value box, or a theme constructed with + [](:func:`~shiny.ui.value_box_theme`). The theme names provide a convenient way to + use your app's Bootstrap theme colors as the foreground or background colors of + the value box. For more control, you can create your own theme with + [](:func:`~shiny.ui.value_box_theme`) where you can pass foreground and background + colors directly. Bootstrap supported color themes: `"blue"`, `"purple"`, + `"pink"`, `"red"`, `"orange"`, `"yellow"`, `"green"`, `"teal"`, and `"cyan"`. + These colors can be used with `bg-NAME`, `text-NAME`, and + `bg-gradient-NAME1-NAME2` to change the background, foreground, or use a + background gradient respectively. If a `theme` string does not start with + `text-` or `bg-`, it will be auto prefixed with `bg-`. + +full_screen: [bool](`bool`) = False + +: If `True`, an icon will appear when hovering over the card body. Clicking the + icon expands the card to fit viewport size. + +height: [Optional](`typing.Optional`)\[[CssUnit](`shiny.ui.css.CssUnit`)\] = None + +: Any valid CSS unit (e.g., `height="200px"`). Doesn't apply when a card is made + `full_screen`. + +fill: [bool](`bool`) = True + +: Whether to allow the value box to grow/shrink to fit a fillable container with + an opinionated height (e.g., [](:func:`~shiny.ui.page_fillable`)). + +class_: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: Utility classes for customizing the appearance of the summary card. Use `bg-*` + and `text-*` classes (e.g, `"bg-danger"` and `"text-light"`) to customize the + background/foreground colors. + +**kwargs: [TagAttrValue](`htmltools.TagAttrValue`) = {} + +: Additional attributes to pass to [](:func:`~shiny.ui.card`). + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +from icons import piggy_bank + +from shiny import App, ui + +app_ui = ui.page_fluid( + ui.layout_column_wrap( + ui.value_box( + "KPI Title", + "$1 Billion Dollars", + "Up 30% VS PREVIOUS 30 DAYS", + showcase=piggy_bank, + theme="bg-gradient-orange-cyan", + full_screen=True, + ), + ui.value_box( + "KPI Title", + "$1 Billion Dollars", + "Up 30% VS PREVIOUS 30 DAYS", + showcase=piggy_bank, + theme="text-green", + showcase_layout="top right", + full_screen=True, + ), + ui.value_box( + "KPI Title", + "$1 Billion Dollars", + "Up 30% VS PREVIOUS 30 DAYS", + showcase=piggy_bank, + theme="purple", + showcase_layout="bottom", + full_screen=True, + ), + ) +) + + +app = App(app_ui, server=None) + +## file: icons.py +from shiny import ui + +piggy_bank = ui.HTML( + '' +) + +``` + + + +# express.ui.panel_well { #shiny.express.ui.panel_well } + +`express.ui.panel_well(**kwargs)` + +Context manager for a well panel + +This function wraps [](:func:`~shiny.ui.panel_well`). + +A well panel is a simple container with a border and some padding. It's useful for +grouping related content together. + +# express.ui.panel_conditional { #shiny.express.ui.panel_conditional } + +`express.ui.panel_conditional(condition, **kwargs)` + +Context manager for a conditional panel + +This function wraps [](:func:`~shiny.ui.panel_conditional`). + +Show UI elements only if a ``JavaScript`` condition is ``true``. + +## Parameters + +condition: [str](`str`) + +: A JavaScript expression that will be evaluated repeatedly to determine whether + the panel should be displayed. + +**kwargs: [TagAttrValue](`htmltools.TagAttrValue`) = {} + +: Attributes to place on the panel tag. + +## Note + +In the JS expression, you can refer to input and output JavaScript objects that +contain the current values of input and output. For example, if you have an input +with an id of foo, then you can use input.foo to read its value. (Be sure not to +modify the input/output objects, as this may cause unpredictable behavior.) + +You are not recommended to use special JavaScript characters such as a period . in +the input id's, but if you do use them anyway, for example, ``id = "foo.bar"``, you +will have to use ``input["foo.bar"]`` instead of ``input.foo.bar`` to read the input +value. + + + +## Tip + +A more powerful (but slower) way to conditionally show UI content is to use +[](:func:`~shiny.render.ui`). + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +from shiny import App, Inputs, Outputs, Session, ui + +app_ui = ui.page_fluid( + ui.input_checkbox("show", "Show radio buttons", False), + ui.panel_conditional( + "input.show", ui.input_radio_buttons("radio", "Choose ", ["slider", "select"]) + ), + ui.panel_conditional( + "input.show && input.radio === 'slider'", + ui.input_slider("slider", None, min=0, max=100, value=50), + ), + ui.panel_conditional( + "input.show && input.radio === 'select'", + ui.input_select("slider", None, ["A", "B", "C"]), + ), +) + + +def server(input: Inputs, output: Outputs, session: Session): + pass + + +app = App(app_ui, server) + +``` + + + +# express.ui.panel_fixed { #shiny.express.ui.panel_fixed } + +`express.ui.panel_fixed(top=None, left=None, right=None, bottom=None, width=None, height=None, draggable=False, cursor='auto', **kwargs)` + +Context manager for a panel of absolutely positioned content. + +This function wraps [](:func:`~shiny.ui.panel_fixed`). + +This function is equivalent to calling [](:func:`~shiny.ui.panel_absolute`) with +``fixed=True`` (i.e., the panel does not scroll with the rest of the page). See +[](:func:`~shiny.ui.panel_absolute`) for more information. + +## Parameters + +**kwargs: [TagAttrValue](`htmltools.TagAttrValue`) = {} + +: Arguments passed along to [](:func:`~shiny.ui.panel_absolute`). + +## See Also + +[](:func:`~shiny.ui.panel_absolute`) + +# express.ui.panel_absolute { #shiny.express.ui.panel_absolute } + +`express.ui.panel_absolute(top=None, left=None, right=None, bottom=None, width=None, height=None, draggable=False, fixed=False, cursor='auto', **kwargs)` + +Context manager for a panel of absolutely positioned content. + +This function wraps [](:func:`~shiny.ui.panel_absolute`). + +Creates a ``<div>`` tag whose CSS position is set to absolute (or fixed if ``fixed = +True``). The way absolute positioning works in HTML is that absolute coordinates are +specified relative to its nearest parent element whose position is not set to static +(which is the default), and if no such parent is found, then relative to the page +borders. If you're not sure what that means, just keep in mind that you may get +strange results if you use this function from inside of certain types of panels. + +## Parameters + +top: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: Distance between the top of the panel, and the top of the page or parent + container. + +left: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: Distance between the left side of the panel, and the left of the page or parent + container. + +right: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: Distance between the right side of the panel, and the right of the page or + parent container. + +bottom: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: Distance between the bottom of the panel, and the bottom of the page or parent + container. + +width: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: Width of the panel. + +height: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: Height of the panel. + +draggable: [bool](`bool`) = False + +: If ``True``, allows the user to move the panel by clicking and dragging. + +fixed: [bool](`bool`) = False + +: Positions the panel relative to the browser window and prevents it from being + scrolled with the rest of the page. + +cursor: [Literal](`typing.Literal`)\['auto', 'move', 'default', 'inherit'\] = 'auto' + +: The type of cursor that should appear when the user mouses over the panel. Use + ``"move"`` for a north-east-south-west icon, ``"default"`` for the usual cursor + arrow, or ``"inherit"`` for the usual cursor behavior (including changing to an + I-beam when the cursor is over text). The default is ``"auto"``, which is + equivalent to ``"move" if draggable else "inherit"``. + +**kwargs: [TagAttrValue](`htmltools.TagAttrValue`) = {} + +: Attributes added to the content's container tag. + +## Tip + +The position (``top``, ``left``, ``right``, ``bottom``) and size (``width``, +``height``) parameters are all optional, but you should specify exactly two of top, +bottom, and height and exactly two of left, right, and width for predictable +results. + +Like most other distance parameters in Shiny, the position and size parameters take +a number (interpreted as pixels) or a valid CSS size string, such as ``"100px"`` +(100 pixels) or ``"25%"``. + +For arcane HTML reasons, to have the panel fill the page or parent you should +specify 0 for ``top``, ``left``, ``right``, and ``bottom`` rather than the more +obvious ``width = "100%"`` and ``height = "100%"``. + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +from shiny import App, Inputs, Outputs, Session, ui + +app_ui = ui.page_fluid( + ui.panel_title("A basic absolute panel example", "Demo"), + ui.panel_absolute( + ui.panel_well( + "Drag me around!", ui.input_slider("n", "N", min=0, max=100, value=20) + ), + draggable=True, + width="300px", + right="50px", + top="50%", + ), +) + + +def server(input: Inputs, output: Outputs, session: Session): + pass + + +app = App(app_ui, server) + +``` + diff --git a/docs/api/ExCard.qmd b/docs/api/ExCard.qmd new file mode 100644 index 000000000..250c3457a --- /dev/null +++ b/docs/api/ExCard.qmd @@ -0,0 +1,345 @@ +# Card + +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. + +# experimental.ui.card_body { #shiny.experimental.ui.card_body } + +`experimental.ui.card_body(*args, fillable=True, min_height=None, max_height=None, max_height_full_screen=MISSING, height=None, padding=None, gap=None, fill=True, class_=None, **kwargs)` + +Card body container + +A general container for the "main content" of a [](:func:`~shiny.ui.card`). This component is designed +to be provided as direct children to [](:func:`~shiny.ui.card`). + +## Parameters + +*args: [TagChild](`htmltools.TagChild`) \| [TagAttrs](`htmltools.TagAttrs`) = () + +: Contents to the card's body. Or tag attributes that are supplied to the + resolved [](:class:`~htmltools.Tag`) object. + +fillable: [bool](`bool`) = True + +: Whether or not the card item should be a fillable (i.e. flexbox) container. + +min_height: [Optional](`typing.Optional`)\[[CssUnit](`shiny.ui.css._css_unit.CssUnit`)\] = None + +: Any valid CSS length unit. If `max_height_full_screen` is missing, it is set to + `max_height`. + +height: [Optional](`typing.Optional`)\[[CssUnit](`shiny.ui.css._css_unit.CssUnit`)\] = None + +: Any valid CSS unit (e.g., `height="200px"`). Doesn't apply when a card is made + `full_screen` (in this case, consider setting a `height` in + [](:func:`~shiny.ui.card_body`)). + +padding: [Optional](`typing.Optional`)\[[CssUnit](`shiny.ui.css._css_unit.CssUnit`) \| [list](`list`)\[[CssUnit](`shiny.ui.css._css_unit.CssUnit`)\]\] = None + +: Padding to use for the body. This can be a numeric vector + (which will be interpreted as pixels) or a character vector with valid CSS + lengths. The length can be between one and four. If one, then that value + will be used for all four sides. If two, then the first value will be used + for the top and bottom, while the second value will be used for left and + right. If three, then the first will be used for top, the second will be + left and right, and the third will be bottom. If four, then the values will + be interpreted as top, right, bottom, and left respectively. + +gap: [Optional](`typing.Optional`)\[[CssUnit](`shiny.ui.css._css_unit.CssUnit`)\] = None + +: A CSS length unit defining the `gap` (i.e., spacing) between elements provided + to `*args`. This argument is only applicable when `fillable = TRUE`. + +fill: [bool](`bool`) = True + +: Whether to allow this element to grow/shrink to fit its `card` container. + +class_: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: Additional CSS classes for the returned Tag. + +**kwargs: [TagAttrValue](`htmltools.TagAttrValue`) = {} + +: Additional HTML attributes for the returned Tag. + +## Returns + +| Type | Description | +|---------------------------------------|---------------------------------------| +| [CardItem](`shiny.ui._card.CardItem`) | A [](:class:`~shiny.ui.CardItem`) object. | + +## See Also + +* [](:func:`~shiny.ui.layout_column_wrap`) for laying out multiple cards + (or multiple columns inside a card). +* [](:func:`~shiny.ui.card`) for creating a card component. +* [](:func:`~shiny.ui.card_header`) for creating a header within the card. +* [](:func:`~shiny.ui.card_title`) for creating a title within the card body. +* [](:func:`~shiny.ui.card_footer`) for creating a footer within the card. + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +import shiny.experimental as x +from shiny import App, ui + +app_ui = ui.page_fluid( + x.ui.card( + x.ui.card_header("This is the header"), + x.ui.card_body( + x.ui.card_title("This is the title"), + ui.p("This is the body."), + ui.p("This is still the body."), + ), + x.ui.card_footer("This is the footer"), + full_screen=True, + ), + x.ui.card( + ui.p("These first two elements will be wrapped in `card_body()` together."), + ui.p("These first two elements will be wrapped in `card_body()` together."), + x.ui.card_body(ui.p("A card body.")), + ui.p("These last two elements will be wrapped in `card_body()` together."), + ui.p("These last two elements will be wrapped in `card_body()` together."), + ), +) + + +app = App(app_ui, server=None) + +``` + + + +# experimental.ui.card_title { #shiny.experimental.ui.card_title } + +`experimental.ui.card_title(*args, container=tags.h5, **kwargs)` + +A card title container + +[](:func:`~shiny.experimental.ui.card_title`) creates a general container for the "title" of +a [](:func:`~shiny.ui.card`). This component is designed +to be provided as a direct child to [](:func:`~shiny.ui.card`). + +## Parameters + +*args: [TagChild](`htmltools.TagChild`) \| [TagAttrs](`htmltools.TagAttrs`) = () + +: Contents to appear in the card's title, or tag attributes to pass to the + resolved [](:class:`~htmltools.Tag`) object. + +container: [TagFunction](`htmltools.TagFunction`) = tags.h5 + +: Method for the returned [](:class:`~htmltools.Tag`) object. Defaults to + [](:func:`~shiny.ui.tags`).h5. + +**kwargs: [TagAttrValue](`htmltools.TagAttrValue`) = {} + +: Additional HTML attributes for the returned [](:class:`~htmltools.Tag`) object. + +## Returns + +| Type | Description | +|--------------------------------------|------------------------------------| +| [Tagifiable](`htmltools.Tagifiable`) | An [](:class:`~htmltools.Tag`) object. | + +## See Also + +* [](:func:`~shiny.ui.card`) for creating a card component. +* [](:func:`~shiny.ui.card_header`) for creating a header within a card. +* [](:func:`~shiny.experimental.ui.card_body`) for putting content inside a card. +* [](:func:`~shiny.ui.card_footer`) for creating a footer within a card. +* [](:func:`~shiny.experimental.ui.card_image`) for adding an image to a card. + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +import shiny.experimental as x +from shiny import App, ui + +app_ui = ui.page_fluid( + x.ui.card( + x.ui.card_header("This is the header"), + x.ui.card_body( + x.ui.card_title("This is the title"), + ui.p("This is the body."), + ui.p("This is still the body."), + ), + x.ui.card_footer("This is the footer"), + full_screen=True, + ) +) + + +app = App(app_ui, server=None) + +``` + + + +# experimental.ui.card_image { #shiny.experimental.ui.card_image } + +`experimental.ui.card_image(file, *args, href=None, border_radius='top', mime_type=None, class_=None, height=None, fill=True, width=None, container=card_body, **kwargs)` + +A card image container + +[](:func:`~shiny.experimental.ui.card_image`) creates a general container for an image within a +[](:func:`~shiny.ui.card`). This component is designed to be +provided as a direct child to [](:func:`~shiny.ui.card`). + +## Parameters + +file: [str](`str`) \| [Path](`pathlib.Path`) \| [PurePath](`pathlib.PurePath`) \| [io](`io`).[BytesIO](`io.BytesIO`) \| None + +: A file path pointing to an image. The image will be base64 encoded and provided to + the `src` attribute of the `` tag. Alternatively, you may set this value to + `None` and provide the `src` yourself via `*args:TagAttrs` or + `**kwargs:TagAttrValue` (e.g., `{"src": "HOSTED_PATH_TO_IMAGE"}` or + `src="HOSTED_PATH_TO_IMAGE"`). + +*args: [TagAttrs](`htmltools.TagAttrs`) = () + +: A dictionary of tag attributes that are supplied to the resolved + [](:class:`~htmltools.Tag`) object. + +href: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: An optional URL to link to. + +border_radius: [Literal](`typing.Literal`)\['top', 'bottom', 'all', 'none'\] = 'top' + +: Where to apply `border-radius` on the image. + +mime_type: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: The mime type of the `file`. + +class_: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: Additional CSS classes for the resolved [](:class:`~htmltools.Tag`) object. + +height: [Optional](`typing.Optional`)\[[CssUnit](`shiny.ui.css.CssUnit`)\] = None + +: Any valid CSS unit (e.g., `height="200px"`). `height` will not apply when a card is made + `full_screen`. In this case, consider setting a `height` in + [](:func:`~shiny.experimental.ui.card_body`). + +fill: [bool](`bool`) = True + +: Whether to allow this element to grow/shrink to fit its `card` container. + +width: [Optional](`typing.Optional`)\[[CssUnit](`shiny.ui.css.CssUnit`)\] = None + +: Any valid CSS unit (e.g., `width="100%"`). + +container: [ImgContainer](`shiny.experimental.ui._card.ImgContainer`) = card_body + +: Method to wrap the returned [](:class:`~htmltools.Tag`) object. Defaults to + [](:func:`~shiny.experimental.ui.card_body`). + If [](:func:`~shiny.experimental.ui.card_body`) is used, each image will be in separate cards. If + the `container` method does not return a [](:class:`~shiny.ui.CardItem`), it + allows for consecutive non-`CardItem` objects to be bundled into a single + [](:func:`~shiny.experimental.ui.card_body`) within [](:func:`~shiny.ui.card`). + +**kwargs: [TagAttrValue](`htmltools.TagAttrValue`) = {} + +: Additional HTML attributes for the resolved [](:class:`~htmltools.Tag`). + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +import shiny.experimental as x +from shiny import App, ui + +app_ui = ui.page_fluid( + ui.tags.style( + """ + .card-body { + border: 1px dashed red; + } + """ + ), + x.ui.card( + x.ui.card_header( + "These two images are in their own individual card_body() container" + ), + x.ui.card_image( + file=None, + src="https://posit.co/wp-content/uploads/2022/10/Posit-logo-h-full-color-RGB-TM.svg", + ), + x.ui.card_image( + file=None, + src="https://posit.co/wp-content/uploads/2022/10/Posit-logo-h-full-color-RGB-TM.svg", + ), + x.ui.card_header("These two images are in the same card_body() container"), + x.ui.card_image( + file=None, + src="https://posit.co/wp-content/uploads/2022/10/Posit-logo-h-full-color-RGB-TM.svg", + container=ui.tags.span, + ), + x.ui.card_image( + file=None, + src="https://posit.co/wp-content/uploads/2022/10/Posit-logo-h-full-color-RGB-TM.svg", + container=ui.tags.span, + ), + ), +) + + +app = App(app_ui, server=None) + +``` + + + +# experimental.ui.ImgContainer { #shiny.experimental.ui.ImgContainer } + +`experimental.ui.ImgContainer()` + +Wraps the return value of `card_image()`. + +## Parameters + +*args: [Tag](`htmltools.Tag`) = () + +: The return value of `card_image()`. + +## Returns + +| Type | Description | +|--------------------------------------|-----------------------------------------------------------------------------------------------| +| [Tagifiable](`htmltools.Tagifiable`) | A tagifiable object, such as a [](:class:`~htmltools.Tag`) or [](:class:`~shiny.ui.CardItem`) object. | + +# experimental.ui.WrapperCallable { #shiny.experimental.ui.WrapperCallable } + +`experimental.ui.WrapperCallable()` + +Wraps children into a [](:class:`~shiny.ui.CardItem`). + +## Parameters + +*args: [TagChild](`htmltools.TagChild`) = () + +: `TagChild` children to wrap. + +## Returns + +| Type | Description | +|---------------------------------------|---------------------------------------| +| [CardItem](`shiny.ui._card.CardItem`) | A [](:class:`~shiny.ui.CardItem`) object. | \ No newline at end of file diff --git a/docs/api/ExceptionTypes.qmd b/docs/api/ExceptionTypes.qmd new file mode 100644 index 000000000..c27833060 --- /dev/null +++ b/docs/api/ExceptionTypes.qmd @@ -0,0 +1,155 @@ +# Exception types + + + +# types.SilentException { #shiny.types.SilentException } + +`types.SilentException()` + +Throw a silent exception. + +Normally, when an exception occurs inside a reactive context, it's either: + +- Displayed to the user (as a big red error message) + - This happens when the exception is raised from an output context (e.g., [](:func:`shiny.render.ui`)) +- Crashes the application + - This happens when the exception is raised from an [](:func:`shiny.reactive.Effect`) + +This exception is used to silently throw inside a reactive context, meaning that +execution is paused, and no output is shown to users (or the python console). + + + +## See Also + +[](:func:`~SilentCancelOutputException`) + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +from shiny import App, Inputs, Outputs, Session, render, ui +from shiny.types import SilentException + +app_ui = ui.page_fluid( + ui.input_text( + "txt", + "Enter text to see it displayed below the input", + width="400px", + ), + ui.output_ui("txt_out"), +) + + +def server(input: Inputs, output: Outputs, session: Session): + @render.ui + def txt_out(): + if not input.txt(): + raise SilentException() + return "Your input: " + input.txt() + + +app = App(app_ui, server) + +``` + + + +# types.SilentCancelOutputException { #shiny.types.SilentCancelOutputException } + +`types.SilentCancelOutputException()` + +Throw a silent exception and don't clear output + +Similar to [](:class:`~SilentException`), but if thrown in an output context, +existing output isn't cleared. + + + +## See Also + +[](:func:`~SilentException`) + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +from shiny import App, Inputs, Outputs, Session, render, ui +from shiny.types import SilentCancelOutputException + +app_ui = ui.page_fluid( + ui.input_text( + "txt", + "Delete the input text completely: it won't get removed below the input", + "Some text", + width="400px", + ), + ui.output_ui("txt_out"), +) + + +def server(input: Inputs, output: Outputs, session: Session): + @render.ui + def txt_out(): + if not input.txt(): + raise SilentCancelOutputException() + return "Your input: " + input.txt() + + +app = App(app_ui, server) + +``` + + + +# types.SafeException { #shiny.types.SafeException } + +`types.SafeException()` + +Throw a safe exception. + +When ``shiny.App.SANITIZE_ERRORS`` is ``True`` (which is the case +in some production environments like Posit Connect), exceptions are sanitized +to prevent leaking of sensitive information. This class provides a way to +generate an error that is OK to be displayed to the user. + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +from shiny import App, Inputs, Outputs, Session, render, ui +from shiny.types import SafeException + +app_ui = ui.page_fluid(ui.output_ui("safe"), ui.output_ui("unsafe")) + + +def server(input: Inputs, output: Outputs, session: Session): + @render.ui + def safe(): + raise SafeException("This is a safe exception") + + @render.ui + def unsafe(): + raise Exception("This is an unsafe exception") + + +app = App(app_ui, server) +app.sanitize_errors = True + +``` + diff --git a/docs/api/Inputs.qmd b/docs/api/Inputs.qmd new file mode 100644 index 000000000..c81c6f137 --- /dev/null +++ b/docs/api/Inputs.qmd @@ -0,0 +1,10 @@ +# Inputs { #shiny.Inputs } + +`Inputs(self, values, ns=Root)` + +A class representing Shiny input values. + +This class provides access to a [](:class:`~shiny.Session`)'s input values. The +input values are reactive [](:class:`~shiny.reactive.Value`)s, and can be accessed with +the ``[]`` operator, or with ``.``. For example, if there is an input named ``x``, +it can be accessed via `input["x"]()` or ``input.x()``. \ No newline at end of file diff --git a/docs/api/MiscTypes.qmd b/docs/api/MiscTypes.qmd new file mode 100644 index 000000000..07440d1f0 --- /dev/null +++ b/docs/api/MiscTypes.qmd @@ -0,0 +1,396 @@ +# Miscellaneous types + + + +# types.MISSING_TYPE { #shiny.types.MISSING_TYPE } + +`types.MISSING_TYPE()` + + + +# types.MISSING { #shiny.types.MISSING } + +`types.MISSING` + + + +# types.FileInfo { #shiny.types.FileInfo } + +`types.FileInfo()` + +Class for information about a file upload. + + + +## See Also + +[](:func:`~shiny.ui.input_file`) + + + +## Example + +See [](:func:`~shiny.ui.input_file`). + +## Attributes + +| Name | Description | +| --- | --- | +| [datapath](#shiny.types.FileInfo.datapath) | The path to the file on the server. | +| [name](#shiny.types.FileInfo.name) | The name of the file being uploaded. | +| [size](#shiny.types.FileInfo.size) | The size of the file in bytes. | +| [type](#shiny.types.FileInfo.type) | The MIME type of the file. | + +# types.ImgData { #shiny.types.ImgData } + +`types.ImgData()` + +Return type for [](:func:`~shiny.render.image`). + + + +## See Also + +[](:func:`~shiny.render.image`) + + + +## Example + +See [](:func:`~shiny.render.image`). + +## Attributes + +| Name | Description | +| --- | --- | +| [alt](#shiny.types.ImgData.alt) | The ``alt`` attribute of the ```` tag. | +| [coordmap](#shiny.types.ImgData.coordmap) | TODO | +| [height](#shiny.types.ImgData.height) | The ``height`` attribute of the ```` tag. | +| [src](#shiny.types.ImgData.src) | The ``src`` attribute of the ```` tag. | +| [style](#shiny.types.ImgData.style) | The ``style`` attribute of the ```` tag. | +| [width](#shiny.types.ImgData.width) | The ``width`` attribute of the ```` tag. | + +# types.NavSetArg { #shiny.types.NavSetArg } + +`types.NavSetArg()` + +A value suitable for passing to a navigation container (e.g., +[](:func:`~shiny.ui.navset_tab`)). + +## Methods + +| Name | Description | +| --- | --- | +| [get_value](#shiny.types.NavSetArg.get_value) | Get the value of this navigation item (if any). This value is only used to determine what navigation item should be shown by default when none is specified (i.e., the first navigation item that returns a value is used to determine the container's ``selected`` value). | +| [resolve](#shiny.types.NavSetArg.resolve) | Resolve information provided by the navigation container. | + +### get_value { #shiny.types.NavSetArg.get_value } + +`types.NavSetArg.get_value()` + +Get the value of this navigation item (if any). + +This value is only used to determine what navigation item should be shown +by default when none is specified (i.e., the first navigation item that +returns a value is used to determine the container's ``selected`` value). + +### resolve { #shiny.types.NavSetArg.resolve } + +`types.NavSetArg.resolve(selected, context)` + +Resolve information provided by the navigation container. + +#### Parameters + +selected: [Optional](`typing.Optional`)\[[str](`str`)\] + +: The value of the navigation item to be shown on page load. + +context: [dict](`dict`)\[[str](`str`), [Any](`typing.Any`)\] + +: Additional context supplied by the navigation container. + +# ui.Sidebar { #shiny.ui.Sidebar } + +`ui.Sidebar(self, tag, collapse_tag, position, open, width, max_height_mobile, color_fg, color_bg)` + +A sidebar object + +Class returned from [](:func:`~shiny.ui.sidebar`). Please do not use this +class directly. Instead, supply the [](:func:`~shiny.ui.sidebar`) object to +[](:func:`~shiny.ui.layout_sidebar`). + +## Attributes + +| Name | Type | Description | +|-------------------|--------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| tag | | The [](:class:`~htmltools.Tag`) object that represents the sidebar. | +| collapse_tag | | The [](:class:`~htmltools.Tag`) object that represents the collapse button. | +| position | | Where the sidebar should appear relative to the main content. | +| open | | The initial state of the sidebar (open or collapsed). | +| width | | A valid CSS unit used for the width of the sidebar. | +| max_height_mobile | | The maximum height of the horizontal sidebar when viewed on mobile devices. The default is `250px` unless the sidebar is included in a [](:func:`~shiny.ui.layout_sidebar`) with a specified height, in which case the default is to take up no more than 50% of the layout container. | +| color_fg | | A foreground color. | +| color_bg | | A background color. | + +## Parameters + +tag: [Tag](`htmltools.Tag`) + +: The [](:class:`~htmltools.Tag`) object that represents the sidebar. + +collapse_tag: [Optional](`typing.Optional`)\[[Tag](`htmltools.Tag`)\] + +: The [](:class:`~htmltools.Tag`) object that represents the collapse button. + +position: [Literal](`typing.Literal`)\['left', 'right'\] + +: Where the sidebar should appear relative to the main content. + +open: [Literal](`typing.Literal`)\['desktop', 'open', 'closed', 'always'\] + +: The initial state of the sidebar (open or collapsed). + +width: [CssUnit](`shiny.ui.css.CssUnit`) + +: A valid CSS unit used for the width of the sidebar. + +max_height_mobile: [Optional](`typing.Optional`)\[[str](`str`) \| [float](`float`)\] + +: The maximum height of the horizontal sidebar when viewed on mobile devices. + The default is `250px` unless the sidebar is included in a + [](:func:`~shiny.ui.layout_sidebar`) with a specified height, in + which case the default is to take up no more than 50% of the layout container. + +color_fg: [Optional](`typing.Optional`)\[[str](`str`)\] + +: A foreground color. + +color_bg: [Optional](`typing.Optional`)\[[str](`str`)\] + +: A background color. + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +from shiny import App, Inputs, Outputs, Session, render, ui + +app_ui = ui.page_fluid( + ui.card( + ui.layout_sidebar( + ui.sidebar("Left sidebar content", id="sidebar_left"), + ui.output_text_verbatim("state_left"), + ) + ), + ui.card( + ui.layout_sidebar( + ui.sidebar("Right sidebar content", id="sidebar_right", position="right"), + ui.output_text_verbatim("state_right"), + ), + ), + ui.card( + ui.layout_sidebar( + ui.sidebar("Closed sidebar content", id="sidebar_closed", open="closed"), + ui.output_text_verbatim("state_closed"), + ) + ), + ui.card( + ui.layout_sidebar( + ui.sidebar("Always sidebar content", id="sidebar_always", open="always"), + ui.output_text_verbatim("state_always"), + ) + ), +) + + +def server(input: Inputs, output: Outputs, session: Session): + @render.text + def state_left(): + return f"input.sidebar_left(): {input.sidebar_left()}" + + @render.text + def state_right(): + return f"input.sidebar_right(): {input.sidebar_right()}" + + @render.text + def state_closed(): + return f"input.sidebar_closed(): {input.sidebar_closed()}" + + @render.text + def state_always(): + return f"input.sidebar_always(): {input.sidebar_always()}" + + +app = App(app_ui, server) + +``` + + + +## Methods + +| Name | Description | +| --- | --- | +| [tagify](#shiny.ui.Sidebar.tagify) | Not implemented | + +### tagify { #shiny.ui.Sidebar.tagify } + +`ui.Sidebar.tagify()` + +Not implemented + +# ui.CardItem { #shiny.ui.CardItem } + +`ui.CardItem(self, item)` + +A wrapper around a [](:class:`~htmltools.Tag`) object that represents the content of a +card item (e.g., [](:func:`~shiny.ui.card_header`) or +[](:func:`~shiny.card_footer`)). + +This class is used to allow for consecutive non-card items to be bundled into a +single group within [](:func:`~shiny.ui.card`). + +## Parameters + +item: [TagChild](`htmltools.TagChild`) + +: A [](:class:`~htmltools.Tag`) object that represents the content of a card item + (e.g., [](:func:`~shiny.ui.card_header`) or + [](:func:`~shiny.card_footer`)). + +## See Also + +* [](:func:`~shiny.ui.card`) for creating a card component. +* [](:func:`~shiny.ui.card_header`) for creating a header within a card. +* [](:func:`~shiny.ui.card_footer`) for creating a footer within a card. + +## Methods + +| Name | Description | +| --- | --- | +| [resolve](#shiny.ui.CardItem.resolve) | Resolves an object with the `CardItem` class by returning the `item` provided at initialization. | +| [tagify](#shiny.ui.CardItem.tagify) | Tagify the `item` | + +### resolve { #shiny.ui.CardItem.resolve } + +`ui.CardItem.resolve()` + +Resolves an object with the `CardItem` class by returning the `item` provided at initialization. + +#### Returns + +| Type | Description | +|----------------------------------|----------------------------------------| +| [TagChild](`htmltools.TagChild`) | The `item` provided at initialization. | + +### tagify { #shiny.ui.CardItem.tagify } + +`ui.CardItem.tagify()` + +Tagify the `item` + +#### Returns + +| Type | Description | +|--------------------------------|------------------------------------------------| +| [TagList](`htmltools.TagList`) | A tagified [](:class:`~htmltools.TagList`) object. | + +# ui.AccordionPanel { #shiny.ui.AccordionPanel } + +`ui.AccordionPanel(self, *args, data_value, icon, title, id, **kwargs)` + +The internal class used to represent an accordion panel. + +This class is used to represent an accordion panel. It is not intended to be +instantiated directly. Instead, use [](:func:`~shiny.ui.accordion_panel`). + +## Parameters + +*args: [TagChild](`htmltools.TagChild`) \| [TagAttrs](`htmltools.TagAttrs`) = () + +: Contents to appear in the accordion panel body, or tag attributes that are supplied to the + returned [](:class:`~htmltools.Tag`) object. + +data_value: [str](`str`) + +: A character string that uniquely identifies this panel. + +icon: [TagChild](`htmltools.TagChild`) \| None + +: A [](:class:`~htmltools.Tag`) which is positioned just before the `title`. + +title: [TagChild](`htmltools.TagChild`) \| None + +: A title to appear in the [](:func:`~shiny.ui.accordion_panel`)'s header. + +id: [str](`str`) \| None + +: A unique id for this panel. + +**kwargs: [TagAttrValue](`htmltools.TagAttrValue`) = {} + +: Tag attributes to the `accordion-body` div Tag. + +## See Also + +* [](:func:`~shiny.ui.accordion`) +* [](:func:`~shiny.ui.update_accordion`) +* [](:func:`~shiny.ui.insert_accordion_panel`) +* [](:func:`~shiny.ui.remove_accordion_panel`) +* [](:func:`~shiny.ui.update_accordion_panel`) + +## Methods + +| Name | Description | +| --- | --- | +| [resolve](#shiny.ui.AccordionPanel.resolve) | Resolve the :class:`~shiny.ui.AccordionPanel` into a :class:`~htmltools.Tag`. | +| [tagify](#shiny.ui.AccordionPanel.tagify) | Resolve the :class:`~shiny.ui.AccordionPanel` into a :class:`~htmltools.Tag`. | + +### resolve { #shiny.ui.AccordionPanel.resolve } + +`ui.AccordionPanel.resolve()` + +Resolve the [](:class:`~shiny.ui.AccordionPanel`) into a +[](:class:`~htmltools.Tag`). + +#### Returns + +| Type | Description | +|------------------------|--------------------------------------------------------------------------------------| +| [Tag](`htmltools.Tag`) | A [](:class:`~htmltools.Tag`) object representing the [](:class:`~shiny.ui.AccordionPanel`). | + +### tagify { #shiny.ui.AccordionPanel.tagify } + +`ui.AccordionPanel.tagify()` + +Resolve the [](:class:`~shiny.ui.AccordionPanel`) into a +[](:class:`~htmltools.Tag`). + +#### Returns + +| Type | Description | +|------------------------|--------------------------------| +| [Tag](`htmltools.Tag`) | A tagified `resolve()`d value. | + +# ui.css.CssUnit { #shiny.ui.css.CssUnit } + +`ui.css.CssUnit` + +Possible python types that can be converted into a CSS unit. Numeric values will be converted to pixels. Values equal to `0` will be converted to `"0"`. Strings will be passed through as-is. + +# ui._input_slider.SliderValueArg { #shiny.ui._input_slider.SliderValueArg } + +`ui._input_slider.SliderValueArg` + + + +# ui._input_slider.SliderStepArg { #shiny.ui._input_slider.SliderStepArg } + +`ui._input_slider.SliderStepArg` + diff --git a/docs/api/OutputRender.qmd b/docs/api/OutputRender.qmd new file mode 100644 index 000000000..c6ef1197d --- /dev/null +++ b/docs/api/OutputRender.qmd @@ -0,0 +1,318 @@ +# Create rendering outputs + + + +# render.renderer.Renderer { #shiny.render.renderer.Renderer } + +`render.renderer.Renderer(self, _fn=None)` + +Renderer cls docs here + +TODO-barret-docs + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +from __future__ import annotations + +from typing import Literal, Optional + +from shiny import App, Inputs, Outputs, Session, ui +from shiny.render.renderer import Renderer, ValueFn + +####### +# Start of package author code +####### + + +class render_capitalize(Renderer[str]): + # The documentation for the class will be displayed when the user hovers over the + # decorator when **no** parenthesis are used. Ex: `@render_capitalize` + # If no documentation is supplied to the `__init__()` method, then this + # documentation will be displayed when parenthesis are used on the decorator. + """ + Render capitalize class documentation goes here. + """ + + to_case: Literal["upper", "lower", "ignore"] + """ + The case to render the value in. + """ + placeholder: bool + """ + Whether to render a placeholder value. (Defaults to `True`) + """ + + def default_ui(self, id: str): + """ + Express UI for the renderer + """ + return ui.output_text_verbatim(id, placeholder=self.placeholder) + + def __init__( + self, + _fn: Optional[ValueFn[str]] | None = None, + *, + to_case: Literal["upper", "lower", "ignore"] = "upper", + placeholder: bool = True, + ) -> None: + # If a different set of documentation is supplied to the `__init__` method, + # then this documentation will be displayed when parenthesis are used on the decorator. + # Ex: `@render_capitalize()` + """ + Render capitalize documentation goes here. + + It is a good idea to talk about parameters here! + + Parameters + ---------- + to_case + The case to render the value. (`"upper"`) + + Options: + - `"upper"`: Render the value in upper case. + - `"lower"`: Render the value in lower case. + - `"ignore"`: Do not alter the case of the value. + + placeholder + Whether to render a placeholder value. (`True`) + """ + # Do not pass params + super().__init__(_fn) + self.widget = None + self.to_case = to_case + + async def render(self) -> str | None: + value = await self.fn() + if value is None: + # If `None` is returned, then do not render anything. + return None + + ret = str(value) + if self.to_case == "upper": + return ret.upper() + if self.to_case == "lower": + return ret.lower() + if self.to_case == "ignore": + return ret + raise ValueError(f"Invalid value for `to_case`: {self.to_case}") + + +class render_upper(Renderer[str]): + """ + Minimal capitalize string transformation renderer. + + No parameters are supplied to this renderer. This allows us to skip the `__init__()` + method and `__init__()` documentation. If you hover over this decorator with and + without parenthesis, you will see this documentation in both situations. + + Note: This renderer is equivalent to `render_capitalize(to="upper")`. + """ + + def default_ui(self, id: str): + """ + Express UI for the renderer + """ + return ui.output_text_verbatim(id, placeholder=True) + + async def transform(self, value: str) -> str: + """ + Transform the value to upper case. + + This method is shorthand for the default `render()` method. It is useful to + transform non-`None` values. (Any `None` value returned by the app author will + be forwarded to the browser.) + + Parameters + ---------- + value + The a non-`None` value to transform. + + Returns + ------- + str + The transformed value. (Must be a subset of `Jsonifiable`.) + """ + + return str(value).upper() + + +####### +# End of package author code +####### + + +####### +# Start of app author code +####### + + +def text_row(id: str, label: str): + return ui.tags.tr( + ui.tags.td(f"{label}:"), + ui.tags.td(ui.output_text_verbatim(id, placeholder=True)), + ) + return ui.row( + ui.column(6, f"{id}:"), + ui.column(6, ui.output_text_verbatim(id, placeholder=True)), + ) + + +app_ui = ui.page_fluid( + ui.h1("Capitalization renderer"), + ui.input_text("caption", "Caption:", "Data summary"), + ui.tags.table( + text_row("upper", "@render_upper"), + text_row("upper_with_paren", "@render_upper()"), + # + text_row("cap_upper", "@render_capitalize"), + text_row("cap_lower", "@render_capitalize(to='lower')"), + ), +) + + +def server(input: Inputs, output: Outputs, session: Session): + # Hovering over `@render_upper` will display the class documentation + @render_upper + def upper(): + return input.caption() + + # Hovering over `@render_upper` will display the class documentation as there is no + # `__init__()` documentation + @render_upper() + def upper_with_paren(): + return input.caption() + + # Hovering over `@render_capitalize` will display the class documentation + @render_capitalize + def cap_upper(): + return input.caption() + + # Hovering over `@render_capitalize` will display the `__init__()` documentation + @render_capitalize(to_case="lower") + def cap_lower(): + return input.caption() + + +app = App(app_ui, server) + +``` + + + +## Attributes + +| Name | Description | +| --- | --- | +| [fn](#shiny.render.renderer.Renderer.fn) | App-supplied output value function which returns type `IT`. This function is always asyncronous as the original app-supplied function possibly wrapped to execute asynchonously. | + +## Methods + +| Name | Description | +| --- | --- | +| [render](#shiny.render.renderer.Renderer.render) | Renderer - render docs here TODO-barret-docs | +| [transform](#shiny.render.renderer.Renderer.transform) | Renderer - transform docs here TODO-barret-docs | + +### render { #shiny.render.renderer.Renderer.render } + +`render.renderer.Renderer.render()` + +Renderer - render docs here + +TODO-barret-docs + +### transform { #shiny.render.renderer.Renderer.transform } + +`render.renderer.Renderer.transform(value)` + +Renderer - transform docs here + +TODO-barret-docs + +# render.renderer.RendererBase { #shiny.render.renderer.RendererBase } + +`render.renderer.RendererBase(self)` + +Base class for all renderers. + +TODO-barret-docs + +## Attributes + +| Name | Description | +| --- | --- | +| [output_id](#shiny.render.renderer.RendererBase.output_id) | Output function name or ID (provided to `@output(id=)`). This value will contain any module prefix. Set when the output is registered with the session. | + +# render.renderer.Jsonifiable { #shiny.render.renderer.Jsonifiable } + +`render.renderer.Jsonifiable` + + + +# render.renderer.ValueFn { #shiny.render.renderer.ValueFn } + +`render.renderer.ValueFn` + +App-supplied output value function which returns type `IT`. This function can be +synchronous or asynchronous. + +# render.renderer.AsyncValueFn { #shiny.render.renderer.AsyncValueFn } + +`render.renderer.AsyncValueFn(self, fn)` + +App-supplied output value function which returns type `IT`. +asynchronous. + +Type definition: `Callable[[], Awaitable[IT]]` + +## Methods + +| Name | Description | +| --- | --- | +| [get_async_fn](#shiny.render.renderer.AsyncValueFn.get_async_fn) | Return the async value function. | +| [get_sync_fn](#shiny.render.renderer.AsyncValueFn.get_sync_fn) | Retrieve the original, synchronous value function function. If the original function was asynchronous, a runtime error will be thrown. | +| [is_async](#shiny.render.renderer.AsyncValueFn.is_async) | Was the original function asynchronous? | + +### get_async_fn { #shiny.render.renderer.AsyncValueFn.get_async_fn } + +`render.renderer.AsyncValueFn.get_async_fn()` + +Return the async value function. + +#### Returns + +| Type | Description | +|----------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------| +| [Callable](`typing.Callable`)\[\[\], [Awaitable](`typing.Awaitable`)\[[IT](`shiny.render.renderer._renderer.IT`)\]\] | Async wrapped value function supplied to the `AsyncValueFn` constructor. | + +### get_sync_fn { #shiny.render.renderer.AsyncValueFn.get_sync_fn } + +`render.renderer.AsyncValueFn.get_sync_fn()` + +Retrieve the original, synchronous value function function. + +If the original function was asynchronous, a runtime error will be thrown. + +#### Returns + +| Type | Description | +|-----------------------------------------------------------------------------------|----------------------------------------------------------------------------| +| [Callable](`typing.Callable`)\[\[\], [IT](`shiny.render.renderer._renderer.IT`)\] | Original, synchronous function supplied to the `AsyncValueFn` constructor. | + +### is_async { #shiny.render.renderer.AsyncValueFn.is_async } + +`render.renderer.AsyncValueFn.is_async()` + +Was the original function asynchronous? + +#### Returns + +| Type | Description | +|----------------|------------------------------------------------| +| [bool](`bool`) | Whether the original function is asynchronous. | \ No newline at end of file diff --git a/docs/api/Outputs.qmd b/docs/api/Outputs.qmd new file mode 100644 index 000000000..c83a958bb --- /dev/null +++ b/docs/api/Outputs.qmd @@ -0,0 +1,5 @@ +# Outputs { #shiny.Outputs } + +`Outputs(self, session, ns, effects, suspend_when_hidden)` + +A class representing Shiny output definitions. \ No newline at end of file diff --git a/docs/api/PageFunctions.qmd b/docs/api/PageFunctions.qmd new file mode 100644 index 000000000..c15442848 --- /dev/null +++ b/docs/api/PageFunctions.qmd @@ -0,0 +1,43 @@ +# Page functions + + + +# express.ui.page_opts { #shiny.express.ui.page_opts } + +`express.ui.page_opts(title=MISSING, lang=MISSING, page_fn=MISSING, fillable=MISSING, full_width=MISSING)` + +Set page-level options for the current app. + +The arguments to this function get passed to [](:func:`~shiny.ui.page_auto`). + +## Parameters + +title: [str](`str`) \| [MISSING_TYPE](`shiny.types.MISSING_TYPE`) = MISSING + +: The browser window title (defaults to the host URL of the page). + +lang: [str](`str`) \| [MISSING_TYPE](`shiny.types.MISSING_TYPE`) = MISSING + +: ISO 639-1 language code for the HTML page, such as ``"en"`` or ``"ko"``. This + will be used as the lang in the ```` tag, as in ````. The + default, `None`, results in an empty string. + +fillable: [bool](`bool`) \| [MISSING_TYPE](`shiny.types.MISSING_TYPE`) = MISSING + +: If there is a top-level sidebar or nav, then the value is passed through to the + [](:func:`~shiny.ui.page_sidebar`) or [](:func:`~shiny.ui.page_navbar`) function. + Otherwise, if ``True``, use [](:func:`~shiny.ui.page_fillable`), where the content + fills the window; if ``False`` (the default), the value of ``full_width`` will + determine which page function is used. + +full_width: [bool](`bool`) \| [MISSING_TYPE](`shiny.types.MISSING_TYPE`) = MISSING + +: This has an effect only if there are no sidebars or top-level navs, and + ``fillable`` is ``False``. If this is ``False`` (the default), use use + [](:func:`~shiny.ui.page_fixed`); if ``True``, use [](:func:`~shiny.ui.page_fillable`). + +page_fn: [Callable](`typing.Callable`)\[..., [Tag](`htmltools.Tag`)\] \| None \| [MISSING_TYPE](`shiny.types.MISSING_TYPE`) = MISSING + +: The page function to use. If ``None`` (the default), will automatically choose + one based on the arguments provided. If not ``None``, this will override all + heuristics for choosing page functions. \ No newline at end of file diff --git a/docs/api/Session.qmd b/docs/api/Session.qmd new file mode 100644 index 000000000..91cba0b64 --- /dev/null +++ b/docs/api/Session.qmd @@ -0,0 +1,616 @@ +# Session { #shiny.Session } + +`Session(self, app, id, conn, debug=False)` + +A class representing a user session. + +## Methods + +| Name | Description | +| --- | --- | +| [close](#shiny.Session.close) | Close the session. | +| [download](#shiny.Session.download) | Deprecated. Please use :class:`~shiny.render.download` instead. | +| [dynamic_route](#shiny.Session.dynamic_route) | Register a function to call when a dynamically generated, session-specific, route is requested. Provides a convenient way to serve-up session-dependent values for other clients/applications to consume. | +| [on_ended](#shiny.Session.on_ended) | Registers a function to be called after the client has disconnected. | +| [on_flush](#shiny.Session.on_flush) | Register a function to call before the next reactive flush. | +| [on_flushed](#shiny.Session.on_flushed) | Register a function to call after the next reactive flush. | +| [send_custom_message](#shiny.Session.send_custom_message) | Send a message to the client. | +| [send_input_message](#shiny.Session.send_input_message) | Send an input message to the session. Sends a message to an input on the session's client web page; if the input is present and bound on the page at the time the message is received, then the input binding object's ``receiveMessage(el, message)`` method will be called. This method should generally not be called directly from Shiny apps, but through friendlier wrapper functions like ``ui.update_text()``. | + +### close { #shiny.Session.close } + +`Session.close(code=1001)` + +Close the session. + +#### Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +from datetime import datetime + +from shiny import App, Inputs, Outputs, Session, reactive, ui + +app_ui = ui.page_fluid( + ui.input_action_button("close", "Close the session"), + ui.p( + """If this example is running on the browser (i.e., via shinylive), + closing the session will log a message to the JavaScript console + (open the browser's developer tools to see it). + """ + ), +) + + +def server(input: Inputs, output: Outputs, session: Session): + def log(): + print("Session ended at: " + datetime.now().strftime("%H:%M:%S")) + + session.on_ended(log) + + @reactive.Effect + @reactive.event(input.close) + async def _(): + await session.close() + + +app = App(app_ui, server) + +``` + + + +### download { #shiny.Session.download } + +`Session.download(id=None, filename=None, media_type=None, encoding='utf-8')` + +Deprecated. Please use [](:class:`~shiny.render.download`) instead. + +#### Parameters + +id: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: The name of the download. + +filename: [Optional](`typing.Optional`)\[[str](`str`) \| [Callable](`typing.Callable`)\[\[\], [str](`str`)\]\] = None + +: The filename of the download. + +media_type: None \| [str](`str`) \| [Callable](`typing.Callable`)\[\[\], [str](`str`)\] = None + +: The media type of the download. + +encoding: [str](`str`) = 'utf-8' + +: The encoding of the download. + +#### Returns + +| Type | Description | +|--------------------------------------------------------------------------------------------------------|-------------------------| +| [Callable](`typing.Callable`)\[\[[DownloadHandler](`shiny.session._session.DownloadHandler`)\], None\] | The decorated function. | + +#### Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +import asyncio +import io +import os +from datetime import date +from typing import Any + +import matplotlib.pyplot as plt +import numpy as np + +from shiny import App, Inputs, Outputs, Session, render, ui + + +def make_example(id: str, label: str, title: str, desc: str, extra: Any = None): + return ui.column( + 4, + ui.div( + {"class": "card mb-4"}, + ui.div(title, class_="card-header"), + ui.div( + {"class": "card-body"}, + ui.p(desc, class_="card-text text-muted"), + extra, + ui.download_button(id, label, class_="btn-primary"), + ), + ), + ) + + +app_ui = ui.page_fluid( + ui.row( + make_example( + "download1", + label="Download CSV", + title="Simple case", + desc="Downloads a pre-existing file, using its existing name on disk.", + ), + ), + ui.row( + make_example( + "download2", + label="Download plot", + title="Dynamic data generation", + desc="Downloads a PNG that's generated on the fly.", + extra=[ + ui.input_text("title", "Plot title", "Random scatter plot"), + ui.input_slider( + "num_points", "Number of data points", min=1, max=100, value=50 + ), + ], + ), + ), + ui.row( + make_example( + "download3", + "Download", + "Dynamic filename", + "Demonstrates that filenames can be generated on the fly (and use Unicode characters!).", + ), + ), + ui.row( + make_example( + "download4", + "Download", + "Failed downloads", + "Throws an error in the download handler, download should not succeed.", + ), + ), + ui.row( + make_example( + "download5", + "Download", + "Undefined download", + "This button doesn't have corresponding server code registered to it, download should result in 404 error", + ), + ), +) + + +def server(input: Inputs, output: Outputs, session: Session): + @render.download() + def download1(): + """ + This is the simplest case. The implementation simply returns the name of a file. + Note that the function name (`download1`) determines which download_button() + corresponds to this function. + """ + + path = os.path.join(os.path.dirname(__file__), "mtcars.csv") + return path + + @render.download(filename="image.png") + def download2(): + """ + Another way to implement a file download is by yielding bytes; either all at + once, like in this case, or by yielding multiple times. When using this + approach, you should pass a filename argument to @render.download, which + determines what the browser will name the downloaded file. + """ + + print(input.num_points()) + x = np.random.uniform(size=input.num_points()) + y = np.random.uniform(size=input.num_points()) + plt.figure() + plt.scatter(x, y) + plt.title(input.title()) + with io.BytesIO() as buf: + plt.savefig(buf, format="png") + yield buf.getvalue() + + @render.download( + filename=lambda: f"æ–°åž‹-{date.today().isoformat()}-{np.random.randint(100,999)}.csv" + ) + async def download3(): + await asyncio.sleep(0.25) + yield "one,two,three\n" + yield "æ–°,1,2\n" + yield "åž‹,4,5\n" + + @output(id="download4") + @render.download(filename="failuretest.txt") + async def _(): + yield "hello" + raise Exception("This error was caused intentionally") + + +app = App(app_ui, server) + +## file: mtcars.csv +mpg,cyl,disp,hp,drat,wt,qsec,vs,am,gear,carb +21,6,160,110,3.9,2.62,16.46,0,1,4,4 +21,6,160,110,3.9,2.875,17.02,0,1,4,4 +22.8,4,108,93,3.85,2.32,18.61,1,1,4,1 +21.4,6,258,110,3.08,3.215,19.44,1,0,3,1 +18.7,8,360,175,3.15,3.44,17.02,0,0,3,2 +18.1,6,225,105,2.76,3.46,20.22,1,0,3,1 +14.3,8,360,245,3.21,3.57,15.84,0,0,3,4 +24.4,4,146.7,62,3.69,3.19,20,1,0,4,2 +22.8,4,140.8,95,3.92,3.15,22.9,1,0,4,2 +19.2,6,167.6,123,3.92,3.44,18.3,1,0,4,4 +17.8,6,167.6,123,3.92,3.44,18.9,1,0,4,4 +16.4,8,275.8,180,3.07,4.07,17.4,0,0,3,3 +17.3,8,275.8,180,3.07,3.73,17.6,0,0,3,3 +15.2,8,275.8,180,3.07,3.78,18,0,0,3,3 +10.4,8,472,205,2.93,5.25,17.98,0,0,3,4 +10.4,8,460,215,3,5.424,17.82,0,0,3,4 +14.7,8,440,230,3.23,5.345,17.42,0,0,3,4 +32.4,4,78.7,66,4.08,2.2,19.47,1,1,4,1 +30.4,4,75.7,52,4.93,1.615,18.52,1,1,4,2 +33.9,4,71.1,65,4.22,1.835,19.9,1,1,4,1 +21.5,4,120.1,97,3.7,2.465,20.01,1,0,3,1 +15.5,8,318,150,2.76,3.52,16.87,0,0,3,2 +15.2,8,304,150,3.15,3.435,17.3,0,0,3,2 +13.3,8,350,245,3.73,3.84,15.41,0,0,3,4 +19.2,8,400,175,3.08,3.845,17.05,0,0,3,2 +27.3,4,79,66,4.08,1.935,18.9,1,1,4,1 +26,4,120.3,91,4.43,2.14,16.7,0,1,5,2 +30.4,4,95.1,113,3.77,1.513,16.9,1,1,5,2 +15.8,8,351,264,4.22,3.17,14.5,0,1,5,4 +19.7,6,145,175,3.62,2.77,15.5,0,1,5,6 +15,8,301,335,3.54,3.57,14.6,0,1,5,8 +21.4,4,121,109,4.11,2.78,18.6,1,1,4,2 + +``` + + + +### dynamic_route { #shiny.Session.dynamic_route } + +`Session.dynamic_route(name, handler)` + +Register a function to call when a dynamically generated, session-specific, +route is requested. + +Provides a convenient way to serve-up session-dependent values for other +clients/applications to consume. + +#### Parameters + +name: [str](`str`) + +: A name for the route (used to determine part of the URL path). + +handler: [DynamicRouteHandler](`shiny.session._session.DynamicRouteHandler`) + +: The function to call when a request is made to the route. This function + should take a single argument (a [](:class:`starlette.requests.Request`) object) + and return a [](:class:`starlette.types.ASGIApp`) object. + +#### Returns + +| Type | Description | +|--------------|-----------------------------| +| [str](`str`) | The URL path for the route. | + +#### Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +from starlette.requests import Request +from starlette.responses import JSONResponse + +from shiny import App, Inputs, Outputs, Session, reactive, ui + +app_ui = ui.page_fluid( + ui.input_action_button("serve", "Click to serve"), ui.div(id="messages") +) + + +def server(input: Inputs, output: Outputs, session: Session): + @reactive.Effect + @reactive.event(input.serve) + def _(): + async def my_handler(request: Request) -> JSONResponse: + return JSONResponse({"n_clicks": input.serve()}, status_code=200) + + path = session.dynamic_route("my_handler", my_handler) + + print("Serving at: ", path) + + ui.insert_ui( + ui.tags.script( + f""" + fetch('{path}') + .then(r => r.json()) + .then(x => {{ $('#messages').text(`Clicked ${{x.n_clicks}} times`); }}); + """ + ), + selector="body", + ) + + +app = App(app_ui, server) + +``` + + + +### on_ended { #shiny.Session.on_ended } + +`Session.on_ended(fn)` + +Registers a function to be called after the client has disconnected. + +#### Parameters + +fn: [Callable](`typing.Callable`)\[\[\], None\] \| [Callable](`typing.Callable`)\[\[\], [Awaitable](`typing.Awaitable`)\[None\]\] + +: The function to call. + +#### Returns + +| Type | Description | +|---------------------------------------------|---------------------------------------------------------| +| [Callable](`typing.Callable`)\[\[\], None\] | A function that can be used to cancel the registration. | + +#### Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +from datetime import datetime + +from shiny import App, Inputs, Outputs, Session, reactive, ui + +app_ui = ui.page_fluid( + ui.input_action_button("close", "Close the session"), +) + + +def server(input: Inputs, output: Outputs, session: Session): + def log(): + print("Session ended at: " + datetime.now().strftime("%H:%M:%S")) + + session.on_ended(log) + + @reactive.Effect + @reactive.event(input.close) + async def _(): + await session.close() + + +app = App(app_ui, server) + +``` + + + +### on_flush { #shiny.Session.on_flush } + +`Session.on_flush(fn, once=True)` + +Register a function to call before the next reactive flush. + +#### Parameters + +fn: [Callable](`typing.Callable`)\[\[\], None\] \| [Callable](`typing.Callable`)\[\[\], [Awaitable](`typing.Awaitable`)\[None\]\] + +: The function to call. + +once: [bool](`bool`) = True + +: Whether to call the function only once or on every flush. + +#### Returns + +| Type | Description | +|---------------------------------------------|---------------------------------------------------------| +| [Callable](`typing.Callable`)\[\[\], None\] | A function that can be used to cancel the registration. | + +#### Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +from datetime import datetime + +from shiny import App, Inputs, Outputs, Session, render, ui + +app_ui = ui.page_fluid( + ui.input_action_button("flush", "Trigger flush"), + ui.output_ui("n_clicks"), + ui.div(id="flush_time"), +) + + +def server(input: Inputs, output: Outputs, session: Session): + def log(): + msg = "A reactive flush occurred at " + datetime.now().strftime("%H:%M:%S:%f") + print(msg) + ui.insert_ui( + ui.p(msg), + selector="#flush_time", + ) + + session.on_flush(log, once=False) + + @render.ui + def n_clicks(): + return "Number of clicks: " + str(input.flush()) + + +app = App(app_ui, server) + +``` + + + +### on_flushed { #shiny.Session.on_flushed } + +`Session.on_flushed(fn, once=True)` + +Register a function to call after the next reactive flush. + +#### Parameters + +fn: [Callable](`typing.Callable`)\[\[\], None\] \| [Callable](`typing.Callable`)\[\[\], [Awaitable](`typing.Awaitable`)\[None\]\] + +: The function to call. + +once: [bool](`bool`) = True + +: Whether to call the function only once or on every flush. + +#### Returns + +| Type | Description | +|---------------------------------------------|---------------------------------------------------------| +| [Callable](`typing.Callable`)\[\[\], None\] | A function that can be used to cancel the registration. | + +#### Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +from datetime import datetime + +from shiny import App, Inputs, Outputs, Session, render, ui + +app_ui = ui.page_fluid( + ui.input_action_button("flush", "Trigger flush"), + ui.output_ui("n_clicks"), + ui.div(id="flush_time"), +) + + +def server(input: Inputs, output: Outputs, session: Session): + def log(): + msg = "A reactive flush occurred at " + datetime.now().strftime("%H:%M:%S:%f") + print(msg) + ui.insert_ui( + ui.p(msg), + selector="#flush_time", + ) + + session.on_flushed(log, once=False) + + @render.ui + def n_clicks(): + return "Number of clicks: " + str(input.flush()) + + +app = App(app_ui, server) + +``` + + + +### send_custom_message { #shiny.Session.send_custom_message } + +`Session.send_custom_message(type, message)` + +Send a message to the client. + +#### Parameters + +type: [str](`str`) + +: The type of message to send. + +message: [dict](`dict`)\[[str](`str`), [object](`object`)\] + +: The message to send. + +#### Note + +Sends messages to the client which can be handled in JavaScript with +``Shiny.addCustomMessageHandler(type, function(message){...})``. Once the +message handler is added, it will be invoked each time ``send_custom_message()`` +is called on the server. + +#### Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +from shiny import App, Inputs, Outputs, Session, reactive, ui + +app_ui = ui.page_fluid( + ui.input_text("msg", "Enter a message"), + ui.input_action_button("submit", "Submit the message"), + # It'd be better to use ui.insert_ui() in order to implement this kind of + # functionality...this is just a basic demo of how custom message handling works. + ui.tags.div(id="messages"), + ui.tags.script( + """ + $(function() { + Shiny.addCustomMessageHandler("append_msg", function(message) { + $("

").text(message.msg).appendTo("#messages"); + }); + }); + """ + ), +) + + +def server(input: Inputs, output: Outputs, session: Session): + @reactive.Effect + @reactive.event(input.submit) + async def _(): + await session.send_custom_message("append_msg", {"msg": input.msg()}) + + +app = App(app_ui, server, debug=True) + +``` + + + +### send_input_message { #shiny.Session.send_input_message } + +`Session.send_input_message(id, message)` + +Send an input message to the session. + +Sends a message to an input on the session's client web page; if the input is +present and bound on the page at the time the message is received, then the +input binding object's ``receiveMessage(el, message)`` method will be called. +This method should generally not be called directly from Shiny apps, but through +friendlier wrapper functions like ``ui.update_text()``. + +#### Parameters + +id: [str](`str`) + +: An id matching the id of an input to update. + +message: [dict](`dict`)\[[str](`str`), [object](`object`)\] + +: The message to send. \ No newline at end of file diff --git a/docs/api/TagTypes.qmd b/docs/api/TagTypes.qmd new file mode 100644 index 000000000..e8b8053b4 --- /dev/null +++ b/docs/api/TagTypes.qmd @@ -0,0 +1,427 @@ +# Tag types + + + +# htmltools.Tag { #htmltools.Tag } + +`Tag(self, _name, *args, _add_ws=True, **kwargs)` + +The HTML tag class. + +A Tag object consists of a name, attributes, and children. The name is a string, the +attributes are held in a TagAttrDict object, and the children are held in a TagList +object. + +This class usually should not be instantiated directly. Instead, use the tag wrapper +functions in ``htmltools.tags``, like ``div()`` or ``a()``. + +## Parameters + +_name: [str](`str`) + +: The tag's name. + +*args: [TagChild](`htmltools._core.TagChild`) \| [TagAttrs](`htmltools._core.TagAttrs`) = () + +: Children for the tag. + +_add_ws: [TagAttrValue](`htmltools._core.TagAttrValue`) = True + +: A ``bool`` indicating whether to add whitespace surrounding the tag (see Note + for details). + +**kwargs: [TagAttrValue](`htmltools._core.TagAttrValue`) = {} + +: Attributes for the tag. + +## Attributes + +| Name | Type | Description | +|----------|----------------------------------------------|-----------------------| +| name | [str](`str`) | The tag's name. | +| attrs | [TagAttrDict](`htmltools._core.TagAttrDict`) | The tag's attributes. | +| children | [TagList](`htmltools._core.TagList`) | The tag's children. | + +## Note + +The `_add_ws` parameter controls whether whitespace is added around the tag. Inline +tags (like `span()` and `a()`) default to `False` and block tags (like `div()` and +`p()`) default to `True`. + +When a tag with `_add_ws=True` is rendered to HTML, whitespace (including +indentation) is added before the opening tag (like `

`), after the closing tag +(like `
`), and also between the opening tag and its first child. This usually +results in formatting that is easier to read. + +The only times that whitespace is not added around tags is when two sibling tags +have `_add_ws=False`, or when a tag and its first child both have `_add_ws=False`. +Bare strings are treated as children with `_add_ws=False`. + +If you need fine control over whitespace in the output HTML, you can create tags +with `_add_ws=False` and manually add whitespace, like `div("\n", span("a"), +_add_ws=False)`. + +## Examples + +```python +>>> from htmltools import div +>>> x = div("hello", id="foo", class_="bar") +>>> x +
hello
+>>> x.show() +``` + +## Methods + +| Name | Description | +| --- | --- | +| [add_class](#htmltools.Tag.add_class) | Add a class value to the HTML class attribute. | +| [add_style](#htmltools.Tag.add_style) | Add a style value(s) to the HTML style attribute. | +| [append](#htmltools.Tag.append) | Append tag children to the end of the list. | +| [extend](#htmltools.Tag.extend) | Extend the children by appending an iterable of children. | +| [get_dependencies](#htmltools.Tag.get_dependencies) | Get any HTML dependencies. | +| [get_html_string](#htmltools.Tag.get_html_string) | Get the HTML string representation of the tag. | +| [has_class](#htmltools.Tag.has_class) | Check if the tag has a particular class value. | +| [insert](#htmltools.Tag.insert) | Insert tag children before a given index. | +| [remove_class](#htmltools.Tag.remove_class) | Remove a class value from the HTML class attribute. | +| [render](#htmltools.Tag.render) | Get string representation as well as its HTML dependencies. | +| [save_html](#htmltools.Tag.save_html) | Save to a HTML file. | +| [show](#htmltools.Tag.show) | Preview as a complete HTML document. | +| [tagify](#htmltools.Tag.tagify) | Convert any tagifiable children to Tag/TagList objects. | + +### add_class { #htmltools.Tag.add_class } + +`Tag.add_class(class_, *, prepend=False)` + +Add a class value to the HTML class attribute. + +#### Parameters + +class_: [str](`str`) + +: The class name to add. + +prepend: [bool](`bool`) = False + +: Bool that determines if the `class` is added to the beginning or end of the + class attribute. + +#### Returns + +| Type | Description | +|--------------------------------|-------------------| +| [TagT](`htmltools._core.TagT`) | The modified tag. | + +### add_style { #htmltools.Tag.add_style } + +`Tag.add_style(style, *, prepend=False)` + +Add a style value(s) to the HTML style attribute. + +#### Parameters + +style: [str](`str`) + +: CSS properties and values already properly formatted. Each should already + contain trailing semicolons. + +prepend: [bool](`bool`) = False + +: Bool that determines if the `style` is added to the beginning or end of the + style attribute. + +#### See Also + +[](:func:`~htmltools.css`) + +#### Returns + +| Type | Description | +|--------------------------------|-------------------| +| [TagT](`htmltools._core.TagT`) | The modified tag. | + +### append { #htmltools.Tag.append } + +`Tag.append(*args)` + +Append tag children to the end of the list. + +### extend { #htmltools.Tag.extend } + +`Tag.extend(x)` + +Extend the children by appending an iterable of children. + +### get_dependencies { #htmltools.Tag.get_dependencies } + +`Tag.get_dependencies(dedup=True)` + +Get any HTML dependencies. + +### get_html_string { #htmltools.Tag.get_html_string } + +`Tag.get_html_string(indent=0, eol='\n')` + +Get the HTML string representation of the tag. + +#### Parameters + +indent: [int](`int`) = 0 + +: The number of spaces to indent the tag. + +eol: [str](`str`) = '\n' + +: The end-of-line character(s). + +### has_class { #htmltools.Tag.has_class } + +`Tag.has_class(class_)` + +Check if the tag has a particular class value. + +#### Parameters + +class_: [str](`str`) + +: The class name to check for. + +#### Returns + +| Type | Description | +|----------------|---------------------------------------------------------| +| [bool](`bool`) | ``True`` if the tag has the class, ``False`` otherwise. | + +### insert { #htmltools.Tag.insert } + +`Tag.insert(index, x)` + +Insert tag children before a given index. + +### remove_class { #htmltools.Tag.remove_class } + +`Tag.remove_class(class_)` + +Remove a class value from the HTML class attribute. + +#### Parameters + +class_: [str](`str`) + +: The class name to remove. + +#### Returns + +| Type | Description | +|--------------------------------|-------------------| +| [TagT](`htmltools._core.TagT`) | The modified tag. | + +### render { #htmltools.Tag.render } + +`Tag.render()` + +Get string representation as well as its HTML dependencies. + +### save_html { #htmltools.Tag.save_html } + +`Tag.save_html(file, *, libdir='lib', include_version=True)` + +Save to a HTML file. + +#### Parameters + +file: [str](`str`) + +: The file to save to. + +libdir: [Optional](`typing.Optional`)\[[str](`str`)\] = 'lib' + +: The directory to save the dependencies to. + +include_version: [bool](`bool`) = True + +: Whether to include the version number in the dependency folder name. + +#### Returns + +| Type | Description | +|--------------------------------------|---------------| +| The path to the generated HTML file. | | + +### show { #htmltools.Tag.show } + +`Tag.show(renderer='auto')` + +Preview as a complete HTML document. + +#### Parameters + +renderer: [Literal](`typing.Literal`)\['auto', 'ipython', 'browser'\] = 'auto' + +: The renderer to use. + +### tagify { #htmltools.Tag.tagify } + +`Tag.tagify()` + +Convert any tagifiable children to Tag/TagList objects. + +# htmltools.TagAttrs { #htmltools.TagAttrs } + +`TagAttrs` + +For dictionaries of tag attributes (e.g., `{"id": "foo"}`), which can be passed as +unnamed arguments to Tag functions like `div()`. + +# htmltools.TagAttrValue { #htmltools.TagAttrValue } + +`TagAttrValue` + +Types that can be passed in as attributes to `Tag` functions. These values will be +converted to strings before being stored as tag attributes. + +# htmltools.TagChild { #htmltools.TagChild } + +`TagChild` + +Types of objects that can be passed as children to Tag functions like `div()`. The `Tag` +functions and the `TagList()` constructor can accept these as unnamed arguments; they +will be flattened and normalized to `TagNode` objects. + +# htmltools.TagList { #htmltools.TagList } + +`TagList(self, *args)` + +Create an HTML tag list (i.e., a fragment of HTML) + +## Parameters + +*args: [TagChild](`htmltools._core.TagChild`) = () + +: The tag children to add to the list. + +## Examples + +```python +>>> from htmltools import TagList, div +>>> TagList("hello", div(id="foo", class_="bar")) +hello +
+``` + +## Methods + +| Name | Description | +| --- | --- | +| [append](#htmltools.TagList.append) | Append tag children to the end of the list. | +| [extend](#htmltools.TagList.extend) | Extend the children by appending an iterable of children. | +| [get_dependencies](#htmltools.TagList.get_dependencies) | Get any dependencies needed to render the HTML. | +| [get_html_string](#htmltools.TagList.get_html_string) | Return the HTML string for this tag list. | +| [insert](#htmltools.TagList.insert) | Insert tag children before a given index. | +| [render](#htmltools.TagList.render) | Get string representation as well as its HTML dependencies. | +| [save_html](#htmltools.TagList.save_html) | Save to a HTML file. | +| [show](#htmltools.TagList.show) | Preview as a complete HTML document. | +| [tagify](#htmltools.TagList.tagify) | Convert any tagifiable children to Tag/TagList objects. | + +### append { #htmltools.TagList.append } + +`TagList.append(*args)` + +Append tag children to the end of the list. + +### extend { #htmltools.TagList.extend } + +`TagList.extend(x)` + +Extend the children by appending an iterable of children. + +### get_dependencies { #htmltools.TagList.get_dependencies } + +`TagList.get_dependencies(dedup=True)` + +Get any dependencies needed to render the HTML. + +#### Parameters + +dedup: [bool](`bool`) = True + +: Whether to deduplicate the dependencies. + +### get_html_string { #htmltools.TagList.get_html_string } + +`TagList.get_html_string(indent=0, eol='\n', *, add_ws=True, _escape_strings=True)` + +Return the HTML string for this tag list. + +#### Parameters + +indent: [int](`int`) = 0 + +: Number of spaces to indent each line of the HTML. + +eol: [str](`str`) = '\n' + +: End-of-line character(s). + +add_ws: [bool](`bool`) = True + +: Whether to add whitespace between the opening tag and the first child. If + either this is True, or the child's add_ws attribute is True, then + whitespace will be added; if they are both False, then no whitespace will be + added. + +### insert { #htmltools.TagList.insert } + +`TagList.insert(index, x)` + +Insert tag children before a given index. + +### render { #htmltools.TagList.render } + +`TagList.render()` + +Get string representation as well as its HTML dependencies. + +### save_html { #htmltools.TagList.save_html } + +`TagList.save_html(file, *, libdir='lib', include_version=True)` + +Save to a HTML file. + +#### Parameters + +file: [str](`str`) + +: The file to save to. + +libdir: [Optional](`typing.Optional`)\[[str](`str`)\] = 'lib' + +: The directory to save the dependencies to. + +include_version: [bool](`bool`) = True + +: Whether to include the version number in the dependency folder name. + +#### Returns + +| Type | Description | +|--------------|--------------------------------------| +| [str](`str`) | The path to the generated HTML file. | + +### show { #htmltools.TagList.show } + +`TagList.show(renderer='auto')` + +Preview as a complete HTML document. + +#### Parameters + +renderer: [Literal](`typing.Literal`)\['auto', 'ipython', 'browser'\] = 'auto' + +: The renderer to use. + +### tagify { #htmltools.TagList.tagify } + +`TagList.tagify()` + +Convert any tagifiable children to Tag/TagList objects. \ No newline at end of file diff --git a/docs/api/_sidebar.yml b/docs/api/_sidebar.yml new file mode 100644 index 000000000..6f1aadd21 --- /dev/null +++ b/docs/api/_sidebar.yml @@ -0,0 +1,203 @@ +website: + sidebar: + - contents: + - api/index.qmd + - contents: + - api/ui.page_sidebar.qmd + - api/ui.page_navbar.qmd + - api/ui.page_sidebar.qmd + - api/ui.page_fillable.qmd + - api/ui.page_fluid.qmd + - api/ui.page_fixed.qmd + - api/ui.page_bootstrap.qmd + - api/ui.page_auto.qmd + - api/ui.page_output.qmd + section: Page containers + - contents: + - api/ui.sidebar.qmd + - api/ui.layout_sidebar.qmd + - api/ui.layout_columns.qmd + - api/ui.layout_column_wrap.qmd + - api/ui.card.qmd + - api/ui.card_header.qmd + - api/ui.card_footer.qmd + - api/ui.popover.qmd + - api/ui.tooltip.qmd + - api/ui.accordion.qmd + - api/ui.accordion_panel.qmd + - api/ui.column.qmd + - api/ui.row.qmd + section: UI Layouts + - contents: + - api/ui.input_select.qmd + - api/ui.input_selectize.qmd + - api/ui.input_slider.qmd + - api/ui.input_date.qmd + - api/ui.input_date_range.qmd + - api/ui.input_checkbox.qmd + - api/ui.input_checkbox_group.qmd + - api/ui.input_switch.qmd + - api/ui.input_radio_buttons.qmd + - api/ui.input_numeric.qmd + - api/ui.input_text.qmd + - api/ui.input_text_area.qmd + - api/ui.input_password.qmd + - api/ui.input_action_button.qmd + - api/ui.input_action_link.qmd + section: UI Inputs + - contents: + - api/ui.value_box.qmd + - api/ui.value_box_theme.qmd + - api/ui.showcase_bottom.qmd + - api/ui.showcase_left_center.qmd + - api/ui.showcase_top_right.qmd + - api/ui.ValueBoxTheme.qmd + - api/ui.ShowcaseLayout.qmd + section: Value boxes + - contents: + - api/ui.nav_panel.qmd + - api/ui.nav_spacer.qmd + - api/ui.nav_menu.qmd + - api/ui.nav_control.qmd + - api/ui.navset_bar.qmd + - api/ui.navset_tab.qmd + - api/ui.navset_pill.qmd + - api/ui.navset_underline.qmd + - api/ui.navset_card_tab.qmd + - api/ui.navset_card_pill.qmd + - api/ui.navset_card_underline.qmd + - api/ui.navset_pill_list.qmd + - api/ui.navset_hidden.qmd + section: Navigation (tab) panels + - contents: + - api/ui.panel_absolute.qmd + - api/ui.panel_fixed.qmd + - api/ui.panel_conditional.qmd + - api/ui.panel_title.qmd + - api/ui.panel_well.qmd + section: UI panels + - contents: + - api/ui.input_file.qmd + - api/ui.download_button.qmd + section: Uploads & downloads + - contents: + - api/ui.HTML.qmd + - api/ui.TagList.qmd + - api/ui.tags.qmd + - api/ui.markdown.qmd + - api/ui.include_css.qmd + - api/ui.include_js.qmd + - api/ui.insert_ui.qmd + - api/ui.remove_ui.qmd + - api/ui.fill.as_fillable_container.qmd + - api/ui.fill.as_fill_item.qmd + - api/ui.fill.remove_all_fill.qmd + - api/ui.css.as_css_unit.qmd + - api/ui.css.as_css_padding.qmd + section: Custom UI + - contents: + - api/ui.update_select.qmd + - api/ui.update_selectize.qmd + - api/ui.update_slider.qmd + - api/ui.update_date.qmd + - api/ui.update_date_range.qmd + - api/ui.update_checkbox.qmd + - api/ui.update_checkbox_group.qmd + - api/ui.update_switch.qmd + - api/ui.update_radio_buttons.qmd + - api/ui.update_numeric.qmd + - api/ui.update_text.qmd + - api/ui.update_text_area.qmd + - api/ui.update_navs.qmd + section: Update inputs + - contents: + - api/ui.update_sidebar.qmd + - api/ui.update_tooltip.qmd + - api/ui.update_popover.qmd + - api/ui.update_accordion.qmd + - api/ui.update_accordion_panel.qmd + - api/ui.insert_accordion_panel.qmd + - api/ui.remove_accordion_panel.qmd + section: Update UI Layouts + - contents: + - api/ui.output_plot.qmd + - api/ui.output_image.qmd + - api/ui.output_table.qmd + - api/ui.output_data_frame.qmd + - api/ui.output_text.qmd + - api/ui.output_text_verbatim.qmd + - api/ui.output_ui.qmd + - api/render.plot.qmd + - api/render.image.qmd + - api/render.table.qmd + - api/render.text.qmd + - api/render.ui.qmd + - api/render.data_frame.qmd + - api/render.DataGrid.qmd + - api/render.DataTable.qmd + - api/OutputRender.qmd + section: Rendering outputs + - contents: + - api/reactive.calc.qmd + - api/reactive.effect.qmd + - api/reactive.value.qmd + - api/reactive.Calc.qmd + - api/reactive.Effect.qmd + - api/reactive.Value.qmd + - api/reactive.event.qmd + - api/reactive.isolate.qmd + - api/reactive.invalidate_later.qmd + - api/reactive.flush.qmd + - api/reactive.poll.qmd + - api/reactive.file_reader.qmd + - api/reactive.lock.qmd + - api/req.qmd + section: Reactive programming + - contents: + - api/run_app.qmd + - api/App.qmd + - api/Inputs.qmd + - api/Outputs.qmd + - api/Session.qmd + section: Create and run applications + - contents: + - api/ui.help_text.qmd + - api/ui.notification_show.qmd + - api/ui.notification_remove.qmd + - api/ui.modal.qmd + - api/ui.modal_show.qmd + - api/ui.modal_remove.qmd + - api/ui.modal_button.qmd + - api/ui.Progress.qmd + section: Display messages + - contents: + - api/module.ui.qmd + - api/module.server.qmd + section: Modules + - contents: + - api/session.get_current_session.qmd + - api/session.require_active_session.qmd + - api/session.session_context.qmd + - api/reactive.get_current_context.qmd + - api/input_handler.input_handlers.qmd + section: Developer facing tools + - contents: + - api/MiscTypes.qmd + - api/TagTypes.qmd + - api/ExceptionTypes.qmd + section: Types + - contents: + - api/ContextManagerComponents.qmd + - api/PageFunctions.qmd + section: Shiny Express + - contents: + - api/ui.panel_main.qmd + - api/ui.panel_sidebar.qmd + - api/ui.nav.qmd + - api/render.transformer.resolve_value_fn.qmd + section: Deprecated + - contents: + - api/ExCard.qmd + section: Experimental + id: api + - id: dummy-sidebar diff --git a/docs/api/index.qmd b/docs/api/index.qmd new file mode 100644 index 000000000..7d44bd5af --- /dev/null +++ b/docs/api/index.qmd @@ -0,0 +1,298 @@ +# Function reference {.doc .doc-index} + +## Page containers + +Create a user interface page container. + +| | | +| --- | --- | +| [ui.page_sidebar](ui.page_sidebar.qmd#shiny.ui.page_sidebar) | Create a page with a sidebar and a title. | +| [ui.page_navbar](ui.page_navbar.qmd#shiny.ui.page_navbar) | Create a page with a navbar and a title. | +| [ui.page_sidebar](ui.page_sidebar.qmd#shiny.ui.page_sidebar) | Create a page with a sidebar and a title. | +| [ui.page_fillable](ui.page_fillable.qmd#shiny.ui.page_fillable) | Create a fillable page. | +| [ui.page_fluid](ui.page_fluid.qmd#shiny.ui.page_fluid) | Create a fluid page. | +| [ui.page_fixed](ui.page_fixed.qmd#shiny.ui.page_fixed) | Create a fixed page. | +| [ui.page_bootstrap](ui.page_bootstrap.qmd#shiny.ui.page_bootstrap) | Create a Bootstrap UI page container. | +| [ui.page_auto](ui.page_auto.qmd#shiny.ui.page_auto) | A page container which automatically decides which page function to use. If there is a top-level nav, this will use :func:`~shiny.ui.page_navbar`. If not, and there is a top-level sidebar, this will use :func:`~shiny.ui.page_sidebar`. If there are neither top-level navs nor sidebars, this will use the ``fillable`` and ``full_width`` arguments to determine which page function to use. | +| [ui.page_output](ui.page_output.qmd#shiny.ui.page_output) | Create a page container where the entire body is a UI output. | + +## UI Layouts + +Control the layout of multiple UI components. + +| | | +| --- | --- | +| [ui.sidebar](ui.sidebar.qmd#shiny.ui.sidebar) | Sidebar element Create a collapsing sidebar layout by providing a `sidebar()` object to the `sidebar=` argument of: * :func:`~shiny.ui.layout_sidebar` * Creates a sidebar layout component which can be dropped inside any Shiny UI page method (e.g. :func:`~shiny.ui.page_fillable`) or :func:`~shiny.ui.card` context. * :func:`~shiny.ui.navset_bar`, :func:`~shiny.ui.navset_card_tab`, and :func:`~shiny.ui.navset_card_pill` * Creates a multi page/tab UI with a singular `sidebar()` (which is shown on every page/tab). | +| [ui.layout_sidebar](ui.layout_sidebar.qmd#shiny.ui.layout_sidebar) | Sidebar layout Create a sidebar layout component which can be dropped inside any Shiny UI page method (e.g. :func:`~shiny.shiny.ui.page_fillable`) or :func:`~shiny.ui.card` context. | +| [ui.layout_columns](ui.layout_columns.qmd#shiny.ui.layout_columns) | Create responsive, column-based grid layouts, based on a 12-column grid. | +| [ui.layout_column_wrap](ui.layout_column_wrap.qmd#shiny.ui.layout_column_wrap) | A grid-like, column-first layout Wraps a 1d sequence of UI elements into a 2d grid. The number of columns (and rows) in the grid depends on the column width and the size of the display. | +| [ui.card](ui.card.qmd#shiny.ui.card) | A Bootstrap card component A general purpose container for grouping related UI elements together with a border and optional padding. To learn more about `card()`s, see [this article](https://rstudio.github.io/bslib/articles/cards.html). | +| [ui.card_header](ui.card_header.qmd#shiny.ui.card_header) | Card header container A general container for the "header" of a :func:`~shiny.ui.card`. This component is designed to be provided as a direct child to :func:`~shiny.ui.card`. The header has a different background color and border than the rest of the card. | +| [ui.card_footer](ui.card_footer.qmd#shiny.ui.card_footer) | Card footer container A general container for the "footer" of a :func:`~shiny.ui.card`. This component is designed to be provided as a direct child to :func:`~shiny.ui.card`. The footer has a different background color and border than the rest of the card. | +| [ui.popover](ui.popover.qmd#shiny.ui.popover) | Add a popover to a UI element. Display additional information when clicking on a UI element (typically a button). | +| [ui.tooltip](ui.tooltip.qmd#shiny.ui.tooltip) | Add a tooltip to a UI element. Display additional information when focusing (or hovering over) a UI element. | +| [ui.accordion](ui.accordion.qmd#shiny.ui.accordion) | Create a vertically collapsing accordion. | +| [ui.accordion_panel](ui.accordion_panel.qmd#shiny.ui.accordion_panel) | Single accordion panel. | +| [ui.column](ui.column.qmd#shiny.ui.column) | Responsive row-column based layout See :func:`~shiny.ui.row` for more information. | +| [ui.row](ui.row.qmd#shiny.ui.row) | Responsive row-column based layout Layout UI components using Bootstrap's grid layout system. Use ``row()`` to group elements that should appear on the same line (if the browser has adequate width) and :func:`~shiny.ui.column` to define how much horizontal space within a 12-unit wide grid each on of these elements should occupy. See the [layout guide](https://shiny.posit.co/articles/layout-guide.html) for more context and examples. (The article is about Shiny for R, but the general principles are the same.) | + +## UI Inputs + +Create UI that prompts the user for input values or interaction. + +| | | +| --- | --- | +| [ui.input_select](ui.input_select.qmd#shiny.ui.input_select) | Create a select list that can be used to choose a single or multiple items from a list of values. | +| [ui.input_selectize](ui.input_selectize.qmd#shiny.ui.input_selectize) | Create a select list that can be used to choose a single or multiple items from a list of values. | +| [ui.input_slider](ui.input_slider.qmd#shiny.ui.input_slider) | Constructs a slider widget to select a number, date, or date-time from a range. | +| [ui.input_date](ui.input_date.qmd#shiny.ui.input_date) | Creates a text input which, when clicked on, brings up a calendar that the user can click on to select dates. | +| [ui.input_date_range](ui.input_date_range.qmd#shiny.ui.input_date_range) | Creates a pair of text inputs which, when clicked on, bring up calendars that the user can click on to select dates. | +| [ui.input_checkbox](ui.input_checkbox.qmd#shiny.ui.input_checkbox) | Create a checkbox that can be used to specify logical values. | +| [ui.input_checkbox_group](ui.input_checkbox_group.qmd#shiny.ui.input_checkbox_group) | Create a group of checkboxes that can be used to toggle multiple choices independently. | +| [ui.input_switch](ui.input_switch.qmd#shiny.ui.input_switch) | Create a switch that can be used to specify logical values. Similar to :func:`~shiny.ui.input_checkbox`, but implies to the user that the change will take effect immediately. | +| [ui.input_radio_buttons](ui.input_radio_buttons.qmd#shiny.ui.input_radio_buttons) | Create a set of radio buttons used to select an item from a list. | +| [ui.input_numeric](ui.input_numeric.qmd#shiny.ui.input_numeric) | Create an input control for entry of numeric values. | +| [ui.input_text](ui.input_text.qmd#shiny.ui.input_text) | Create an input control for entry of text values. | +| [ui.input_text_area](ui.input_text_area.qmd#shiny.ui.input_text_area) | Create a textarea input control for entry of unstructured text values. | +| [ui.input_password](ui.input_password.qmd#shiny.ui.input_password) | Create an password control for entry of passwords. | +| [ui.input_action_button](ui.input_action_button.qmd#shiny.ui.input_action_button) | Creates an action button whose value is initially zero, and increments by one each time it is pressed. | +| [ui.input_action_link](ui.input_action_link.qmd#shiny.ui.input_action_link) | Creates a link whose value is initially zero, and increments by one each time it is pressed. | + +## Value boxes + +Prominently display a value and label in a box that can be expanded to show more information. + +| | | +| --- | --- | +| [ui.value_box](ui.value_box.qmd#shiny.ui.value_box) | Value box An opinionated (:func:`~shiny.ui.card`-powered) box, designed for displaying a `value` and `title`. Optionally, a `showcase` can provide context for what the `value` represents (for example, it could hold an icon, or even a :func:`~shiny.ui.output_plot`). | +| [ui.value_box_theme](ui.value_box_theme.qmd#shiny.ui.value_box_theme) | Value box theme A theme for a :func:`~shiny.ui.value_box`. Themes provide a convenient way to use your app's Bootstrap theme colors as the foreground or background colors of the value box. For more control, you can create your own theme with :func:`~shiny.ui.value_box_theme` where you can pass foreground and background value. See [rstudio/bslib#themes](https://rstudio.github.io/bslib/reference/value_box.html#themes) for more examples. | +| [ui.showcase_bottom](ui.showcase_bottom.qmd#shiny.ui.showcase_bottom) | Showcase bottom A :func:`~shiny.ui.showcase_bottom` is a :class:`~shiny.ui.ShowcaseLayout` with the following default properties: * `width` is `"100%"` * `width_full_screen` is `None` * `height` is `"auto"` * `height_full_screen` is `"2fr"` * `max_height` is `"100px"` * `max_height_full_screen` is `None` See Also -------- * :func:`~shiny.ui.showcase_left_center` * :func:`~shiny.ui.showcase_top_right` * :func:`~shiny.ui.value_box` | +| [ui.showcase_left_center](ui.showcase_left_center.qmd#shiny.ui.showcase_left_center) | Showcase left center A :func:`~shiny.ui.showcase_left_center` is a :class:`~shiny.ui.ShowcaseLayout` with the following default properties: * `width` is `"30%"` * `width_full_screen` is `"1fr"` * `max_height` is `"100px"` * `max_height_full_screen` is `"67%"` See Also -------- * :func:`~shiny.ui.showcase_top_right` * :func:`~shiny.ui.showcase_bottom` * :func:`~shiny.ui.value_box` | +| [ui.showcase_top_right](ui.showcase_top_right.qmd#shiny.ui.showcase_top_right) | Showcase top right A :func:`~shiny.ui.showcase_top_right` is a :class:`~shiny.ui.ShowcaseLayout` with the following default properties: * `width` is `"40%"` * `width_full_screen` is `"1fr"` * `max_height` is `"75px"` * `max_height_full_screen` is `"67%"` See Also -------- * :func:`~shiny.ui.showcase_left_center` * :func:`~shiny.ui.showcase_bottom` * :func:`~shiny.ui.value_box` | +| [ui.ValueBoxTheme](ui.ValueBoxTheme.qmd#shiny.ui.ValueBoxTheme) | | +| [ui.ShowcaseLayout](ui.ShowcaseLayout.qmd#shiny.ui.ShowcaseLayout) | Showcase layout Base layout information utilized to display :func:`~shiny.ui.value_box`'s `showcase` value. See Also -------- * :func:`~shiny.ui.showcase_left_center` * :func:`~shiny.ui.showcase_top_right` * :func:`~shiny.ui.showcase_bottom` * :func:`~shiny.ui.value_box` | + +## Navigation (tab) panels + +Create segments of UI content. + +| | | +| --- | --- | +| [ui.nav_panel](ui.nav_panel.qmd#shiny.ui.nav_panel) | Create a nav item pointing to some internal content. | +| [ui.nav_spacer](ui.nav_spacer.qmd#shiny.ui.nav_spacer) | Create space between nav items. See Also -------- * ~shiny.ui.nav_panel * ~shiny.ui.nav_menu * ~shiny.ui.nav_control * ~shiny.ui.navset_bar * ~shiny.ui.navset_tab * ~shiny.ui.navset_pill * ~shiny.ui.navset_underline * ~shiny.ui.navset_card_tab * ~shiny.ui.navset_card_pill * ~shiny.ui.navset_card_underline * ~shiny.ui.navset_pill_list * ~shiny.ui.navset_hidden Example ------- See :func:`~shiny.ui.nav_panel` | +| [ui.nav_menu](ui.nav_menu.qmd#shiny.ui.nav_menu) | Create a menu of nav items. | +| [ui.nav_control](ui.nav_control.qmd#shiny.ui.nav_control) | Place a control in the navigation container. | +| [ui.navset_bar](ui.navset_bar.qmd#shiny.ui.navset_bar) | Render nav items as a navbar. | +| [ui.navset_tab](ui.navset_tab.qmd#shiny.ui.navset_tab) | Render nav items as a tabset. | +| [ui.navset_pill](ui.navset_pill.qmd#shiny.ui.navset_pill) | Render nav items as a pillset. | +| [ui.navset_underline](ui.navset_underline.qmd#shiny.ui.navset_underline) | Render nav items whose active/focused navigation links are styled with an underline. | +| [ui.navset_card_tab](ui.navset_card_tab.qmd#shiny.ui.navset_card_tab) | Render nav items as a tabset inside a card container. | +| [ui.navset_card_pill](ui.navset_card_pill.qmd#shiny.ui.navset_card_pill) | Render nav items as a pillset inside a card container. | +| [ui.navset_card_underline](ui.navset_card_underline.qmd#shiny.ui.navset_card_underline) | Render nav items inside a card container. Active/focused navigation links are styled with an underline. | +| [ui.navset_pill_list](ui.navset_pill_list.qmd#shiny.ui.navset_pill_list) | Render nav items as a vertical pillset. | +| [ui.navset_hidden](ui.navset_hidden.qmd#shiny.ui.navset_hidden) | Render nav contents without the nav items. | + +## UI panels + +Visually group together a section of UI components. + +| | | +| --- | --- | +| [ui.panel_absolute](ui.panel_absolute.qmd#shiny.ui.panel_absolute) | Create a panel of absolutely positioned content. Creates a `
` tag whose CSS position is set to absolute (or fixed if ``fixed = True``). In HTML, absolute coordinates are specified relative to an element's nearest parent element whose position is not set to static (the default). If no such parent is found, the coordinates are relative to the page borders. If you're not sure what that means, just keep in mind that you may get strange results if you use this function from inside of certain types of panels. | +| [ui.panel_fixed](ui.panel_fixed.qmd#shiny.ui.panel_fixed) | Create a panel of absolutely positioned content. This function is equivalent to calling :func:`~shiny.ui.panel_absolute` with ``fixed=True`` (i.e., the panel does not scroll with the rest of the page). See :func:`~shiny.ui.panel_absolute` for more information. | +| [ui.panel_conditional](ui.panel_conditional.qmd#shiny.ui.panel_conditional) | Create a conditional panel. Show UI elements only if a ``JavaScript`` condition is ``true``. | +| [ui.panel_title](ui.panel_title.qmd#shiny.ui.panel_title) | Create title(s) for the application. | +| [ui.panel_well](ui.panel_well.qmd#shiny.ui.panel_well) | Create a well panel. Creates a panel with a slightly inset border and gray background. Equivalent to Bootstrap's ``well`` CSS class. | + +## Uploads & downloads + +Allow users to upload and download files. + +| | | +| --- | --- | +| [ui.input_file](ui.input_file.qmd#shiny.ui.input_file) | Create a file upload control that can be used to upload one or more files. | +| [ui.download_button](ui.download_button.qmd#shiny.ui.download_button) | Create a download button | + +## Custom UI + +Lower-level UI functions for creating custom HTML/CSS/JS + +| | | +| --- | --- | +| [ui.HTML](ui.HTML.qmd#shiny.ui.HTML) | Mark a string as raw HTML. This will prevent the string from being escaped when rendered inside an HTML tag. | +| [ui.TagList](ui.TagList.qmd#shiny.ui.TagList) | Create an HTML tag list (i.e., a fragment of HTML) | +| [ui.tags](ui.tags.qmd#shiny.ui.tags) | Functions for creating HTML tags. | +| [ui.markdown](ui.markdown.qmd#shiny.ui.markdown) | Convert a string of markdown to :func:`ui.HTML`. | +| [ui.include_css](ui.include_css.qmd#shiny.ui.include_css) | Include a CSS file. | +| [ui.include_js](ui.include_js.qmd#shiny.ui.include_js) | Include a JavaScript file. | +| [ui.insert_ui](ui.insert_ui.qmd#shiny.ui.insert_ui) | Insert UI objects. | +| [ui.remove_ui](ui.remove_ui.qmd#shiny.ui.remove_ui) | Remove UI objects. | +| [ui.fill.as_fillable_container](ui.fill.as_fillable_container.qmd#shiny.ui.fill.as_fillable_container) | | +| [ui.fill.as_fill_item](ui.fill.as_fill_item.qmd#shiny.ui.fill.as_fill_item) | Coerce a tag to a fill item. Filling layouts are built on the foundation of _fillable containers_ and _fill items_ (_fill carriers_ are both _fillable containers_ and _fill items_). This is why most UI components (e.g., :func:`~shiny.ui.card`, :func:`~shiny.ui.layout_sidebar`) possess both `fillable` and `fill` arguments (to control their fill behavior). However, sometimes it's useful to add, remove, and/or test fillable/fill properties on arbitrary :class:`~htmltools.Tag`, which these functions are designed to do. | +| [ui.fill.remove_all_fill](ui.fill.remove_all_fill.qmd#shiny.ui.fill.remove_all_fill) | Remove any filling layouts from a tag. Filling layouts are built on the foundation of _fillable containers_ and _fill items_ (_fill carriers_ are both _fillable containers_ and _fill items_). This is why most UI components (e.g., :func:`~shiny.ui.card`, :func:`~shiny.ui.layout_sidebar`) possess both `fillable` and `fill` arguments (to control their fill behavior). However, sometimes it's useful to add, remove, and/or test fillable/fill properties on arbitrary :class:`~htmltools.Tag`, which these functions are designed to do. | +| [ui.css.as_css_unit](ui.css.as_css_unit.qmd#shiny.ui.css.as_css_unit) | Convert a value into a CSS unit. | +| [ui.css.as_css_padding](ui.css.as_css_padding.qmd#shiny.ui.css.as_css_padding) | Convert a CSS unit or list of CSS units into a CSS padding value. | + +## Update inputs + +Programmatically update input values. + +| | | +| --- | --- | +| [ui.update_select](ui.update_select.qmd#shiny.ui.update_select) | Change the value of a select input on the client. | +| [ui.update_selectize](ui.update_selectize.qmd#shiny.ui.update_selectize) | Change the value of a selectize.js powered input on the client. | +| [ui.update_slider](ui.update_slider.qmd#shiny.ui.update_slider) | Change the value of a slider input on the client. | +| [ui.update_date](ui.update_date.qmd#shiny.ui.update_date) | Change the value of a date input on the client. | +| [ui.update_date_range](ui.update_date_range.qmd#shiny.ui.update_date_range) | Change the start and end values of a date range input on the client. | +| [ui.update_checkbox](ui.update_checkbox.qmd#shiny.ui.update_checkbox) | Change the value of a checkbox input on the client. | +| [ui.update_checkbox_group](ui.update_checkbox_group.qmd#shiny.ui.update_checkbox_group) | Change the value of a checkbox group input on the client. | +| [ui.update_switch](ui.update_switch.qmd#shiny.ui.update_switch) | Change the value of a switch input on the client. | +| [ui.update_radio_buttons](ui.update_radio_buttons.qmd#shiny.ui.update_radio_buttons) | Change the value of a radio input on the client. | +| [ui.update_numeric](ui.update_numeric.qmd#shiny.ui.update_numeric) | Change the value of a number input on the client. | +| [ui.update_text](ui.update_text.qmd#shiny.ui.update_text) | Change the value of a text input on the client. | +| [ui.update_text_area](ui.update_text_area.qmd#shiny.ui.update_text_area) | Change the value of a text input on the client. | +| [ui.update_navs](ui.update_navs.qmd#shiny.ui.update_navs) | Change the value of a navs container on the client. | + +## Update UI Layouts + + + +| | | +| --- | --- | +| [ui.update_sidebar](ui.update_sidebar.qmd#shiny.ui.update_sidebar) | Update a sidebar's visibility. Set a :func:`~shiny.ui.sidebar` state during an active Shiny user session. | +| [ui.update_tooltip](ui.update_tooltip.qmd#shiny.ui.update_tooltip) | Update tooltip contents. | +| [ui.update_popover](ui.update_popover.qmd#shiny.ui.update_popover) | Update the contents or title of a popover. | +| [ui.update_accordion](ui.update_accordion.qmd#shiny.ui.update_accordion) | Dynamically set accordions' states. Dynamically (i.e., programmatically) update/modify :func:`~shiny.ui.accordion`s in a Shiny app. These functions require an `id` to be provided to the :func:`~shiny.ui.accordion` and must also be called within an active Shiny session. | +| [ui.update_accordion_panel](ui.update_accordion_panel.qmd#shiny.ui.update_accordion_panel) | Dynamically update accordion panel contents. Dynamically (i.e., programmatically) update/modify :func:`~shiny.ui.accordion` panels in a Shiny app. These functions require an `id` to be provided to the :func:`~shiny.ui.accordion` and must also be called within an active Shiny session. | +| [ui.insert_accordion_panel](ui.insert_accordion_panel.qmd#shiny.ui.insert_accordion_panel) | Insert an :func:`~shiny.ui.accordion_panel`. | +| [ui.remove_accordion_panel](ui.remove_accordion_panel.qmd#shiny.ui.remove_accordion_panel) | Remove an :func:`~shiny.ui.accordion_panel`. | + +## Rendering outputs + +UI (output_*()) and server (render)ing functions for generating content server-side. + +| | | +| --- | --- | +| [ui.output_plot](ui.output_plot.qmd#shiny.ui.output_plot) | Create a output container for a static plot. Place a :func:`~shiny.render.plot` result in the user interface. See :func:`~shiny.render.plot` for more details on what types of plots are supported. | +| [ui.output_image](ui.output_image.qmd#shiny.ui.output_image) | Create a output container for a static image. | +| [ui.output_table](ui.output_table.qmd#shiny.ui.output_table) | Create a output container for a table. | +| [ui.output_data_frame](ui.output_data_frame.qmd#shiny.ui.output_data_frame) | Create an output container for an interactive table or grid. Features fast virtualized scrolling, sorting, filtering, and row selection (single or multiple). | +| [ui.output_text](ui.output_text.qmd#shiny.ui.output_text) | Create a output container for some text. | +| [ui.output_text_verbatim](ui.output_text_verbatim.qmd#shiny.ui.output_text_verbatim) | Create a output container for some text. Place a :func:`~shiny.render.text` result in the user interface. Differs from :func:`~shiny.ui.output_text` in that it wraps the text in a fixed-width container with a gray-ish background color and border. | +| [ui.output_ui](ui.output_ui.qmd#shiny.ui.output_ui) | Create a output container for a UI (i.e., HTML) element. | +| [render.plot](render.plot.qmd#shiny.render.plot) | Reactively render a plot object as an HTML image. | +| [render.image](render.image.qmd#shiny.render.image) | Reactively render a image file as an HTML image. | +| [render.table](render.table.qmd#shiny.render.table) | Reactively render a pandas ``DataFrame`` object (or similar) as a basic HTML table. Consider using :func:`~shiny.render.data_frame` instead of this renderer, as it provides high performance virtual scrolling, built-in filtering and sorting, and a better default appearance. This renderer may still be helpful if you use pandas styling features that are not currently supported by :func:`~shiny.render.data_frame`. | +| [render.text](render.text.qmd#shiny.render.text) | Reactively render text. | +| [render.ui](render.ui.qmd#shiny.render.ui) | Reactively render HTML content. | +| [render.data_frame](render.data_frame.qmd#shiny.render.data_frame) | Decorator for a function that returns a pandas `DataFrame` object (or similar) to render as an interactive table or grid. Features fast virtualized scrolling, sorting, filtering, and row selection (single or multiple). | +| [render.DataGrid](render.DataGrid.qmd#shiny.render.DataGrid) | Holds the data and options for a ``shiny.render.data_frame`` output, for a spreadsheet-like view. | +| [render.DataTable](render.DataTable.qmd#shiny.render.DataTable) | Holds the data and options for a ``shiny.render.data_frame`` output, for a spreadsheet-like view. | +| [Create rendering outputs](OutputRender.qmd) | | + +## Reactive programming + + + +| | | +| --- | --- | +| [reactive.calc](reactive.calc.qmd#shiny.reactive.calc) | Mark a function as a reactive calculation. A reactive calculation is a function whose return value depends on other reactive value(s) (i.e., :class:`~shiny.Inputs`, :class:`~shiny.reactive.Value`s, and other reactive calculations). Whenever a reactive value changes, any reactive calculations that depend on it are "invalidated" and automatically re-execute if called while invalid. If a reactive calculation is marked as invalidated, any other reactive calculations that recently called it are also marked as invalidated. In this way, invalidations ripple through reactive calculations that depend on each other. | +| [reactive.effect](reactive.effect.qmd#shiny.reactive.effect) | Mark a function as a reactive side effect. A reactive effect is like a reactive calculation (:func:`~shiny.reactive.calc`) in that it can read reactive values and call reactive calculations, and will automatically re-execute when those dependencies change. But unlike reactive calculations, it doesn't return a result and can't be used as an input to other reactive expressions. Thus, reactive effects are only useful for their side effects (for example, performing I/O). Another contrast between reactive calculations and effects is their execution strategy. Reactive calculations use lazy evaluation; that is, when their dependencies change, they don't re-execute right away but rather wait until they are called by someone else. Indeed, if they are not called, then they will never re-execute. In contrast, effects use eager evaluation; as soon as their dependencies change, they schedule themselves to re-execute. | +| [reactive.value](reactive.value.qmd#shiny.reactive.value) | | +| [reactive.Calc](reactive.Calc.qmd#shiny.reactive.Calc) | | +| [reactive.Effect](reactive.Effect.qmd#shiny.reactive.Effect) | | +| [reactive.Value](reactive.Value.qmd#shiny.reactive.Value) | Create a reactive value. Reactive values are the source of reactivity in Shiny. Changes to reactive values invalidate downstream reactive functions (:func:`~shiny.reactive.calc`, :func:`~shiny.reactive.effect`, and `render` functions decorated with `@output`). When these functions are invalidated, they get scheduled to re-execute. Shiny input values are read-only reactive values. For example, `input.x` is a reactive value object, and to get the current value, you can call `input.x()` or `input.x.get()`. When you do that inside of a reactive function, the function takes a dependency on the reactive value. | +| [reactive.event](reactive.event.qmd#shiny.reactive.event) | Mark a function to react only when an "event" occurs. Shiny's reactive programming framework is primarily designed for calculated values (:func:`~shiny.reactive.calc`) and side-effect-causing actions (:func:`~shiny.reactive.effect`) that respond to **any** of their inputs changing. That's often what is desired in Shiny apps, but not always: sometimes you want to wait for a specific action to be taken from the user, like clicking an :func:`~shiny.ui.input_action_button`, before calculating or taking an action. You do not want the calculation or action to be prematurely triggered if other reactive values that it calls are invalidated. The reactive value (or function) which triggers other calculations or actions in this way is called an event. These situations demand a more imperative, "event handling" style of programming, which ``@reactive.event()`` provides. It does this by using the :func:`~shiny.reactive.isolate` primitive under-the-hood to essentially "limit" the set of reactive dependencies to those in ``args``. In other words, the event can call as many reactive values as it likes in its code body without taking a reactive dependency on them; it will be invalidated only when a dependency listed in args is invalidated. | +| [reactive.isolate](reactive.isolate.qmd#shiny.reactive.isolate) | Create a non-reactive scope within a reactive scope. Ordinarily, the simple act of reading a reactive value causes a relationship to be established between the caller and the reactive value, where a change to the reactive value will cause the caller to re-execute. (The same applies for the act of getting a reactive calculation's value.) `with isolate()` lets you read a reactive value or calculation without establishing this relationship. ``with isolate()`` can also be useful for calling reactive calculations at the console, which can be useful for debugging. To do so, wrap the calls to the reactive calculation with ``with isolate()``. | +| [reactive.invalidate_later](reactive.invalidate_later.qmd#shiny.reactive.invalidate_later) | Scheduled Invalidation When called from within a reactive context, :func:`~shiny.reactive.invalidate_later` schedules the reactive context to be invalidated in the given number of seconds. | +| [reactive.flush](reactive.flush.qmd#shiny.reactive.flush) | Run any pending invalidations (i.e., flush the reactive environment). Warning ------- You shouldn't ever need to call this function inside of a Shiny app. It's only useful for testing and running reactive code interactively in the console. | +| [reactive.poll](reactive.poll.qmd#shiny.reactive.poll) | Create a reactive polling object. Polling is a technique that approximates "real-time" or streaming updates, as if a data source were pushing notifications each time it is updated. The data source does not actually push notifications; a polling object repeatedly checks for changes in an efficient way at specified intervals. If a change is detected, the polling object runs a function to re-read the data source. A reactive polling object is constructed using two functions: a polling function, which is a fast-running, inexpensive function that is used to determine whether some data source has changed (such as the timestamp of a file, or a `SELECT MAX(updated) FROM table` query); and a slower-running reading function that actually loads and returns the data that is desired. The `poll()` function is intended to be used as a decorator: the poll function is passed as the `poll_func` arg to `@poll()`, while the data reading function is the target of the decorator. Reactive consumers can invoke the resulting polling object to get the current data, and will automatically invalidate when the polling function detects a change. Polling objects also cache the results of the read function; for this reason, apps where all sessions depend on the same data source may want to declare the polling object at the top level of app.py (outside of the server function). Both `poll_func` and the decorated (data reading) function can read reactive values and :class:`~shiny.reactive.calc` objects. Any invalidations triggered by reactive dependencies will apply to the reactive polling object immediately (not waiting for the `interval_secs` delay to expire). | +| [reactive.file_reader](reactive.file_reader.qmd#shiny.reactive.file_reader) | Create a reactive file reader. This is a decorator, meant to be applied to a no-argument function that reads data from a file on disk. Whenever the file changes (or to be precise, the file size or last modified time changes), past readers of the data are reactively invalidated. This makes it incredibly easy to write apps that automatically update all of their outputs as soon as files on disk change. Note that `file_reader` works only on single files, not directories of files. Both the `filepath` function and the decorated (file reading) function can read reactive values and :class:`~shiny.reactive.calc` objects. Any invalidations triggered by reactive dependencies will apply to the reactive file reader object immediately (not waiting for the `interval_secs` delay to expire). | +| [reactive.lock](reactive.lock.qmd#shiny.reactive.lock) | A lock that should be held whenever manipulating the reactive graph. For example, :func:`~shiny.reactive.lock` makes it safe to set a :class:`~reactive.Value` and call :func:`~shiny.reactive.flush` from a different :class:`~asyncio.Task` than the one that is running the Shiny :class:`~shiny.Session`. | +| [req](req.qmd#shiny.req) | Throw a silent exception for falsy values. This is a convenient shorthand for throwing :func:`~shiny.types.SilentException` / :func:`~shiny.types.SilentCancelOutputException` if any of the arguments are falsy. The term "falsy" generally indicates that a value is considered `False` when encountered in a logical context. We use the term a little loosely here; our usage tries to match the intuitive notions of "Is this value missing or available?", or "Has the user provided an answer?", or in the case of action buttons, "Has the button been clicked?". So `False`, `None`, `0`, and `""` would be examples of Falsy values. | + +## Create and run applications + + + +| | | +| --- | --- | +| [run_app](run_app.qmd#shiny.run_app) | Starts a Shiny app. Press ``Ctrl+C`` (or ``Ctrl+Break`` on Windows) to stop the app. | +| [App](App.qmd#shiny.App) | Create a Shiny app instance. | +| [Inputs](Inputs.qmd#shiny.Inputs) | A class representing Shiny input values. This class provides access to a :class:`~shiny.Session`'s input values. The input values are reactive :class:`~shiny.reactive.Value`s, and can be accessed with the ``[]`` operator, or with ``.``. For example, if there is an input named ``x``, it can be accessed via `input["x"]()` or ``input.x()``. | +| [Outputs](Outputs.qmd#shiny.Outputs) | A class representing Shiny output definitions. | +| [Session](Session.qmd#shiny.Session) | A class representing a user session. | + +## Display messages + + + +| | | +| --- | --- | +| [ui.help_text](ui.help_text.qmd#shiny.ui.help_text) | Create a help text element Help text is stylized text which can be added to the user interface to provide additional explanation or context. Text passed to :func:`~shiny.ui.help_text` receives the Bootstrap `help-block` class. | +| [ui.notification_show](ui.notification_show.qmd#shiny.ui.notification_show) | Show a notification to the user. A notification is a message that appears near the bottom corner of the app. Notifications normally disappear after a short period of time, and should multiple notifications appear together, they will stack on top of one another. | +| [ui.notification_remove](ui.notification_remove.qmd#shiny.ui.notification_remove) | Remove a notification. :func:`~shiny.ui.notification_remove` provides a way to remove a notification programatically. Notifications can also be removed manually by the user, or automatically after a specififed amont of time passes. | +| [ui.modal](ui.modal.qmd#shiny.ui.modal) | Creates the UI for a modal dialog, using Bootstrap's modal class. A modal is a dialog box that appears in front of the app. Modals are typically used for showing important messages, or for presenting UI that requires input from the user, such as a user name and/or password input. | +| [ui.modal_show](ui.modal_show.qmd#shiny.ui.modal_show) | Show a modal dialog. :func:`~shiny.ui.modal_show` is used to display a modal that has been created with :func:`~shiny.ui.modal`. | +| [ui.modal_remove](ui.modal_remove.qmd#shiny.ui.modal_remove) | Remove a modal dialog box. :func:`~shiny.ui.modal_remove` provides a way to remove a modal programatically. Modals can also be removed manually by the user if a :func:`~shiny.ui.modal_button` is provided, or if the modal is created with `easy_close=True`. | +| [ui.modal_button](ui.modal_button.qmd#shiny.ui.modal_button) | Creates a button that will dismiss a :func:`modal`. :func:`~shiny.ui.modal_button` is usually passed to the `footer` of a :func:`~shiny.ui.modal` to add a button to the footer that will close the :func:`~shiny.ui.modal`. | +| [ui.Progress](ui.Progress.qmd#shiny.ui.Progress) | Initialize a progress bar. :func:`~shiny.ui.Progress` creates a computation manager that can be used with `with` to run a block of code. Shiny will display a progress bar while the code runs, which you can update by calling the `set()` and `message()` methods of the computation manager at strategic points in the code block. | + +## Modules + + + +| | | +| --- | --- | +| [module.ui](module.ui.qmd#shiny.module.ui) | | +| [module.server](module.server.qmd#shiny.module.server) | | + +## Developer facing tools + + + +| | | +| --- | --- | +| [session.get_current_session](session.get_current_session.qmd#shiny.session.get_current_session) | Get the current user session. | +| [session.require_active_session](session.require_active_session.qmd#shiny.session.require_active_session) | Raise an exception if no Shiny session is currently active. | +| [session.session_context](session.session_context.qmd#shiny.session.session_context) | A context manager for current session. | +| [reactive.get_current_context](reactive.get_current_context.qmd#shiny.reactive.get_current_context) | Get the current reactive context. | +| [input_handler.input_handlers](input_handler.input_handlers.qmd#shiny.input_handler.input_handlers) | Manage Shiny input handlers. Add and/or remove input handlers of a given ``type``. Shiny uses these handlers to pre-process input values from the client (after being deserialized) before passing them to the ``input`` argument of an :func:`~shiny.App`'s ``server`` function. The ``type`` is based on the ``getType()`` JavaScript method on the relevant Shiny input binding. See `this article `_ for more information on how to create custom input bindings. (The article is about Shiny for R, but the JavaScript and general principles are the same.) Methods -------- add(type: str, force: bool = False) -> Callable[[InputHandlerType], None] Register an input handler. This method returns a decorator that registers the decorated function as the handler for the given ``type``. This handler should accept three arguments: - the input ``value`` - the input ``name`` - the :class:`~shiny.Session` object remove(type: str) Unregister an input handler. Note ---- ``add()`` ing an input handler will make it persist for the duration of the Python process (unless Shiny is explicitly reloaded). For that reason, verbose naming is encouraged to minimize the risk of colliding with other Shiny input binding(s) which happen to use the same ``type`` (if the binding is bundled with a package, we recommend the format of "packageName.widgetName"). Example ------- ```{python} #\| eval: false from shiny.input_handler import input_handlers @input_handlers.add("mypackage.intify") def _(value, name, session): return int(value) ``` On the Javascript side, the associated input binding must have a corresponding ``getType`` method: ```{python} #\| eval: false getType: function(el) { return "mypackage.intify"; } ``` | + +## Types + + + +| | | +| --- | --- | +| [Miscellaneous types](MiscTypes.qmd) | | +| [Tag types](TagTypes.qmd) | | +| [Exception types](ExceptionTypes.qmd) | | + +## Shiny Express + +Functions for Shiny Express applications + +| | | +| --- | --- | +| [Context manager components](ContextManagerComponents.qmd) | | +| [Page functions](PageFunctions.qmd) | | + +## Deprecated + + + +| | | +| --- | --- | +| [ui.panel_main](ui.panel_main.qmd#shiny.ui.panel_main) | Deprecated. Please supply the `*args` of :func:`~shiny.ui.panel_main` directly to :func:`~shiny.ui.layout_sidebar`. | +| [ui.panel_sidebar](ui.panel_sidebar.qmd#shiny.ui.panel_sidebar) | Deprecated. Please use :func:`~shiny.ui.sidebar` instead. | +| [ui.nav](ui.nav.qmd#shiny.ui.nav) | Deprecated. Please use `nav_panel()` instead of `nav()`. | +| [render.transformer.resolve_value_fn](render.transformer.resolve_value_fn.qmd#shiny.render.transformer.resolve_value_fn) | Resolve the value function This function is used to resolve the value function (`value_fn`) to an object of type `IT`. If the value function is asynchronous, it will be awaited. If the value function is synchronous, it will be called. While always using an async method within an output transform function is not appropriate, this method may be safely used to avoid boilerplate. Replace this: ```python if is_async_callable(_fn): x = await _fn() else: x = cast(ValueFnSync[IT], _fn)() ``` With this: ```python x = await resolve_value_fn(_fn) ``` | + +## Experimental + +These methods are under consideration and are considered unstable. However, if there is a method you are excited about, please let us know! + +| | | +| --- | --- | +| [Card](ExCard.qmd) | 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. | \ No newline at end of file diff --git a/docs/api/input_handler.input_handlers.qmd b/docs/api/input_handler.input_handlers.qmd new file mode 100644 index 000000000..4913114b5 --- /dev/null +++ b/docs/api/input_handler.input_handlers.qmd @@ -0,0 +1,60 @@ +# input_handler.input_handlers { #shiny.input_handler.input_handlers } + +`input_handler.input_handlers` + +Manage Shiny input handlers. + +Add and/or remove input handlers of a given ``type``. Shiny uses these handlers to +pre-process input values from the client (after being deserialized) before passing them +to the ``input`` argument of an [](:func:`~shiny.App`)'s ``server`` function. + +The ``type`` is based on the ``getType()`` JavaScript method on the relevant Shiny +input binding. See `this article `_ +for more information on how to create custom input bindings. (The article is about +Shiny for R, but the JavaScript and general principles are the same.) + + + +## Methods + +add(type: str, force: bool = False) -> Callable[[InputHandlerType], None] + Register an input handler. This method returns a decorator that registers the + decorated function as the handler for the given ``type``. This handler should + accept three arguments: + - the input ``value`` + - the input ``name`` + - the [](:class:`~shiny.Session`) object +remove(type: str) + Unregister an input handler. + + + +## Note + +``add()`` ing an input handler will make it persist for the duration of the Python +process (unless Shiny is explicitly reloaded). For that reason, verbose naming is +encouraged to minimize the risk of colliding with other Shiny input binding(s) which +happen to use the same ``type`` (if the binding is bundled with a package, we +recommend the format of "packageName.widgetName"). + + + +## Example + +```{python} +#| eval: false +from shiny.input_handler import input_handlers +@input_handlers.add("mypackage.intify") +def _(value, name, session): + return int(value) +``` + +On the Javascript side, the associated input binding must have a corresponding +``getType`` method: + +```{python} +#| eval: false +getType: function(el) { + return "mypackage.intify"; +} +``` \ No newline at end of file diff --git a/docs/api/module.server.qmd b/docs/api/module.server.qmd new file mode 100644 index 000000000..7e6604053 --- /dev/null +++ b/docs/api/module.server.qmd @@ -0,0 +1,4 @@ +# module.server { #shiny.module.server } + +`module.server(fn)` + diff --git a/docs/api/module.ui.qmd b/docs/api/module.ui.qmd new file mode 100644 index 000000000..4715d06db --- /dev/null +++ b/docs/api/module.ui.qmd @@ -0,0 +1,4 @@ +# module.ui { #shiny.module.ui } + +`module.ui(fn)` + diff --git a/docs/api/reactive.calc.qmd b/docs/api/reactive.calc.qmd new file mode 100644 index 000000000..6760d7b3c --- /dev/null +++ b/docs/api/reactive.calc.qmd @@ -0,0 +1,54 @@ +# reactive.Calc { #shiny.reactive.Calc } + +`reactive.Calc` + + + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +import random +import time + +from shiny import App, Inputs, Outputs, Session, reactive, render, ui + +app_ui = ui.page_fluid( + ui.input_action_button("first", "Invalidate first (slow) computation"), + " ", + ui.input_action_button("second", "Invalidate second (fast) computation"), + ui.br(), + ui.output_ui("result"), +) + + +def server(input: Inputs, output: Outputs, session: Session): + @reactive.Calc + def first(): + input.first() + p = ui.Progress() + for i in range(30): + p.set(i / 30, message="Computing, please wait...") + time.sleep(0.1) + p.close() + return random.randint(1, 1000) + + @reactive.Calc + def second(): + input.second() + return random.randint(1, 1000) + + @render.ui + def result(): + return first() + second() + + +app = App(app_ui, server) + +``` + diff --git a/docs/api/reactive.effect.qmd b/docs/api/reactive.effect.qmd new file mode 100644 index 000000000..c80d9104b --- /dev/null +++ b/docs/api/reactive.effect.qmd @@ -0,0 +1,33 @@ +# reactive.Effect { #shiny.reactive.Effect } + +`reactive.Effect` + + + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +from shiny import App, Inputs, Outputs, Session, reactive, ui + +app_ui = ui.page_fluid(ui.input_action_button("btn", "Press me!")) + + +def server(input: Inputs, output: Outputs, session: Session): + @reactive.Effect + @reactive.event(input.btn) + def _(): + ui.insert_ui( + ui.p("Number of clicks: ", input.btn()), selector="#btn", where="afterEnd" + ) + + +app = App(app_ui, server) + +``` + diff --git a/docs/api/reactive.event.qmd b/docs/api/reactive.event.qmd new file mode 100644 index 000000000..ff9982bab --- /dev/null +++ b/docs/api/reactive.event.qmd @@ -0,0 +1,143 @@ +# reactive.event { #shiny.reactive.event } + +`reactive.event(*args, ignore_none=True, ignore_init=False)` + +Mark a function to react only when an "event" occurs. + +Shiny's reactive programming framework is primarily designed for calculated values +([](:func:`~shiny.reactive.calc`)) and side-effect-causing actions +([](:func:`~shiny.reactive.effect`)) that respond to **any** of their inputs changing. +That's often what is desired in Shiny apps, but not always: sometimes you want to +wait for a specific action to be taken from the user, like clicking an +[](:func:`~shiny.ui.input_action_button`), before calculating or taking an action. You +do not want the calculation or action to be prematurely triggered if other reactive +values that it calls are invalidated. The reactive value (or function) which triggers +other calculations or actions in this way is called an event. + +These situations demand a more imperative, "event handling" style of programming, +which ``@reactive.event()`` provides. It does this by using the +[](:func:`~shiny.reactive.isolate`) primitive under-the-hood to essentially "limit" the +set of reactive dependencies to those in ``args``. In other words, the event can call +as many reactive values as it likes in its code body without taking a reactive +dependency on them; it will be invalidated only when a dependency listed in args is +invalidated. + +## Parameters + +*args: [Callable](`typing.Callable`)\[\[\], [object](`object`)\] \| [Callable](`typing.Callable`)\[\[\], [Awaitable](`typing.Awaitable`)\[[object](`object`)\]\] = () + +: One or more callables that represent the event; most likely this will be a + reactive input value linked to a [](:func:`~shiny.ui.input_action_button`) or + similar (e.g., ``input.click``), but it can also be a (reactive or non-reactive) + function that returns a value. + +ignore_none: [bool](`bool`) = True + +: Whether to ignore the event if the value is ``None`` or ``0``. + +ignore_init: [bool](`bool`) = False + +: If ``False``, the event triggers on the first run. + +## Returns + +| Type | Description | +|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------| +| [Callable](`typing.Callable`)\[\[[Callable](`typing.Callable`)\[\[\], [T](`shiny.reactive._reactives.T`)\]\], [Callable](`typing.Callable`)\[\[\], [T](`shiny.reactive._reactives.T`)\]\] | A decorator that marks a function as an event handler. | + +## Tip + +This decorator must be applied before the relevant reactivity decorator (i.e., +``@reactive.event`` must be applied before ``@reactive.effect``, ``@reactive.calc``, +``@render.ui``, etc). + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +import random + +from shiny import App, Inputs, Outputs, Session, reactive, render, ui + +app_ui = ui.page_fluid( + ui.markdown( + f""" + This example demonstrates how `@reactive.event()` can be used to restrict + execution of: (1) a `@render` function, (2) `@reactive.Calc`, or (3) + `@reactive.Effect`. + + In all three cases, the output is dependent on a random value that gets updated + every 0.5 seconds (currently, it is {ui.output_ui("number", inline=True)}), but + the output is only updated when the button is clicked. + """ + ), + ui.row( + ui.column( + 3, + ui.input_action_button("btn_out", "(1) Update number"), + ui.output_text("out_out"), + ), + ui.column( + 3, + ui.input_action_button("btn_calc", "(2) Show 1 / number"), + ui.output_text("out_calc"), + ), + ui.column( + 3, + ui.input_action_button("btn_effect", "(3) Log number"), + ui.div(id="out_effect"), + ), + ), +) + + +def server(input: Inputs, output: Outputs, session: Session): + # Update a random number every second + val = reactive.Value(random.randint(0, 1000)) + + @reactive.Effect + def _(): + reactive.invalidate_later(0.5) + val.set(random.randint(0, 1000)) + + # Always update this output when the number is updated + @render.ui + def number(): + return val.get() + + # Since ignore_none=False, the function executes before clicking the button. + # (input.btn_out() is 0 on page load, but @@reactive.event() treats 0 as None for + # action buttons.) + @render.text + @reactive.event(input.btn_out, ignore_none=False) + def out_out(): + return str(val.get()) + + @reactive.Calc + @reactive.event(input.btn_calc) + def calc(): + return 1 / val.get() + + @render.text + def out_calc(): + return str(calc()) + + @reactive.Effect + @reactive.event(input.btn_effect) + def _(): + ui.insert_ui( + ui.p("Random number!", val.get()), + selector="#out_effect", + where="afterEnd", + ) + + +app = App(app_ui, server) + +``` + diff --git a/docs/api/reactive.file_reader.qmd b/docs/api/reactive.file_reader.qmd new file mode 100644 index 000000000..a60a9acec --- /dev/null +++ b/docs/api/reactive.file_reader.qmd @@ -0,0 +1,137 @@ +# reactive.file_reader { #shiny.reactive.file_reader } + +`reactive.file_reader(filepath, interval_secs=1, *, priority=1, session=MISSING)` + +Create a reactive file reader. + +This is a decorator, meant to be applied to a no-argument function that reads data +from a file on disk. Whenever the file changes (or to be precise, the file size or +last modified time changes), past readers of the data are reactively invalidated. +This makes it incredibly easy to write apps that automatically update all of their +outputs as soon as files on disk change. + +Note that `file_reader` works only on single files, not directories of files. + +Both the `filepath` function and the decorated (file reading) function can read +reactive values and [](:class:`~shiny.reactive.calc`) objects. Any invalidations +triggered by reactive dependencies will apply to the reactive file reader object +immediately (not waiting for the `interval_secs` delay to expire). + +## Parameters + +filepath: [str](`str`) \| [os](`os`).[PathLike](`os.PathLike`)\[[str](`str`)\] \| [Callable](`typing.Callable`)\[\[\], [str](`str`)\] \| [Callable](`typing.Callable`)\[\[\], [os](`os`).[PathLike](`os.PathLike`)\[[str](`str`)\]\] + +: Either a string indicating the file path to be monitored, or, a no-argument + function that returns such a string. The latter is useful if the file to be + monitored depends on some user input, the current date/time, etc. + + The file path provided MUST exist, otherwise Shiny will treat it as an unhandled + error and close the session. + + If a function is used, make sure it is high performance (or is cached, i.e. use + a :class:`~shiny.reactive.calc)`, as it will be called very frequently. + +interval_secs: [float](`float`) = 1 + +: The number of seconds to wait after each time the file metadata is checked. + Note: depending on what other tasks are executing, the actual wait time may far + exceed this value. + +priority: [int](`int`) = 1 + +: Reactive polling is implemented using an [](:class:`~shiny.reactive.effect`) to call + `poll_func` on a timer; use the `priority` argument to control the order of this + Effect's execution versus other Effects in your app. See + [](:func:`~shiny.reactive.effect`) for more details. + +session: [MISSING_TYPE](`shiny.types.MISSING_TYPE`) \| [Session](`shiny.session.Session`) \| None = MISSING + +: A [](:class:`~shiny.Session`) instance. If not provided, a session is inferred via + [](:func:`~shiny.session.get_current_session`). If there is no current session (i.e. + `poll` is being created outside of the server function), the lifetime of this + reactive poll object will not be tied to any specific session. + +## Returns + +| Type | Description | +|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------| +| [Callable](`typing.Callable`)\[\[[Callable](`typing.Callable`)\[\[\], [T](`shiny.reactive._poll.T`)\]\], [Callable](`typing.Callable`)\[\[\], [T](`shiny.reactive._poll.T`)\]\] | A decorator that should be applied to a no-argument function that (expensively) | +| reads whatever data is desired. (This function may be a regular function or a | | +| co-routine function.) The result of the decorator is a reactive | | +| class:`~shiny.reactive.calc` that always returns up-to-date data, and invalidates | | +| callers when changes are detected via polling. | | + +## See Also + +[](:func:`~shiny.reactive.poll`) + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +import pathlib + +import pandas as pd + +from shiny import App, Inputs, Outputs, Session, reactive, render, ui + +dir = pathlib.Path(__file__).parent + +app_ui = ui.page_fluid(ui.output_table("result"), class_="p-3") + + +@reactive.file_reader(dir / "mtcars.csv") +def read_file(): + return pd.read_csv(dir / "mtcars.csv") + + +def server(input: Inputs, output: Outputs, session: Session): + @render.table + def result(): + return read_file() + + +app = App(app_ui, server) + +## file: mtcars.csv +mpg,cyl,disp,hp,drat,wt,qsec,vs,am,gear,carb +21,6,160,110,3.9,2.62,16.46,0,1,4,4 +21,6,160,110,3.9,2.875,17.02,0,1,4,4 +22.8,4,108,93,3.85,2.32,18.61,1,1,4,1 +21.4,6,258,110,3.08,3.215,19.44,1,0,3,1 +18.7,8,360,175,3.15,3.44,17.02,0,0,3,2 +18.1,6,225,105,2.76,3.46,20.22,1,0,3,1 +14.3,8,360,245,3.21,3.57,15.84,0,0,3,4 +24.4,4,146.7,62,3.69,3.19,20,1,0,4,2 +22.8,4,140.8,95,3.92,3.15,22.9,1,0,4,2 +19.2,6,167.6,123,3.92,3.44,18.3,1,0,4,4 +17.8,6,167.6,123,3.92,3.44,18.9,1,0,4,4 +16.4,8,275.8,180,3.07,4.07,17.4,0,0,3,3 +17.3,8,275.8,180,3.07,3.73,17.6,0,0,3,3 +15.2,8,275.8,180,3.07,3.78,18,0,0,3,3 +10.4,8,472,205,2.93,5.25,17.98,0,0,3,4 +10.4,8,460,215,3,5.424,17.82,0,0,3,4 +14.7,8,440,230,3.23,5.345,17.42,0,0,3,4 +32.4,4,78.7,66,4.08,2.2,19.47,1,1,4,1 +30.4,4,75.7,52,4.93,1.615,18.52,1,1,4,2 +33.9,4,71.1,65,4.22,1.835,19.9,1,1,4,1 +21.5,4,120.1,97,3.7,2.465,20.01,1,0,3,1 +15.5,8,318,150,2.76,3.52,16.87,0,0,3,2 +15.2,8,304,150,3.15,3.435,17.3,0,0,3,2 +13.3,8,350,245,3.73,3.84,15.41,0,0,3,4 +19.2,8,400,175,3.08,3.845,17.05,0,0,3,2 +27.3,4,79,66,4.08,1.935,18.9,1,1,4,1 +26,4,120.3,91,4.43,2.14,16.7,0,1,5,2 +30.4,4,95.1,113,3.77,1.513,16.9,1,1,5,2 +15.8,8,351,264,4.22,3.17,14.5,0,1,5,4 +19.7,6,145,175,3.62,2.77,15.5,0,1,5,6 +15,8,301,335,3.54,3.57,14.6,0,1,5,8 +21.4,4,121,109,4.11,2.78,18.6,1,1,4,2 + +``` + diff --git a/docs/api/reactive.flush.qmd b/docs/api/reactive.flush.qmd new file mode 100644 index 000000000..578b96d91 --- /dev/null +++ b/docs/api/reactive.flush.qmd @@ -0,0 +1,12 @@ +# reactive.flush { #shiny.reactive.flush } + +`reactive.flush()` + +Run any pending invalidations (i.e., flush the reactive environment). + + + +## Warning + +You shouldn't ever need to call this function inside of a Shiny app. It's only +useful for testing and running reactive code interactively in the console. \ No newline at end of file diff --git a/docs/api/reactive.get_current_context.qmd b/docs/api/reactive.get_current_context.qmd new file mode 100644 index 000000000..578f706e3 --- /dev/null +++ b/docs/api/reactive.get_current_context.qmd @@ -0,0 +1,17 @@ +# reactive.get_current_context { #shiny.reactive.get_current_context } + +`reactive.get_current_context()` + +Get the current reactive context. + +## Returns + +| Type | Description | +|-------------------------------------------|----------------------| +| [Context](`shiny.reactive._core.Context`) | A [](:class:`~Context`). | + +## Raises + +| Type | Description | +|--------------------------------|------------------------------------------| +| [RuntimeError](`RuntimeError`) | If called outside of a reactive context. | \ No newline at end of file diff --git a/docs/api/reactive.invalidate_later.qmd b/docs/api/reactive.invalidate_later.qmd new file mode 100644 index 000000000..4cd28f68e --- /dev/null +++ b/docs/api/reactive.invalidate_later.qmd @@ -0,0 +1,56 @@ +# reactive.invalidate_later { #shiny.reactive.invalidate_later } + +`reactive.invalidate_later(delay, *, session=MISSING)` + +Scheduled Invalidation + +When called from within a reactive context, [](:func:`~shiny.reactive.invalidate_later`) +schedules the reactive context to be invalidated in the given number of seconds. + +## Parameters + +delay: [float](`float`) + +: The number of seconds to wait before invalidating. + +## Note + +When called within a reactive function (i.e., [](:func:`~reactive.effect`), [](:func:`~reactive.calc`), +[](:func:`render.ui`), etc.), that reactive context is invalidated (and re-executes) +after the interval has passed. The re-execution will reset the invalidation flag, so +in a typical use case, the object will keep re-executing and waiting for the +specified interval. It's possible to stop this cycle by adding conditional logic +that prevents the ``invalidate_later`` from being run. + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +import random + +from shiny import App, Inputs, Outputs, Session, reactive, render, ui + +app_ui = ui.page_fluid(ui.output_ui("value")) + + +def server(input: Inputs, output: Outputs, session: Session): + @reactive.Effect + def _(): + reactive.invalidate_later(0.5) + print("Random int: ", random.randint(0, 10000)) + + @render.ui + def value(): + reactive.invalidate_later(0.5) + return "Random int: " + str(random.randint(0, 10000)) + + +app = App(app_ui, server) + +``` + diff --git a/docs/api/reactive.isolate.qmd b/docs/api/reactive.isolate.qmd new file mode 100644 index 000000000..0cc3ec5ea --- /dev/null +++ b/docs/api/reactive.isolate.qmd @@ -0,0 +1,67 @@ +# reactive.isolate { #shiny.reactive.isolate } + +`reactive.isolate()` + +Create a non-reactive scope within a reactive scope. + +Ordinarily, the simple act of reading a reactive value causes a relationship to be +established between the caller and the reactive value, where a change to the +reactive value will cause the caller to re-execute. (The same applies for the act of +getting a reactive calculation's value.) `with isolate()` lets you read a reactive +value or calculation without establishing this relationship. + +``with isolate()`` can also be useful for calling reactive calculations at the +console, which can be useful for debugging. To do so, wrap the calls to the reactive +calculation with ``with isolate()``. + +## Returns + +| Type | Description | +|-----------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| [Generator](`typing.Generator`)\[None, None, None\] | A context manager that executes the given expression in a scope where reactive values can be read, but do not cause the reactive scope of the caller to be re-evaluated when they change. | + +## See Also + +[](:func:`~shiny.reactive.event`) + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +import matplotlib.pyplot as plt +import numpy as np + +from shiny import App, Inputs, Outputs, Session, reactive, render, ui + +app_ui = ui.page_fluid( + ui.input_slider("n", "Number of observations", min=0, max=1000, value=500), + ui.input_action_button("go", "Go!", class_="btn-success"), + ui.output_plot("plot"), +) + + +def server(input: Inputs, output: Outputs, session: Session): + @render.plot(alt="A histogram") + def plot(): + # Take a reactive dependency on the action button... + input.go() + + # ...but don't take a reactive dependency on the slider + with reactive.isolate(): + np.random.seed(19680801) + x = 100 + 15 * np.random.randn(input.n()) + + fig, ax = plt.subplots() + ax.hist(x, bins=30, density=True) + return fig + + +app = App(app_ui, server) + +``` + diff --git a/docs/api/reactive.lock.qmd b/docs/api/reactive.lock.qmd new file mode 100644 index 000000000..2e460f882 --- /dev/null +++ b/docs/api/reactive.lock.qmd @@ -0,0 +1,9 @@ +# reactive.lock { #shiny.reactive.lock } + +`reactive.lock()` + +A lock that should be held whenever manipulating the reactive graph. + +For example, [](:func:`~shiny.reactive.lock`) makes it safe to set a [](:class:`~reactive.Value`) and call +[](:func:`~shiny.reactive.flush`) from a different [](:class:`~asyncio.Task`) than the one that +is running the Shiny [](:class:`~shiny.Session`). \ No newline at end of file diff --git a/docs/api/reactive.poll.qmd b/docs/api/reactive.poll.qmd new file mode 100644 index 000000000..8baca98cb --- /dev/null +++ b/docs/api/reactive.poll.qmd @@ -0,0 +1,222 @@ +# reactive.poll { #shiny.reactive.poll } + +`reactive.poll(poll_func, interval_secs=1, *, equals=eq, priority=0, session=MISSING)` + +Create a reactive polling object. + +Polling is a technique that approximates "real-time" or streaming updates, as if a +data source were pushing notifications each time it is updated. The data source does +not actually push notifications; a polling object repeatedly checks for changes in an +efficient way at specified intervals. If a change is detected, the polling object runs +a function to re-read the data source. + +A reactive polling object is constructed using two functions: a polling function, +which is a fast-running, inexpensive function that is used to determine whether some +data source has changed (such as the timestamp of a file, or a `SELECT MAX(updated) +FROM table` query); and a slower-running reading function that actually loads and +returns the data that is desired. The `poll()` function is intended to be used as a +decorator: the poll function is passed as the `poll_func` arg to `@poll()`, while +the data reading function is the target of the decorator. + +Reactive consumers can invoke the resulting polling object to get the current data, +and will automatically invalidate when the polling function detects a change. +Polling objects also cache the results of the read function; for this reason, apps +where all sessions depend on the same data source may want to declare the polling +object at the top level of app.py (outside of the server function). + +Both `poll_func` and the decorated (data reading) function can read reactive values +and [](:class:`~shiny.reactive.calc`) objects. Any invalidations triggered by reactive +dependencies will apply to the reactive polling object immediately (not waiting for +the `interval_secs` delay to expire). + +## Parameters + +poll_func: [Callable](`typing.Callable`)\[\[\], [Any](`typing.Any`)\] \| [Callable](`typing.Callable`)\[\[\], [Awaitable](`typing.Awaitable`)\[[Any](`typing.Any`)\]\] + +: A function to be called frequently to determine whether a data source has + changed. The return value should be something that can be compared inexpensively + using `==`. Both regular functions and co-routine functions are allowed. + + Note that the `poll_func` should NOT return a bool that indicates whether the + data source has changed. Rather, each `poll_func` return value will be checked + for equality with its preceding `poll_func` return value (using `==` semantics + by default), and if it differs, the data source will be considered changed. + +interval_secs: [float](`float`) = 1 + +: The number of seconds to wait after each `poll_func` invocation before polling + again. Note: depending on what other tasks are executing, the actual wait time + may far exceed this value. + +equals: [Callable](`typing.Callable`)\[\[[Any](`typing.Any`), [Any](`typing.Any`)\], [bool](`bool`)\] = eq + +: The function that will be used to compare each `poll_func` return value with its + immediate predecessor. + +priority: [int](`int`) = 0 + +: Reactive polling is implemented using an [](:class:`~shiny.reactive.effect`) to call + `poll_func` on a timer; use the `priority` argument to control the order of this + Effect's execution versus other Effects in your app. See + [](:func:`~shiny.reactive.effect`) for more details. + +session: [MISSING_TYPE](`shiny.types.MISSING_TYPE`) \| [Session](`shiny.session.Session`) \| None = MISSING + +: A [](:class:`~shiny.Session`) instance. If not provided, a session is inferred via + [](:func:`~shiny.session.get_current_session`). If there is no current session (i.e. + `poll` is being created outside of the server function), the lifetime of this + reactive poll object will not be tied to any specific session. + +## Returns + +| Type | Description | +|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------| +| [Callable](`typing.Callable`)\[\[[Callable](`typing.Callable`)\[\[\], [T](`shiny.reactive._poll.T`)\]\], [Callable](`typing.Callable`)\[\[\], [T](`shiny.reactive._poll.T`)\]\] | A decorator that should be applied to a no-argument function that (expensively) | +| reads whatever data is desired. (This function may be a regular function or a | | +| co-routine function.) The result of the decorator is a reactive | | +| class:`~shiny.reactive.calc` that always returns up-to-date data, and invalidates | | +| callers when changes are detected via polling. | | + +## See Also + +[](:func:`~shiny.reactive.file_reader`) + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +import asyncio +import random +import sqlite3 +from datetime import datetime +from typing import Any, Awaitable + +import pandas as pd + +from shiny import App, Inputs, Outputs, Session, reactive, render, ui + +SYMBOLS = ["AAA", "BBB", "CCC", "DDD", "EEE", "FFF"] + + +def timestamp() -> str: + return datetime.now().strftime("%x %X") + + +def rand_price() -> float: + return round(random.random() * 250, 2) + + +# === Initialize the database ========================================= + + +def init_db(con: sqlite3.Connection) -> None: + cur = con.cursor() + try: + cur.executescript( + """ + CREATE TABLE stock_quotes (timestamp text, symbol text, price real); + CREATE INDEX idx_timestamp ON stock_quotes (timestamp); + """ + ) + cur.executemany( + "INSERT INTO stock_quotes (timestamp, symbol, price) VALUES (?, ?, ?)", + [(timestamp(), symbol, rand_price()) for symbol in SYMBOLS], + ) + con.commit() + finally: + cur.close() + + +conn = sqlite3.connect(":memory:") +init_db(conn) + + +# === Randomly update the database with an asyncio.task ============== + + +def update_db(con: sqlite3.Connection) -> None: + """Update a single stock price entry at random""" + + cur = con.cursor() + try: + sym = SYMBOLS[random.randint(0, len(SYMBOLS) - 1)] + print(f"Updating {sym}") + cur.execute( + "UPDATE stock_quotes SET timestamp = ?, price = ? WHERE symbol = ?", + (timestamp(), rand_price(), sym), + ) + con.commit() + finally: + cur.close() + + +async def update_db_task(con: sqlite3.Connection) -> Awaitable[None]: + """Task that alternates between sleeping and updating prices""" + while True: + await asyncio.sleep(random.random() * 1.5) + update_db(con) + + +asyncio.create_task(update_db_task(conn)) + + +# === Create the reactive.poll object =============================== + + +def tbl_last_modified() -> Any: + df = pd.read_sql_query("SELECT MAX(timestamp) AS timestamp FROM stock_quotes", conn) + return df["timestamp"].to_list() + + +@reactive.poll(tbl_last_modified, 0.5) +def stock_quotes() -> pd.DataFrame: + return pd.read_sql_query("SELECT timestamp, symbol, price FROM stock_quotes", conn) + + +# === Define the Shiny UI and server =============================== + +app_ui = ui.page_fluid( + ui.row( + ui.column( + 8, + ui.markdown( + """ + # `shiny.reactive.poll` demo + + This example app shows how to stream results from a database (in this + case, an in-memory sqlite3) with the help of `shiny.reactive.poll`. + """ + ), + class_="mb-3", + ), + ), + ui.input_selectize("symbols", "Filter by symbol", [""] + SYMBOLS, multiple=True), + ui.output_ui("table"), +) + + +def server(input: Inputs, output: Outputs, session: Session) -> None: + def filtered_quotes(): + df = stock_quotes() + if input.symbols(): + df = df[df["symbol"].isin(input.symbols())] + return df + + @render.ui + def table(): + return ui.HTML( + filtered_quotes().to_html( + index=False, classes="table font-monospace w-auto" + ) + ) + + +app = App(app_ui, server) + +``` + diff --git a/docs/api/reactive.value.qmd b/docs/api/reactive.value.qmd new file mode 100644 index 000000000..91af34414 --- /dev/null +++ b/docs/api/reactive.value.qmd @@ -0,0 +1,183 @@ +# reactive.Value { #shiny.reactive.Value } + +`reactive.Value(self, value=MISSING, *, read_only=False)` + +Create a reactive value. + +Reactive values are the source of reactivity in Shiny. Changes to reactive values +invalidate downstream reactive functions ([](:func:`~shiny.reactive.calc`), +[](:func:`~shiny.reactive.effect`), and `render` functions decorated with `@output`). +When these functions are invalidated, they get scheduled to re-execute. + +Shiny input values are read-only reactive values. For example, `input.x` is a +reactive value object, and to get the current value, you can call `input.x()` or +`input.x.get()`. When you do that inside of a reactive function, the function takes +a dependency on the reactive value. + +## Parameters + +value: [T](`shiny.reactive._reactives.T`) \| [MISSING_TYPE](`shiny.types.MISSING_TYPE`) = MISSING + +: An optional initial value. + +read_only: [bool](`bool`) = False + +: If ``True``, then the reactive value cannot be `set()`. + +## Returns + +| Type | Description | +|--------|----------------------------------| +| | An instance of a reactive value. | + +## Raises + +| Type | Description | +|-------------------------------------------------------------------------------------------|-----------------------------------------------------------------| +| ~[shiny](`shiny`).[types](`shiny.types`).[SilentException](`shiny.types.SilentException`) | If [](:func:`~Value.get`) is called before a value is provided/set. | + +## Note + +A reactive value may only be read from within a reactive function (e.g., +[](:func:`~shiny.reactive.calc`), [](:func:`~shiny.reactive.effect`), +[](:func:`shiny.render.text`), etc.) and, when doing so, the function takes a reactive +dependency on the value (i.e., when the value changes, the calling reactive function +will re-execute). + + + +## See Also + +[](:func:`~shiny.Inputs`) [](:func:`~shiny.reactive.calc`) [](:func:`~shiny.reactive.effect`) + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +from shiny import App, Inputs, Outputs, Session, reactive, render, ui + +app_ui = ui.page_fluid( + ui.input_action_button("minus", "-1"), + " ", + ui.input_action_button("plus", "+1"), + ui.br(), + ui.output_text("value"), +) + + +def server(input: Inputs, output: Outputs, session: Session): + val = reactive.Value(0) + + @reactive.Effect + @reactive.event(input.minus) + def _(): + newVal = val.get() - 1 + val.set(newVal) + + @reactive.Effect + @reactive.event(input.plus) + def _(): + newVal = val.get() + 1 + val.set(newVal) + + @render.text + def value(): + return str(val.get()) + + +app = App(app_ui, server) + +``` + + + +## Methods + +| Name | Description | +| --- | --- | +| [freeze](#shiny.reactive.Value.freeze) | Freeze the reactive value. Freezing is equivalent to unsetting the value, but it does not invalidate dependents. | +| [get](#shiny.reactive.Value.get) | Read the reactive value. | +| [is_set](#shiny.reactive.Value.is_set) | Check if the reactive value is set. | +| [set](#shiny.reactive.Value.set) | Set the reactive value to a new value. | +| [unset](#shiny.reactive.Value.unset) | Unset the reactive value. | + +### freeze { #shiny.reactive.Value.freeze } + +`reactive.Value.freeze()` + +Freeze the reactive value. + +Freezing is equivalent to unsetting the value, but it does not invalidate +dependents. + +### get { #shiny.reactive.Value.get } + +`reactive.Value.get()` + +Read the reactive value. + +#### Returns + +| Type | Description | +|------------------------------------|---------------| +| [T](`shiny.reactive._reactives.T`) | A value. | + +#### Raises + +| Type | Description | +|-------------------------------------------------------------------------------------------|---------------------------------------------| +| ~[shiny](`shiny`).[types](`shiny.types`).[SilentException](`shiny.types.SilentException`) | If the value is not set. | +| [RuntimeError](`RuntimeError`) | If called from outside a reactive function. | + +### is_set { #shiny.reactive.Value.is_set } + +`reactive.Value.is_set()` + +Check if the reactive value is set. + +#### Returns + +| Type | Description | +|----------------|----------------------------------------------------| +| [bool](`bool`) | ``True`` if the value is set, ``False`` otherwise. | + +### set { #shiny.reactive.Value.set } + +`reactive.Value.set(value)` + +Set the reactive value to a new value. + +#### Parameters + +value: [T](`shiny.reactive._reactives.T`) + +: A value. + +#### Returns + +| Type | Description | +|----------------|-----------------------------------------------------------------------------| +| [bool](`bool`) | ``True`` if the value was set to a different value and ``False`` otherwise. | + +#### Raises + +| Type | Description | +|--------------------------------|------------------------------------------| +| [RuntimeError](`RuntimeError`) | If called on a read-only reactive value. | + +### unset { #shiny.reactive.Value.unset } + +`reactive.Value.unset()` + +Unset the reactive value. + +#### Returns + +| Type | Description | +|--------|--------------------------------------------------------| +| None | ``True`` if the value was set prior to this unsetting. | \ No newline at end of file diff --git a/docs/api/render.DataGrid.qmd b/docs/api/render.DataGrid.qmd new file mode 100644 index 000000000..b19cb84e1 --- /dev/null +++ b/docs/api/render.DataGrid.qmd @@ -0,0 +1,58 @@ +# render.DataGrid { #shiny.render.DataGrid } + +`render.DataGrid(self, data, *, width='fit-content', height='500px', summary=True, filters=False, row_selection_mode='none')` + +Holds the data and options for a ``shiny.render.data_frame`` output, for a +spreadsheet-like view. + +## Parameters + +data: [object](`object`) + +: A pandas `DataFrame` object, or any object that has a `.to_pandas()` method + (e.g., a Polars data frame or Arrow table). + +width: [str](`str`) \| [float](`float`) \| None = 'fit-content' + +: A _maximum_ amount of vertical space for the data grid to occupy, in CSS units + (e.g. `"400px"`) or as a number, which will be interpreted as pixels. The + default is `fit-content`, which sets the grid's width according to its contents. + Set this to `100%` to use the maximum available horizontal space. + +height: [Union](`typing.Union`)\[[str](`str`), [float](`float`), None\] = '500px' + +: A _maximum_ amount of vertical space for the data grid to occupy, in CSS units + (e.g. `"400px"`) or as a number, which will be interpreted as pixels. If there + are more rows than can fit in this space, the grid will scroll. Set the height + to `None` to allow the grid to grow to fit all of the rows (this is not + recommended for large data sets, as it may crash the browser). + +summary: [Union](`typing.Union`)\[[bool](`bool`), [str](`str`)\] = True + +: If `True` (the default), shows a message like "Viewing rows 1 through 10 of 20" + below the grid when not all of the rows are being shown. If `False`, the message + is not displayed. You can also specify a string template to customize the + message, containing `{start}`, `{end}`, and `{total}` tokens. For example: + `"Viendo filas {start} a {end} de {total}"`. + +filters: [bool](`bool`) = False + +: If `True`, shows a row of filter inputs below the headers, one for each column. + +row_selection_mode: [Literal](`typing.Literal`)\['none', 'single', 'multiple'\] = 'none' + +: Use `"none"` to disable row selection, `"single"` to allow a single row to be + selected at a time, and `"multiple"` to allow multiple rows to be selected by + clicking on them individually. + +## Returns + +| Type | Description | +|--------|----------------------------------------------------------------------------------------------| +| | An object suitable for being returned from a `@render.data_frame`-decorated output function. | + +## See Also + +[](:func:`~shiny.ui.output_data_frame`) +[](:func:`~shiny.render.data_frame`) +[](:class:`~shiny.render.DataTable`) \ No newline at end of file diff --git a/docs/api/render.DataTable.qmd b/docs/api/render.DataTable.qmd new file mode 100644 index 000000000..d847bd5b2 --- /dev/null +++ b/docs/api/render.DataTable.qmd @@ -0,0 +1,58 @@ +# render.DataTable { #shiny.render.DataTable } + +`render.DataTable(self, data, *, width='fit-content', height='500px', summary=True, filters=False, row_selection_mode='none')` + +Holds the data and options for a ``shiny.render.data_frame`` output, for a +spreadsheet-like view. + +## Parameters + +data: [object](`object`) + +: A pandas `DataFrame` object, or any object that has a `.to_pandas()` method + (e.g., a Polars data frame or Arrow table). + +width: [Union](`typing.Union`)\[[str](`str`), [float](`float`), None\] = 'fit-content' + +: A _maximum_ amount of vertical space for the data table to occupy, in CSS units + (e.g. `"400px"`) or as a number, which will be interpreted as pixels. The + default is `fit-content`, which sets the table's width according to its + contents. Set this to `100%` to use the maximum available horizontal space. + +height: [Union](`typing.Union`)\[[str](`str`), [float](`float`), None\] = '500px' + +: A _maximum_ amount of vertical space for the data table to occupy, in CSS units + (e.g. `"400px"`) or as a number, which will be interpreted as pixels. If there + are more rows than can fit in this space, the table body will scroll. Set the + height to `None` to allow the table to grow to fit all of the rows (this is not + recommended for large data sets, as it may crash the browser). + +summary: [Union](`typing.Union`)\[[bool](`bool`), [str](`str`)\] = True + +: If `True` (the default), shows a message like "Viewing rows 1 through 10 of 20" + below the grid when not all of the rows are being shown. If `False`, the message + is not displayed. You can also specify a string template to customize the + message, containing `{start}`, `{end}`, and `{total}` tokens. For example: + `"Viendo filas {start} a {end} de {total}"`. + +filters: [bool](`bool`) = False + +: If `True`, shows a row of filter inputs below the headers, one for each column. + +row_selection_mode: [Union](`typing.Union`)\[[Literal](`typing.Literal`)\['none'\], [Literal](`typing.Literal`)\['single'\], [Literal](`typing.Literal`)\['multiple'\]\] = 'none' + +: Use `"none"` to disable row selection, `"single"` to allow a single row to be + selected at a time, and `"multiple"` to allow multiple rows to be selected by + clicking on them individually. + +## Returns + +| Type | Description | +|--------|----------------------------------------------------------------------------------------------| +| | An object suitable for being returned from a `@render.data_frame`-decorated output function. | + +## See Also + +[](:func:`~shiny.ui.output_data_frame`) +[](:func:`~shiny.render.data_frame`) +[](:class:`~shiny.render.DataGrid`) \ No newline at end of file diff --git a/docs/api/render.data_frame.qmd b/docs/api/render.data_frame.qmd new file mode 100644 index 000000000..cb272b58c --- /dev/null +++ b/docs/api/render.data_frame.qmd @@ -0,0 +1,184 @@ +# render.data_frame { #shiny.render.data_frame } + +`render.data_frame()` + +Decorator for a function that returns a pandas `DataFrame` object (or similar) to +render as an interactive table or grid. Features fast virtualized scrolling, sorting, +filtering, and row selection (single or multiple). + +## Returns + +| Type | Description | +|--------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| | A decorator for a function that returns any of the following: 1. A [](:class:`~shiny.render.DataGrid`) or [](:class:`~shiny.render.DataTable`) object, which can be used to customize the appearance and behavior of the data frame output. 2. A pandas [](:class:`DataFrame`) object. (Equivalent to `shiny.render.DataGrid(df)`.) 3. Any object that has a `.to_pandas()` method (e.g., a Polars data frame or Arrow table). (Equivalent to `shiny.render.DataGrid(df.to_pandas())`.) | + +## Row Selection + +When using the row selection feature, you can access the selected rows by using the +`input._selected_rows()` function, where `` is the `id` of the +[](:func:`~shiny.ui.output_data_frame`). The value returned will be `None` 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._selected_rows())]`. + + + +## Tip + +This decorator should be applied **before** the ``@output`` decorator (if that +decorator is used). Also, the name of the decorated function (or +``@output(id=...)``) should match the ``id`` of a [](:func:`~shiny.ui.output_table`) +container (see [](:func:`~shiny.ui.output_table`) for example usage). + + + +## See Also + +* [](:func:`~shiny.ui.output_data_frame`) +* [](:class:`~shiny.render.DataGrid`) and [](:class:`~shiny.render.DataTable`) are the + objects you can return from the rendering function to specify options. + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +import pandas # noqa: F401 (this line needed for Shinylive to load plotly.express) +import plotly.express as px +import plotly.graph_objs as go +from shinywidgets import output_widget, render_widget + +from shiny import App, reactive, render, req, session, ui + +# Load the Gapminder dataset +df = px.data.gapminder() + +# Prepare a summary DataFrame +summary_df = ( + df.groupby("country") + .agg( + { + "pop": ["min", "max", "mean"], + "lifeExp": ["min", "max", "mean"], + "gdpPercap": ["min", "max", "mean"], + } + ) + .reset_index() +) + +summary_df.columns = ["_".join(col).strip() for col in summary_df.columns.values] +summary_df.rename(columns={"country_": "country"}, inplace=True) + +app_ui = ui.page_fillable( + {"class": "p-3"}, + ui.p( + ui.strong("Instructions:"), + " Select one or more countries in the table below to see more information.", + ), + ui.layout_column_wrap( + ui.card( + ui.output_data_frame("summary_data"), + ), + ui.layout_column_wrap( + ui.card( + output_widget("country_detail_pop", height="100%"), + ), + ui.card( + output_widget("country_detail_percap", height="100%"), + ), + width=1 / 2, + ), + width=1, + ), +) + + +def server(input, output, session): + @render.data_frame + def summary_data(): + return render.DataGrid( + summary_df.round(2), + row_selection_mode="multiple", + width="100%", + height="100%", + ) + + @reactive.Calc + def filtered_df(): + # input.summary_data_selected_rows() is a tuple, so we must convert it to list, + # as that's what Pandas requires for indexing. + selected_idx = list(req(input.summary_data_selected_rows())) + countries = summary_df.iloc[selected_idx]["country"] + # Filter data for selected countries + return df[df["country"].isin(countries)] + + @render_widget + def country_detail_pop(): + # Create the plot + fig = px.line( + filtered_df(), + x="year", + y="pop", + color="country", + title="Population Over Time", + ) + widget = go.FigureWidget(fig) + + @synchronize_size("country_detail_pop") + def on_size_changed(width, height): + widget.layout.width = width + widget.layout.height = height + + return widget + + @render_widget + def country_detail_percap(): + # Create the plot + fig = px.line( + filtered_df(), + x="year", + y="gdpPercap", + color="country", + title="GDP per Capita Over Time", + ) + widget = go.FigureWidget(fig) + + @synchronize_size("country_detail_percap") + def on_size_changed(width, height): + widget.layout.width = width + widget.layout.height = height + + return widget + + +# This is a hacky workaround to help Plotly plots automatically +# resize to fit their container. In the future we'll have a +# built-in solution for this. +def synchronize_size(output_id): + def wrapper(func): + input = session.get_current_session().input + + @reactive.Effect + def size_updater(): + func( + input[f".clientdata_output_{output_id}_width"](), + input[f".clientdata_output_{output_id}_height"](), + ) + + # When the output that we're synchronizing to is invalidated, + # clean up the size_updater Effect. + reactive.get_current_context().on_invalidate(size_updater.destroy) + + return size_updater + + return wrapper + + +app = App(app_ui, server) + +``` + diff --git a/docs/api/render.image.qmd b/docs/api/render.image.qmd new file mode 100644 index 000000000..058f427a6 --- /dev/null +++ b/docs/api/render.image.qmd @@ -0,0 +1,31 @@ +# render.image { #shiny.render.image } + +`render.image(self, _fn=None, *, delete_file=False)` + +Reactively render a image file as an HTML image. + +## Parameters + +delete_file: [bool](`bool`) = False + +: If ``True``, the image file will be deleted after rendering. + +## Returns + +| Type | Description | +|--------|---------------------------------------------------------------------------------| +| | A decorator for a function that returns an [](:func:`~shiny.types.ImgData`) object. | + +## Tip + +The name of the decorated function (or ``@output(id=...)``) should match the ``id`` +of a [](:func:`~shiny.ui.output_image`) container (see [](:func:`~shiny.ui.output_image`) +for example usage). + + + +## See Also + +[](:func:`~shiny.ui.output_image`) +[](:func:`~shiny.types.ImgData`) +[](:func:`~shiny.render.plot`) \ No newline at end of file diff --git a/docs/api/render.plot.qmd b/docs/api/render.plot.qmd new file mode 100644 index 000000000..25fc92f78 --- /dev/null +++ b/docs/api/render.plot.qmd @@ -0,0 +1,55 @@ +# render.plot { #shiny.render.plot } + +`render.plot(self, _fn=None, *, alt=None, width=MISSING, height=MISSING, **kwargs)` + +Reactively render a plot object as an HTML image. + +## Parameters + +alt: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: Alternative text for the image if it cannot be displayed or viewed (i.e., the + user uses a screen reader). + +width: [float](`float`) \| None \| [MISSING_TYPE](`shiny.types.MISSING_TYPE`) = MISSING + +: Width of the plot in pixels. If ``None`` or ``MISSING``, the width will be + determined by the size of the corresponding [](:func:`~shiny.ui.output_plot`). (You + should not need to use this argument in most Shiny apps--set the desired width + on [](:func:`~shiny.ui.output_plot`) instead.) + +height: [float](`float`) \| None \| [MISSING_TYPE](`shiny.types.MISSING_TYPE`) = MISSING + +: Height of the plot in pixels. If ``None`` or ``MISSING``, the height will be + determined by the size of the corresponding [](:func:`~shiny.ui.output_plot`). (You + should not need to use this argument in most Shiny apps--set the desired height + on [](:func:`~shiny.ui.output_plot`) instead.) + +**kwargs: [object](`object`) = {} + +: Additional keyword arguments passed to the relevant method for saving the image + (e.g., for matplotlib, arguments to ``savefig()``; for PIL and plotnine, + arguments to ``save()``). + +## Returns + +| Type | Description | +|--------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| | A decorator for a function that returns any of the following: 1. A [](:class:`matplotlib.figure.Figure`) instance. 2. An [](:class:`matplotlib.artist.Artist`) instance. 3. A list/tuple of Figure/Artist instances. 4. An object with a 'figure' attribute pointing to a [](:class:`matplotlib.figure.Figure`) instance. 5. A [](:class:`PIL.Image.Image`) instance. | +| It's also possible to use the ``matplotlib.pyplot`` interface; in that case, your | | +| function should just call pyplot functions and not return anything. (Note that if | | +| the decorated function is async, then it's not safe to use pyplot. Shiny will detect | | +| this case and throw an error asking you to use matplotlib's object-oriented | | +| interface instead.) | | + +## Tip + +The name of the decorated function (or ``@output(id=...)``) should match the ``id`` +of a [](:func:`~shiny.ui.output_plot`) container (see [](:func:`~shiny.ui.output_plot`) for +example usage). + + + +## See Also + +[](:func:`~shiny.ui.output_plot`) [](:func:`~shiny.render.image`) \ No newline at end of file diff --git a/docs/api/render.table.qmd b/docs/api/render.table.qmd new file mode 100644 index 000000000..b591fdf79 --- /dev/null +++ b/docs/api/render.table.qmd @@ -0,0 +1,50 @@ +# render.table { #shiny.render.table } + +`render.table(self, _fn=None, *, index=False, classes='table shiny-table w-auto', border=0, **kwargs)` + +Reactively render a pandas ``DataFrame`` object (or similar) as a basic HTML +table. + +Consider using [](:func:`~shiny.render.data_frame`) instead of this renderer, as +it provides high performance virtual scrolling, built-in filtering and sorting, +and a better default appearance. This renderer may still be helpful if you +use pandas styling features that are not currently supported by +[](:func:`~shiny.render.data_frame`). + +## Parameters + +index: [bool](`bool`) = False + +: Whether to print index (row) labels. (Ignored for pandas [](:class:`Styler`) + objects; call ``style.hide(axis="index")`` from user code instead.) + +classes: [str](`str`) = 'table shiny-table w-auto' + +: CSS classes (space separated) to apply to the resulting table. By default, we + use `table shiny-table w-auto` which is designed to look reasonable with + Bootstrap 5. (Ignored for pandas [](:class:`Styler`) objects; call + ``style.set_table_attributes('class="dataframe table shiny-table w-auto"')`` + from user code instead.) + +**kwargs: [object](`object`) = {} + +: Additional keyword arguments passed to ``pandas.DataFrame.to_html()`` or + ``pandas.io.formats.style.Styler.to_html()``. + +## Returns + +| Type | Description | +|--------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| | A decorator for a function that returns any of the following: 1. A pandas [](:class:`DataFrame`) object. 2. A pandas [](:class:`Styler`) object. 3. Any object that has a `.to_pandas()` method (e.g., a Polars data frame or Arrow table). | + +## Tip + +The name of the decorated function (or ``@output(id=...)``) should match the ``id`` +of a [](:func:`~shiny.ui.output_table`) container (see [](:func:`~shiny.ui.output_table`) +for example usage). + + + +## See Also + +[](:func:`~shiny.ui.output_table`) for the corresponding UI component to this render function. \ No newline at end of file diff --git a/docs/api/render.text.qmd b/docs/api/render.text.qmd new file mode 100644 index 000000000..6291d508b --- /dev/null +++ b/docs/api/render.text.qmd @@ -0,0 +1,23 @@ +# render.text { #shiny.render.text } + +`render.text()` + +Reactively render text. + +## Returns + +| Type | Description | +|--------|---------------------------------------------------| +| | A decorator for a function that returns a string. | + +## Tip + +The name of the decorated function (or ``@output(id=...)``) should match the ``id`` +of a [](:func:`~shiny.ui.output_text`) container (see [](:func:`~shiny.ui.output_text`) for +example usage). + + + +## See Also + +[](:func:`~shiny.ui.output_text`) \ No newline at end of file diff --git a/docs/api/render.transformer.resolve_value_fn.qmd b/docs/api/render.transformer.resolve_value_fn.qmd new file mode 100644 index 000000000..5c120f201 --- /dev/null +++ b/docs/api/render.transformer.resolve_value_fn.qmd @@ -0,0 +1,38 @@ +# render.transformer.resolve_value_fn { #shiny.render.transformer.resolve_value_fn } + +`render.transformer.resolve_value_fn(value_fn)` + +Resolve the value function + +This function is used to resolve the value function (`value_fn`) to an object of +type `IT`. If the value function is asynchronous, it will be awaited. If the value +function is synchronous, it will be called. + +While always using an async method within an output transform function is not +appropriate, this method may be safely used to avoid boilerplate. + +Replace this: +```python +if is_async_callable(_fn): + x = await _fn() +else: + x = cast(ValueFnSync[IT], _fn)() +``` + +With this: +```python +x = await resolve_value_fn(_fn) +``` + +## Parameters + +value_fn: [ValueFn](`shiny.render.transformer._transformer.ValueFn`)\[[IT](`shiny.render.transformer._transformer.IT`)\] + +: App-supplied output value function which returns type `IT`. This function can be + synchronous or asynchronous. + +## Returns + +| Type | Description | +|--------------------------------------------------|-------------------------------------| +| [IT](`shiny.render.transformer._transformer.IT`) | The resolved value from `value_fn`. | \ No newline at end of file diff --git a/docs/api/render.ui.qmd b/docs/api/render.ui.qmd new file mode 100644 index 000000000..a26370778 --- /dev/null +++ b/docs/api/render.ui.qmd @@ -0,0 +1,23 @@ +# render.ui { #shiny.render.ui } + +`render.ui()` + +Reactively render HTML content. + +## Returns + +| Type | Description | +|--------|----------------------------------------------------------------------------------------| +| | A decorator for a function that returns an object of type [](:class:`~shiny.ui.TagChild`). | + +## Tip + +The name of the decorated function (or ``@output(id=...)``) should match the ``id`` +of a [](:func:`~shiny.ui.output_ui`) container (see [](:func:`~shiny.ui.output_ui`) for +example usage). + + + +## See Also + +[](:func:`~shiny.ui.output_ui`) \ No newline at end of file diff --git a/docs/api/req.qmd b/docs/api/req.qmd new file mode 100644 index 000000000..f714f1447 --- /dev/null +++ b/docs/api/req.qmd @@ -0,0 +1,90 @@ +# req { #shiny.req } + +`req(*args, cancel_output=False)` + +Throw a silent exception for falsy values. + +This is a convenient shorthand for throwing [](:func:`~shiny.types.SilentException`) / +[](:func:`~shiny.types.SilentCancelOutputException`) if any of the arguments are falsy. + +The term "falsy" generally indicates that a value is considered `False` when +encountered in a logical context. We use the term a little loosely here; our usage +tries to match the intuitive notions of "Is this value missing or available?", or +"Has the user provided an answer?", or in the case of action buttons, "Has the +button been clicked?". So `False`, `None`, `0`, and `""` would be examples of Falsy +values. + +## Parameters + +*args: [T](`shiny._validation.T`) = () + +: Any number of arguments to check. + +cancel_output: [bool](`bool`) = False + +: If ``True``, throw [](:func:`~shiny.types.SilentCancelOutputException`) instead of + [](:func:`~shiny.types.SilentException`). + +## Returns + +| Type | Description | +|------------------------------------|---------------------------------------------------------------------| +| [T](`shiny._validation.T`) \| None | The first argument. If no arguments are provided, returns ``None``. | + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +from shiny import App, Inputs, Outputs, Session, reactive, render, req, ui +from shiny.types import SafeException + +app_ui = ui.page_fluid( + ui.input_action_button("safe", "Throw a safe error"), + ui.output_ui("safe"), + ui.input_action_button("unsafe", "Throw an unsafe error"), + ui.output_ui("unsafe"), + ui.input_text( + "txt", + "Enter some text below, then remove it. Notice how the text is never fully removed.", + ), + ui.output_ui("txt_out"), +) + + +def server(input: Inputs, output: Outputs, session: Session): + @reactive.Calc + def safe_click(): + req(input.safe()) + return input.safe() + + @render.ui + def safe(): + raise SafeException(f"You've clicked {str(safe_click())} times") + + @render.ui + def unsafe(): + req(input.unsafe()) + raise Exception(f"Super secret number of clicks: {str(input.unsafe())}") + + @reactive.Effect + def _(): + req(input.unsafe()) + print("unsafe clicks:", input.unsafe()) + # raise Exception("Observer exception: this should cause a crash") + + @render.ui + def txt_out(): + req(input.txt(), cancel_output=True) + return input.txt() + + +app = App(app_ui, server) +app.sanitize_errors = True + +``` + diff --git a/docs/api/run_app.qmd b/docs/api/run_app.qmd new file mode 100644 index 000000000..4baa4436e --- /dev/null +++ b/docs/api/run_app.qmd @@ -0,0 +1,99 @@ +# run_app { #shiny.run_app } + +`run_app(app='app:app', host='127.0.0.1', port=8000, *, autoreload_port=0, reload=False, reload_dirs=None, reload_includes=RELOAD_INCLUDES_DEFAULT, reload_excludes=RELOAD_EXCLUDES_DEFAULT, ws_max_size=16777216, log_level=None, app_dir='.', factory=False, launch_browser=False, **kwargs)` + +Starts a Shiny app. Press ``Ctrl+C`` (or ``Ctrl+Break`` on Windows) to stop the app. + +## Parameters + +app: [str](`str`) \| [shiny](`shiny`).[App](`shiny.App`) = 'app:app' + +: The app to run. The default, ``app:app``, represents the "usual" case where the + application is named ``app`` inside a ``app.py`` file within the current working + directory. In other cases, the app location can be specified as a + ``:`` string where the ``:`` is only necessary if + the application is named something other than ``app``. Note that ```` + can be a relative path to a ``.py`` file or a directory (with an ``app.py`` file + inside of it); and in this case, the relative path is resolved relative to the + ``app_dir`` directory. + +host: [str](`str`) = '127.0.0.1' + +: The address that the app should listen on. + +port: [int](`int`) = 8000 + +: The port that the app should listen on. Set to 0 to use a random port. + +autoreload_port: [int](`int`) = 0 + +: The port that should be used for an additional websocket that is used to support + hot-reload. Set to 0 to use a random port. + +reload: [bool](`bool`) = False + +: Enable auto-reload. + +reload_dirs: [Optional](`typing.Optional`)\[[list](`list`)\[[str](`str`)\]\] = None + +: A list of directories (in addition to the app directory) to watch for changes that + will trigger an app reload. + +reload_includes: [list](`list`)\[[str](`str`)\] \| [tuple](`tuple`)\[[str](`str`), ...\] = RELOAD_INCLUDES_DEFAULT + +: List or tuple of file globs to indicate which files should be monitored for + changes. Can be combined with `reload_excludes`. + +reload_excludes: [list](`list`)\[[str](`str`)\] \| [tuple](`tuple`)\[[str](`str`), ...\] = RELOAD_EXCLUDES_DEFAULT + +: List or tuple of file globs to indicate which files should be excluded from + reload monitoring. Can be combined with `reload_includes` + +ws_max_size: [int](`int`) = 16777216 + +: WebSocket max size message in bytes. + +log_level: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: Log level. + +app_dir: [Optional](`typing.Optional`)\[[str](`str`)\] = '.' + +: The directory to look for ``app`` under (by adding this to the ``PYTHONPATH``). + +factory: [bool](`bool`) = False + +: Treat ``app`` as an application factory, i.e. a () -> callable. + +launch_browser: [bool](`bool`) = False + +: Launch app browser after app starts, using the Python webbrowser module. + +**kwargs: [object](`object`) = {} + +: Additional keyword arguments which are passed to ``uvicorn.run``. For more + information see [Uvicorn documentation](https://www.uvicorn.org/). + +## Tip + +The ``shiny run`` command-line interface (which comes installed with Shiny) provides +the same functionality as [](:func:`~shiny.run_app`). + +## Examples + +```{python} +#|eval: false +from shiny import run_app + +# Run ``app`` inside ``./app.py`` +run_app() + +# Run ``app`` inside ``./myapp.py`` (or ``./myapp/app.py``) +run_app("myapp") + +# Run ``my_app`` inside ``./myapp.py`` (or ``./myapp/app.py``) +run_app("myapp:my_app") + +# Run ``my_app`` inside ``../myapp.py`` (or ``../myapp/app.py``) +run_app("myapp:my_app", app_dir="..") +``` \ No newline at end of file diff --git a/docs/api/session.get_current_session.qmd b/docs/api/session.get_current_session.qmd new file mode 100644 index 000000000..87d4f5be2 --- /dev/null +++ b/docs/api/session.get_current_session.qmd @@ -0,0 +1,23 @@ +# session.get_current_session { #shiny.session.get_current_session } + +`session.get_current_session()` + +Get the current user session. + +## Returns + +| Type | Description | +|------------------------------------------------------------------------------|-----------------------------------------------------------| +| [Optional](`typing.Optional`)\[[Session](`shiny.session._session.Session`)\] | The current session if one is active, otherwise ``None``. | + +## Note + +Shiny apps should not need to call this function directly. Instead, it is intended to +be used by Shiny developers who wish to create new functions that should only be +called from within an active Shiny session. + + + +## See Also + +[](:func:`~require_active_session`) \ No newline at end of file diff --git a/docs/api/session.require_active_session.qmd b/docs/api/session.require_active_session.qmd new file mode 100644 index 000000000..be425a863 --- /dev/null +++ b/docs/api/session.require_active_session.qmd @@ -0,0 +1,34 @@ +# session.require_active_session { #shiny.session.require_active_session } + +`session.require_active_session(session)` + +Raise an exception if no Shiny session is currently active. + +## Parameters + +session: [Optional](`typing.Optional`)\[[Session](`shiny.session._session.Session`)\] + +: A [](:class:`~shiny.Session`) instance. If not provided, the session is inferred via + [](:func:`~shiny.session.get_current_session`). + +## Returns + +| Type | Description | +|---------------------------------------------|---------------| +| [Session](`shiny.session._session.Session`) | The session. | + +## Note + +Shiny apps should not need to call this function directly. Instead, it is intended to +be used by Shiny developers who wish to create new functions that should only be +called from within an active Shiny session. + +## Raises + +| Type | Description | +|----------------------------|---------------------------| +| [ValueError](`ValueError`) | If session is not active. | + +## See Also + +[](:func:`~get_current_session`) \ No newline at end of file diff --git a/docs/api/session.session_context.qmd b/docs/api/session.session_context.qmd new file mode 100644 index 000000000..be4b028ab --- /dev/null +++ b/docs/api/session.session_context.qmd @@ -0,0 +1,12 @@ +# session.session_context { #shiny.session.session_context } + +`session.session_context(session)` + +A context manager for current session. + +## Parameters + +session: [Optional](`typing.Optional`)\[[Session](`shiny.session._session.Session`)\] + +: A [](:class:`~shiny.Session`) instance. If not provided, the instance is inferred via + [](:func:`~shiny.session.get_current_session`). \ No newline at end of file diff --git a/docs/api/ui.HTML.qmd b/docs/api/ui.HTML.qmd new file mode 100644 index 000000000..4864c9fa9 --- /dev/null +++ b/docs/api/ui.HTML.qmd @@ -0,0 +1,16 @@ +# ui.HTML { #shiny.ui.HTML } + +`ui.HTML()` + +Mark a string as raw HTML. This will prevent the string from being escaped when +rendered inside an HTML tag. + +## Examples + +```python +>>> from htmltools import HTML, div +>>> div("

Hello

") +
<p>Hello</p>
+>>> div(HTML("

Hello

")) +

Hello

+``` \ No newline at end of file diff --git a/docs/api/ui.Progress.qmd b/docs/api/ui.Progress.qmd new file mode 100644 index 000000000..570f3bef1 --- /dev/null +++ b/docs/api/ui.Progress.qmd @@ -0,0 +1,195 @@ +# ui.Progress { #shiny.ui.Progress } + +`ui.Progress(self, min=0, max=1, session=None)` + +Initialize a progress bar. + +[](:func:`~shiny.ui.Progress`) creates a computation manager that can be used with `with` to +run a block of code. Shiny will display a progress bar while the code runs, which +you can update by calling the `set()` and `message()` methods of the computation +manager at strategic points in the code block. + +## Parameters + +min: [int](`int`) = 0 + +: The value that represents the starting point of the progress bar. Must be less + than ``max``. + +max: [int](`int`) = 1 + +: The value that represents the end of the progress bar. Must be greater than + ``min``. + +session: [Optional](`typing.Optional`)\[[Session](`shiny.session.Session`)\] = None + +: The [](:class:`~shiny.Session`) instance that the progress bar should appear in. If not + provided, the session is inferred via [](:func:`~shiny.session.get_current_session`). + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +import asyncio + +from shiny import App, Inputs, Outputs, Session, reactive, render, ui + +app_ui = ui.page_fluid( + ui.input_action_button("button", "Compute"), + ui.output_text("compute"), +) + + +def server(input: Inputs, output: Outputs, session: Session): + @render.text + @reactive.event(input.button) + async def compute(): + with ui.Progress(min=1, max=15) as p: + p.set(message="Calculation in progress", detail="This may take a while...") + + for i in range(1, 15): + p.set(i, message="Computing") + await asyncio.sleep(0.1) + # Normally use time.sleep() instead, but it doesn't yet work in Pyodide. + # https://github.com/pyodide/pyodide/issues/2354 + + return "Done computing!" + + +app = App(app_ui, server) + +``` + + + +## Methods + +| Name | Description | +| --- | --- | +| [close](#shiny.ui.Progress.close) | Close the progress bar. You can also use the Progress object as a context manager, which will cause the progress bar to close on exit. | +| [inc](#shiny.ui.Progress.inc) | Increment the progress bar. Like ``set``, this updates the progress panel. The difference is that ``inc`` increases the progress bar by amount, instead of setting it to a specific value. | +| [set](#shiny.ui.Progress.set) | Opens and updates the progress panel. When called the first time, the progress panel is displayed. | + +### close { #shiny.ui.Progress.close } + +`ui.Progress.close()` + +Close the progress bar. You can also use the Progress object as a context +manager, which will cause the progress bar to close on exit. + +#### Parameters + +self + +: The object instance + +#### Note + +Removes the progress panel. Future calls to set and close will be ignored. + +#### Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +from datetime import datetime + +from shiny import App, Inputs, Outputs, Session, reactive, ui + +app_ui = ui.page_fluid( + ui.input_action_button("close", "Close the session"), + ui.p( + """If this example is running on the browser (i.e., via shinylive), + closing the session will log a message to the JavaScript console + (open the browser's developer tools to see it). + """ + ), +) + + +def server(input: Inputs, output: Outputs, session: Session): + def log(): + print("Session ended at: " + datetime.now().strftime("%H:%M:%S")) + + session.on_ended(log) + + @reactive.Effect + @reactive.event(input.close) + async def _(): + await session.close() + + +app = App(app_ui, server) + +``` + + + +### inc { #shiny.ui.Progress.inc } + +`ui.Progress.inc(amount=0.1, message=None, detail=None)` + +Increment the progress bar. + +Like ``set``, this updates the progress panel. The difference is that ``inc`` +increases the progress bar by amount, instead of setting it to a specific value. + +#### Parameters + +self + +: The object instance + +amount: [float](`float`) = 0.1 + +: The amount to increment in progress. + +message: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: The message to be displayed to the user or ``None`` to hide the current + message (if any). + +detail: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: The detail message to be displayed to the user or ``None`` to hide the current + detail message (if any). The detail message will be shown with a + de-emphasized appearance relative to message. + +### set { #shiny.ui.Progress.set } + +`ui.Progress.set(value=None, message=None, detail=None)` + +Opens and updates the progress panel. + +When called the first time, the progress panel is displayed. + +#### Parameters + +self + +: The object instance + +value: [Optional](`typing.Optional`)\[[float](`float`)\] = None + +: The value at which to set the progress bar, relative to ``min`` and ``max``. + ``None`` hides the progress bar, if it is currently visible. + +message: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: The message to be displayed to the user or ``None`` to hide the current + message (if any). + +detail: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: The detail message to be displayed to the user or ``None`` to hide the + current detail message (if any). The detail message will be shown with a + de-emphasized appearance relative to message. \ No newline at end of file diff --git a/docs/api/ui.ShowcaseLayout.qmd b/docs/api/ui.ShowcaseLayout.qmd new file mode 100644 index 000000000..a7201c7a0 --- /dev/null +++ b/docs/api/ui.ShowcaseLayout.qmd @@ -0,0 +1,28 @@ +# ui.ShowcaseLayout { #shiny.ui.ShowcaseLayout } + +`ui.ShowcaseLayout(self, *, class_, width='33%', width_full_screen='1fr', height=None, height_full_screen=None, max_height='100px', max_height_full_screen='67%')` + +Showcase layout + +Base layout information utilized to display [](:func:`~shiny.ui.value_box`)'s `showcase` value. + + + +## See Also + +* [](:func:`~shiny.ui.showcase_left_center`) +* [](:func:`~shiny.ui.showcase_top_right`) +* [](:func:`~shiny.ui.showcase_bottom`) +* [](:func:`~shiny.ui.value_box`) + +## Attributes + +| Name | Description | +| --- | --- | +| [class_](#shiny.ui.ShowcaseLayout.class_) | CSS class to set on the layout | +| [height](#shiny.ui.ShowcaseLayout.height) | Height of the showcase area | +| [height_full_screen](#shiny.ui.ShowcaseLayout.height_full_screen) | Height of the showcase area when the value box is full screen | +| [max_height](#shiny.ui.ShowcaseLayout.max_height) | Maximum height of the showcase area | +| [max_height_full_screen](#shiny.ui.ShowcaseLayout.max_height_full_screen) | Maximum height of the showcase area when the value box is full screen | +| [width](#shiny.ui.ShowcaseLayout.width) | Width of the showcase area | +| [width_full_screen](#shiny.ui.ShowcaseLayout.width_full_screen) | Width of the showcase area when the value box is full screen | \ No newline at end of file diff --git a/docs/api/ui.TagList.qmd b/docs/api/ui.TagList.qmd new file mode 100644 index 000000000..8fc6db327 --- /dev/null +++ b/docs/api/ui.TagList.qmd @@ -0,0 +1,137 @@ +# ui.TagList { #shiny.ui.TagList } + +`ui.TagList(self, *args)` + +Create an HTML tag list (i.e., a fragment of HTML) + +## Parameters + +*args: [TagChild](`htmltools._core.TagChild`) = () + +: The tag children to add to the list. + +## Examples + +```python +>>> from htmltools import TagList, div +>>> TagList("hello", div(id="foo", class_="bar")) +hello +
+``` + +## Methods + +| Name | Description | +| --- | --- | +| [append](#shiny.ui.TagList.append) | Append tag children to the end of the list. | +| [extend](#shiny.ui.TagList.extend) | Extend the children by appending an iterable of children. | +| [get_dependencies](#shiny.ui.TagList.get_dependencies) | Get any dependencies needed to render the HTML. | +| [get_html_string](#shiny.ui.TagList.get_html_string) | Return the HTML string for this tag list. | +| [insert](#shiny.ui.TagList.insert) | Insert tag children before a given index. | +| [render](#shiny.ui.TagList.render) | Get string representation as well as its HTML dependencies. | +| [save_html](#shiny.ui.TagList.save_html) | Save to a HTML file. | +| [show](#shiny.ui.TagList.show) | Preview as a complete HTML document. | +| [tagify](#shiny.ui.TagList.tagify) | Convert any tagifiable children to Tag/TagList objects. | + +### append { #shiny.ui.TagList.append } + +`ui.TagList.append(*args)` + +Append tag children to the end of the list. + +### extend { #shiny.ui.TagList.extend } + +`ui.TagList.extend(x)` + +Extend the children by appending an iterable of children. + +### get_dependencies { #shiny.ui.TagList.get_dependencies } + +`ui.TagList.get_dependencies(dedup=True)` + +Get any dependencies needed to render the HTML. + +#### Parameters + +dedup: [bool](`bool`) = True + +: Whether to deduplicate the dependencies. + +### get_html_string { #shiny.ui.TagList.get_html_string } + +`ui.TagList.get_html_string(indent=0, eol='\n', *, add_ws=True, _escape_strings=True)` + +Return the HTML string for this tag list. + +#### Parameters + +indent: [int](`int`) = 0 + +: Number of spaces to indent each line of the HTML. + +eol: [str](`str`) = '\n' + +: End-of-line character(s). + +add_ws: [bool](`bool`) = True + +: Whether to add whitespace between the opening tag and the first child. If + either this is True, or the child's add_ws attribute is True, then + whitespace will be added; if they are both False, then no whitespace will be + added. + +### insert { #shiny.ui.TagList.insert } + +`ui.TagList.insert(index, x)` + +Insert tag children before a given index. + +### render { #shiny.ui.TagList.render } + +`ui.TagList.render()` + +Get string representation as well as its HTML dependencies. + +### save_html { #shiny.ui.TagList.save_html } + +`ui.TagList.save_html(file, *, libdir='lib', include_version=True)` + +Save to a HTML file. + +#### Parameters + +file: [str](`str`) + +: The file to save to. + +libdir: [Optional](`typing.Optional`)\[[str](`str`)\] = 'lib' + +: The directory to save the dependencies to. + +include_version: [bool](`bool`) = True + +: Whether to include the version number in the dependency folder name. + +#### Returns + +| Type | Description | +|--------------|--------------------------------------| +| [str](`str`) | The path to the generated HTML file. | + +### show { #shiny.ui.TagList.show } + +`ui.TagList.show(renderer='auto')` + +Preview as a complete HTML document. + +#### Parameters + +renderer: [Literal](`typing.Literal`)\['auto', 'ipython', 'browser'\] = 'auto' + +: The renderer to use. + +### tagify { #shiny.ui.TagList.tagify } + +`ui.TagList.tagify()` + +Convert any tagifiable children to Tag/TagList objects. \ No newline at end of file diff --git a/docs/api/ui.ValueBoxTheme.qmd b/docs/api/ui.ValueBoxTheme.qmd new file mode 100644 index 000000000..feb3cadca --- /dev/null +++ b/docs/api/ui.ValueBoxTheme.qmd @@ -0,0 +1,4 @@ +# ui.ValueBoxTheme { #shiny.ui.ValueBoxTheme } + +`ui.ValueBoxTheme(class_, fg, bg)` + diff --git a/docs/api/ui.accordion.qmd b/docs/api/ui.accordion.qmd new file mode 100644 index 000000000..e9ea09128 --- /dev/null +++ b/docs/api/ui.accordion.qmd @@ -0,0 +1,135 @@ +# ui.accordion { #shiny.ui.accordion } + +`ui.accordion(*args, id=None, open=None, multiple=True, class_=None, width=None, height=None, **kwargs)` + +Create a vertically collapsing accordion. + +## Parameters + +*args: [AccordionPanel](`shiny.ui._accordion.AccordionPanel`) \| [TagAttrs](`htmltools.TagAttrs`) = () + +: [](:class:`~shiny.ui.AccordionPanel`) objects returned from + [](:func:`~shiny.ui.accordion_panel`). Or tag attributes that are + supplied to the returned [](:class:`~htmltools.Tag`) object. + +id: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: If provided, you can use `input.id()` in your server logic to determine which of + the [](:func:`~shiny.ui.accordion_panel`)s are currently active. The + value will correspond to the [](:func:`~shiny.ui.accordion_panel`)'s + `value` argument. + +open: [Optional](`typing.Optional`)\[[bool](`bool`) \| [str](`str`) \| [list](`list`)\[[str](`str`)\]\] = None + +: A list of [](:func:`~shiny.ui.accordion_panel`) values to open (i.e., + show) by default. The default value of `None` will open the first + [](:func:`~shiny.ui.accordion_panel`). Use a value of `True` to open + all (or `False` to open none) of the items. It's only possible to open more than + one panel when `multiple=True`. + +multiple: [bool](`bool`) = True + +: Whether multiple [](:func:`~shiny.ui.accordion_panel`) can be open at + once. + +class_: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: Additional CSS classes to include on the accordion div. + +width: [Optional](`typing.Optional`)\[[CssUnit](`shiny.ui.css._css_unit.CssUnit`)\] = None + +: Any valid CSS unit; for example, height="100%". + +height: [Optional](`typing.Optional`)\[[CssUnit](`shiny.ui.css._css_unit.CssUnit`)\] = None + +: Any valid CSS unit; for example, height="100%". + +**kwargs: [TagAttrValue](`htmltools.TagAttrValue`) = {} + +: Attributes to this tag. + +## Returns + +| Type | Description | +|------------------------|-----------------------------| +| [Tag](`htmltools.Tag`) | Accordion panel Tag object. | + + + + +## References + +[Bootstrap Accordion](https://getbootstrap.com/docs/5.3/components/accordion/) + + + +## See Also + +* [](:func:`~shiny.ui.accordion_panel`) +* [](:func:`~shiny.ui.update_accordion`) +* [](:func:`~shiny.ui.insert_accordion_panel`) +* [](:func:`~shiny.ui.remove_accordion_panel`) +* [](:func:`~shiny.ui.update_accordion_panel`) + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +from shiny import App, Inputs, Outputs, Session, reactive, render, ui + + +def make_items(): + return [ + ui.accordion_panel(f"Section {letter}", f"Some narrative for section {letter}") + for letter in "ABCDE" + ] + + +# # First shown by default +# ui.accordion(*make_items()) + +# # Nothing shown by default +# ui.accordion(*make_items(), open=False) +# # Everything shown by default +# ui.accordion(*make_items(), open=True) + +# # Show particular sections +# ui.accordion(*make_items(), open="Section B") +# ui.accordion(*make_items(), open=["Section A", "Section B"]) + + +app_ui = ui.page_fluid( + ui.markdown("#### Accordion: (`multiple=False`)"), + # Provide an id to create a shiny input binding + ui.accordion(*make_items(), id="acc_single", multiple=False), + ui.output_text_verbatim("acc_single_val", placeholder=True), + ui.tags.br(), + ui.markdown("#### Accordion: (`multiple=True`)"), + ui.accordion(*make_items(), id="acc_multiple"), + ui.output_text_verbatim("acc_multiple_val", placeholder=True), +) + + +def server(input: Inputs, output: Outputs, session: Session): + @reactive.Effect + def _(): + print(input.acc()) + + @render.text + def acc_multiple_val(): + return "input.acc_multiple(): " + str(input.acc_multiple()) + + @render.text + def acc_single_val(): + return "input.acc_single(): " + str(input.acc_single()) + + +app = App(app_ui, server) + +``` + diff --git a/docs/api/ui.accordion_panel.qmd b/docs/api/ui.accordion_panel.qmd new file mode 100644 index 000000000..ad945579b --- /dev/null +++ b/docs/api/ui.accordion_panel.qmd @@ -0,0 +1,91 @@ +# ui.accordion_panel { #shiny.ui.accordion_panel } + +`ui.accordion_panel(title, *args, value=MISSING, icon=None, **kwargs)` + +Single accordion panel. + +## Parameters + +title: [TagChild](`htmltools.TagChild`) + +: A title to appear in the [](:func:`~shiny.ui.accordion_panel`)'s header. + +*args: [TagChild](`htmltools.TagChild`) \| [TagAttrs](`htmltools.TagAttrs`) = () + +: Contents to the accordion panel body. Or tag attributes that are supplied to the + returned [](:class:`~htmltools.Tag`) object. + +value: [Optional](`typing.Optional`)\[[str](`str`)\] \| [MISSING_TYPE](`shiny.types.MISSING_TYPE`) = MISSING + +: A character string that uniquely identifies this panel. If `MISSING`, the + `title` will be used. + +icon: [Optional](`typing.Optional`)\[[TagChild](`htmltools.TagChild`)\] = None + +: A [](:class:`~htmltools.Tag`) which is positioned just before the `title`. + +**kwargs: [TagAttrValue](`htmltools.TagAttrValue`) = {} + +: Tag attributes to the `accordion-body` div Tag. + +## Returns + +| Type | Description | +|--------------------------------------------------------|--------------------------| +| [AccordionPanel](`shiny.ui._accordion.AccordionPanel`) | `AccordionPanel` object. | + + + + +## References + +[Bootstrap Accordion](https://getbootstrap.com/docs/5.3/components/accordion/) + + + +## See Also + +* [](:func:`~shiny.ui.accordion`) +* [](:func:`~shiny.ui.update_accordion`) +* [](:func:`~shiny.ui.insert_accordion_panel`) +* [](:func:`~shiny.ui.remove_accordion_panel`) +* [](:func:`~shiny.ui.update_accordion_panel`) + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +from shiny import App, Inputs, Outputs, Session, reactive, render, ui + +items = [ + ui.accordion_panel(f"Section {letter}", f"Some narrative for section {letter}") + for letter in "ABCDE" +] + +app_ui = ui.page_fluid( + # Provide an id to create a shiny input binding + ui.accordion(*items, id="acc"), + ui.h4("Accordion:"), + ui.output_text_verbatim("acc_val", placeholder=True), +) + + +def server(input: Inputs, output: Outputs, session: Session): + @reactive.Effect + def _(): + print(input.acc()) + + @render.text + def acc_val(): + return "input.acc(): " + str(input.acc()) + + +app = App(app_ui, server) + +``` + diff --git a/docs/api/ui.card.qmd b/docs/api/ui.card.qmd new file mode 100644 index 000000000..cf05b3393 --- /dev/null +++ b/docs/api/ui.card.qmd @@ -0,0 +1,76 @@ +# ui.card { #shiny.ui.card } + +`ui.card(*args, full_screen=False, height=None, max_height=None, min_height=None, fill=True, class_=None, **kwargs)` + +A Bootstrap card component + +A general purpose container for grouping related UI elements together with a border +and optional padding. To learn more about `card()`s, see [this +article](https://rstudio.github.io/bslib/articles/cards.html). + +## Parameters + +*args: [TagChild](`htmltools.TagChild`) \| [TagAttrs](`htmltools.TagAttrs`) \| [CardItem](`shiny.ui._card.CardItem`) = () + +: UI elements. + +full_screen: [bool](`bool`) = False + +: If `True`, an icon will appear when hovering over the card body. Clicking the + icon expands the card to fit viewport size. + +height: [Optional](`typing.Optional`)\[[CssUnit](`shiny.ui.css._css_unit.CssUnit`)\] = None + +: Any valid CSS unit (e.g., `height="200px"`). Doesn't apply when a card is made + `full_screen`. + +fill: [bool](`bool`) = True + +: Whether or not to allow the card to grow/shrink to fit a fillable container with + an opinionated height (e.g., [](:func:`~shiny.ui.page_fillable`)). + +class_: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: Additional CSS classes for the returned Tag. + +**kwargs: [TagAttrValue](`htmltools.TagAttrValue`) = {} + +: HTML attributes on the returned Tag. + +## Returns + +| Type | Description | +|------------------------|------------------------------------| +| [Tag](`htmltools.Tag`) | An [](:func:`~shiny.ui.tags.div`) tag. | + +## See Also + +* [](:func:`~shiny.ui.card_header`) for creating a header within the card. +* [](:func:`~shiny.ui.card_footer`) for creating a footer within the card. + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +from shiny import App, ui + +app_ui = ui.page_fluid( + ui.card( + ui.card_header("This is the header"), + ui.p("This is the body."), + ui.p("This is still the body."), + ui.card_footer("This is the footer"), + full_screen=True, + ), +) + + +app = App(app_ui, server=None) + +``` + diff --git a/docs/api/ui.card_footer.qmd b/docs/api/ui.card_footer.qmd new file mode 100644 index 000000000..696b0ded1 --- /dev/null +++ b/docs/api/ui.card_footer.qmd @@ -0,0 +1,59 @@ +# ui.card_footer { #shiny.ui.card_footer } + +`ui.card_footer(*args, **kwargs)` + +Card footer container + +A general container for the "footer" of a [](:func:`~shiny.ui.card`). This component is designed +to be provided as a direct child to [](:func:`~shiny.ui.card`). + +The footer has a different background color and border than the rest of the card. + +## Parameters + +*args: [TagChild](`htmltools.TagChild`) \| [TagAttrs](`htmltools.TagAttrs`) = () + +: Contents to the footer container. Or tag attributes that are supplied to the + resolved [](:class:`~htmltools.Tag`) object. + +**kwargs: [TagAttrValue](`htmltools.TagAttrValue`) = {} + +: Additional HTML attributes for the returned Tag. + +## Returns + +| Type | Description | +|---------------------------------------|---------------------------------------| +| [CardItem](`shiny.ui._card.CardItem`) | A [](:class:`~shiny.ui.CardItem`) object. | + +## See Also + +* [](:func:`~shiny.ui.card`) for creating a card component. +* [](:func:`~shiny.ui.card_footer`) for creating a footer within the card. + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +from shiny import App, ui + +app_ui = ui.page_fluid( + ui.card( + ui.card_header("This is the header"), + ui.p("This is the body."), + ui.p("This is still the body."), + ui.card_footer("This is the footer"), + full_screen=True, + ) +) + + +app = App(app_ui, server=None) + +``` + diff --git a/docs/api/ui.card_header.qmd b/docs/api/ui.card_header.qmd new file mode 100644 index 000000000..79a4a9c17 --- /dev/null +++ b/docs/api/ui.card_header.qmd @@ -0,0 +1,63 @@ +# ui.card_header { #shiny.ui.card_header } + +`ui.card_header(*args, container=tags.div, **kwargs)` + +Card header container + +A general container for the "header" of a [](:func:`~shiny.ui.card`). This component is designed +to be provided as a direct child to [](:func:`~shiny.ui.card`). + +The header has a different background color and border than the rest of the card. + +## Parameters + +*args: [TagChild](`htmltools.TagChild`) \| [TagAttrs](`htmltools.TagAttrs`) = () + +: Contents to the header container. Or tag attributes that are supplied to the + resolved [](:class:`~htmltools.Tag`) object. + +container: [TagFunction](`htmltools.TagFunction`) = tags.div + +: Method for the returned Tag object. Defaults to [](:func:`~shiny.ui.tags.div`). + +**kwargs: [TagAttrValue](`htmltools.TagAttrValue`) = {} + +: Additional HTML attributes for the returned Tag. + +## Returns + +| Type | Description | +|---------------------------------------|---------------------------------------| +| [CardItem](`shiny.ui._card.CardItem`) | A [](:class:`~shiny.ui.CardItem`) object. | + +## See Also + +* [](:func:`~shiny.ui.card`) for creating a card component. +* [](:func:`~shiny.ui.card_footer`) for creating a footer within the card. + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +from shiny import App, ui + +app_ui = ui.page_fluid( + ui.card( + ui.card_header("This is the header"), + ui.p("This is the body."), + ui.p("This is still the body."), + ui.card_footer("This is the footer"), + full_screen=True, + ) +) + + +app = App(app_ui, server=None) + +``` + diff --git a/docs/api/ui.column.qmd b/docs/api/ui.column.qmd new file mode 100644 index 000000000..8548d5de7 --- /dev/null +++ b/docs/api/ui.column.qmd @@ -0,0 +1,35 @@ +# ui.column { #shiny.ui.column } + +`ui.column(width, *args, offset=0, **kwargs)` + +Responsive row-column based layout + +See [](:func:`~shiny.ui.row`) for more information. + +## Parameters + +width: [int](`int`) + +: The width of the column (an integer between 1 and 12). + +*args: [TagChild](`htmltools.TagChild`) \| [TagAttrs](`htmltools.TagAttrs`) = () + +: UI elements to place within the column. + +offset: [int](`int`) = 0 + +: The number of columns to offset this column from the end of the previous column. + +**kwargs: [TagAttrValue](`htmltools.TagAttrValue`) = {} + +: Attributes to place on the column tag. + +## Returns + +| Type | Description | +|------------------------|---------------| +| [Tag](`htmltools.Tag`) | A UI element. | + +## See Also + +[](:func:`~shiny.ui.row`) \ No newline at end of file diff --git a/docs/api/ui.css.as_css_padding.qmd b/docs/api/ui.css.as_css_padding.qmd new file mode 100644 index 000000000..be33b1a75 --- /dev/null +++ b/docs/api/ui.css.as_css_padding.qmd @@ -0,0 +1,17 @@ +# ui.css.as_css_padding { #shiny.ui.css.as_css_padding } + +`ui.css.as_css_padding(padding)` + +Convert a CSS unit or list of CSS units into a CSS padding value. + +## Parameters + +padding: [CssUnit](`shiny.ui.css._css_unit.CssUnit`) \| [list](`list`)\[[CssUnit](`shiny.ui.css._css_unit.CssUnit`)\] \| None + +: A CSS unit or list of CSS units. + +## Returns + +| Type | Description | +|----------------------|----------------------| +| [str](`str`) \| None | A CSS padding value. | \ No newline at end of file diff --git a/docs/api/ui.css.as_css_unit.qmd b/docs/api/ui.css.as_css_unit.qmd new file mode 100644 index 000000000..46fe4eaa3 --- /dev/null +++ b/docs/api/ui.css.as_css_unit.qmd @@ -0,0 +1,17 @@ +# ui.css.as_css_unit { #shiny.ui.css.as_css_unit } + +`ui.css.as_css_unit(value)` + +Convert a value into a CSS unit. + +## Parameters + +value: None \| [CssUnit](`shiny.ui.css._css_unit.CssUnit`) + +: A value to convert into a CSS unit. + +## Returns + +| Type | Description | +|----------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------| +| None \| [str](`str`) | If the `value` is `None`, then `None`. If the value is `0`, then `"0"`. If the `value` is numeric, then a formatted pixel value. Otherwise, the `value` as-is. | \ No newline at end of file diff --git a/docs/api/ui.download_button.qmd b/docs/api/ui.download_button.qmd new file mode 100644 index 000000000..622b3ac97 --- /dev/null +++ b/docs/api/ui.download_button.qmd @@ -0,0 +1,109 @@ +# ui.download_button { #shiny.ui.download_button } + +`ui.download_button(id, label, *, icon=None, width=None, **kwargs)` + +Create a download button + +## Parameters + +id: [str](`str`) + +: An id for the download. + +label: [TagChild](`htmltools.TagChild`) + +: An input label. + +icon: [TagChild](`htmltools.TagChild`) = None + +: An icon to display on the button. + +width: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: The width of the button. + +**kwargs: [TagAttrValue](`htmltools.TagAttrValue`) = {} + +: Additional attributes for the button. + +## Returns + +| Type | Description | +|------------------------|---------------| +| [Tag](`htmltools.Tag`) | A UI element | + +## See Also + +* [](:class:`~shiny.render.download`) +* [](:func:`~shiny.ui.download_link`) + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +import asyncio +import random +from datetime import date + +from shiny import App, Inputs, Outputs, Session, render, ui + +app_ui = ui.page_fluid( + ui.download_button("downloadData", "Download"), +) + + +def server(input: Inputs, output: Outputs, session: Session): + @render.download( + filename=lambda: f"æ–°åž‹-{date.today().isoformat()}-{random.randint(100,999)}.csv" + ) + async def downloadData(): + await asyncio.sleep(0.25) + yield "one,two,three\n" + yield "æ–°,1,2\n" + yield "åž‹,4,5\n" + + +app = App(app_ui, server) + +## file: mtcars.csv +mpg,cyl,disp,hp,drat,wt,qsec,vs,am,gear,carb +21,6,160,110,3.9,2.62,16.46,0,1,4,4 +21,6,160,110,3.9,2.875,17.02,0,1,4,4 +22.8,4,108,93,3.85,2.32,18.61,1,1,4,1 +21.4,6,258,110,3.08,3.215,19.44,1,0,3,1 +18.7,8,360,175,3.15,3.44,17.02,0,0,3,2 +18.1,6,225,105,2.76,3.46,20.22,1,0,3,1 +14.3,8,360,245,3.21,3.57,15.84,0,0,3,4 +24.4,4,146.7,62,3.69,3.19,20,1,0,4,2 +22.8,4,140.8,95,3.92,3.15,22.9,1,0,4,2 +19.2,6,167.6,123,3.92,3.44,18.3,1,0,4,4 +17.8,6,167.6,123,3.92,3.44,18.9,1,0,4,4 +16.4,8,275.8,180,3.07,4.07,17.4,0,0,3,3 +17.3,8,275.8,180,3.07,3.73,17.6,0,0,3,3 +15.2,8,275.8,180,3.07,3.78,18,0,0,3,3 +10.4,8,472,205,2.93,5.25,17.98,0,0,3,4 +10.4,8,460,215,3,5.424,17.82,0,0,3,4 +14.7,8,440,230,3.23,5.345,17.42,0,0,3,4 +32.4,4,78.7,66,4.08,2.2,19.47,1,1,4,1 +30.4,4,75.7,52,4.93,1.615,18.52,1,1,4,2 +33.9,4,71.1,65,4.22,1.835,19.9,1,1,4,1 +21.5,4,120.1,97,3.7,2.465,20.01,1,0,3,1 +15.5,8,318,150,2.76,3.52,16.87,0,0,3,2 +15.2,8,304,150,3.15,3.435,17.3,0,0,3,2 +13.3,8,350,245,3.73,3.84,15.41,0,0,3,4 +19.2,8,400,175,3.08,3.845,17.05,0,0,3,2 +27.3,4,79,66,4.08,1.935,18.9,1,1,4,1 +26,4,120.3,91,4.43,2.14,16.7,0,1,5,2 +30.4,4,95.1,113,3.77,1.513,16.9,1,1,5,2 +15.8,8,351,264,4.22,3.17,14.5,0,1,5,4 +19.7,6,145,175,3.62,2.77,15.5,0,1,5,6 +15,8,301,335,3.54,3.57,14.6,0,1,5,8 +21.4,4,121,109,4.11,2.78,18.6,1,1,4,2 + +``` + diff --git a/docs/api/ui.fill.as_fill_item.qmd b/docs/api/ui.fill.as_fill_item.qmd new file mode 100644 index 000000000..b28ab4fc7 --- /dev/null +++ b/docs/api/ui.fill.as_fill_item.qmd @@ -0,0 +1,109 @@ +# ui.fill.as_fill_item { #shiny.ui.fill.as_fill_item } + +`ui.fill.as_fill_item(tag)` + +Coerce a tag to a fill item. + +Filling layouts are built on the foundation of _fillable containers_ and _fill +items_ (_fill carriers_ are both _fillable containers_ and _fill items_). This is +why most UI components (e.g., [](:func:`~shiny.ui.card`), +[](:func:`~shiny.ui.layout_sidebar`)) possess both `fillable` and `fill` arguments (to +control their fill behavior). However, sometimes it's useful to add, remove, and/or +test fillable/fill properties on arbitrary [](:class:`~htmltools.Tag`), which these +functions are designed to do. + +## Parameters + +tag: [TagT](`shiny.ui.fill._fill.TagT`) + +: a Tag object. + +## Returns + +| Type | Description | +|------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------| +| [TagT](`shiny.ui.fill._fill.TagT`) | A copy of the original [](:class:`~htmltools.Tag`) object (`tag`) with additional attributes (and an [](:class:`~htmltools.HTMLDependency`)). | + +## See Also + +* [](:func:`~shiny.ui.fill.as_fillable_container`) +* [](:func:`~shiny.ui.fill.remove_all_fill`) + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +from __future__ import annotations + +import htmltools + +from shiny import App, ui +from shiny.ui import fill + + +def outer_inner() -> htmltools.Tag: + inner = ui.div( + id="inner", + style=htmltools.css( + height="200px", + border="3px blue solid", + ), + ) + outer = ui.div( + inner, + id="outer", + style=htmltools.css( + height="300px", + border="3px red solid", + ), + ) + return outer + + +outer0 = outer_inner() + +outer1 = outer_inner() +outer1.children[0] = fill.as_fill_item(outer1.children[0]) + +outer2 = outer_inner() +outer2 = fill.as_fillable_container(outer2) +outer2.children[0] = fill.as_fill_item(outer2.children[0]) + + +app_ui = ui.page_fluid( + ui.markdown( + """\ + # `as_fill_item()` + + For an item to fill its parent element, + * the item must have `as_fill_item()` be called on it + * the parent container must have `as_fillable_container()` called on it + + Iff both methods are called, the inner child will naturally expand into its parent container. + """ + ), + ui.row( + ui.column(4, ui.h5("Default behavior")), + ui.column(4, ui.h5(ui.markdown("`as_fill_item(blue)`"))), + ui.column( + 4, + ui.h5(ui.markdown("`as_fill_item(blue)` + `as_fillable_container(red)`")), + ), + ), + ui.row( + ui.column(4, ui.div(outer0)), + ui.column(4, ui.div(outer1)), + ui.column(4, ui.span(outer2)), + ), +) + + +app = App(app_ui, server=None) + +``` + diff --git a/docs/api/ui.fill.as_fillable_container.qmd b/docs/api/ui.fill.as_fillable_container.qmd new file mode 100644 index 000000000..c2d488d0c --- /dev/null +++ b/docs/api/ui.fill.as_fillable_container.qmd @@ -0,0 +1,83 @@ +# ui.fill.as_fillable_container { #shiny.ui.fill.as_fillable_container } + +`ui.fill.as_fillable_container(tag)` + + + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +from __future__ import annotations + +import htmltools + +from shiny import App, ui +from shiny.ui import fill + + +def outer_inner() -> htmltools.Tag: + inner = ui.div( + id="inner", + style=htmltools.css( + height="200px", + border="3px blue solid", + ), + ) + outer = ui.div( + inner, + id="outer", + style=htmltools.css( + height="300px", + border="3px red solid", + ), + ) + return outer + + +outer0 = outer_inner() + +outer1 = outer_inner() +outer1 = fill.as_fillable_container(outer1) + +outer2 = outer_inner() +outer2 = fill.as_fillable_container(outer2) +outer2.children[0] = fill.as_fill_item(outer2.children[0]) + +app_ui = ui.page_fluid( + ui.markdown( + """\ + # `as_fillable_container()` + + For an item to fill its parent element, + * the item must have `as_fill_item()` be called on it + * the parent container must have `as_fillable_container()` called on it + + Iff both methods are called, the inner child will naturally expand into its parent container. + """ + ), + ui.row( + ui.column(4, ui.h5("Default behavior")), + ui.column(4, ui.h5(ui.markdown("`as_fillable_container(red)`"))), + ui.column( + 4, + ui.h5(ui.markdown("`as_fill_item(blue)` + `as_fillable_container(red)`")), + ), + ), + ui.row( + ui.column(4, ui.div(outer0)), + ui.column(4, ui.div(outer1)), + ui.column(4, ui.span(outer2)), + ), +) + + +app = App(app_ui, server=None) + +``` + diff --git a/docs/api/ui.fill.remove_all_fill.qmd b/docs/api/ui.fill.remove_all_fill.qmd new file mode 100644 index 000000000..c4aea35ac --- /dev/null +++ b/docs/api/ui.fill.remove_all_fill.qmd @@ -0,0 +1,33 @@ +# ui.fill.remove_all_fill { #shiny.ui.fill.remove_all_fill } + +`ui.fill.remove_all_fill(tag)` + +Remove any filling layouts from a tag. + +Filling layouts are built on the foundation of _fillable containers_ and _fill +items_ (_fill carriers_ are both _fillable containers_ and _fill items_). This is +why most UI components (e.g., [](:func:`~shiny.ui.card`), +[](:func:`~shiny.ui.layout_sidebar`)) possess both `fillable` and `fill` arguments (to +control their fill behavior). However, sometimes it's useful to add, remove, and/or +test fillable/fill properties on arbitrary [](:class:`~htmltools.Tag`), which these +functions are designed to do. + +## Parameters + +tag: [TagT](`shiny.ui.fill._fill.TagT`) + +: a Tag object. + +## Returns + +| Type | Description | +|------------------------------------|-------------------------------------------------------------------------------------| +| [TagT](`shiny.ui.fill._fill.TagT`) | The original [](:class:`~htmltools.Tag`) object with filling layout attributes removed. | + + + + +## See Also + +* [](:func:`~shiny.ui.fill.as_fill_item`) +* [](:func:`~shiny.ui.fill.as_fillable_container`) \ No newline at end of file diff --git a/docs/api/ui.help_text.qmd b/docs/api/ui.help_text.qmd new file mode 100644 index 000000000..01f435090 --- /dev/null +++ b/docs/api/ui.help_text.qmd @@ -0,0 +1,24 @@ +# ui.help_text { #shiny.ui.help_text } + +`ui.help_text(*args, **kwargs)` + +Create a help text element + +Help text is stylized text which can be added to the user interface to provide additional explanation +or context. Text passed to [](:func:`~shiny.ui.help_text`) receives the Bootstrap `help-block` class. + +## Parameters + +*args: [TagChild](`htmltools.TagChild`) \| [TagAttrs](`htmltools.TagAttrs`) = () + +: UI elements to include inside the help text. + +**kwargs: [TagAttrValue](`htmltools.TagAttrValue`) = {} + +: Attributes to add to the text container. + +## Returns + +| Type | Description | +|------------------------|---------------| +| [Tag](`htmltools.Tag`) | A UI element | \ No newline at end of file diff --git a/docs/api/ui.include_css.qmd b/docs/api/ui.include_css.qmd new file mode 100644 index 000000000..761265dea --- /dev/null +++ b/docs/api/ui.include_css.qmd @@ -0,0 +1,103 @@ +# ui.include_css { #shiny.ui.include_css } + +`ui.include_css(path, *, method='link')` + +Include a CSS file. + +## Parameters + +path: [Path](`pathlib.Path`) \| [str](`str`) + +: A path to a CSS file. + +method: [Literal](`typing.Literal`)\['link', 'link_files', 'inline'\] = 'link' + +: One of the following: + + * ``"link"`` is the link to the CSS file via a [](:func:`~ui.tags.link`) tag. This + method is generally preferable to ``"inline"`` since it allows the browser to + cache the file. + * ``"link_files"`` is the same as ``"link"``, but also allow for the CSS file to + request other files within ``path``'s immediate parent directory (e.g., + ``@import()`` another file). Note that this isn't the default behavior because + you should **be careful not to include files in the same directory as ``path`` + that contain sensitive information**. A good general rule of thumb to follow + is to have ``path`` be located in a subdirectory of the app directory. For + example, if the app's source is located at ``/app/app.py``, then ``path`` + should be somewhere like ``/app/css/custom.css`` (and all the other relevant + accompanying 'safe' files should be located under ``/app/css/``). + * ``"inline"`` is the inline the CSS file contents within a + [](:func:`~ui.tags.style`) tag. + +## Returns + +| Type | Description | +|------------------------|---------------------------------------------------------------------------------------------------------------| +| [Tag](`htmltools.Tag`) | If ``method="inline"``, returns a [](:func:`~ui.tags.style`) tag; otherwise, returns a [](:func:`~ui.tags.link`) tag. | + +## Note + +By default this places a [](:func:`~ui.tags.link`) (or [](:func:`~ui.tags.style`)) tag in +the [](:func:`~ui.tags.body`) of the document, which isn't optimal for performance, and +may result in a Flash of Unstyled Content (FOUC). To instead place the CSS in the +[](:func:`~ui.tags.head`) of the document, you can wrap it in ``head_content``: + +```{python} +#| eval: false +from htmltools import head_content +from shiny import ui + +ui.page_fluid( + ui.head_content(ui.include_css("custom.css")), + + # You can also inline css by passing a dictionary with a `style` element. + ui.div( + {"style": "font-weight: bold;"}, + ui.p("Some text!"), + ) +) +``` + + + +## See Also + +[](:func:`~ui.tags.style`) +[](:func:`~ui.tags.link`) +[](:func:`~include_js`) + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +from pathlib import Path + +from shiny import App, ui + +css_file = Path(__file__).parent / "css" / "styles.css" + +app_ui = ui.page_fluid( + "Almost before we knew it, we had left the ground!!!", + ui.include_css(css_file), + ui.div( + # Style individual elements with an attribute dictionary. + {"style": "font-weight: bold"}, + ui.p("Bold text"), + ), +) + +app = App(app_ui, None) + +## file: css/styles.css +body { + font-size: 3rem; + background-color: pink +} + +``` + diff --git a/docs/api/ui.include_js.qmd b/docs/api/ui.include_js.qmd new file mode 100644 index 000000000..9c05b051d --- /dev/null +++ b/docs/api/ui.include_js.qmd @@ -0,0 +1,67 @@ +# ui.include_js { #shiny.ui.include_js } + +`ui.include_js(path, *, method='link', **kwargs)` + +Include a JavaScript file. + +## Parameters + +path: [Path](`pathlib.Path`) \| [str](`str`) + +: A path to a JS file. + +method: [Literal](`typing.Literal`)\['link', 'link_files', 'inline'\] = 'link' + +: One of the following: + + * ``"link"`` is the link to the CSS file via a [](:func:`~ui.tags.link`) tag. This + method is generally preferable to ``"inline"`` since it allows the browser to + cache the file. + * ``"link_files"`` is the same as ``"link"``, but also allow for the CSS file to + request other files within ``path``'s immediate parent directory (e.g., + ``@import()`` another file). Note that this isn't the default behavior because + you should **be careful not to include files in the same directory as ``path`` + that contain sensitive information**. A good general rule of thumb to follow + is to have ``path`` be located in a subdirectory of the app directory. For + example, if the app's source is located at ``/app/app.py``, then ``path`` + should be somewhere like ``/app/css/custom.css`` (and all the other relevant + accompanying 'safe' files should be located under ``/app/css/``). + * ``"inline"`` is the inline the CSS file contents within a + [](:func:`~ui.tags.style`) tag. + +**kwargs: [TagAttrValue](`htmltools.TagAttrValue`) = {} + +: Attributes which are passed on to `~ui.tags.script`. + +## Returns + +| Type | Description | +|------------------------|--------------------------------| +| [Tag](`htmltools.Tag`) | A [](:func:`~ui.tags.script`) tag. | + +## Note + +This places a [](:func:`~ui.tags.script`) tag in the [](:func:`~ui.tags.body`) of the +document. If you want to place the tag in the [](:func:`~ui.tags.head`) of the +document instead, you can wrap it in ``head_content`` (in this case, just +make sure you're aware that the DOM probably won't be ready when the script +is executed). + +```{python} +#| eval: false +ui.page_fluid( + ui.head_content(ui.include_js("custom.js")), +) + +# Alternately you can inline Javscript by changing the method. +ui.page_fluid( + ui.head_content(ui.include_js("custom.js", method = "inline")), +) +``` + + + +## See Also + +[](:func:`~ui.tags.script`) +[](:func:`~include_css`) \ No newline at end of file diff --git a/docs/api/ui.input_action_button.qmd b/docs/api/ui.input_action_button.qmd new file mode 100644 index 000000000..392a53a6d --- /dev/null +++ b/docs/api/ui.input_action_button.qmd @@ -0,0 +1,108 @@ +# ui.input_action_button { #shiny.ui.input_action_button } + +`ui.input_action_button(id, label, *, icon=None, width=None, **kwargs)` + +Creates an action button whose value is initially zero, and increments by one each +time it is pressed. + +## Parameters + +id: [str](`str`) + +: An input id. + +label: [TagChild](`htmltools.TagChild`) + +: An input label. + +icon: [TagChild](`htmltools.TagChild`) = None + +: An icon to appear inline with the button/link. + +width: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: The CSS width, e.g. '400px', or '100%' + +**kwargs: [TagAttrValue](`htmltools.TagAttrValue`) = {} + +: Attributes to be applied to the button. + +## Returns + +| Type | Description | +|------------------------|---------------| +| [Tag](`htmltools.Tag`) | A UI element | + +## Notes + +::: {.callout-note title="Server value"} +An integer representing the number of clicks. +::: + + + +## See Also + +[](:func:`~shiny.ui.input_action_link`) +[](:func:`~shiny.reactive.event`) + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +import matplotlib.pyplot as plt +import numpy as np + +from shiny import App, Inputs, Outputs, Session, reactive, render, ui + +app_ui = ui.page_fluid( + ui.input_slider("n", "Number of observations", min=0, max=1000, value=500), + ui.input_action_button("go", "Go!", class_="btn-success"), + ui.output_plot("plot"), +) + + +def server(input: Inputs, output: Outputs, session: Session): + @render.plot(alt="A histogram") + # Use reactive.event() to invalidate the plot only when the button is pressed + # (not when the slider is changed) + @reactive.event(input.go, ignore_none=False) + def plot(): + np.random.seed(19680801) + x = 100 + 15 * np.random.randn(input.n()) + fig, ax = plt.subplots() + ax.hist(x, bins=30, density=True) + return fig + + +app = App(app_ui, server) + +## file: app-express.py +import matplotlib.pyplot as plt +import numpy as np + +from shiny import reactive, render +from shiny.express import input, ui + +ui.input_slider("n", "Number of observations", min=0, max=1000, value=500) +ui.input_action_button("go", "Go!", class_="btn-success") + + +@render.plot(alt="A histogram") +# Use reactive.event() to invalidate the plot only when the button is pressed +# (not when the slider is changed) +@reactive.event(input.go, ignore_none=False) +def plot(): + np.random.seed(19680801) + x = 100 + 15 * np.random.randn(input.n()) + fig, ax = plt.subplots() + ax.hist(x, bins=30, density=True) + return fig + +``` + diff --git a/docs/api/ui.input_action_link.qmd b/docs/api/ui.input_action_link.qmd new file mode 100644 index 000000000..8b14b9641 --- /dev/null +++ b/docs/api/ui.input_action_link.qmd @@ -0,0 +1,82 @@ +# ui.input_action_link { #shiny.ui.input_action_link } + +`ui.input_action_link(id, label, *, icon=None, **kwargs)` + +Creates a link whose value is initially zero, and increments by one each time it is +pressed. + +## Parameters + +id: [str](`str`) + +: An input id. + +label: [TagChild](`htmltools.TagChild`) + +: An input label. + +icon: [TagChild](`htmltools.TagChild`) = None + +: An icon to appear inline with the button/link. + +**kwargs: [TagAttrValue](`htmltools.TagAttrValue`) = {} + +: Attributes to be applied to the link. + +## Returns + +| Type | Description | +|------------------------|---------------| +| [Tag](`htmltools.Tag`) | A UI element | + +## Notes + +::: {.callout-note title="Server value"} +An integer representing the number of clicks. +::: + + + +## See Also + +[](:func:`~shiny.ui.input_action_button`) +[](:func:`~shiny.reactive.event`) + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +import matplotlib.pyplot as plt +import numpy as np + +from shiny import App, Inputs, Outputs, Session, reactive, render, ui + +app_ui = ui.page_fluid( + ui.input_slider("n", "Number of observations", min=0, max=1000, value=500), + ui.input_action_link("go", "Go!"), + ui.output_plot("plot"), +) + + +def server(input: Inputs, output: Outputs, session: Session): + @render.plot(alt="A histogram") + # reactive.event() to invalidate the plot when the button is pressed but not when + # the slider is changed + @reactive.event(input.go, ignore_none=False) + def plot(): + np.random.seed(19680801) + x = 100 + 15 * np.random.randn(input.n()) + fig, ax = plt.subplots() + ax.hist(x, bins=30, density=True) + return fig + + +app = App(app_ui, server) + +``` + diff --git a/docs/api/ui.input_checkbox.qmd b/docs/api/ui.input_checkbox.qmd new file mode 100644 index 000000000..e5ab7720d --- /dev/null +++ b/docs/api/ui.input_checkbox.qmd @@ -0,0 +1,72 @@ +# ui.input_checkbox { #shiny.ui.input_checkbox } + +`ui.input_checkbox(id, label, value=False, *, width=None)` + +Create a checkbox that can be used to specify logical values. + +## Parameters + +id: [str](`str`) + +: An input id. + +label: [TagChild](`htmltools.TagChild`) + +: An input label. + +value: [bool](`bool`) = False + +: Initial value. + +width: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: The CSS width, e.g. '400px', or '100%' + +## Returns + +| Type | Description | +|------------------------|---------------| +| [Tag](`htmltools.Tag`) | A UI element. | + +## Notes + +::: {.callout-note title="Server value"} +``True`` if checked, ``False`` otherwise. +::: + + + +## See Also + +[](:func:`~shiny.ui.input_switch`) +[](:func:`~shiny.ui.update_checkbox`) +[](:func:`~shiny.ui.input_checkbox_group`) +[](:func:`~shiny.ui.input_radio_buttons`) + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +from shiny import App, Inputs, Outputs, Session, render, ui + +app_ui = ui.page_fluid( + ui.input_checkbox("somevalue", "Some value", False), + ui.output_ui("value"), +) + + +def server(input: Inputs, output: Outputs, session: Session): + @render.ui + def value(): + return input.somevalue() + + +app = App(app_ui, server) + +``` + diff --git a/docs/api/ui.input_checkbox_group.qmd b/docs/api/ui.input_checkbox_group.qmd new file mode 100644 index 000000000..e00ef0b51 --- /dev/null +++ b/docs/api/ui.input_checkbox_group.qmd @@ -0,0 +1,91 @@ +# ui.input_checkbox_group { #shiny.ui.input_checkbox_group } + +`ui.input_checkbox_group(id, label, choices, *, selected=None, inline=False, width=None)` + +Create a group of checkboxes that can be used to toggle multiple choices +independently. + +## Parameters + +id: [str](`str`) + +: An input id. + +label: [TagChild](`htmltools.TagChild`) + +: An input label. + +choices: [ChoicesArg](`shiny.ui._input_check_radio.ChoicesArg`) + +: Either a list of choices or a dictionary mapping choice values to labels. Note + that if a dictionary is provided, the keys are used as the (input) values so + that the dictionary values can hold HTML labels. + +selected: [Optional](`typing.Optional`)\[[str](`str`) \| [list](`list`)\[[str](`str`)\]\] = None + +: The values that should be initially selected, if any. + +inline: [bool](`bool`) = False + +: If `True`, the result is displayed inline. + +width: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: The CSS width, e.g. '400px', or '100%'. + +## Returns + +| Type | Description | +|------------------------|---------------| +| [Tag](`htmltools.Tag`) | A UI element. | + +## Notes + +::: {.callout-note title="Server value"} +A tuple of string(s) with the selected value(s) (if any). +::: + + + +## See Also + +[](:func:`~shiny.ui.update_checkbox_group`) +[](:func:`~shiny.ui.input_checkbox`) +[](:func:`~shiny.ui.input_radio_buttons`) + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +from shiny import App, Inputs, Outputs, Session, render, req, ui + +app_ui = ui.page_fluid( + ui.input_checkbox_group( + "colors", + "Choose color(s):", + { + "red": ui.span("Red", style="color: #FF0000;"), + "green": ui.span("Green", style="color: #00AA00;"), + "blue": ui.span("Blue", style="color: #0000AA;"), + }, + ), + ui.output_ui("val"), +) + + +def server(input: Inputs, output: Outputs, session: Session): + @render.ui + def val(): + req(input.colors()) + return "You chose " + ", ".join(input.colors()) + + +app = App(app_ui, server) + +``` + diff --git a/docs/api/ui.input_date.qmd b/docs/api/ui.input_date.qmd new file mode 100644 index 000000000..e503f4b12 --- /dev/null +++ b/docs/api/ui.input_date.qmd @@ -0,0 +1,156 @@ +# ui.input_date { #shiny.ui.input_date } + +`ui.input_date(id, label, *, value=None, min=None, max=None, format='yyyy-mm-dd', startview='month', weekstart=0, language='en', width=None, autoclose=True, datesdisabled=None, daysofweekdisabled=None)` + +Creates a text input which, when clicked on, brings up a calendar that the user can +click on to select dates. + +## Parameters + +id: [str](`str`) + +: An input id. + +label: [TagChild](`htmltools.TagChild`) + +: An input label. + +value: [Optional](`typing.Optional`)\[[date](`datetime.date`) \| [str](`str`)\] = None + +: The starting date. Either a [](:class:`~datetime.date`) object, or a string in + `yyyy-mm-dd` format. If None (the default), will use the current date in the + client's time zone. + +min: [Optional](`typing.Optional`)\[[date](`datetime.date`) \| [str](`str`)\] = None + +: The minimum allowed date. Either a [](:class:`~datetime.date`) object, or a string in + yyyy-mm-dd format. + +max: [Optional](`typing.Optional`)\[[date](`datetime.date`) \| [str](`str`)\] = None + +: The maximum allowed date. Either a [](:class:`~datetime.date`) object, or a string in + yyyy-mm-dd format. + +format: [str](`str`) = 'yyyy-mm-dd' + +: The format of the date to display in the browser. Defaults to `"yyyy-mm-dd"`. + +startview: [str](`str`) = 'month' + +: The date range shown when the input object is first clicked. Can be "month" (the + default), "year", or "decade". + +weekstart: [int](`int`) = 0 + +: Which day is the start of the week. Should be an integer from 0 (Sunday) to 6 + (Saturday). + +language: [str](`str`) = 'en' + +: The language used for month and day names. Default is "en". Other valid values + include "ar", "az", "bg", "bs", "ca", "cs", "cy", "da", "de", "el", "en-AU", + "en-GB", "eo", "es", "et", "eu", "fa", "fi", "fo", "fr-CH", "fr", "gl", "he", + "hr", "hu", "hy", "id", "is", "it-CH", "it", "ja", "ka", "kh", "kk", "ko", "kr", + "lt", "lv", "me", "mk", "mn", "ms", "nb", "nl-BE", "nl", "no", "pl", "pt-BR", + "pt", "ro", "rs-latin", "rs", "ru", "sk", "sl", "sq", "sr-latin", "sr", "sv", + "sw", "th", "tr", "uk", "vi", "zh-CN", and "zh-TW". + +width: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: The CSS width, e.g. '400px', or '100%' + +autoclose: [bool](`bool`) = True + +: Whether or not to close the datepicker immediately when a date is selected. + +datesdisabled: [Optional](`typing.Optional`)\[[list](`list`)\[[str](`str`)\]\] = None + +: Which dates should be disabled (in `yyyy-mm-dd` format). + +daysofweekdisabled: [Optional](`typing.Optional`)\[[list](`list`)\[[int](`int`)\]\] = None + +: Days of the week that should be disabled. Should be a integer vector with values + from 0 (Sunday) to 6 (Saturday). + +## Returns + +| Type | Description | +|------------------------|---------------| +| [Tag](`htmltools.Tag`) | A UI element. | + +## Note + +The date ``format`` string specifies how the date will be displayed in the browser. +It allows the following values: + +- ``yy``: Year without century (12) +- ``yyyy``: Year with century (2012) +- ``mm``: Month number, with leading zero (01-12) +- ``m``: Month number, without leading zero (1-12) +- ``M``: Abbreviated month name +- ``MM``: Full month name +- ``dd``: Day of month with leading zero +- ``d``: Day of month without leading zero +- ``D``: Abbreviated weekday name +- ``DD``: Full weekday name + + + +## Notes + +::: {.callout-note title="Server value"} +A [](:class:`~datetime.date`) object. +::: + + + +## See Also + +[](:func:`~shiny.ui.update_date`) +[](:func:`~shiny.ui.input_date_range`) + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +from datetime import date + +from shiny import App, Inputs, Outputs, Session, ui + +app_ui = ui.page_fluid( + ui.input_date("date1", "Date:", value="2016-02-29"), + # Default value is the date in client's time zone + ui.input_date("date2", "Date:"), + # value is always yyyy-mm-dd, even if the display format is different + ui.input_date("date3", "Date:", value="2016-02-29", format="mm/dd/yy"), + # Pass in a Date object + ui.input_date("date4", "Date:", value=date(2016, 2, 29)), + # Use different language and different first day of week + ui.input_date("date5", "Date:", language="ru", weekstart=1), + # Start with decade view instead of default month view + ui.input_date("date6", "Date:", startview="decade"), + # Disable Mondays and Tuesdays. + ui.input_date("date7", "Date:", daysofweekdisabled=[1, 2]), + # Disable specific dates. + ui.input_date( + "date8", + "Date:", + value="2016-02-29", + datesdisabled=["2016-03-01", "2016-03-02"], + ), +) + + +def server(input: Inputs, output: Outputs, session: Session): + pass + + +app = App(app_ui, server) + +``` + diff --git a/docs/api/ui.input_date_range.qmd b/docs/api/ui.input_date_range.qmd new file mode 100644 index 000000000..73e53c59b --- /dev/null +++ b/docs/api/ui.input_date_range.qmd @@ -0,0 +1,162 @@ +# ui.input_date_range { #shiny.ui.input_date_range } + +`ui.input_date_range(id, label, *, start=None, end=None, min=None, max=None, format='yyyy-mm-dd', startview='month', weekstart=0, language='en', separator=' to ', width=None, autoclose=True)` + +Creates a pair of text inputs which, when clicked on, bring up calendars that the +user can click on to select dates. + +## Parameters + +id: [str](`str`) + +: An input id. + +label: [TagChild](`htmltools.TagChild`) + +: An input label. + +start: [Optional](`typing.Optional`)\[[date](`datetime.date`) \| [str](`str`)\] = None + +: The initial start date. Either a [](:class:`~datetime.date`) object, or a string in + yyyy-mm-dd format. If ``None`` (the default), will use the current date in the + client's time zone. + +end: [Optional](`typing.Optional`)\[[date](`datetime.date`) \| [str](`str`)\] = None + +: The initial end date. Either a [](:class:`~datetime.date`) object, or a string in + yyyy-mm-dd format. If ``None`` (the default), will use the current date in the + client's time zone. + +min: [Optional](`typing.Optional`)\[[date](`datetime.date`) \| [str](`str`)\] = None + +: The minimum allowed date. Either a [](:class:`~datetime.date`) object, or a string in + yyyy-mm-dd format. + +max: [Optional](`typing.Optional`)\[[date](`datetime.date`) \| [str](`str`)\] = None + +: The maximum allowed date. Either a [](:class:`~datetime.date`) object, or a string in + yyyy-mm-dd format. + +format: [str](`str`) = 'yyyy-mm-dd' + +: The format of the date to display in the browser. + +startview: [str](`str`) = 'month' + +: The date range shown when the input object is first clicked. Can be "month" (the + default), "year", or "decade". + +weekstart: [int](`int`) = 0 + +: Which day is the start of the week. Should be an integer from 0 (Sunday) to 6 + (Saturday). + +language: [str](`str`) = 'en' + +: The language used for month and day names. Default is "en". Other valid values + include "ar", "az", "bg", "bs", "ca", "cs", "cy", "da", "de", "el", "en-AU", + "en-GB", "eo", "es", "et", "eu", "fa", "fi", "fo", "fr-CH", "fr", "gl", "he", + "hr", "hu", "hy", "id", "is", "it-CH", "it", "ja", "ka", "kh", "kk", "ko", "kr", + "lt", "lv", "me", "mk", "mn", "ms", "nb", "nl-BE", "nl", "no", "pl", "pt-BR", + "pt", "ro", "rs-latin", "rs", "ru", "sk", "sl", "sq", "sr-latin", "sr", "sv", + "sw", "th", "tr", "uk", "vi", "zh-CN", and "zh-TW". + +separator: [str](`str`) = ' to ' + +: String to display between the start and end input boxes. + +width: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: The CSS width, e.g. '400px', or '100%' + +autoclose: [bool](`bool`) = True + +: Whether or not to close the datepicker immediately when a date is selected. + +## Returns + +| Type | Description | +|------------------------|---------------| +| [Tag](`htmltools.Tag`) | A UI element. | + +## Note + +The date ``format`` string specifies how the date will be displayed in the browser. +It allows the following values: + +- ``yy``: Year without century (12) +- ``yyyy``: Year with century (2012) +- ``mm``: Month number, with leading zero (01-12) +- ``m``: Month number, without leading zero (1-12) +- ``M``: Abbreviated month name +- ``MM``: Full month name +- ``dd``: Day of month with leading zero +- ``d``: Day of month without leading zero +- ``D``: Abbreviated weekday name +- ``DD``: Full weekday name + + + +## Notes + +::: {.callout-note title="Server value"} +A tuple of [](:class:`~datetime.date`) objects. +::: + + + +## See Also + +[](:func:`~shiny.ui.update_date_range`) +[](:func:`~shiny.ui.input_date`) + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +from datetime import date + +from shiny import App, Inputs, Outputs, Session, ui + +app_ui = ui.page_fluid( + ui.input_date_range( + "daterange1", "Date range:", start="2001-01-01", end="2010-12-31" + ), + # Default start and end is the current date in the client's time zone + ui.input_date_range("daterange2", "Date range:"), + # start and end are always specified in yyyy-mm-dd, even if the display + # format is different + ui.input_date_range( + "daterange3", + "Date range:", + start="2001-01-01", + end="2010-12-31", + min="2001-01-01", + max="2012-12-21", + format="mm/dd/yy", + separator=" - ", + ), + # Pass in Date objects + ui.input_date_range( + "daterange4", "Date range:", start=date(2001, 1, 1), end=date(2010, 12, 31) + ), + # Use different language and different first day of week + ui.input_date_range("daterange5", "Date range:", language="de", weekstart=1), + # Start with decade view instead of default month view + ui.input_date_range("daterange6", "Date range:", startview="decade"), +) + + +def server(input: Inputs, output: Outputs, session: Session): + pass + + +app = App(app_ui, server) + +``` + diff --git a/docs/api/ui.input_file.qmd b/docs/api/ui.input_file.qmd new file mode 100644 index 000000000..149ff1b99 --- /dev/null +++ b/docs/api/ui.input_file.qmd @@ -0,0 +1,143 @@ +# ui.input_file { #shiny.ui.input_file } + +`ui.input_file(id, label, *, multiple=False, accept=None, width=None, button_label='Browse...', placeholder='No file selected', capture=None)` + +Create a file upload control that can be used to upload one or more files. + +## Parameters + +id: [str](`str`) + +: An input id. + +label: [TagChild](`htmltools.TagChild`) + +: An input label. + +multiple: [bool](`bool`) = False + +: Whether the user should be allowed to select and upload multiple files at once. + +accept: [Optional](`typing.Optional`)\[[str](`str`) \| [list](`list`)\[[str](`str`)\]\] = None + +: Unique file type specifier(s) which give the browser a hint as to the type of + file the server expects. Many browsers use this to prevent the user from + selecting an invalid file. Examples of valid values include a case insensitive + extension (e.g. ``.csv`` or ``.rds``), a valid MIME type (e.g. ``text/plain`` or + ``application/pdf``) or one of ``audio/*``, ``video/*``, or ``image/*`` meaning + any audio, video, or image type, respectively. + +width: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: The CSS width, e.g. '400px', or '100%' + +button_label: [str](`str`) = 'Browse...' + +: The label used on the button. + +placeholder: [str](`str`) = 'No file selected' + +: The text to show on the input before a file has been uploaded. + +capture: [Optional](`typing.Optional`)\[[Literal](`typing.Literal`)\['environment', 'user'\]\] = None + +: On mobile devices, this can be used to open the device's camera for input. If + "environment", it will open the rear-facing camera. If "user", it will open the + front-facing camera. By default, it will accept either still photos or video. To + accept only still photos, use ``accept="image/*"``; to accept only video, use + ``accept="video/*"``. + +## Returns + +| Type | Description | +|------------------------|---------------| +| [Tag](`htmltools.Tag`) | A UI element. | + +## Notes + + +::: {.callout-note title="Server value"} +A list of dictionaries (one for each file upload) with the following keys: + +* ``name``: The filename provided by the web browser. This is *not* the path to read + to get at the actual data that was uploaded (see 'datapath'). +* ``size``: The size of the uploaded data, in bytes. +* ``type``: The MIME type reported by the browser (for example, 'text/plain'), or + empty string if the browser didn't know. +* ``datapath``: The path to a temp file that contains the data that was uploaded. + This file may be deleted if the user performs another upload operation. +::: + + + +## See Also + +[](:func:`~shiny.ui.download_button`) + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +import pandas as pd + +from shiny import App, Inputs, Outputs, Session, reactive, render, ui +from shiny.types import FileInfo + +app_ui = ui.page_fluid( + ui.input_file("file1", "Choose CSV File", accept=[".csv"], multiple=False), + ui.input_checkbox_group( + "stats", + "Summary Stats", + choices=["Row Count", "Column Count", "Column Names"], + selected=["Row Count", "Column Count", "Column Names"], + ), + ui.output_table("summary"), +) + + +def server(input: Inputs, output: Outputs, session: Session): + @reactive.Calc + def parsed_file(): + file: list[FileInfo] | None = input.file1() + if file is None: + return pd.DataFrame() + return pd.read_csv( # pyright: ignore[reportUnknownMemberType] + file[0]["datapath"] + ) + + @render.table + def summary(): + df = parsed_file() + + if df.empty: + return pd.DataFrame() + + # Get the row count, column count, and column names of the DataFrame + row_count = df.shape[0] + column_count = df.shape[1] + names = df.columns.tolist() + column_names = ", ".join(str(name) for name in names) + + # Create a new DataFrame to display the information + info_df = pd.DataFrame( + { + "Row Count": [row_count], + "Column Count": [column_count], + "Column Names": [column_names], + } + ) + + # input.stats() is a list of strings; subset the columns based on the selected + # checkboxes + return info_df.loc[:, input.stats()] + + +app = App(app_ui, server) + +``` + diff --git a/docs/api/ui.input_numeric.qmd b/docs/api/ui.input_numeric.qmd new file mode 100644 index 000000000..1f8568294 --- /dev/null +++ b/docs/api/ui.input_numeric.qmd @@ -0,0 +1,81 @@ +# ui.input_numeric { #shiny.ui.input_numeric } + +`ui.input_numeric(id, label, value, *, min=None, max=None, step=None, width=None)` + +Create an input control for entry of numeric values. + +## Parameters + +id: [str](`str`) + +: An input id. + +label: [TagChild](`htmltools.TagChild`) + +: An input label. + +value: [float](`float`) + +: Initial value. + +min: [Optional](`typing.Optional`)\[[float](`float`)\] = None + +: The minimum allowed value. + +max: [Optional](`typing.Optional`)\[[float](`float`)\] = None + +: The maximum allowed value. + +step: [Optional](`typing.Optional`)\[[float](`float`)\] = None + +: Interval to use when stepping between min and max. + +width: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: The CSS width, e.g. '400px', or '100%' + +## Returns + +| Type | Description | +|------------------------|---------------| +| [Tag](`htmltools.Tag`) | A UI element. | + +## Notes + +::: {.callout-note title="Server value"} +A numeric value. +::: + + + +## See Also + +[](:func:`~shiny.ui.update_numeric`) + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +from shiny import App, Inputs, Outputs, Session, render, ui + +app_ui = ui.page_fluid( + ui.input_numeric("obs", "Observations:", 10, min=1, max=100), + ui.output_text_verbatim("value"), +) + + +def server(input: Inputs, output: Outputs, session: Session): + @render.text + def value(): + return input.obs() + + +app = App(app_ui, server) + +``` + diff --git a/docs/api/ui.input_password.qmd b/docs/api/ui.input_password.qmd new file mode 100644 index 000000000..a447b2043 --- /dev/null +++ b/docs/api/ui.input_password.qmd @@ -0,0 +1,75 @@ +# ui.input_password { #shiny.ui.input_password } + +`ui.input_password(id, label, value='', *, width=None, placeholder=None)` + +Create an password control for entry of passwords. + +## Parameters + +id: [str](`str`) + +: An input id. + +label: [TagChild](`htmltools.TagChild`) + +: An input label. + +value: [str](`str`) = '' + +: Initial value. + +width: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: The CSS width, e.g., '400px', or '100%'. + +placeholder: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: The placeholder of the input. + +## Returns + +| Type | Description | +|------------------------|---------------| +| [Tag](`htmltools.Tag`) | A UI element. | + +## Notes + +::: {.callout-note title="Server value"} +A string of the password input. The default value is unless value is provided. +::: + + + +## See Also + +[](:func:`~shiny.ui.update_text`) + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +from shiny import App, Inputs, Outputs, Session, reactive, render, ui + +app_ui = ui.page_fluid( + ui.input_password("password", "Password:"), + ui.input_action_button("go", "Go"), + ui.output_text_verbatim("value"), +) + + +def server(input: Inputs, output: Outputs, session: Session): + @render.text + @reactive.event(input.go) + def value(): + return input.password() + + +app = App(app_ui, server) + +``` + diff --git a/docs/api/ui.input_radio_buttons.qmd b/docs/api/ui.input_radio_buttons.qmd new file mode 100644 index 000000000..b4d34a728 --- /dev/null +++ b/docs/api/ui.input_radio_buttons.qmd @@ -0,0 +1,88 @@ +# ui.input_radio_buttons { #shiny.ui.input_radio_buttons } + +`ui.input_radio_buttons(id, label, choices, *, selected=None, inline=False, width=None)` + +Create a set of radio buttons used to select an item from a list. + +## Parameters + +id: [str](`str`) + +: An input id. + +label: [TagChild](`htmltools.TagChild`) + +: An input label. + +choices: [ChoicesArg](`shiny.ui._input_check_radio.ChoicesArg`) + +: Either a list of choices or a dictionary mapping choice values to labels. Note + that if a dictionary is provided, the keys are used as the (input) values so + that the dictionary values can hold HTML labels. + +selected: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: The values that should be initially selected, if any. + +inline: [bool](`bool`) = False + +: If ``True``, the result is displayed inline. + +width: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: The CSS width, e.g. '400px', or '100%'. + +## Returns + +| Type | Description | +|------------------------|---------------| +| [Tag](`htmltools.Tag`) | A UI element | + +## Notes + +::: {.callout-note title="Server value"} +A string with the selected value. +::: + + + +## See Also + +[](:func:`~shiny.ui.update_radio_buttons`) +[](:func:`~shiny.ui.input_checkbox_group`) +[](:func:`~shiny.ui.input_checkbox`) + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +from shiny import App, Inputs, Outputs, Session, render, ui + +app_ui = ui.page_fluid( + ui.input_radio_buttons( + "rb", + "Choose one:", + { + "html": ui.HTML("Red Text"), + "text": "Normal text", + }, + ), + ui.output_ui("val"), +) + + +def server(input: Inputs, output: Outputs, session: Session): + @render.ui + def val(): + return "You chose " + input.rb() + + +app = App(app_ui, server) + +``` + diff --git a/docs/api/ui.input_select.qmd b/docs/api/ui.input_select.qmd new file mode 100644 index 000000000..f04454b00 --- /dev/null +++ b/docs/api/ui.input_select.qmd @@ -0,0 +1,106 @@ +# ui.input_select { #shiny.ui.input_select } + +`ui.input_select(id, label, choices, *, selected=None, multiple=False, selectize=False, width=None, size=None)` + +Create a select list that can be used to choose a single or multiple items from a +list of values. + +## Parameters + +id: [str](`str`) + +: An input id. + +label: [TagChild](`htmltools.TagChild`) + +: An input label. + +choices: [SelectChoicesArg](`shiny.ui._input_select.SelectChoicesArg`) + +: Either a list of choices or a dictionary mapping choice values to labels. Note + that if a dictionary is provided, the keys are used as the (input) values so + that the dictionary values can hold HTML labels. A dictionary of dictionaries is + also supported, and in that case, the top-level keys are treated as + ```` labels. + +selected: [Optional](`typing.Optional`)\[[str](`str`) \| [list](`list`)\[[str](`str`)\]\] = None + +: The values that should be initially selected, if any. + +multiple: [bool](`bool`) = False + +: Is selection of multiple items allowed? + +selectize: [bool](`bool`) = False + +: Whether to use selectize.js or not. + +width: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: The CSS width, e.g. '400px', or '100%' + +size: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: Number of items to show in the selection box; a larger number will result in a + taller box. Normally, when ``multiple=False``, a select input will be a + drop-down list, but when size is set, it will be a box instead. + +## Returns + +| Type | Description | +|------------------------|---------------| +| [Tag](`htmltools.Tag`) | A UI element. | + +## Notes + +::: {.callout-note title="Server value"} +If `multiple=False`, the server value is a string with the value of the selected item. +If `multiple=True`, the server value is a tuple containing the values of the +selected items. When ``multiple=True`` and nothing is selected, this value +will be ``None``. +::: + + + +## See Also + +[](:func:`~shiny.ui.input_selectize`) +[](:func:`~shiny.ui.update_select`) +[](:func:`~shiny.ui.input_radio_buttons`) +[](:func:`~shiny.ui.input_checkbox_group`) + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +from shiny import App, Inputs, Outputs, Session, render, ui + +app_ui = ui.page_fluid( + ui.input_select( + "state", + "Choose a state:", + { + "East Coast": {"NY": "New York", "NJ": "New Jersey", "CT": "Connecticut"}, + "West Coast": {"WA": "Washington", "OR": "Oregon", "CA": "California"}, + "Midwest": {"MN": "Minnesota", "WI": "Wisconsin", "IA": "Iowa"}, + }, + ), + ui.output_text("value"), +) + + +def server(input: Inputs, output: Outputs, session: Session): + @render.text + def value(): + return "You choose: " + str(input.state()) + + +app = App(app_ui, server) + +``` + diff --git a/docs/api/ui.input_selectize.qmd b/docs/api/ui.input_selectize.qmd new file mode 100644 index 000000000..9f502a864 --- /dev/null +++ b/docs/api/ui.input_selectize.qmd @@ -0,0 +1,94 @@ +# ui.input_selectize { #shiny.ui.input_selectize } + +`ui.input_selectize(id, label, choices, *, selected=None, multiple=False, width=None)` + +Create a select list that can be used to choose a single or multiple items from a +list of values. + +## Parameters + +id: [str](`str`) + +: An input id. + +label: [TagChild](`htmltools.TagChild`) + +: An input label. + +choices: [SelectChoicesArg](`shiny.ui._input_select.SelectChoicesArg`) + +: Either a list of choices or a dictionary mapping choice values to labels. Note + that if a dictionary is provided, the keys are used as the (input) values so + that the dictionary values can hold HTML labels. A dictionary of dictionaries is + also supported, and in that case, the top-level keys are treated as + ```` labels. + +selected: [Optional](`typing.Optional`)\[[str](`str`) \| [list](`list`)\[[str](`str`)\]\] = None + +: The values that should be initially selected, if any. + +multiple: [bool](`bool`) = False + +: Is selection of multiple items allowed? + +width: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: The CSS width, e.g. '400px', or '100%' + +## Returns + +| Type | Description | +|------------------------|---------------| +| [Tag](`htmltools.Tag`) | A UI element. | + +## Notes + +::: {.callout-note title="Server value"} +If `multiple=False`, the server value is a string with the value of the selected item. +If `multiple=True`, the server value is a tuple containing the values of the +selected items. When ``multiple=True`` and nothing is selected, this value +will be ``None``. +::: + + + +## See Also + +[](:func:`~shiny.ui.input_select`) [](:func:`~shiny.ui.input_radio_buttons`) [](:func:`~shiny.ui.input_checkbox_group`) + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +from shiny import App, Inputs, Outputs, Session, render, ui + +app_ui = ui.page_fluid( + ui.input_selectize( + "state", + "Choose a state:", + { + "East Coast": {"NY": "New York", "NJ": "New Jersey", "CT": "Connecticut"}, + "West Coast": {"WA": "Washington", "OR": "Oregon", "CA": "California"}, + "Midwest": {"MN": "Minnesota", "WI": "Wisconsin", "IA": "Iowa"}, + }, + multiple=True, + ), + ui.output_text("value"), +) + + +def server(input: Inputs, output: Outputs, session: Session): + @render.text + def value(): + return "You choose: " + str(input.state()) + + +app = App(app_ui, server) + +``` + diff --git a/docs/api/ui.input_slider.qmd b/docs/api/ui.input_slider.qmd new file mode 100644 index 000000000..1c3aee03b --- /dev/null +++ b/docs/api/ui.input_slider.qmd @@ -0,0 +1,134 @@ +# ui.input_slider { #shiny.ui.input_slider } + +`ui.input_slider(id, label, min, max, value, *, step=None, ticks=False, animate=False, width=None, sep=',', pre=None, post=None, time_format=None, timezone=None, drag_range=True)` + +Constructs a slider widget to select a number, date, or date-time from a range. + +## Parameters + +id: [str](`str`) + +: An input id. + +label: [TagChild](`htmltools.TagChild`) + +: An input label. + +min: [SliderValueArg](`shiny.ui._input_slider.SliderValueArg`) + +: The minimum allowed value. + +max: [SliderValueArg](`shiny.ui._input_slider.SliderValueArg`) + +: The maximum allowed value. + +value: [SliderValueArg](`shiny.ui._input_slider.SliderValueArg`) \| [Iterable](`typing.Iterable`)\[[SliderValueArg](`shiny.ui._input_slider.SliderValueArg`)\] + +: Initial value. + +step: [Optional](`typing.Optional`)\[[SliderStepArg](`shiny.ui._input_slider.SliderStepArg`)\] = None + +: Interval to use when stepping between min and max. + +ticks: [bool](`bool`) = False + +: ``False`` to hide tick marks, ``True`` to show them according to some simple + heuristics. + +animate: [bool](`bool`) \| [AnimationOptions](`shiny.ui._input_slider.AnimationOptions`) = False + +: ``True`` to show simple animation controls with default settings; ``False`` not + to; or a custom settings list, such as those created using + [](:class:`~AnimationOptions`). + +width: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: The CSS width, e.g. '400px', or '100%' + +sep: [str](`str`) = ',' + +: Separator between thousands places in numbers. + +pre: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: A prefix string to put in front of the value. + +post: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: A suffix string to put after the value. + +time_format: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: Only used if the slider values are [](:class:`~datetime.date`) or + [](:class:`~datetime.datetime`) objects. A time format string, to be passed to the + Javascript strftime library. See https://github.com/samsonjs/strftime for more + details. For Dates, the default is "%F" (like "2015-07-01"), and for Datetimes, + the default is "%F %T" (like "2015-07-01 15:32:10"). + +timezone: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: Only used if the values are [](:class:`~datetime.datetime`) objects. A string + specifying the time zone offset for the displayed times, in the format "+HHMM" + or "-HHMM". If ``None`` (the default), times will be displayed in the browser's + time zone. The value "+0000" will result in UTC time. + +drag_range: [bool](`bool`) = True + +: This option is used only if it is a range slider (with two values). If ``True`` + (the default), the range can be dragged. In other words, the min and max can be + dragged together. If ``False``, the range cannot be dragged. + +## Returns + +| Type | Description | +|------------------------|---------------| +| [Tag](`htmltools.Tag`) | A UI element | + +## Notes + +::: {.callout-note title="Server value"} +A number, date, or date-time (depending on the class of value), or in the case of +slider range, a tuple of two numbers/dates/date-times. +::: + + + +## See Also + +[](:func:`~shiny.ui.update_slider`) + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +import matplotlib.pyplot as plt +import numpy as np + +from shiny import App, Inputs, Outputs, Session, render, ui + +app_ui = ui.page_fluid( + ui.input_slider("obs", "Number of bins:", min=10, max=100, value=30), + ui.output_plot("distPlot"), +) + + +def server(input: Inputs, output: Outputs, session: Session): + @render.plot + def distPlot(): + np.random.seed(19680801) + x = 100 + 15 * np.random.randn(437) + + fig, ax = plt.subplots() + ax.hist(x, input.obs(), density=True) + return fig + + +app = App(app_ui, server) + +``` + diff --git a/docs/api/ui.input_switch.qmd b/docs/api/ui.input_switch.qmd new file mode 100644 index 000000000..ea8819960 --- /dev/null +++ b/docs/api/ui.input_switch.qmd @@ -0,0 +1,74 @@ +# ui.input_switch { #shiny.ui.input_switch } + +`ui.input_switch(id, label, value=False, *, width=None)` + +Create a switch that can be used to specify logical values. Similar to +[](:func:`~shiny.ui.input_checkbox`), but implies to the user that the change will take effect +immediately. + +## Parameters + +id: [str](`str`) + +: An input id. + +label: [TagChild](`htmltools.TagChild`) + +: An input label. + +value: [bool](`bool`) = False + +: Initial value. + +width: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: The CSS width, e.g. '400px', or '100%' + +## Returns + +| Type | Description | +|------------------------|---------------| +| [Tag](`htmltools.Tag`) | A UI element. | + +## Notes + +::: {.callout-note title="Server value"} +``True`` if checked, ``False`` otherwise. +::: + + + +## See Also + +[](:func:`~shiny.ui.input_checkbox`) +[](:func:`~shiny.ui.update_switch`) +[](:func:`~shiny.ui.input_checkbox_group`) +[](:func:`~shiny.ui.input_radio_buttons`) + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +from shiny import App, Inputs, Outputs, Session, render, ui + +app_ui = ui.page_fluid( + ui.input_switch("somevalue", "Some value", False), + ui.output_ui("value"), +) + + +def server(input: Inputs, output: Outputs, session: Session): + @render.ui + def value(): + return input.somevalue() + + +app = App(app_ui, server) + +``` + diff --git a/docs/api/ui.input_text.qmd b/docs/api/ui.input_text.qmd new file mode 100644 index 000000000..4c78fee79 --- /dev/null +++ b/docs/api/ui.input_text.qmd @@ -0,0 +1,87 @@ +# ui.input_text { #shiny.ui.input_text } + +`ui.input_text(id, label, value='', *, width=None, placeholder=None, autocomplete='off', spellcheck=None)` + +Create an input control for entry of text values. + +## Parameters + +id: [str](`str`) + +: An input id. + +label: [TagChild](`htmltools.TagChild`) + +: An input label. + +value: [str](`str`) = '' + +: Initial value. + +width: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: The CSS width, e.g., '400px', or '100%'. + +placeholder: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: A hint as to what can be entered into the control. + +autocomplete: [Optional](`typing.Optional`)\[[str](`str`)\] = 'off' + +: Whether to enable browser autocompletion of the text input (default is ``None``). + If `None`, then it will use the browser's default behavior. Other possible values + include "on", "off", "name", "username", and "email". See + https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/autocomplete for + more. + +spellcheck: [Optional](`typing.Optional`)\[[Literal](`typing.Literal`)\['true', 'false'\]\] = None + +: Whether to enable browser spell checking of the text input (default is ``None``). If + None, then it will use the browser's default behavior. + +## Returns + +| Type | Description | +|------------------------|---------------| +| [Tag](`htmltools.Tag`) | A UI element | + +## Notes + +::: {.callout-note title="Server value"} +A string containing the current text input. The default value is ``""`` unless +``value`` is provided. +::: + + + +## See Also + +[](:func:`~shiny.ui.input_text_area`) + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +from shiny import App, Inputs, Outputs, Session, render, ui + +app_ui = ui.page_fluid( + ui.input_text("caption", "Caption:", "Data summary"), + ui.output_text_verbatim("value"), +) + + +def server(input: Inputs, output: Outputs, session: Session): + @render.text + def value(): + return input.caption() + + +app = App(app_ui, server) + +``` + diff --git a/docs/api/ui.input_text_area.qmd b/docs/api/ui.input_text_area.qmd new file mode 100644 index 000000000..43ad0235a --- /dev/null +++ b/docs/api/ui.input_text_area.qmd @@ -0,0 +1,130 @@ +# ui.input_text_area { #shiny.ui.input_text_area } + +`ui.input_text_area(id, label, value='', *, width=None, height=None, cols=None, rows=None, placeholder=None, resize=None, autoresize=False, autocomplete=None, spellcheck=None)` + +Create a textarea input control for entry of unstructured text values. + +## Parameters + +id: [str](`str`) + +: An input id. + +label: [TagChild](`htmltools.TagChild`) + +: An input label. + +value: [str](`str`) = '' + +: Initial value. + +width: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: The CSS width, e.g., '400px', or '100%'. + +height: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: The CSS height, e.g., '400px', or '100%'. + +cols: [Optional](`typing.Optional`)\[[int](`int`)\] = None + +: Value of the visible character columns of the input, e.g., 80. This argument will + only take effect if there is not a CSS width rule defined for this element; such + a rule could come from the width argument of this function or from a containing + page layout such as [](:func:`~shiny.ui.page_fluid`). + +rows: [Optional](`typing.Optional`)\[[int](`int`)\] = None + +: The value of the visible character rows of the input, e.g., 6. If the height + argument is specified, height will take precedence in the browser's rendering. + +placeholder: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: A hint as to what can be entered into the control. + +resize: [Optional](`typing.Optional`)\[[Literal](`typing.Literal`)\['none', 'both', 'horizontal', 'vertical'\]\] = None + +: Which directions the textarea box can be resized. Can be one of "both", "none", + "vertical", and "horizontal". The default, ``None``, will use the client + browser's default setting for resizing textareas. + +autoresize: [bool](`bool`) = False + +: If True, then the textarea will automatically resize the height to fit the input + text. + +autocomplete: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: Whether to enable browser autocompletion of the text input (default is "off"). + If `None`, then it will use the browser's default behavior. Other possible + values include "on", "name", "username", and "email". See [Mozilla's autocomplete + documentation](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/autocomplete) + for more. + +spellcheck: [Optional](`typing.Optional`)\[[Literal](`typing.Literal`)\['true', 'false'\]\] = None + +: Whether to enable browser spell checking of the text input (default is ``None``). If + None, then it will use the browser's default behavior. + +## Returns + +| Type | Description | +|------------------------|---------------| +| [Tag](`htmltools.Tag`) | A UI element | + +## Notes + + +::: {.callout-note title="Server value"} +A string containing the current text input. The default value is ``""`` unless +``value`` is provided. +::: + + + +## See Also + +[](:func:`~shiny.ui.input_text`) + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +from shiny import App, Inputs, Outputs, Session, render, ui + +app_ui = ui.page_fluid( + ui.input_text_area( + "caption_regular", + "Caption:", + "Data summary\nwith\nmultiple\nlines", + ), + ui.output_text_verbatim("value_regular", placeholder=True), + ui.input_text_area( + "caption_autoresize", + ui.markdown("Caption (w/ `autoresize=True`):"), + "Data summary\nwith\nmultiple\nlines", + autoresize=True, + ), + ui.output_text_verbatim("value_autoresize", placeholder=True), +) + + +def server(input: Inputs, output: Outputs, session: Session): + @render.text + def value_regular(): + return input.caption_regular() + + @render.text + def value_autoresize(): + return input.caption_autoresize() + + +app = App(app_ui, server) + +``` + diff --git a/docs/api/ui.insert_accordion_panel.qmd b/docs/api/ui.insert_accordion_panel.qmd new file mode 100644 index 000000000..370710324 --- /dev/null +++ b/docs/api/ui.insert_accordion_panel.qmd @@ -0,0 +1,83 @@ +# ui.insert_accordion_panel { #shiny.ui.insert_accordion_panel } + +`ui.insert_accordion_panel(id, panel, target=None, position='after', session=None)` + +Insert an [](:func:`~shiny.ui.accordion_panel`). + +## Parameters + +id: [str](`str`) + +: A string that matches an existing [](:func:`~shiny.ui.accordion`)'s `id`. + +panel: [AccordionPanel](`shiny.ui._accordion.AccordionPanel`) + +: An [](:func:`~shiny.ui.accordion_panel`) object to insert. + +target: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: The `value` of an existing panel to insert next to. + +position: [Literal](`typing.Literal`)\['after', 'before'\] = 'after' + +: Should `panel` be added before or after the target? When `target=None`, + `"after"` will append after the last panel and `"before"` will prepend before + the first panel. + +session: [Optional](`typing.Optional`)\[[Session](`shiny.session.Session`)\] = None + +: A Shiny session object (the default should almost always be used). + +## References + +[Bootstrap Accordion](https://getbootstrap.com/docs/5.3/components/accordion/) + + + +## See Also + +* [](:func:`~shiny.ui.accordion`) +* [](:func:`~shiny.ui.accordion_panel`) +* [](:func:`~shiny.ui.update_accordion`) +* [](:func:`~shiny.ui.remove_accordion_panel`) +* [](:func:`~shiny.ui.update_accordion_panel`) + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +import random + +from shiny import App, Inputs, Outputs, Session, reactive, ui + + +def make_panel(letter: str) -> ui.AccordionPanel: + return ui.accordion_panel( + f"Section {letter}", f"Some narrative for section {letter}" + ) + + +items = [make_panel(letter) for letter in "ABCDE"] + +app_ui = ui.page_fluid( + ui.input_action_button("add_panel", "Add random panel", class_="mt-3 mb-3"), + ui.accordion(*items, id="acc", multiple=True), +) + + +def server(input: Inputs, output: Outputs, session: Session): + @reactive.Effect + @reactive.event(input.add_panel) + def _(): + ui.insert_accordion_panel("acc", make_panel(str(random.randint(0, 10000)))) + + +app = App(app_ui, server) + +``` + diff --git a/docs/api/ui.insert_ui.qmd b/docs/api/ui.insert_ui.qmd new file mode 100644 index 000000000..2477fcb2f --- /dev/null +++ b/docs/api/ui.insert_ui.qmd @@ -0,0 +1,96 @@ +# ui.insert_ui { #shiny.ui.insert_ui } + +`ui.insert_ui(ui, selector, where='beforeEnd', multiple=False, immediate=False, session=None)` + +Insert UI objects. + +## Parameters + +ui: [TagChild](`htmltools.TagChild`) + +: The UI object you want to insert. This can be anything that you usually put + inside your app's UI function. If you're inserting multiple elements in one + call, make sure to wrap them in either a [](:func:`~shiny.ui.TagList`) or a + [](:func:`~shiny.ui.tags.div`) (the latter option has the advantage that you can + give it an id to make it easier to reference or remove it later on). If you want + to insert raw HTML, use [](:func:`~shiny.ui.HTML`). + +selector: [str](`str`) + +: A string that is accepted by jQuery's selector (i.e. the string ``s`` to be + placed in a ``$(s)`` jQuery call) which determines the element(s) relative to + which you want to insert your UI object. + +where: [Literal](`typing.Literal`)\['beforeBegin', 'afterBegin', 'beforeEnd', 'afterEnd'\] = 'beforeEnd' + +: Where your UI object should go relative to the selector: "beforeBegin": + before the selector element itself; "beforeEnd": just inside the selector + element, after its last child (default); "afterEnd": after the selector + element itself. Adapted from + https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentHTML. + +multiple: [bool](`bool`) = False + +: In case your selector matches more than one element, ``multiple`` + determines whether Shiny should insert the UI object relative to all + matched elements or just relative to the first matched element (default). + +immediate: [bool](`bool`) = False + +: Whether the UI object should be immediately inserted or removed, or whether + Shiny should wait until all outputs have been updated and all effects have been + run (default). + +session: [Optional](`typing.Optional`)\[[Session](`shiny.session.Session`)\] = None + +: A [](:class:`~shiny.Session`) instance. If not provided, it is inferred via + [](:func:`~shiny.session.get_current_session`). + +## Note + +This function allows you to dynamically add arbitrary UI into your app, whenever you +want, as many times as you want. Unlike [](:func:`~shiny.render.ui`), the UI generated +with `insert_ui` is persistent: once it's created, it stays there until removed by +[](:func:`remove_ui`). Each new call to `insert_ui` creates more UI objects, in addition +to the ones already there (all independent from one another). To update a part of +the UI (ex: an input object), you must use the appropriate render function or a +customized reactive function. + + + +## See Also + +[](:func:`~shiny.ui.remove_ui`) +[](:func:`~shiny.render.ui`) + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +from shiny import App, Inputs, Outputs, Session, reactive, ui + +app_ui = ui.page_fluid( + ui.input_action_button("add", "Add UI"), +) + + +def server(input: Inputs, output: Outputs, session: Session): + @reactive.Effect + @reactive.event(input.add) + def _(): + ui.insert_ui( + ui.input_text("txt" + str(input.add()), "Enter some text"), + selector="#add", + where="afterEnd", + ) + + +app = App(app_ui, server) + +``` + diff --git a/docs/api/ui.layout_column_wrap.qmd b/docs/api/ui.layout_column_wrap.qmd new file mode 100644 index 000000000..c35f9db6c --- /dev/null +++ b/docs/api/ui.layout_column_wrap.qmd @@ -0,0 +1,115 @@ +# ui.layout_column_wrap { #shiny.ui.layout_column_wrap } + +`ui.layout_column_wrap(*args, width=MISSING, fixed_width=False, heights_equal='all', fill=True, fillable=True, height=None, height_mobile=None, gap=None, class_=None, **kwargs)` + +A grid-like, column-first layout + +Wraps a 1d sequence of UI elements into a 2d grid. The number of columns +(and rows) in the grid depends on the column width and the size of the display. + +## Parameters + +*args: [TagChild](`htmltools.TagChild`) \| [TagAttrs](`htmltools.TagAttrs`) = () + +: Unnamed arguments should be UI elements (e.g., + [](:func:`~shiny.ui.card`)). Named arguments become attributes on the + containing [](:class:`~htmltools.Tag`) element. + +width: [CssUnit](`shiny.ui.css.CssUnit`) \| None \| [MISSING_TYPE](`shiny.types.MISSING_TYPE`) = MISSING + +: The desired width of each card. It can be one of the following: + + * A (unit-less) number between 0 and 1, specified as `1/num`, where `num` + represents the number of desired columns. + * A CSS length unit representing either the minimum (when `fixed_width=False`) + or fixed width (`fixed_width=True`). + * `None`, which allows power users to set the `grid-template-columns` CSS + property manually, either via a `style` attribute or a CSS stylesheet. + * If missing, a value of `200px` will be used. + +fixed_width: [bool](`bool`) = False + +: When `width` is greater than 1 or is a CSS length unit, e.g., `"200px"`, + `fixed_width` indicates whether that `width` value represents the absolute size + of each column (`fixed_width=TRUE`) or the minimum size of a column + (`fixed_width=FALSE`). + + When `fixed_width=FALSE`, new columns are added to a row when `width` space is + available and columns will never exceed the container or viewport size. + + When `fixed_width=TRUE`, all columns will be exactly `width` wide, which may + result in columns overflowing the parent container. + +heights_equal: [Literal](`typing.Literal`)\['all', 'row'\] = 'all' + +: If `"all"` (the default), every card in every row of the grid will have the same + height. If `"row"`, then every card in _each_ row of the grid will have the same + height, but heights may vary between rows. + +fill: [bool](`bool`) = True + +: Whether or not to allow the layout to grow/shrink to fit a fillable container + with an opinionated height (e.g., [](:func:`~shiny.ui.page_fillable`)). + +fillable: [bool](`bool`) = True + +: Whether or not each element is wrapped in a fillable container. + +height: [Optional](`typing.Optional`)\[[CssUnit](`shiny.ui.css.CssUnit`)\] = None + +: Any valid CSS unit to use for the height. + +height_mobile: [Optional](`typing.Optional`)\[[CssUnit](`shiny.ui.css.CssUnit`)\] = None + +: Any valid CSS unit to use for the height when on mobile devices (or narrow + windows). + +gap: [Optional](`typing.Optional`)\[[CssUnit](`shiny.ui.css.CssUnit`)\] = None + +: Any valid CSS unit to use for the gap between columns. + +class_: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: A CSS class to apply to the containing element. + +**kwargs: [TagAttrValue](`htmltools.TagAttrValue`) = {} + +: Additional attributes to apply to the containing element. + +## Returns + +| Type | Description | +|------------------------|------------------------------------| +| [Tag](`htmltools.Tag`) | A [](:class:`~htmltools.Tag`) element. | + +## See Also + +* [](:func:`~shiny.ui.layout_columns`) for laying out elements into a responsive + 12-column grid. + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +from shiny import App, ui + +y = ui.card("A simple card") + +app_ui = ui.page_fluid( + # Always has 2 columns (on non-mobile) + ui.layout_column_wrap(y, y, y, width=1 / 2), + ui.hr(), + # Has three columns when viewport is wider than 750px + ui.layout_column_wrap(y, y, y, width="250px"), +) + + +app = App(app_ui, server=None) + +``` + diff --git a/docs/api/ui.layout_columns.qmd b/docs/api/ui.layout_columns.qmd new file mode 100644 index 000000000..d6fa3ba21 --- /dev/null +++ b/docs/api/ui.layout_columns.qmd @@ -0,0 +1,198 @@ +# ui.layout_columns { #shiny.ui.layout_columns } + +`ui.layout_columns(*args, col_widths=None, row_heights=None, fill=True, fillable=True, gap=None, class_=None, height=None, **kwargs)` + +Create responsive, column-based grid layouts, based on a 12-column grid. + +## Parameters + +*args: [TagChild](`htmltools.TagChild`) \| [TagAttrs](`htmltools.TagAttrs`) = () + +: Child elements or attributes to be added to the layout. + +col_widths: [BreakpointsUser](`shiny.ui._layout_columns.BreakpointsUser`)\[[int](`int`)\] = None + +: The widths of the columns, possibly at different breakpoints. Can be one of the + following: + + * `None` (the default): Automatically determines a sensible number of columns + based on the number of children given to the layout. + * A list or tuple of integers between 1 and 12, where each element represents + the number of columns for the relevant UI element. Column widths are recycled + to extend the values in `col_widths` to match the actual number of items in + the layout, and children are wrapped onto the next row when a row exceeds 12 + column units. For example, `col_widths=(4, 8, 12)` allocates 4 columns to the + first element, 8 columns to the second element, and 12 columns to the third + element (which wraps to the next row). Negative values are also allowed, and + are treated as empty columns. For example, `col_widths=(-2, 8, -2)` would + allocate 8 columns to an element (with 2 empty columns on either side). + * A dictionary of column widths at different breakpoints. The keys should be + one of `"xs"`, `"sm"`, `"md"`, `"lg"`, `"xl"`, or `"xxl"`, and the values are + either of the above. For example, `col_widths={"sm": (3, 3, 6), "lg": (4)}`. + +row_heights: [BreakpointsUser](`shiny.ui._layout_columns.BreakpointsUser`)\[[CssUnit](`shiny.ui.css.CssUnit`)\] = None + +: The heights of the rows, possibly at different breakpoints. Can be one of the + following: + + * A numeric vector, where each value represents the + [fractional unit](https://css-tricks.com/introduction-fr-css-unit/) + (`fr`) height of the relevant row. If there are more rows than values + provided, the pattern will be repeated. For example, `row_heights=(1, 2)` + allows even rows to take up twice as much space as odd rows. + * A list of numeric or CSS length units, where each value represents the height + of the relevant row. If more rows are needed than values provided, the pattern + will repeat. For example, `row_heights=["auto", 1]` allows the height of odd + rows to be driven my it's contents and even rows to be + [`1fr`](https://css-tricks.com/introduction-fr-css-unit/). + * A single string containing CSS length units. In this case, the value is + supplied directly to `grid-auto-rows`. + * A dictionary of row heights at different breakpoints, where each key is a + breakpoint name (one of `"xs"`, `"sm"`, `"md"`, `"lg"`, `"xl"`, or `"xxl"`) + and where the values may be any of the above options. + +fill: [bool](`bool`) = True + +: Whether or not to allow the layout to grow/shrink to fit a fillable container + with an opinionated height (e.g., [](:func:`~shiny.ui.page_fillable`)). + +fillable: [bool](`bool`) = True + +: Whether or not each element is wrapped in a fillable container. + +gap: [Optional](`typing.Optional`)\[[CssUnit](`shiny.ui.css.CssUnit`)\] = None + +: Any valid CSS unit to use for the gap between columns. + +class_: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: CSS class(es) to apply to the containing element. + +height: [Optional](`typing.Optional`)\[[CssUnit](`shiny.ui.css.CssUnit`)\] = None + +: Any valid CSS unit to use for the height. + +**kwargs: [TagAttrValue](`htmltools.TagAttrValue`) = {} + +: Additional attributes to apply to the containing element. + +## Returns + +| Type | Description | +|------------------------|-------------------------------------| +| [Tag](`htmltools.Tag`) | An [](:class:`~htmltools.Tag`) element. | + +## See Also + +* [](:func:`~shiny.ui.layout_column_wrap`) for laying out elements into a uniform grid. + + + +## Reference + +* [Bootstrap CSS Grid](https://getbootstrap.com/docs/5.3/layout/grid/) +* [Bootstrap Breakpoints](https://getbootstrap.com/docs/5.3/layout/breakpoints/) + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +from model_plots import * # model plots and cards + +from shiny import App, Inputs, Outputs, Session, render, ui + +app_ui = ui.page_fluid( + ui.panel_title(ui.h2("Model Dashboard")), + ui.markdown("Using `ui.layout_columns()` for the layout."), + ui.layout_columns( + card_loss, + card_acc, + card_feat, + col_widths={"sm": (5, 7, 12)}, + # row_heights=(2, 3), + # height="700px", + ), +) + + +def server(input: Inputs, output: Outputs, session: Session): + @render.plot + def loss_over_time(): + return plot_loss_over_time() + + @render.plot + def accuracy_over_time(): + return plot_accuracy_over_time() + + @render.plot + def feature_importance(): + return plot_feature_importance() + + +app = App(app_ui, server) + +## file: model_plots.py +import matplotlib.pyplot as plt +import numpy as np + +from shiny import ui + + +def plot_loss_over_time(): + epochs = np.arange(1, 101) + loss = 1000 / np.sqrt(epochs) + np.random.rand(100) * 25 + + fig = plt.figure(figsize=(10, 6)) + plt.plot(epochs, loss) + plt.xlabel("Epochs") + plt.ylabel("Loss") + return fig + + +def plot_accuracy_over_time(): + epochs = np.arange(1, 101) + accuracy = np.sqrt(epochs) / 12 + np.random.rand(100) * 0.15 + accuracy = [np.min([np.max(accuracy[:i]), 1]) for i in range(1, 101)] + + fig = plt.figure(figsize=(10, 6)) + plt.plot(epochs, accuracy) + plt.xlabel("Epochs") + plt.ylabel("Accuracy") + return fig + + +def plot_feature_importance(): + features = ["Product Category", "Price", "Brand", "Rating", "Number of Reviews"] + importance = np.random.rand(5) + + fig = plt.figure(figsize=(10, 6)) + plt.barh(features, importance) + plt.xlabel("Importance") + return fig + + +card_loss = ui.card( + ui.card_header("Loss Over Time"), + ui.output_plot("loss_over_time"), + full_screen=True, +) + +card_acc = ui.card( + ui.card_header("Accuracy Over Time"), + ui.output_plot("accuracy_over_time"), + full_screen=True, +) + +card_feat = ui.card( + ui.card_header("Feature Importance"), + ui.output_plot("feature_importance"), + full_screen=True, +) + +``` + diff --git a/docs/api/ui.layout_sidebar.qmd b/docs/api/ui.layout_sidebar.qmd new file mode 100644 index 000000000..7f3b10fe0 --- /dev/null +++ b/docs/api/ui.layout_sidebar.qmd @@ -0,0 +1,117 @@ +# ui.layout_sidebar { #shiny.ui.layout_sidebar } + +`ui.layout_sidebar(sidebar, *args, fillable=True, fill=True, bg=None, fg=None, border=None, border_radius=None, border_color=None, gap=None, padding=None, height=None, **kwargs)` + +Sidebar layout + +Create a sidebar layout component which can be dropped inside any Shiny UI page +method (e.g. [](:func:`~shiny.shiny.ui.page_fillable`)) or +[](:func:`~shiny.ui.card`) context. + +## Parameters + +*args: [TagChild](`htmltools.TagChild`) \| [TagAttrs](`htmltools.TagAttrs`) = () + +: One argument needs to be of class [](:class:`~shiny.ui.Sidebar`) object created by + [](:func:`~shiny.ui.sidebar`). The remaining arguments will contain the contents to + the main content area. Or tag attributes that are supplied to the resolved + [](:class:`~htmltools.Tag`) object. + +fillable: [bool](`bool`) = True + +: Whether or not the main content area should be wrapped in a fillable container. + See [](:func:`~shiny.ui.as_fillable_container`) for details. + +fill: [bool](`bool`) = True + +: Whether or not the sidebar layout should be wrapped in a fillable container. See + [](:func:`~shiny.ui.as_fill_item`) for details. + +bg: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: A background or foreground color. + +border: [Optional](`typing.Optional`)\[[bool](`bool`)\] = None + +: Whether or not to show a border around the sidebar layout. + +border_radius: [Optional](`typing.Optional`)\[[bool](`bool`)\] = None + +: Whether or not to round the corners of the sidebar layout. + +border_color: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: A border color. + +gap: [Optional](`typing.Optional`)\[[CssUnit](`shiny.ui.css.CssUnit`)\] = None + +: A CSS length unit defining the vertical `gap` (i.e., spacing) between elements + provided to `*args`. This value will only be used if `fillable` is `True`. + +padding: [Optional](`typing.Optional`)\[[CssUnit](`shiny.ui.css.CssUnit`) \| [list](`list`)\[[CssUnit](`shiny.ui.css.CssUnit`)\]\] = None + +: Padding within the sidebar itself. This can be a numeric vector (which will be + interpreted as pixels) or a character vector with valid CSS lengths. `padding` + may be one to four values. + + * If a single value, then that value will be used for all four sides. + * If two, then the first value will be used for the top and bottom, while + the second value will be used for left and right. + * If three values, then the first will be used for top, the second will be left + and right, and the third will be bottom. + * If four, then the values will be interpreted as top, right, bottom, and left + respectively. + +height: [Optional](`typing.Optional`)\[[CssUnit](`shiny.ui.css.CssUnit`)\] = None + +: Any valid CSS unit to use for the height. + +## Returns + +| Type | Description | +|---------------------------------------|-----------------------------------| +| [CardItem](`shiny.ui._card.CardItem`) | A [](:class:`~htmltools.Tag`) object. | + +## See Also + +* [](:func:`~shiny.ui.sidebar`) + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +import matplotlib.pyplot as plt +import numpy as np + +from shiny import App, Inputs, Outputs, Session, render, ui + +app_ui = ui.page_fluid( + ui.layout_sidebar( + ui.sidebar( + ui.input_slider("n", "N", min=0, max=100, value=20), + ), + ui.output_plot("plot"), + ), +) + + +def server(input: Inputs, output: Outputs, session: Session): + @render.plot(alt="A histogram") + def plot() -> object: + np.random.seed(19680801) + x = 100 + 15 * np.random.randn(437) + + fig, ax = plt.subplots() + ax.hist(x, input.n(), density=True) + return fig + + +app = App(app_ui, server) + +``` + diff --git a/docs/api/ui.markdown.qmd b/docs/api/ui.markdown.qmd new file mode 100644 index 000000000..3e0e906a6 --- /dev/null +++ b/docs/api/ui.markdown.qmd @@ -0,0 +1,74 @@ +# ui.markdown { #shiny.ui.markdown } + +`ui.markdown(text, *, render_func=None, **kwargs)` + +Convert a string of markdown to [](:func:`ui.HTML`). + +## Parameters + +text: [str](`str`) + +: A string of text containing markdown. + +render_func: [Optional](`typing.Optional`)\[[Callable](`typing.Callable`)\[\[[str](`str`)\], [str](`str`)\]\] = None + +: A function (with at least 1 argument) which accepts a string of markdown and + returns a string of HTML. By default, a customized instance of the + [](:class:`MarkdownIt`) class (which supports Github-flavored markdown) from the + ``markdown-it`` package is used. + +**kwargs: [object](`object`) = {} + +: Additional keyword arguments passed to the ``render_func``. + +## Returns + +| Type | Description | +|--------------------------|-----------------------------------------------------| +| [HTML](`htmltools.HTML`) | An [](:func:`ui.HTML`) string of the rendered markdown. | + +## Note + +Use [](:func:`ui.include_markdown`) instead if you want to include local images (or +other files) in the markdown. + + + +## See Also + +[](:func:`ui.include_markdown`) + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +from shiny import App, Inputs, Outputs, Session, ui + +ui_app = ui.page_fluid( + ui.markdown( + """ + # Hello World + + This is **markdown** and here is some `code`: + + ```python + print('Hello world!') + ``` + """ + ) +) + + +def server(input: Inputs, output: Outputs, session: Session): + pass + + +app = App(ui_app, server) + +``` + diff --git a/docs/api/ui.modal.qmd b/docs/api/ui.modal.qmd new file mode 100644 index 000000000..f2cd3366f --- /dev/null +++ b/docs/api/ui.modal.qmd @@ -0,0 +1,90 @@ +# ui.modal { #shiny.ui.modal } + +`ui.modal(*args, title=None, footer=MISSING, size='m', easy_close=False, fade=True, **kwargs)` + +Creates the UI for a modal dialog, using Bootstrap's modal class. + +A modal is a dialog box that appears in front of the app. Modals are +typically used for showing important messages, or for presenting UI that requires +input from the user, such as a user name and/or password input. + +## Parameters + +*args: [TagChild](`htmltools.TagChild`) \| [TagAttrs](`htmltools.TagAttrs`) = () + +: UI elements for the body of the modal. + +title: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: An optional title for the modal dialog. + +footer: [TagChild](`htmltools.TagChild`) \| [MISSING_TYPE](`shiny.types.MISSING_TYPE`) = MISSING + +: UI for footer. Use ``None`` for no footer. + +size: [Literal](`typing.Literal`)\['m', 's', 'l', 'xl'\] = 'm' + +: The size of the modal dialogue box. Use one of "s" for small, "m" (the default) + for medium, or "l" for large. + +easy_close: [bool](`bool`) = False + +: If ``True``, the modal dialog can be dismissed by clicking outside the dialog + box, or by pressing the Escape key. If ``False`` (the default), the modal dialog + can't be dismissed in those ways; instead it must be dismissed by clicking on a + ``modal_button()``, or from a call to ``modal_remove()`` on the server. + +fade: [bool](`bool`) = True + +: If ``False``, the modal dialog will have no fade-in animation (it will simply + appear rather than fade in to view). + +**kwargs: [TagAttrValue](`htmltools.TagAttrValue`) = {} + +: Attributes to be applied to the modal's body tag. + +## Returns + +| Type | Description | +|------------------------|---------------| +| [Tag](`htmltools.Tag`) | A UI element | + +## See Also + +[](:func:`~shiny.ui.modal_show`) +[](:func:`~shiny.ui.modal_remove`) +[](:func:`~shiny.ui.modal_button`) + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +from shiny import App, Inputs, Outputs, Session, reactive, ui + +app_ui = ui.page_fluid( + ui.input_action_button("show", "Show modal dialog"), +) + + +def server(input: Inputs, output: Outputs, session: Session): + @reactive.Effect + @reactive.event(input.show) + def _(): + m = ui.modal( + "This is a somewhat important message.", + title="Somewhat important message", + easy_close=True, + footer=None, + ) + ui.modal_show(m) + + +app = App(app_ui, server) + +``` + diff --git a/docs/api/ui.modal_button.qmd b/docs/api/ui.modal_button.qmd new file mode 100644 index 000000000..01b6e111a --- /dev/null +++ b/docs/api/ui.modal_button.qmd @@ -0,0 +1,39 @@ +# ui.modal_button { #shiny.ui.modal_button } + +`ui.modal_button(label, icon=None, **kwargs)` + +Creates a button that will dismiss a [](:func:`modal`). [](:func:`~shiny.ui.modal_button`) is usually +passed to the `footer` of a [](:func:`~shiny.ui.modal`) to add a button to the footer that will close +the [](:func:`~shiny.ui.modal`). + +## Parameters + +label: [TagChild](`htmltools.TagChild`) + +: An input label. + +icon: [TagChild](`htmltools.TagChild`) = None + +: An icon to appear inline with the button/link. + +**kwargs: [TagAttrValue](`htmltools.TagAttrValue`) = {} + +: Attributes to be applied to the button. + +## Returns + +| Type | Description | +|------------------------|---------------| +| [Tag](`htmltools.Tag`) | A UI element | + +## See Also + +[](:func:`~shiny.ui.modal`) +[](:func:`~shiny.ui.modal_show`) +[](:func:`~shiny.ui.modal_remove`) + + + +## Example + +See [](:func:`modal`). \ No newline at end of file diff --git a/docs/api/ui.modal_remove.qmd b/docs/api/ui.modal_remove.qmd new file mode 100644 index 000000000..4553cfd05 --- /dev/null +++ b/docs/api/ui.modal_remove.qmd @@ -0,0 +1,27 @@ +# ui.modal_remove { #shiny.ui.modal_remove } + +`ui.modal_remove(session=None)` + +Remove a modal dialog box. + +[](:func:`~shiny.ui.modal_remove`) provides a way to remove a modal programatically. +Modals can also be removed manually by the user if a [](:func:`~shiny.ui.modal_button`) +is provided, or if the modal is created with `easy_close=True`. + +## Parameters + +session: [Optional](`typing.Optional`)\[[Session](`shiny.session.Session`)\] = None + +: The [](:class:`~shiny.Session`) instance that contains the modal to remove. If not + provided, the session is inferred via [](:func:`~shiny.session.get_current_session`). + +## See Also + +[](:func:`~shiny.ui.modal_show`) +[](:func:`~shiny.ui.modal`) + + + +## Example + +See [](:func:`modal`). \ No newline at end of file diff --git a/docs/api/ui.modal_show.qmd b/docs/api/ui.modal_show.qmd new file mode 100644 index 000000000..a64cff6bd --- /dev/null +++ b/docs/api/ui.modal_show.qmd @@ -0,0 +1,30 @@ +# ui.modal_show { #shiny.ui.modal_show } + +`ui.modal_show(modal, session=None)` + +Show a modal dialog. + +[](:func:`~shiny.ui.modal_show`) is used to display a modal that has been +created with [](:func:`~shiny.ui.modal`). + +## Parameters + +modal: [Tag](`htmltools.Tag`) + +: Typically a [](:func:`modal`) instance. + +session: [Optional](`typing.Optional`)\[[Session](`shiny.session.Session`)\] = None + +: The [](:class:`~shiny.Session`) instance to display the modal in. If not provided, + the session is inferred via [](:func:`~shiny.session.get_current_session`). + +## See Also + +[](:func:`~shiny.ui.modal_remove`) +[](:func:`~shiny.ui.modal`) + + + +## Example + +See [](:func:`modal`). \ No newline at end of file diff --git a/docs/api/ui.nav.qmd b/docs/api/ui.nav.qmd new file mode 100644 index 000000000..b7e109efc --- /dev/null +++ b/docs/api/ui.nav.qmd @@ -0,0 +1,5 @@ +# ui.nav { #shiny.ui.nav } + +`ui.nav(title, *args, value=None, icon=None)` + +Deprecated. Please use `nav_panel()` instead of `nav()`. \ No newline at end of file diff --git a/docs/api/ui.nav_control.qmd b/docs/api/ui.nav_control.qmd new file mode 100644 index 000000000..dc5183ee7 --- /dev/null +++ b/docs/api/ui.nav_control.qmd @@ -0,0 +1,32 @@ +# ui.nav_control { #shiny.ui.nav_control } + +`ui.nav_control(*args)` + +Place a control in the navigation container. + +## Parameters + +*args: [TagChild](`htmltools.TagChild`) = () + +: UI elements to display as the nav item. + +## See Also + +* [](:func:`~shiny.ui.nav_panel`) +* [](:func:`~shiny.ui.nav_menu`) +* [](:func:`~shiny.ui.nav_spacer`) +* [](:func:`~shiny.ui.navset_bar`) +* [](:func:`~shiny.ui.navset_tab`) +* [](:func:`~shiny.ui.navset_pill`) +* [](:func:`~shiny.ui.navset_underline`) +* [](:func:`~shiny.ui.navset_card_tab`) +* [](:func:`~shiny.ui.navset_card_pill`) +* [](:func:`~shiny.ui.navset_card_underline`) +* [](:func:`~shiny.ui.navset_pill_list`) +* [](:func:`~shiny.ui.navset_hidden`) + + + +## Example + +See [](:func:`~shiny.ui.nav_panel`) \ No newline at end of file diff --git a/docs/api/ui.nav_menu.qmd b/docs/api/ui.nav_menu.qmd new file mode 100644 index 000000000..0882ee632 --- /dev/null +++ b/docs/api/ui.nav_menu.qmd @@ -0,0 +1,61 @@ +# ui.nav_menu { #shiny.ui.nav_menu } + +`ui.nav_menu(title, *args, value=None, icon=None, align='left')` + +Create a menu of nav items. + +## Parameters + +title: [TagChild](`htmltools.TagChild`) + +: A title to display. Can be a character string or UI elements (i.e., tags). + +*args: [NavPanel](`shiny.ui._navs.NavPanel`) \| [str](`str`) = () + +: A collection of nav items (e.g., [](:func:`~shiny.ui.nav_panel`)) and/or strings. + Strings will be rendered as a section header unless the string is a set + of two or more hyphens (e.g., ``---``), in which case it will be rendered + as a divider. + +value: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: The value of the item. Use this value to determine whether the item is active + (when an ``id`` is provided to the nav container) or to programmatically + select the item (e.g., [](:func:`~shiny.ui.update_navs`)). You can also + provide the value to the ``selected`` argument of the navigation container + (e.g., [](:func:`~shiny.ui.navset_tab`)). + +icon: [TagChild](`htmltools.TagChild`) = None + +: An icon to appear inline with the button/link. + +align: [Literal](`typing.Literal`)\['left', 'right'\] = 'left' + +: Horizontal alignment of the dropdown menu relative to dropdown toggle. + +## Returns + +| Type | Description | +|-------------------------------------|-----------------------------------------------------| +| [NavMenu](`shiny.ui._navs.NavMenu`) | A UI element representing both the navigation menu. | + +## See Also + +* [](:func:`~shiny.ui.nav_panel`) +* [](:func:`~shiny.ui.nav_control`) +* [](:func:`~shiny.ui.nav_spacer`) +* [](:func:`~shiny.ui.navset_bar`) +* [](:func:`~shiny.ui.navset_tab`) +* [](:func:`~shiny.ui.navset_pill`) +* [](:func:`~shiny.ui.navset_underline`) +* [](:func:`~shiny.ui.navset_card_tab`) +* [](:func:`~shiny.ui.navset_card_pill`) +* [](:func:`~shiny.ui.navset_card_underline`) +* [](:func:`~shiny.ui.navset_pill_list`) +* [](:func:`~shiny.ui.navset_hidden`) + + + +## Example + +See [](:func:`~shiny.ui.nav_panel`) \ No newline at end of file diff --git a/docs/api/ui.nav_panel.qmd b/docs/api/ui.nav_panel.qmd new file mode 100644 index 000000000..fb9290e79 --- /dev/null +++ b/docs/api/ui.nav_panel.qmd @@ -0,0 +1,150 @@ +# ui.nav_panel { #shiny.ui.nav_panel } + +`ui.nav_panel(title, *args, value=None, icon=None)` + +Create a nav item pointing to some internal content. + +## Parameters + +title: [TagChild](`htmltools.TagChild`) + +: A title to display. Can be a character string or UI elements (i.e., tags). + +*args: [TagChild](`htmltools.TagChild`) = () + +: UI elements to display when the item is active. + +value: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: The value of the item. Use this value to determine whether the item is active + (when an ``id`` is provided to the nav container) or to programmatically + select the item (e.g., [](:func:`~shiny.ui.update_navs`)). You can also + provide the value to the ``selected`` argument of the navigation container + (e.g., [](:func:`~shiny.ui.navset_tab`)). + +icon: [TagChild](`htmltools.TagChild`) = None + +: An icon to appear inline with the button/link. + +## See Also + +* [](:func:`~shiny.ui.nav_menu`) +* [](:func:`~shiny.ui.nav_control`) +* [](:func:`~shiny.ui.nav_spacer`) +* [](:func:`~shiny.ui.navset_bar`) +* [](:func:`~shiny.ui.navset_tab`) +* [](:func:`~shiny.ui.navset_pill`) +* [](:func:`~shiny.ui.navset_underline`) +* [](:func:`~shiny.ui.navset_card_tab`) +* [](:func:`~shiny.ui.navset_card_pill`) +* [](:func:`~shiny.ui.navset_card_underline`) +* [](:func:`~shiny.ui.navset_pill_list`) +* [](:func:`~shiny.ui.navset_hidden`) + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +from typing import List + +from shiny import App, Inputs, Outputs, Session, reactive, ui +from shiny.types import NavSetArg + + +def nav_controls(prefix: str) -> List[NavSetArg]: + return [ + ui.nav_panel("a", prefix + ": tab a content"), + ui.nav_panel("b", prefix + ": tab b content"), + ui.nav_panel("c", prefix + ": tab c content"), + ui.nav_spacer(), + ui.nav_menu( + "Links", + ui.nav_control( + ui.a( + "Shiny", + href="https://shiny.posit.co/py/", + target="_blank", + ) + ), + "----", + "Plain text", + "----", + ui.nav_control( + ui.a( + "Posit", + href="https://posit.co", + target="_blank", + ) + ), + align="right", + ), + ] + + +app_ui = ui.page_navbar( + *nav_controls("page_navbar"), + title="page_navbar()", + id="navbar_id", + footer=ui.div( + {"style": "width:80%;margin: 0 auto"}, + ui.tags.style( + """ + h4 { + margin-top: 3em; + } + """ + ), + ui.h4("navset_tab()"), + ui.navset_tab(*nav_controls("navset_tab()")), + ui.h4("navset_pill()"), + ui.navset_pill(*nav_controls("navset_pill()")), + ui.h4("navset_underline()"), + ui.navset_underline(*nav_controls("navset_underline()")), + ui.h4("navset_card_tab()"), + ui.navset_card_tab(*nav_controls("navset_card_tab()")), + ui.h4("navset_card_pill()"), + ui.navset_card_pill(*nav_controls("navset_card_pill()")), + ui.h4("navset_card_underline()"), + ui.navset_card_underline(*nav_controls("navset_card_underline()")), + ui.h4("navset_pill_list()"), + ui.navset_pill_list(*nav_controls("navset_pill_list()")), + ) +) + + +def server(input: Inputs, output: Outputs, session: Session): + @reactive.Effect + def _(): + print("Current navbar page: ", input.navbar_id()) + + +app = App(app_ui, server) + +## file: __pycache__/app-basic.cpython-311.pyc +## type: binary +pw0NCgAAAAB74qZlKQEAAOMAAAAAAAAAAAAAAAAKAAAAAAAAAPPWAAAAlwBkAGQBbABtAVoBbQJaAm0DWgMBAAIAZQNqBAAAAAAAAAAAAgBlA2oFAAAAAAAAAABkAqYBAACrAQAAAAAAAAAAAgBlA2oGAAAAAAAAAAACAGUDagcAAAAAAAAAAGQDZASmAgAAqwIAAAAAAAAAAAIAZQNqBwAAAAAAAAAAZAVkBqYCAACrAgAAAAAAAAAApgIAAKsCAAAAAAAAAACmAgAAqwIAAAAAAAAAAFoIZAdlAmYCZAiEBFoJAgBlAWUIZQmmAgAAqwIAAAAAAAAAAFoKZAlTACkK6QAAAAApA9oDQXBw2gZJbnB1dHPaAnVpehFCYXNpYyBOYXYgRXhhbXBsZdoDT25lehJGaXJzdCB0YWIgY29udGVudC7aA1R3b3oTU2Vjb25kIHRhYiBjb250ZW50LtoFaW5wdXRjAQAAAAAAAAAAAAAAAQAAAAMAAADzBgAAAJcAZABTACkBTqkAKQFyCAAAAHMBAAAAIPpuL1VzZXJzL2dhcnJpY2svd29yay9wb3NpdC1kZXYvcHktc2hpbnkud29ya3RyZWVzL2V4cHJlc3MvcGFuZWwtdGl0bGUvc2hpbnkvYXBpLWV4YW1wbGVzL25hdl9wYW5lbC9hcHAtYmFzaWMucHnaBnNlcnZlcnIMAAAADAAAAHMHAAAAgADYBAiARPMAAAAATikL2gVzaGlueXIDAAAAcgQAAAByBQAAANoKcGFnZV9maXhlZNoLcGFuZWxfdGl0bGXaCm5hdnNldF90YWLaCW5hdl9wYW5lbNoGYXBwX3VpcgwAAADaA2FwcHIKAAAAcg0AAAByCwAAAPoIPG1vZHVsZT5yFQAAAAEAAABzrQAAAPADAQEB2AAh0AAh0AAh0AAh0AAh0AAh0AAh0AAh0AAh0AAh4AkWiBKMHdgEEoBChE7QEybRBCfUBCfYBBGAQoRN2AgUiAKMDJBV0Bww0Qgx1Agx2AgUiAKMDJBV0Bwx0Qgy1Agy8QUDBQb0AAMFBvEFBgoC9AAGCgKABvASAQEJkCbwAAEBCfAAAQEJ8AABAQnwAAEBCfAIAAcKgGOIJpAm0QYZ1AYZgAOAA4ADcg0AAAA= +## file: app-basic.py +from shiny import App, Inputs, ui + +app_ui = ui.page_fixed( + ui.panel_title("Basic Nav Example"), + ui.navset_tab( + ui.nav_panel("One", "First tab content."), + ui.nav_panel("Two", "Second tab content."), + ), +) + + +def server(input: Inputs): + pass + + +app = App(app_ui, server) + +``` + diff --git a/docs/api/ui.nav_spacer.qmd b/docs/api/ui.nav_spacer.qmd new file mode 100644 index 000000000..2e9d2b6f6 --- /dev/null +++ b/docs/api/ui.nav_spacer.qmd @@ -0,0 +1,28 @@ +# ui.nav_spacer { #shiny.ui.nav_spacer } + +`ui.nav_spacer()` + +Create space between nav items. + + + +## See Also + +* [](:func:`~shiny.ui.nav_panel`) +* [](:func:`~shiny.ui.nav_menu`) +* [](:func:`~shiny.ui.nav_control`) +* [](:func:`~shiny.ui.navset_bar`) +* [](:func:`~shiny.ui.navset_tab`) +* [](:func:`~shiny.ui.navset_pill`) +* [](:func:`~shiny.ui.navset_underline`) +* [](:func:`~shiny.ui.navset_card_tab`) +* [](:func:`~shiny.ui.navset_card_pill`) +* [](:func:`~shiny.ui.navset_card_underline`) +* [](:func:`~shiny.ui.navset_pill_list`) +* [](:func:`~shiny.ui.navset_hidden`) + + + +## Example + +See [](:func:`~shiny.ui.nav_panel`) \ No newline at end of file diff --git a/docs/api/ui.navset_bar.qmd b/docs/api/ui.navset_bar.qmd new file mode 100644 index 000000000..2ad4627e3 --- /dev/null +++ b/docs/api/ui.navset_bar.qmd @@ -0,0 +1,106 @@ +# ui.navset_bar { #shiny.ui.navset_bar } + +`ui.navset_bar(*args, title, id=None, selected=None, sidebar=None, fillable=True, gap=None, padding=None, position='static-top', header=None, footer=None, bg=None, inverse=False, underline=True, collapsible=True, fluid=True)` + +Render nav items as a navbar. + +## Parameters + +*args: [NavSetArg](`shiny.types.NavSetArg`) \| [MetadataNode](`htmltools.MetadataNode`) \| [Sequence](`typing.Sequence`)\[[MetadataNode](`htmltools.MetadataNode`)\] = () + +: A collection of nav items (e.g., [](:func:`shiny.ui.nav_panel`)). + +title: [TagChild](`htmltools.TagChild`) + +: Title to display in the navbar. + +id: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: If provided, will create an input value that holds the currently selected nav + item. + +selected: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: Choose a particular nav item to select by default value (should match it's + ``value``). + +sidebar: [Optional](`typing.Optional`)\[[Sidebar](`shiny.ui._sidebar.Sidebar`)\] = None + +: A [](:class:`~shiny.ui.Sidebar`) component to display on every [](:func:`~shiny.ui.nav_panel`) page. + +fillable: [bool](`bool`) \| [list](`list`)\[[str](`str`)\] = True + +: Whether or not to allow fill items to grow/shrink to fit the browser window. If + `True`, all `nav()` pages are fillable. A character vector, matching the value + of `nav()`s to be filled, may also be provided. Note that, if a `sidebar` is + provided, `fillable` makes the main content portion fillable. + +gap: [Optional](`typing.Optional`)\[[CssUnit](`shiny.ui.css.CssUnit`)\] = None + +: A CSS length unit defining the gap (i.e., spacing) between elements provided to + `*args`. + +padding: [Optional](`typing.Optional`)\[[CssUnit](`shiny.ui.css.CssUnit`) \| [list](`list`)\[[CssUnit](`shiny.ui.css.CssUnit`)\]\] = None + +: Padding to use for the body. This can be a numeric vector (which will be + interpreted as pixels) or a character vector with valid CSS lengths. The length + can be between one and four. If one, then that value will be used for all four + sides. If two, then the first value will be used for the top and bottom, while + the second value will be used for left and right. If three, then the first will + be used for top, the second will be left and right, and the third will be + bottom. If four, then the values will be interpreted as top, right, bottom, and + left respectively. + +position: [Literal](`typing.Literal`)\['static-top', 'fixed-top', 'fixed-bottom', 'sticky-top'\] = 'static-top' + +: Determines whether the navbar should be displayed at the top of the page with + normal scrolling behavior ("static-top"), pinned at the top ("fixed-top"), or + pinned at the bottom ("fixed-bottom"). Note that using "fixed-top" or + "fixed-bottom" will cause the navbar to overlay your body content, unless you + add padding (e.g., ``tags.style("body {padding-top: 70px;}")``). + +header: [TagChild](`htmltools.TagChild`) = None + +: UI to display above the selected content. + +footer: [TagChild](`htmltools.TagChild`) = None + +: UI to display below the selected content. + +bg: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: Background color of the navbar (a CSS color). + +inverse: [bool](`bool`) = False + +: Either ``True`` for a light text color or ``False`` for a dark text color. + +collapsible: [bool](`bool`) = True + +: ``True`` to automatically collapse the navigation elements into an expandable menu on mobile devices or narrow window widths. + +fluid: [bool](`bool`) = True + +: ``True`` to use fluid layout; ``False`` to use fixed layout. + +## See Also + +* [](:func:`~shiny.ui.page_navbar`) +* [](:func:`~shiny.ui.nav_panel`) +* [](:func:`~shiny.ui.nav_menu`) +* [](:func:`~shiny.ui.nav_control`) +* [](:func:`~shiny.ui.nav_spacer`) +* [](:func:`~shiny.ui.navset_tab`) +* [](:func:`~shiny.ui.navset_pill`) +* [](:func:`~shiny.ui.navset_underline`) +* [](:func:`~shiny.ui.navset_card_tab`) +* [](:func:`~shiny.ui.navset_card_pill`) +* [](:func:`~shiny.ui.navset_card_underline`) +* [](:func:`~shiny.ui.navset_pill_list`) +* [](:func:`~shiny.ui.navset_hidden`) + + + +## Example + +See [](:func:`~shiny.ui.nav_panel`). \ No newline at end of file diff --git a/docs/api/ui.navset_card_pill.qmd b/docs/api/ui.navset_card_pill.qmd new file mode 100644 index 000000000..d80f87a39 --- /dev/null +++ b/docs/api/ui.navset_card_pill.qmd @@ -0,0 +1,58 @@ +# ui.navset_card_pill { #shiny.ui.navset_card_pill } + +`ui.navset_card_pill(*args, id=None, selected=None, title=None, sidebar=None, header=None, footer=None, placement='above')` + +Render nav items as a pillset inside a card container. + +## Parameters + +*args: [NavSetArg](`shiny.types.NavSetArg`) = () + +: A collection of nav items (e.g., [](:func:`shiny.ui.nav_panel`)). + +id: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: If provided, will create an input value that holds the currently selected nav + item. + +selected: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: Choose a particular nav item to select by default value (should match it's + ``value``). + +sidebar: [Optional](`typing.Optional`)\[[Sidebar](`shiny.ui._sidebar.Sidebar`)\] = None + +: A [](:class:`shiny.ui.Sidebar`) component to display on every [](:func:`~shiny.ui.nav_panel`) page. + +header: [TagChild](`htmltools.TagChild`) = None + +: UI to display above the selected content. + +footer: [TagChild](`htmltools.TagChild`) = None + +: UI to display below the selected content. + +placement: [Literal](`typing.Literal`)\['above', 'below'\] = 'above' + +: Placement of the nav items relative to the content. + +## See Also + +* [](:func:`~shiny.ui.nav_panel`) +* [](:func:`~shiny.ui.nav_menu`) +* [](:func:`~shiny.ui.nav_control`) +* [](:func:`~shiny.ui.nav_spacer`) +* [](:func:`~shiny.ui.navset_bar`) +* [](:func:`~shiny.ui.navset_tab`) +* [](:func:`~shiny.ui.navset_pill`) +* [](:func:`~shiny.ui.navset_underline`) +* [](:func:`~shiny.ui.navset_card_tab`) +* [](:func:`~shiny.ui.navset_card_underline`) +* [](:func:`~shiny.ui.navset_pill_list`) +* [](:func:`~shiny.ui.navset_hidden`) + + + +## Example + +See [](:func:`~shiny.ui.nav_panel`) \ No newline at end of file diff --git a/docs/api/ui.navset_card_tab.qmd b/docs/api/ui.navset_card_tab.qmd new file mode 100644 index 000000000..006d7fdd0 --- /dev/null +++ b/docs/api/ui.navset_card_tab.qmd @@ -0,0 +1,54 @@ +# ui.navset_card_tab { #shiny.ui.navset_card_tab } + +`ui.navset_card_tab(*args, id=None, selected=None, title=None, sidebar=None, header=None, footer=None)` + +Render nav items as a tabset inside a card container. + +## Parameters + +*args: [NavSetArg](`shiny.types.NavSetArg`) = () + +: A collection of nav items (e.g., [](:func:`shiny.ui.nav_panel`)). + +id: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: If provided, will create an input value that holds the currently selected nav + item. + +selected: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: Choose a particular nav item to select by default value (should match it's + ``value``). + +sidebar: [Optional](`typing.Optional`)\[[Sidebar](`shiny.ui._sidebar.Sidebar`)\] = None + +: A `Sidebar` component to display on every `nav()` page. + +header: [TagChild](`htmltools.TagChild`) = None + +: UI to display above the selected content. + +footer: [TagChild](`htmltools.TagChild`) = None + +: UI to display below the selected content. + +## See Also + +* [](:func:`~shiny.ui.nav_panel`) +* [](:func:`~shiny.ui.nav_menu`) +* [](:func:`~shiny.ui.nav_control`) +* [](:func:`~shiny.ui.nav_spacer`) +* [](:func:`~shiny.ui.navset_bar`) +* [](:func:`~shiny.ui.navset_tab`) +* [](:func:`~shiny.ui.navset_pill`) +* [](:func:`~shiny.ui.navset_underline`) +* [](:func:`~shiny.ui.navset_card_pill`) +* [](:func:`~shiny.ui.navset_card_underline`) +* [](:func:`~shiny.ui.navset_pill_list`) +* [](:func:`~shiny.ui.navset_hidden`) + + + +## Example + +See [](:func:`~shiny.ui.nav_panel`) \ No newline at end of file diff --git a/docs/api/ui.navset_card_underline.qmd b/docs/api/ui.navset_card_underline.qmd new file mode 100644 index 000000000..f7eed9950 --- /dev/null +++ b/docs/api/ui.navset_card_underline.qmd @@ -0,0 +1,58 @@ +# ui.navset_card_underline { #shiny.ui.navset_card_underline } + +`ui.navset_card_underline(*args, id=None, selected=None, title=None, sidebar=None, header=None, footer=None, placement='above')` + +Render nav items inside a card container. Active/focused navigation links are styled with an underline. + +## Parameters + +*args: [NavSetArg](`shiny.types.NavSetArg`) = () + +: A collection of nav items (e.g., [](:func:`shiny.ui.nav_panel`)). + +id: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: If provided, will create an input value that holds the currently selected nav + item. + +selected: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: Choose a particular nav item to select by default value (should match it's + ``value``). + +sidebar: [Optional](`typing.Optional`)\[[Sidebar](`shiny.ui._sidebar.Sidebar`)\] = None + +: A [](:class:`shiny.ui.Sidebar`) component to display on every [](:func:`~shiny.ui.nav_panel`) page. + +header: [TagChild](`htmltools.TagChild`) = None + +: UI to display above the selected content. + +footer: [TagChild](`htmltools.TagChild`) = None + +: UI to display below the selected content. + +placement: [Literal](`typing.Literal`)\['above', 'below'\] = 'above' + +: Placement of the nav items relative to the content. + +## See Also + +* [](:func:`~shiny.ui.nav_panel`) +* [](:func:`~shiny.ui.nav_menu`) +* [](:func:`~shiny.ui.nav_control`) +* [](:func:`~shiny.ui.nav_spacer`) +* [](:func:`~shiny.ui.navset_bar`) +* [](:func:`~shiny.ui.navset_tab`) +* [](:func:`~shiny.ui.navset_pill`) +* [](:func:`~shiny.ui.navset_underline`) +* [](:func:`~shiny.ui.navset_card_tab`) +* [](:func:`~shiny.ui.navset_card_pill`) +* [](:func:`~shiny.ui.navset_pill_list`) +* [](:func:`~shiny.ui.navset_hidden`) + + + +## Example + +See [](:func:`~shiny.ui.nav_panel`) \ No newline at end of file diff --git a/docs/api/ui.navset_hidden.qmd b/docs/api/ui.navset_hidden.qmd new file mode 100644 index 000000000..5da0c2c78 --- /dev/null +++ b/docs/api/ui.navset_hidden.qmd @@ -0,0 +1,86 @@ +# ui.navset_hidden { #shiny.ui.navset_hidden } + +`ui.navset_hidden(*args, id=None, selected=None, header=None, footer=None)` + +Render nav contents without the nav items. + +## Parameters + +*args: [NavSetArg](`shiny.types.NavSetArg`) = () + +: A collection of nav items (e.g., [](:func:`shiny.ui.nav_panel`)). + +id: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: If provided, will create an input value that holds the currently selected nav + item. + +selected: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: Choose a particular nav item to select by default value (should match it's + ``value``). + +header: [TagChild](`htmltools.TagChild`) = None + +: UI to display above the selected content. + +footer: [TagChild](`htmltools.TagChild`) = None + +: UI to display below the selected content. + +## See Also + +* [](:func:`~shiny.ui.nav_panel`) +* [](:func:`~shiny.ui.nav_menu`) +* [](:func:`~shiny.ui.nav_control`) +* [](:func:`~shiny.ui.nav_spacer`) +* [](:func:`~shiny.ui.navset_bar`) +* [](:func:`~shiny.ui.navset_tab`) +* [](:func:`~shiny.ui.navset_pill`) +* [](:func:`~shiny.ui.navset_underline`) +* [](:func:`~shiny.ui.navset_card_tab`) +* [](:func:`~shiny.ui.navset_card_pill`) +* [](:func:`~shiny.ui.navset_card_underline`) +* [](:func:`~shiny.ui.navset_pill_list`) + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +from shiny import App, Inputs, Outputs, Session, reactive, ui + +app_ui = ui.page_fluid( + ui.layout_sidebar( + ui.panel_sidebar( + ui.input_radio_buttons( + "controller", "Controller", ["1", "2", "3"], selected="1" + ) + ), + ui.panel_main( + ui.navset_hidden( + ui.nav_panel(None, "Panel 1 content", value="panel1"), + ui.nav_panel(None, "Panel 2 content", value="panel2"), + ui.nav_panel(None, "Panel 3 content", value="panel3"), + id="hidden_tabs", + ), + ), + ) +) + + +def server(input: Inputs, output: Outputs, session: Session): + @reactive.Effect + @reactive.event(input.controller) + def _(): + ui.update_navs("hidden_tabs", selected="panel" + str(input.controller())) + + +app = App(app_ui, server) + +``` + diff --git a/docs/api/ui.navset_pill.qmd b/docs/api/ui.navset_pill.qmd new file mode 100644 index 000000000..faf9fe2c4 --- /dev/null +++ b/docs/api/ui.navset_pill.qmd @@ -0,0 +1,50 @@ +# ui.navset_pill { #shiny.ui.navset_pill } + +`ui.navset_pill(*args, id=None, selected=None, header=None, footer=None)` + +Render nav items as a pillset. + +## Parameters + +*args: [NavSetArg](`shiny.types.NavSetArg`) = () + +: A collection of nav items (e.g., [](:func:`shiny.ui.nav_panel`)). + +id: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: If provided, will create an input value that holds the currently selected nav + item. + +selected: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: Choose a particular nav item to select by default value (should match it's + ``value``). + +header: [TagChild](`htmltools.TagChild`) = None + +: UI to display above the selected content. + +footer: [TagChild](`htmltools.TagChild`) = None + +: UI to display below the selected content. + +## See Also + +* [](:func:`~shiny.ui.nav_panel`) +* [](:func:`~shiny.ui.nav_menu`) +* [](:func:`~shiny.ui.nav_control`) +* [](:func:`~shiny.ui.nav_spacer`) +* [](:func:`~shiny.ui.navset_bar`) +* [](:func:`~shiny.ui.navset_tab`) +* [](:func:`~shiny.ui.navset_underline`) +* [](:func:`~shiny.ui.navset_card_tab`) +* [](:func:`~shiny.ui.navset_card_pill`) +* [](:func:`~shiny.ui.navset_card_underline`) +* [](:func:`~shiny.ui.navset_pill_list`) +* [](:func:`~shiny.ui.navset_hidden`) + + + +## Example + +See [](:func:`~shiny.ui.nav_panel`) \ No newline at end of file diff --git a/docs/api/ui.navset_pill_list.qmd b/docs/api/ui.navset_pill_list.qmd new file mode 100644 index 000000000..c911cbc6d --- /dev/null +++ b/docs/api/ui.navset_pill_list.qmd @@ -0,0 +1,58 @@ +# ui.navset_pill_list { #shiny.ui.navset_pill_list } + +`ui.navset_pill_list(*args, id=None, selected=None, header=None, footer=None, well=True, widths=(4, 8))` + +Render nav items as a vertical pillset. + +## Parameters + +*args: [NavSetArg](`shiny.types.NavSetArg`) \| [MetadataNode](`htmltools.MetadataNode`) = () + +: A collection of nav items (e.g., [](:func:`shiny.ui.nav_panel`)). + +id: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: If provided, will create an input value that holds the currently selected nav + item. + +selected: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: Choose a particular nav item to select by default value (should match its + ``value``). + +header: [TagChild](`htmltools.TagChild`) = None + +: UI to display above the selected content. + +footer: [TagChild](`htmltools.TagChild`) = None + +: UI to display below the selected content. + +well: [bool](`bool`) = True + +: ``True`` to place a well (gray rounded rectangle) around the navigation list. + +widths: [tuple](`tuple`)\[[int](`int`), [int](`int`)\] = (4, 8) + +: Column widths of the navigation list and tabset content areas respectively. + +## See Also + +* [](:func:`~shiny.ui.nav_panel`) +* [](:func:`~shiny.ui.nav_menu`) +* [](:func:`~shiny.ui.nav_control`) +* [](:func:`~shiny.ui.nav_spacer`) +* [](:func:`~shiny.ui.navset_bar`) +* [](:func:`~shiny.ui.navset_tab`) +* [](:func:`~shiny.ui.navset_pill`) +* [](:func:`~shiny.ui.navset_underline`) +* [](:func:`~shiny.ui.navset_card_tab`) +* [](:func:`~shiny.ui.navset_card_pill`) +* [](:func:`~shiny.ui.navset_card_underline`) +* [](:func:`~shiny.ui.navset_hidden`) + + + +## Example + +See [](:func:`~shiny.ui.nav_panel`) \ No newline at end of file diff --git a/docs/api/ui.navset_tab.qmd b/docs/api/ui.navset_tab.qmd new file mode 100644 index 000000000..8dfdadb5b --- /dev/null +++ b/docs/api/ui.navset_tab.qmd @@ -0,0 +1,53 @@ +# ui.navset_tab { #shiny.ui.navset_tab } + +`ui.navset_tab(*args, id=None, selected=None, header=None, footer=None)` + +Render nav items as a tabset. + +## Parameters + +*args: [NavSetArg](`shiny.types.NavSetArg`) = () + +: A collection of nav items (e.g., [](:func:`shiny.ui.nav_panel`)). + +id: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: If provided, will create an input value that holds the currently selected nav + item. + +selected: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: Choose a particular nav item to select by default value (should match it's + ``value``). + +header: [TagChild](`htmltools.TagChild`) = None + +: UI to display above the selected content. + +footer: [TagChild](`htmltools.TagChild`) = None + +: UI to display below the selected content. + + + + +## See Also + +* [](:func:`~shiny.ui.nav_panel`) +* [](:func:`~shiny.ui.nav_menu`) +* [](:func:`~shiny.ui.nav_control`) +* [](:func:`~shiny.ui.nav_spacer`) +* [](:func:`~shiny.ui.navset_bar`) +* [](:func:`~shiny.ui.navset_pill`) +* [](:func:`~shiny.ui.navset_underline`) +* [](:func:`~shiny.ui.navset_card_tab`) +* [](:func:`~shiny.ui.navset_card_pill`) +* [](:func:`~shiny.ui.navset_card_underline`) +* [](:func:`~shiny.ui.navset_pill_list`) +* [](:func:`~shiny.ui.navset_hidden`) + + + +## Example + +See [](:func:`~shiny.ui.nav_panel`) \ No newline at end of file diff --git a/docs/api/ui.navset_underline.qmd b/docs/api/ui.navset_underline.qmd new file mode 100644 index 000000000..66e1069bc --- /dev/null +++ b/docs/api/ui.navset_underline.qmd @@ -0,0 +1,50 @@ +# ui.navset_underline { #shiny.ui.navset_underline } + +`ui.navset_underline(*args, id=None, selected=None, header=None, footer=None)` + +Render nav items whose active/focused navigation links are styled with an underline. + +## Parameters + +*args: [NavSetArg](`shiny.types.NavSetArg`) = () + +: A collection of nav items (e.g., [](:func:`shiny.ui.nav_panel`)). + +id: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: If provided, will create an input value that holds the currently selected nav + item. + +selected: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: Choose a particular nav item to select by default value (should match it's + ``value``). + +header: [TagChild](`htmltools.TagChild`) = None + +: UI to display above the selected content. + +footer: [TagChild](`htmltools.TagChild`) = None + +: UI to display below the selected content. + +## See Also + +* [](:func:`~shiny.ui.nav_panel`) +* [](:func:`~shiny.ui.nav_menu`) +* [](:func:`~shiny.ui.nav_control`) +* [](:func:`~shiny.ui.nav_spacer`) +* [](:func:`~shiny.ui.navset_bar`) +* [](:func:`~shiny.ui.navset_tab`) +* [](:func:`~shiny.ui.navset_pill`) +* [](:func:`~shiny.ui.navset_card_tab`) +* [](:func:`~shiny.ui.navset_card_pill`) +* [](:func:`~shiny.ui.navset_card_underline`) +* [](:func:`~shiny.ui.navset_pill_list`) +* [](:func:`~shiny.ui.navset_hidden`) + + + +## Example + +See [](:func:`~shiny.ui.nav_panel`) \ No newline at end of file diff --git a/docs/api/ui.notification_remove.qmd b/docs/api/ui.notification_remove.qmd new file mode 100644 index 000000000..b40e6a2e2 --- /dev/null +++ b/docs/api/ui.notification_remove.qmd @@ -0,0 +1,37 @@ +# ui.notification_remove { #shiny.ui.notification_remove } + +`ui.notification_remove(id, *, session=None)` + +Remove a notification. + +[](:func:`~shiny.ui.notification_remove`) provides a way to remove a notification programatically. +Notifications can also be removed manually by the user, or automatically after a +specififed amont of time passes. + +## Parameters + +id: [str](`str`) + +: The ``id`` of the notification to remove. + +session: [Optional](`typing.Optional`)\[[Session](`shiny.session.Session`)\] = None + +: The [](:class:`~shiny.Session`) in which the notification appears. If not provided, the session is inferred via + [](:func:`~shiny.session.get_current_session`). + +## Returns + +| Type | Description | +|--------------|----------------------------| +| [str](`str`) | The notification's ``id``. | + +## See Also + +[](:func:`~shiny.ui.notification_show`) +[](:func:`~shiny.ui.modal`) + + + +## Example + +See [](:func:`notification_show`). \ No newline at end of file diff --git a/docs/api/ui.notification_show.qmd b/docs/api/ui.notification_show.qmd new file mode 100644 index 000000000..96526856f --- /dev/null +++ b/docs/api/ui.notification_show.qmd @@ -0,0 +1,104 @@ +# ui.notification_show { #shiny.ui.notification_show } + +`ui.notification_show(ui, *, action=None, duration=5, close_button=True, id=None, type='default', session=None)` + +Show a notification to the user. + +A notification is a message that appears near the bottom corner of the app. +Notifications normally disappear after a short period of time, and should multiple +notifications appear together, they will stack on top of one another. + +## Parameters + +ui: [TagChild](`htmltools.TagChild`) + +: Contents of the notification message. + +action: [Optional](`typing.Optional`)\[[TagChild](`htmltools.TagChild`)\] = None + +: Message content that represents an action. For example, this could be a link + that the user can click on. This is separate from ui so customized layouts can + handle the main notification content separately from the action content. + +duration: [Optional](`typing.Optional`)\[[int](`int`) \| [float](`float`)\] = 5 + +: Number of seconds to display the message before it disappears. Use ``None`` to + prevent the message from disappearing automatically. The user will need to click + the corner of the notification to close it. + +close_button: [bool](`bool`) = True + +: If ``True``, display a button which will make the notification disappear when + clicked. If ``False`` do not display. + +id: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: An optional unique identifier for the notification. If supplied, any existing + notification with the same ``id`` will be replaced with this one (otherwise, a + new notification is created). + +type: [Literal](`typing.Literal`)\['default', 'message', 'warning', 'error'\] = 'default' + +: A string which controls the color of the notification. This should be one of + "default" (gray), "message" (blue), "warning" (yellow), or "error" (red). + +session: [Optional](`typing.Optional`)\[[Session](`shiny.session.Session`)\] = None + +: The [](:class:`~shiny.Session`) in which the notification should appear. If not + provided, the session is inferred via [](:func:`~shiny.session.get_current_session`). + +## Returns + +| Type | Description | +|--------------|----------------------------| +| [str](`str`) | The notification's ``id``. | + +## See Also + +[](:func:`~shiny.ui.notification_remove`) +[](:func:`~shiny.ui.modal`) + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +from shiny import App, Inputs, Outputs, Session, reactive, ui + +app_ui = ui.page_fluid( + ui.input_action_button("show", "Show"), + " ", + ui.input_action_button("remove", "Remove"), +) + + +def server(input: Inputs, output: Outputs, session: Session): + ids: list[str] = [] + n: int = 0 + + @reactive.Effect + @reactive.event(input.show) + def _(): + nonlocal ids + nonlocal n + # Save the ID for removal later + id = ui.notification_show("Message " + str(n), duration=None) + ids.append(id) + n += 1 + + @reactive.Effect + @reactive.event(input.remove) + def _(): + nonlocal ids + if ids: + ui.notification_remove(ids.pop()) + + +app = App(app_ui, server, debug=True) + +``` + diff --git a/docs/api/ui.output_data_frame.qmd b/docs/api/ui.output_data_frame.qmd new file mode 100644 index 000000000..3a8244455 --- /dev/null +++ b/docs/api/ui.output_data_frame.qmd @@ -0,0 +1,22 @@ +# ui.output_data_frame { #shiny.ui.output_data_frame } + +`ui.output_data_frame(id)` + +Create an output container for an interactive table or grid. Features fast +virtualized scrolling, sorting, filtering, and row selection (single or multiple). + +## Parameters + +id: [str](`str`) + +: An output id. + +## Returns + +| Type | Description | +|------------------------|---------------| +| [Tag](`htmltools.Tag`) | A UI element. | + +## See Also + +[](:func:`~shiny.render.data_frame`) \ No newline at end of file diff --git a/docs/api/ui.output_image.qmd b/docs/api/ui.output_image.qmd new file mode 100644 index 000000000..1be992fc1 --- /dev/null +++ b/docs/api/ui.output_image.qmd @@ -0,0 +1,109 @@ +# ui.output_image { #shiny.ui.output_image } + +`ui.output_image(id, width='100%', height='400px', *, inline=False, click=False, dblclick=False, hover=False, brush=False, fill=False)` + +Create a output container for a static image. + +## Parameters + +id: [str](`str`) + +: An output id. + +width: [str](`str`) \| [float](`float`) \| [int](`int`) = '100%' + +: The CSS width, e.g. '400px', or '100%'. + +height: [str](`str`) \| [float](`float`) \| [int](`int`) = '400px' + +: The CSS height, e.g. '100%' or '600px'. + +inline: [bool](`bool`) = False + +: If ``True``, the result is displayed inline. + +click: [bool](`bool`) \| [ClickOpts](`shiny.ui._plot_output_opts.ClickOpts`) = False + +: This can be a boolean or an object created by [](:func:`~shiny.ui.click_opts`). The + default is `False`, but if you use `True` (or equivalently, `click_opts()`), the + plot will send coordinates to the server whenever it is clicked, and the value + will be accessible via `input.xx_click()`, where `xx` is replaced with the ID of + this plot. The input value will be a dictionary with `x` and `y` elements + indicating the mouse position. + +dblclick: [bool](`bool`) \| [DblClickOpts](`shiny.ui._plot_output_opts.DblClickOpts`) = False + +: This is just like the `click` parameter, but for double-click events. + +hover: [bool](`bool`) \| [HoverOpts](`shiny.ui._plot_output_opts.HoverOpts`) = False + +: Similar to the `click` argument, this can be a boolean or an object created by + [](:func:`~shiny.ui.hover_opts`). The default is `False`, but if you use `True` (or + equivalently, `hover_opts()`), the plot will send coordinates to the server + whenever it is clicked, and the value will be accessible via `input.xx_hover()`, + where `xx` is replaced with the ID of this plot. The input value will be a + dictionary with `x` and `y` elements indicating the mouse position. To control + the hover time or hover delay type, use [](:func:`~shiny.ui.hover_opts`). + +brush: [bool](`bool`) \| [BrushOpts](`shiny.ui._plot_output_opts.BrushOpts`) = False + +: Similar to the `click` argument, this can be a boolean or an object created by + [](:func:`~shiny.ui.brush_opts`). The default is `False`, but if you use `True` (or + equivalently, `brush_opts()`), the plot will allow the user to "brush" in the + plotting area, and will send information about the brushed area to the server, + and the value will be accessible via `input.plot_brush()`. Brushing means that + the user will be able to draw a rectangle in the plotting area and drag it + around. The value will be a named list with `xmin`, `xmax`, `ymin`, and `ymax` + elements indicating the brush area. To control the brush behavior, use + [](:func:`~shiny.ui.brush_opts`). Multiple `output_image`/`output_plot` calls may + share the same `id` value; brushing one image or plot will cause any other + brushes with the same `id` to disappear. + +fill: [bool](`bool`) = False + +: Whether or not to allow the image output to grow/shrink to fit a fillable + container with an opinionated height (e.g., [](:func:`~shiny.ui.page_fillable`)). + +## Returns + +| Type | Description | +|------------------------|---------------| +| [Tag](`htmltools.Tag`) | A UI element | + +## See Also + +* [](:func:`~shiny.render.image`) +* [](:func:`~shiny.ui.output_plot`) + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +from shiny import App, Inputs, Outputs, Session, render, ui +from shiny.types import ImgData + +app_ui = ui.page_fluid(ui.output_image("image")) + + +def server(input: Inputs, output: Outputs, session: Session): + @render.image + def image(): + from pathlib import Path + + dir = Path(__file__).resolve().parent + img: ImgData = {"src": str(dir / "posit-logo.png"), "width": "100px"} + return img + + +app = App(app_ui, server) + +## file: posit-logo.png +## type: binary +iVBORw0KGgoAAAANSUhEUgAAAMgAAAA0CAYAAADPCHf8AAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAhGVYSWZNTQAqAAAACAAFARIAAwAAAAEAAQAAARoABQAAAAEAAABKARsABQAAAAEAAABSASgAAwAAAAEAAgAAh2kABAAAAAEAAABaAAAAAAAAASwAAAABAAABLAAAAAEAA6ABAAMAAAABAAEAAKACAAQAAAABAAAAyKADAAQAAAABAAAANAAAAACDRp3hAAAACXBIWXMAAC4jAAAuIwF4pT92AAACzGlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNi4wLjAiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyIKICAgICAgICAgICAgeG1sbnM6ZXhpZj0iaHR0cDovL25zLmFkb2JlLmNvbS9leGlmLzEuMC8iPgogICAgICAgICA8dGlmZjpZUmVzb2x1dGlvbj4zMDA8L3RpZmY6WVJlc29sdXRpb24+CiAgICAgICAgIDx0aWZmOlJlc29sdXRpb25Vbml0PjI8L3RpZmY6UmVzb2x1dGlvblVuaXQ+CiAgICAgICAgIDx0aWZmOlhSZXNvbHV0aW9uPjMwMDwvdGlmZjpYUmVzb2x1dGlvbj4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgICAgPGV4aWY6UGl4ZWxYRGltZW5zaW9uPjQwMDwvZXhpZjpQaXhlbFhEaW1lbnNpb24+CiAgICAgICAgIDxleGlmOkNvbG9yU3BhY2U+MTwvZXhpZjpDb2xvclNwYWNlPgogICAgICAgICA8ZXhpZjpQaXhlbFlEaW1lbnNpb24+MTA0PC9leGlmOlBpeGVsWURpbWVuc2lvbj4KICAgICAgPC9yZGY6RGVzY3JpcHRpb24+CiAgIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+CrD9EM4AACEOSURBVHja7V0JeBRVtu6A4q5PXJ8L8BQVBZV0dwgBAr13QggqmkFBlCVd3SRAluosIEi7PMZRERWUCUl3J2ERgoPOfOpzR8Vlxm0cEWXccUd20tmTvu+cqrrdtytVvWRh4kzqy/06vVTdqrrnv+f855x7SqPp3/q3Y7clsf9nZmaeAK8Dmc8G9Mmz9ng8A3Jycgb+Fu84gRtN4NxJ5M3v3/ooOBAUJpPFbTZbtkP7h8lkfstisdxrNpvPorLYp846x1M3KBIodQN/K8DYbjAcF/GZJ/J9/9a3wJGWlnaS2Wx90WazEwAJNLPQrFYbvn5itVovUNA0/9ots7Tmpoyy2jprkVcfAZw6BArpc7My8WgGEAYYhNMdX+9IvrmJ0z2zd+7Vl1Dw9MtkH5qEJevEZDLdgeAwGIzN0NonTTJ2YDMYDM0iSCzr2N+rAG1AlNbz424vrZ015c4nibXYG7S5fc/a3P5sVqsIQOkDaq8uRzOQMDdub27qec2cPr/BqdtJ8lNIo1PXeMg1dpgAENIPkL6oQYxGy0uoORAc0AhtRqOpA8BDwOT6VOIlfUeL2MtqZ9hLqom1qOLg5CWbyJSlW4id979vdfucWeWPnxmeBeoGHmv7MMQvPGHydnS+/oqAQ3dfA6f7hRSNJQFOFzw4L7mhkdPtO+Qa3Q+QPgwQAIAKQIwSQMy7VAAi/D9hwoQzwQwbDZzlannDz0ETnd3j4AKNcXP28j8BQNbdZeOrJtp434sZpbVE+Iz3/ZDh9nvsRVXDjyVPEYAh4xdN87XpjZy2FgDRjsBocuqOQFt7MFd7DWiPd5pBgxzkdEP6AdJ3TSwAwF3UxJJMq6D4amyyWu0IkEolE4u+Bw00w2KxosZpAs7SQhu8b8TPASSuGCZaFwBSUjMdwWArWreUog9MrVTQKpU23ts81fMUsbt9DTa3tyqj0JvG7mvweI7rSZ4i8AuGaH8z23BiPafLAWC8TPJSCClMJQ2c9hsAxmKqLXCD798FgDT0A6TPk/TBINAfiSQdCbopRNJBu3xus9kuln4/QAVgMxEIkyYZgqwGwvf4OWiS+b0GEGtx5TK5V8u0sOJSK191l93t/w5/A2Se2Er8z2aUVk/NXPjoCRFA6Yb5JZhRzEUFgF+AVigIcNpdpCCVkAVjgGNo3w44tXMOLEw9PbQfaJkKne74hn6A/Ba2AZKQnwXtfmgfgLn1BQLGaDSvoR4sJTNerkEkEy3ItLbeB0ihCBAUdrkZZc6vOctWWs2BJvkgCzgKNrvb+yGYZHlgfg3uCk9R4hctudorART3g0bYi2YUCD2S720Bl9aOJJ0FhqBtxJlp4DEGSBKNG0nX2jveE+VZOKJvqf+kXu5f8Bz1UL+hsdbBxAYCfQaYWSeGv1aWnc4aRDDLCNPaWYAYDD3o7lcCSPh8PQPY9/i/zV2Vbee9z2SU1gg8BcyxH+2l/rvNxesuZ/dT4ykUGBH8wpk8EYCwIeDQBgVgcLpDAJLVDfP0yZ0AxQxKDwEkCQdArVFBYP5X3cSB6VFHRhIDxJh2fjznGM+WSOA4wX6T8B7B7wfRa5L6GiQJNXuMAcw4DJIAcms0gJjN1nzpnAYpjaXCfUxiv2PArwldU1SAhMU6SYyLsOTel2or8VVY3b5G5ClA9hsBOP4MdyRPofEUnPHZwB4BfgFm0/SAQ7c9zC90XzVxunIq6CIv8QwgKoP1r9AgMJDnw0ClmUxWm8kEfyaTNj09/Ry5gGm6lzbRSUBhxj154kTrZTBLToD+rRZxGwv9Dx05cuQghRk34XugtB+aROglMhqtk2i/8JqCJpFc4HoKoGobmFjTGBOrE0DgnGYnyouiaazYGkRx50gzKqPcP8zmrvQAQPbgcTLL1hM773ve6vbeYJjtP1G+/765yReAdigMcLrPyCKJX3Dat5qc+ttInuHUCF7iiS5k3QQItYmvgTHfAK/VQBRrws3sh7YN2hSckeA3RSAfr4BAHgC7uQN+IxBMo9HUBm0ffPc62NT3IGAUb3SCHh/RrWkZAkB0QV9Por0OgtDI9g2tHfquh+92Suc8k6ZsJNo/89skOIYR2oNwzB1w/L0Gg6kVeEIQPkNPE14z9Gs8BN+/B+/XwL3Jys7OPlmtXyovsE8q3Kcn2HsN+0r32roV73UYmLZ5eN3SOKxHDxf0+xo0IvEOBiCGoHQ/3sLfib9nx9JaDf1sgtc/sJrKaLSlWq12OL7Fa7fb74axWwggm4rfWSy2uXhdYS9WceVyESDbj4tfDYe1CnIRIO/zQLO8lw0cZdqyreS6Et/H0/mqggvz15xFZmtGdHDDV9VzYw6R4vHopkV+sbXZqbfmaGT8Ik4NgACqyxk5qCterDDxs0622zPQi0JEO1Zs+F783PwSCgJ6XvAzaYAkT4roTcHPUHDg5uIgNYPAboHvRiQopNSMQy11ERxjNRxrHz0XFADWaxP25IieIHre8P+3cC7LMjMzT4+zfxqdxkg3bJY3xePZ6ASg2C9+TvsVzw9Bas6n9j/LA5hI+i0ZGcr3OjNzMppIS8LawrxB/MwS8TuZ5mBbkL0P8uOL42f+dvjw4SHnEmp+nPjgN5+hVhTBajmUnm4cj541eO/W2N3Vv8u+E7lEZQnVEIIWIXG6b2U8ZZfHM0jPezM1pRtrh/PVzYPLnyCjiv17nl54x4HAgizS4RjybYfjnBWBvHGjo/GLmO5gZuAbnfq3W5z6owfmpFwcL0DorDZpktmKMzEMfCt6QyT1LTUDzpxUONsY70nEwGCT7OI2eKWCCjO7aY6S21KNgIszl+U2ELZfEWww4xLmXIJqfWOgjZ4fCq7kNv0nHMOs5hnqHMQzL0ZBwsZcSwfjKYp2zR1hd635b3A+17L9Ml6oaeLxO93rZhEIliLGtPsjvA+lpTDnowoSej6RY2gUxlYEtPUjao7Sc5o4ceJlNpvtacGastnuxWAm9Lsb2gvwPg9MpNrZ2ZhqUlj5Hrpv04oeOonlD/EQRHn8Ard2x0U3fuGa/tXThXeS+WU+oinfTKbyVYQveuw5Tdm2a9l944mnKHm9gLP8dyOn44/kao+CRmo5PDflkkQBInIJcyffOnvTYw2MQsNBImJQy1ISYyZPCgupdYUIDBM9RjDBfgkFi2hyoMCb89T6Z7xDPM6w0j1oT7TPsHAa2iRtgpNDppzwg9DdGJ1km/lQiMFkWYf3gt7L7jQKYBjrnRQg4fE3jQEza7sEkAo4x0L47EIA+wp4v1STVb5Rl1FW+2Fm+UYyBcwiMJE+tfPVvK3Yd7GCVyqpU/yCAZDIL3R8PZfyJSkYR4jrSkK4M3d8mD9vVpq7ejFoq6+NS7eSGxZvIFPcvpcyeP+0HBkg5fEUFHY5SW9wJusbXfrVAU57mBSOBQ6j6wAtsvkrTncGw016BCBKqlxlVlUElgSS22IJKQzMfVKUuV0S8m71L82cQTSVlEDC8IJrQahhljYIOVHd7DMk0HDMNuR31KXb1wDCaOwz0NlB+Sjch2HS/1dB/5cJv8xcuPAEe1l1FoBjm93tI9mebQiUQ3beuxa4xRh2QOtAiAVgMLM0EO6rQVhXgaDuRzctzOykwaHbetg53qrxkJDA5wBPyeZ9uXbe/7esOzaTrKV1xMb7PgbzbpGB33R2WHoJcIu6iOAhWZh5QqNTOw0I+XOtLj1BYEA/+1tdugcbXGF3cLxelEQBIg1qO7W/GdtcVaBxHzST4GYfhlnpUrm5xdjms9E8UTHhQv2o9a+m4eh54fUh8Wb7ZID5uOQZalO/7oj+2HNRMr0kYbd4YQY+heUjiQAETSyJczRJ59YWS7sxJlZEg89b5CaWgpwkRbrrw1N0xA8nl/mvtvLeB0Fwf6HRcwDN81NL/Dl1eZ5T2aDOYcdYC87cCAhpJj8AhHkVAqaTBmDdxCCcNuAp0M+fMVFScBJAf5N5/+9zeN9V7Pn8xGUPCThS3NDHLsHrtXAMBhA/aOT0CzCjN8LMS8DFmCBA2jEtQuIWmAf0M/IEeG2VcoNIlMFrkwRmg9xbJKn1i5GMI5BUBF0QOkpW4beNIDw/Q5+h/iWO1K5+7oK59dn48eNPY0GKiYFwrE+RZymAPChpAmwHoP2Ir9BvK5iCROG6hfMUeYh1jZLzIUGAyEi6jZL0YKIkHZvkZNnDkPQkNvDL3Jckuemr6L41F1SeZy/1u6bw3g9vXLaFmO7YQjSlGz69we0tBoGd2eBMfTPoGkVIQRqp58Z8FeD0JQdyUy+KEb/oHE/hq3VZbt/j2e6qpozl28jEkurAFLe/dkXxyqmt3NA1QW7IfoyRtLhQY+ifAqBkfZEZ9kTE4w7uJkDaRSExfw1CtgDVMNqoGH+QPB9u2H+PNHjtKgJOBfsaOrmE7X/rIzj4KjN4UOQygl3/Gux/u2QGXASfDcH+Yf8CXGzECJ7CdRjaJK9MiczkGQLf16OGkO1H/0cwONHssNkmXoxaEMwOPew3A87HB/0eCMclDAI44PuVcu9YFwFyKwC3Btpj0CqgPQKAfCGamxd+sx3O8WH8PbyupQ32eRwmgCo4Z0+3o+wemVdK2MrqJswvevy1uoLl5KcF0wnJu5y0O0eQPVz2ty3c6Bz2p+9z3PHxCCwCsgJ+G+7j/TPyitb+PrdgdaumdBPJAp7yeNED5APnnOARbvwacptmCHuOGHTszsKoOAHSLpJO06tsfEEheHg2Dk4UkLShPY3ZrKyAiu5c8wHlQTcGw+aUsSTataDZAIO/ivFAEaV0cujrc2r2SPzjCsyMlYGCiJ4xwazaB1rngijXjUBdSz1YcI0rlGbfRAGiJsTw/fXRAoUWi/22Xk/4kfOLFjCXiOPku1odl+4heZeQdsc5Bz+Zf/uee91riJb3tYFW2ZLO+256dKHn9HhyspS8UT+7Moa15l5SGHSc9U7z/DTy7nwuOK947ZcaviZ4Wdkm8l+lG3do+PVcXslj53cl76srAEGhQtMDTRBch8AINpuHNIAKOwIIg3mSQHcokUQQ4DdYAYDfO1QGXNhH0lx8aOIS94vonxUmEMBVsY4HQMlmBO48OF9VgEog+V5aM26ksRX5BtdRaLXa71Y0TboAEJr6IaWlDKRrRGCsZsWTaoK/j5I61AMbCC+YURYk2sAxCCmeQBqcYw7WO8c/2uIcfpXG8/ZgTcmGhVPcvg+mLd1Mporer8/tbn9ZRuHaYSy/od4vgYvIZgbgLKlNnPaPQLzrSdE40uhKBX4x+mkyT5P1fY7mpOuBp9wAPGVqaTWZhmn3vHcf9HFfVmntlWwaTC9pkDYx8GdaTvN71I5FQYICL3le2lWE7VB6evp/M4K1SW1GlOICL8eTwkGvBRP/oI/PxOvpJERUi61kQYqgxSCnmnmI502DhnAvvoHfb0avGKafyGd6JolR012AqOw/45gnK0Z4qHI0AwOO5FkYeMNlrJhqHnDqdjc6dcUYc+gkGGAiWUu8NiDcW4FkB6d6tiGhP2or9lbJc7LCpFt3cr1TOx3A92L7fD3NwfoFiPd9LLlnN3uJT2t3V68GgBxFD1tGib8F+qmzlPrHKjkaegogIgE23RPHTU+SvFEXIgjUbHr4Loi5VDS3CoTt7yrC3C72bb0l3gFntJJbCXRhDSKALikMEHM+mkdS8E7NxduG90cESyg63YCpHXDNZXBNl0RLbznWAOnxCj3Ulm+Ym3zB0VxtewcIbqNDtx2LIaBA099tl9LMcdaW8xQz77vKWlx1H2b3ZgPZngwcwuKu3q4p3zpTU7r7tKZ5mqENzpSlmJBICsbSHKx3GxzJrqOc7mwFcp8kmlFhN3FmaeVFcPzFAMgvMLg5uXzDM3FEirsFEBi0uxOYlZJAzb+lJPRUQFFIqP2OniEF80YCk/kocoR4Xdf0esRESiEzQC0W8AmCk9V+qEUkwWuJIwYUcjfj9UgVSQ7Dda2mC56iCPhvGyDfAUAO52qb0I3qYTNvoxBiuRAbgCdklvjnWnn/y1P5SvIg/wj5LH/Oxy3cVd+T/FRy2JFc3+TU+QNObcY3s4edGI83SojGMt6vDN6fklFSDZqkZltva5B4AUKPB4P0JyWyToOGmFBIA1HQ75HOBFmcqeEYX1LuE28quaTFLoV2UI14w3G/pdnHkblfWHbHFhFviQUWJu5AzbB90Pcs+dqOfxuAfAtm1JFcbWvbfP0OcTZHjRHbW4Qg0XEVx7Ofad01t95euPqn9/LzSHBBOiF5eiGACMd/oyFXqwvTFJKEpXtier7gd3QVI2YQ20tqSGZp7VM0rtJXAKLGK5io+gzpeKMwX0suyKLHSSD0u5m4RSIAGYoxGiXNJAHkOyTn8hhAWpp9MOy3MZyPJdyPthhRfUazGNpoHhjc0zKlXKzfPEAwjgEapC3g0H1f70ye2Mm7Jas0IRBwZvZGgg4m0B02t/fr7GV1xFxaSzQlG//mK7w/l3DDlge4lB8w0CeU6eG0rwUc2pn75oaEQOiDXTmo5HbGbGNbceUiDGBmlK1/pq9oECqgQIT/oqxBDEHRJBHTqcWZ3rxfia9I2cF7MfaQAEAkom5D4DWoAQ89bZhewR6XNVExxRvuySs06Mbcmzb1OEvn9Bqz2XYTFdZ/G4B8Py9tMMzyHyM/6MhLwZT0FxqdKdO+z0k7KSzEmoFEHuwr843DIg9WHhdPYZqKv9UKJDqL99kJk1pxZN7IwfWc1onry8kCyQng0H3dwumXHOZ0l7Ln4xHWuYdNN1PR2gutbm8xkPPdmKaSuXgjySzb8Ggf4SChyoEYa1CITFNeAaCx6mkOEBx7txjgUuUrlngHnP4GAHgDBhaVOJAEkL+qXEvIZS2ZgOlSyj2eY5CJZEdNb6GRe8wmTk0V6wckmmrS5wDCguQIgKRpvi4XCbQw2y9Khdle/4+AM7XgF9e4c+nvvXP/cNo0ft0sO1+1PbN8vbT81vuj3V19ryXCDQvkHoSdMJoBtUSTM9kM4NhEy/g0croGeF9zyGGcFHFziiquznZ7V4Fm2i/liGHbit4zHRto7D0v1r2xAEK/A0E3qxxLcvOaf2J4BQrh8yrBxVA+E+tGjraFXc3m9dGCafi9fFJh/weiPYIVMIx9gOAZcKLAaD7cj3q6xiIaSBCk1CFBXeTdBQgt2hAFIAtjeNKSegQkNLfpCDcmK8ClPtOCyYELrgQOMfqXDtcoz6PFK8s0Jeu/HL1kM8lesolMdXvfncz7crPKN54Zvumk07p0Wk+X7ac5f8zl9Zz+fxu4sT+SRSkkyA0hrc4rXt1QcI9jotu/cRzvax23dCsBkBwG0r8mw115TY+EeuKKg6A9bbqDBp+izNyS/W9+UU3gJdv+GVaYcWGTRIzbVNJTOnAmZ4QsSWWh1SBJe4zHfRQIOgOQyFgBC3zoqxTOsQUzi9XctpITwAH9vM4u4lLRvvez964XNYgwVjABKWl7+fLl7oME00VYu584z732M9et7xzkkGxfQloW2Mmb+YvIA4vu36lxrzew+1cgWY9nDQmc9PuMBoB+Bx7ijIvecXFHHi58gNy09AlyWtkmsmjRI2Rl4crHMRWFXZTlibE0uKci6TDzf4Tr0CM8agoFAMxm60q1KDYjMAU0NUQSNi26ZNUycaVlpD+Ec7jCyX/yoBx6xTAZTyWuQuMwR2lWMXsNwFtGwP7bpSAnRqQRSHWYq8UKqfya4VgPqFyzpH3N/p7UILgiUW1/dgJSqgmAmQATJybE6ZS9Ueysvzh/xVnT+KpZV5Suf+7UYn/HnDI/eWVBya4O7pKdZP7/kKa5FwWD3MVPgYa58a8zZ54ebwKhvJ+Cgooh6Xx10QC+5sPBAIoh7pqOG9zet9/Nn783mJ9K2nLP39fMjao87Jpo0jD7kVBcpndysZjgGvAK4zQ2jykcuTbCrG15VqmgWWRWrPkAXWugkcroSF6vZ6PkcEmZuObDsH8xG4WnGxZPwJV4cJyDUbJ6KUDXy2dYNEvQmyadQxubso5OBNQmyJuQXymkmKyKBhCYYKp6EiDoQGA8bETZjBW9hHQigjEbBef5kJSsubpLHEWIMTCeIFNJxaV23nenrcT3FQbkpoIZdb3b+9cRZRscmvIdZx7kzjzjqCvdAbzkPbIoTeApQOh3Njp0BfVzks+J9EqF07vlFeMnF/mvhn4eBk5x4DrPU2BG+ck0t/fJHL7SKhSrnq0Z0eIafW8Aza/CNNH75dS+Drzl9oPS4ig171dPZvNKpBPbLhjErZjJKhYUECLhwRj2uGSqRQ4Os5ovXWXWj1hTIgnsz9DX81iEAI5Xi8tDof0iCmPUdHkUPlwUNZqZ/YeCAP8f3VfJLKSRczS78FkecIynw0UULB/EMrHgHJf3hIlFtQHyI5XkyhBApKIWb6A2EYtKWBokEON3uIgrpauOnSSszWsv8fttvLdFKjnaDMK7EZpJbZ9ml9be4NA9jUUYpMVSv7a4dL+vdyZfpbzmxDPA4vZZMFUkvDjLvx/6fsjmrhqltA8BMAQc2tkAjjfEFBihnz1NnHb5UceYy3sxmzfCfSlfb8Ds164u3MKg/czM/kmdTQdxhouR7tEuxTEiihEwazJUlgwbWqW14vJM4uGw/xF2FaBamkl40ZUl4tpp0Qr1REubVZZe31WAhNzRYkVGc7TJIEhjOazXDa9D/Mz6nHisOC0Pm/uFU+zu6jkgrDsyyzcQ1BgAkO+waPXk4prLFdZyJCkVfwOB1TY79Y+KiYdppJFLaQ84x20mrvMFjnKNu/aUm0u8s6/jfe9MwSryy7YiAHdDP8XowlUi9/JngWDf9bl6Q4NTVwP9tUhFrJugbarndMbeAohshR5TDEA9iIbLV2lMAPrIiTbwaPIgB4gj3SOo0H8UYFNwWP8i5zCS122yKEQGEudqvXiuHWdp1B7vU67VXTevTOMujjGZhM5V4f7IvWuxrQ4AxfQpy+pQWHEmf9Na7J1tKas4Q40vKKbHM+oKU9ePcKnLWh2Xf0KcQ8kBp4lsLrz7+YtK1v995OInyKl8TXuau/ql3xVX3up2P3BKOADoOS5mijyTht/M6S4FMC5v5HRfS88HOZRI2Z9urEmPp+Hg0CofpTEGQzgPdP9i8h9N9+hCoYhOAiL1/yLDnTqlf4DwOhlN1KVCEbKluEQew+luoDAy1mQfDMf/mqk0k9D50XQbebBUdcsoqb4F14ZbiitWdeIlcdtpJKkuxzOIrWzySMEjEyoW3rN7RnEFSQdtMbu8hlQtvBvXevypfs7wEE+p83gGbU/g0WnyB+n8cNuIs+pztTubON3RQ/OSh/Y0QBKoakJn9zb6aDHqtdLEKPtDzwWLr4nF1KyxSg1F1S5i38L6iD/Kq3ioeIeykctQLxaTYhJM9LolcHBKfEsGkE7Fp2MAJPQ5AH4i9COUZJJK+nTEU+kF/5fI+rooa9NlJpZQOA54AF9ZLswoYjXE+NxgJDKrF+266/h19uuLq5428v7gZUu2EJO7+meT2/fAt/kzNrZzw1pJ/ggS4FIONLvGPljvSBkZPlQXamNJwJKeD9LQCxqEVuxjuYa87lKoXlN43bjlfRC6iYmQQfZ3mOaOT1tii6Wp1HxqY1PRaf8gaB9B/zcoHVs9Td50IeznxaXBUgG8CPtdXmtKft1SLS44Z4tdLuQsQJQcGnD+VIMUxzJ9mGMZMK9MjH+YKB9qlxVsaKf8SZp09tE4UNzu3lDp0aJ1d1JTJ57BZLNrp5Z6T7PxvtvRRJss8YsMvuqfN5V6+akLvKElm4fnG3UNzrQ1AZjtJf7QFuC0T8j5Q7zLaYWUFIPmuK6UHo0FEDF3SgDHc2JJS4uQsSovBoDCJBUwwDXnr2Dht5EjcwZ1MeUhiVn8dCpWO0GvFbweoUKoVjkQZtMDMPh/xmAadcmqLWBSEzrJxsdSrPfB68dYoEG8RqXrtlEnQYP4xFqzkyZXRolj5Ejp8ajlgljOVHw1tdrt9tCa+Vj3jeEj5+FqRzjul6hNwudqC40VrsFB4GJZWCYOEn9F/kRq88qXuVoKKobgKkIg9V/jcw6R5MP/r9qKfdOjFaBrdKVdCCApb+S0XwjP/8gX8r5ebXGmTP81b2Tc9Xm7U5s33kg6DEC5NGNZDAZzPgzKClyHDa9VWJcWbvxSDGDB/5erCV3i8ahO0WssEHE9miDo8cL6s1g3CtoDBoOpEOMDzBNiu9p/RMQZPU9Go/1aTM8H4VsC5trDtF8MiuK5GI2WG9EbFke/tILLuVLd33S2iQW57UbmAToJgRo5Fh4HxmcemFNL4HgeuGflOMHYbMZU9hELCd+X2ADpXNndUlyVbOG9j4HGOCQkJ/LeDhvv32At8kXkUckrJspLhmKhtyaXfhaAYwcmSIp5X7rPGrlkPhBR0ke5wntvA4TNxYpXA/RghfOuHGtAD/Q/oCuar7cru8foN95JJ/HzUwWIjF8YDJ7jLLzPLhSXK/ETkbf49wJQ7ofXESwvUarCGEldOq9PbxbWwGufBIAEpeTF/c0u3YMRNbZkNXyPBUBoNi99hgUtJEAbfa/p3uMO4hIEed+y/ntaOJMoWHqw3yT2ORzy1o1rSKJFHuStm8ftDBB8BJucX1jcvjnAMd7JWvIEQZcwAOITAMqiybIqI4k+3FOpaHXAmXxtM6d/CIBxWOIp7WCKba7P1ZoiSXoozeSYAKTXCgH0b317Cz3+oFB8/EEoDYSvGiosfuJ932RL/MLOe1+2llTl9OTzCdXiKftvu/ZCAEYpaJJ/Up7SyOlfb3Hqb9k394rQIqtdOSMHAUDe6wdI/9Z7AEEeUSQ+/kB4cpTb+xiQ7yPCk6P4qg6721dj4WsnROMXPbXJeQqCoYXTzQCg7KCLrECr7A4AeBrmikXNsApLoo+B7gdI/xbXJgYKtyAQngBwrMelrMgvABQ/W4t999n4ioT4RY8BRYGngPllbnRotzQ6tR1S3teRFpf+3npOuwsAUt/DgcJ+gPRvGo3dXTsDC0jjo9Okxx/stLtrFtjca8/tDr/oMaAo8ZRc7TUAiJVgWh3EulpY7R3+30ufnd4PkP6tx7bM8pq5uMbbynuft/D+aXJ+4fF4BvSVc5Wlz2sCeSnn4/NIgKt83uzSN/w6Tzu8KwAxmy2h5LZwM7RKALmrHyD/yRykvFo3uXx9BvuZfN1GX9vkPOXAzOGnN7r0N+/NHXUe1TqxjsFEYzNougJNK6HP5pOeUbiiHyD9m+pTpPrypsRT4r/cUKG3CdJDHP8BmuRjpv0dH/pIEw57pVJG//abkLKkfxW/6Gme0kVwY4DpRFz1Jm/4eb/m+M/e/h8DUqoulnOQEAAAAABJRU5ErkJggg== +``` + diff --git a/docs/api/ui.output_plot.qmd b/docs/api/ui.output_plot.qmd new file mode 100644 index 000000000..b8f2b461e --- /dev/null +++ b/docs/api/ui.output_plot.qmd @@ -0,0 +1,117 @@ +# ui.output_plot { #shiny.ui.output_plot } + +`ui.output_plot(id, width='100%', height='400px', *, inline=False, click=False, dblclick=False, hover=False, brush=False, fill=MISSING)` + +Create a output container for a static plot. + +Place a [](:func:`~shiny.render.plot`) result in the user interface. See +[](:func:`~shiny.render.plot`) for more details on what types of plots are supported. + +## Parameters + +id: [str](`str`) + +: An output id. + +width: [str](`str`) \| [float](`float`) \| [int](`int`) = '100%' + +: The CSS width, e.g. '400px', or '100%'. + +height: [str](`str`) \| [float](`float`) \| [int](`int`) = '400px' + +: The CSS height, e.g. '100%' or '600px'. + +inline: [bool](`bool`) = False + +: If ``True``, the result is displayed inline. + +click: [bool](`bool`) \| [ClickOpts](`shiny.ui._plot_output_opts.ClickOpts`) = False + +: This can be a boolean or an object created by [](:func:`~shiny.ui.click_opts`). The + default is `False`, but if you use `True` (or equivalently, `click_opts()`), the + plot will send coordinates to the server whenever it is clicked, and the value + will be accessible via `input.xx_click()`, where `xx` is replaced with the ID of + this plot. The input value will be a dictionary with `x` and `y` elements + indicating the mouse position. + +dblclick: [bool](`bool`) \| [DblClickOpts](`shiny.ui._plot_output_opts.DblClickOpts`) = False + +: This is just like the `click` parameter, but for double-click events. + +hover: [bool](`bool`) \| [HoverOpts](`shiny.ui._plot_output_opts.HoverOpts`) = False + +: Similar to the `click` argument, this can be a boolean or an object created by + [](:func:`~shiny.ui.hover_opts`). The default is `False`, but if you use `True` (or + equivalently, `hover_opts()`), the plot will send coordinates to the server + whenever it is clicked, and the value will be accessible via `input.xx_hover()`, + where `xx` is replaced with the ID of this plot. The input value will be a + dictionary with `x` and `y` elements indicating the mouse position. To control + the hover time or hover delay type, use [](:func:`~shiny.ui.hover_opts`). + +brush: [bool](`bool`) \| [BrushOpts](`shiny.ui._plot_output_opts.BrushOpts`) = False + +: Similar to the `click` argument, this can be a boolean or an object created by + [](:func:`~shiny.ui.brush_opts`). The default is `False`, but if you use `True` (or + equivalently, `brush_opts()`), the plot will allow the user to "brush" in the + plotting area, and will send information about the brushed area to the server, + and the value will be accessible via `input.plot_brush()`. Brushing means that + the user will be able to draw a rectangle in the plotting area and drag it + around. The value will be a named list with `xmin`, `xmax`, `ymin`, and `ymax` + elements indicating the brush area. To control the brush behavior, use + [](:func:`~shiny.ui.brush_opts`). Multiple `output_image`/`output_plot` calls may + share the same `id` value; brushing one image or plot will cause any other + brushes with the same `id` to disappear. + +fill: [bool](`bool`) \| [MISSING_TYPE](`shiny.types.MISSING_TYPE`) = MISSING + +: Whether or not to allow the plot output to grow/shrink to fit a fillable + container with an opinionated height (e.g., [](:func:`~shiny.ui.page_fillable`)). If + no `fill` value is provided, it will default to the inverse of `inline`. + +## Returns + +| Type | Description | +|------------------------|---------------| +| [Tag](`htmltools.Tag`) | A UI element | + +## See Also + +* [](:func:`~shiny.render.plot`) +* [](:func:`~shiny.ui.output_image`) + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +import matplotlib.pyplot as plt +import numpy as np + +from shiny import App, Inputs, Outputs, Session, render, ui + +app_ui = ui.page_fluid( + ui.input_slider( + "n", "input_slider()", min=10, max=100, value=50, step=5, animate=True + ), + ui.output_plot("p"), +) + + +def server(input: Inputs, output: Outputs, session: Session): + @render.plot + def p(): + np.random.seed(19680801) + x_rand = 100 + 15 * np.random.randn(437) + fig, ax = plt.subplots() + ax.hist(x_rand, int(input.n()), density=True) + return fig + + +app = App(app_ui, server) + +``` + diff --git a/docs/api/ui.output_table.qmd b/docs/api/ui.output_table.qmd new file mode 100644 index 000000000..0ca5fbfc4 --- /dev/null +++ b/docs/api/ui.output_table.qmd @@ -0,0 +1,136 @@ +# ui.output_table { #shiny.ui.output_table } + +`ui.output_table(id, **kwargs)` + +Create a output container for a table. + +## Parameters + +id: [str](`str`) + +: An output id. + +**kwargs: [TagAttrValue](`htmltools.TagAttrValue`) = {} + +: Additional attributes to add to the container. + +## Returns + +| Type | Description | +|------------------------|---------------| +| [Tag](`htmltools.Tag`) | | + +## See Also + +* [](:func:`~shiny.render.table`) + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +import pathlib + +import pandas as pd + +from shiny import App, Inputs, Outputs, Session, render, ui + +dir = pathlib.Path(__file__).parent +mtcars = pd.read_csv(dir / "mtcars.csv") + + +app_ui = ui.page_fluid( + ui.input_checkbox("highlight", "Highlight min/max values"), + ui.output_table("result"), + # Legend + ui.panel_conditional( + "input.highlight", + ui.panel_absolute( + "Yellow is maximum, grey is minimum", + bottom="6px", + right="6px", + class_="p-1 bg-light border", + ), + ), + class_="p-3", +) + + +def server(input: Inputs, output: Outputs, session: Session): + @render.table + def result(): + if not input.highlight(): + # If we're not highlighting values, we can simply + # return the pandas data frame as-is; @render.table + # will call .to_html() on it. + return mtcars + else: + # We need to use the pandas Styler API. The default + # formatting options for Styler are not the same as + # DataFrame.to_html(), so we set a few options to + # make them match. + return ( + mtcars.style.set_table_attributes( + 'class="dataframe shiny-table table w-auto"' + ) + .hide(axis="index") + .format( + { + "mpg": "{0:0.1f}", + "disp": "{0:0.1f}", + "drat": "{0:0.2f}", + "wt": "{0:0.3f}", + "qsec": "{0:0.2f}", + } + ) + .set_table_styles( + [dict(selector="th", props=[("text-align", "right")])] + ) + .highlight_min(color="silver") + .highlight_max(color="yellow") + ) + + +app = App(app_ui, server) + +## file: mtcars.csv +mpg,cyl,disp,hp,drat,wt,qsec,vs,am,gear,carb +21,6,160,110,3.9,2.62,16.46,0,1,4,4 +21,6,160,110,3.9,2.875,17.02,0,1,4,4 +22.8,4,108,93,3.85,2.32,18.61,1,1,4,1 +21.4,6,258,110,3.08,3.215,19.44,1,0,3,1 +18.7,8,360,175,3.15,3.44,17.02,0,0,3,2 +18.1,6,225,105,2.76,3.46,20.22,1,0,3,1 +14.3,8,360,245,3.21,3.57,15.84,0,0,3,4 +24.4,4,146.7,62,3.69,3.19,20,1,0,4,2 +22.8,4,140.8,95,3.92,3.15,22.9,1,0,4,2 +19.2,6,167.6,123,3.92,3.44,18.3,1,0,4,4 +17.8,6,167.6,123,3.92,3.44,18.9,1,0,4,4 +16.4,8,275.8,180,3.07,4.07,17.4,0,0,3,3 +17.3,8,275.8,180,3.07,3.73,17.6,0,0,3,3 +15.2,8,275.8,180,3.07,3.78,18,0,0,3,3 +10.4,8,472,205,2.93,5.25,17.98,0,0,3,4 +10.4,8,460,215,3,5.424,17.82,0,0,3,4 +14.7,8,440,230,3.23,5.345,17.42,0,0,3,4 +32.4,4,78.7,66,4.08,2.2,19.47,1,1,4,1 +30.4,4,75.7,52,4.93,1.615,18.52,1,1,4,2 +33.9,4,71.1,65,4.22,1.835,19.9,1,1,4,1 +21.5,4,120.1,97,3.7,2.465,20.01,1,0,3,1 +15.5,8,318,150,2.76,3.52,16.87,0,0,3,2 +15.2,8,304,150,3.15,3.435,17.3,0,0,3,2 +13.3,8,350,245,3.73,3.84,15.41,0,0,3,4 +19.2,8,400,175,3.08,3.845,17.05,0,0,3,2 +27.3,4,79,66,4.08,1.935,18.9,1,1,4,1 +26,4,120.3,91,4.43,2.14,16.7,0,1,5,2 +30.4,4,95.1,113,3.77,1.513,16.9,1,1,5,2 +15.8,8,351,264,4.22,3.17,14.5,0,1,5,4 +19.7,6,145,175,3.62,2.77,15.5,0,1,5,6 +15,8,301,335,3.54,3.57,14.6,0,1,5,8 +21.4,4,121,109,4.11,2.78,18.6,1,1,4,2 + +``` + diff --git a/docs/api/ui.output_text.qmd b/docs/api/ui.output_text.qmd new file mode 100644 index 000000000..a1f68eddf --- /dev/null +++ b/docs/api/ui.output_text.qmd @@ -0,0 +1,87 @@ +# ui.output_text { #shiny.ui.output_text } + +`ui.output_text(id, inline=False, container=None)` + +Create a output container for some text. + +## Parameters + +id: [str](`str`) + +: An output id. + +inline: [bool](`bool`) = False + +: If ``True``, the result is displayed inline. + +container: [Optional](`typing.Optional`)\[[TagFunction](`htmltools.TagFunction`)\] = None + +: A Callable that returns the output container. + +## Returns + +| Type | Description | +|------------------------|---------------| +| [Tag](`htmltools.Tag`) | A UI element | + +## Note + +Text is HTML-escaped prior to rendering. + + + +## See Also + +* [](:func:`~shiny.render.text`) +* [](:func:`~shiny.ui.output_text_verbatim`) + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +from shiny import App, Inputs, Outputs, Session, render, ui + +app_ui = ui.page_fluid( + ui.input_text("txt", "Enter the text to display below:", "delete me"), + ui.row( + ui.column(6, ui.code("ui.output_text()"), ui.output_text("text")), + ui.column( + 6, + ui.code("ui.output_text_verbatim(placeholder=True)"), + ui.output_text_verbatim("verb", placeholder=True), + ), + ), + ui.row( + ui.column(6), + ui.column( + 6, + ui.code("ui.output_text_verbatim(placeholder=False)"), + ui.output_text_verbatim("verb_no_placeholder", placeholder=False), + ), + ), +) + + +def server(input: Inputs, output: Outputs, session: Session): + @render.text + def text(): + return input.txt() + + @render.text + def verb(): + return input.txt() + + @render.text + def verb_no_placeholder(): + return input.txt() + + +app = App(app_ui, server) + +``` + diff --git a/docs/api/ui.output_text_verbatim.qmd b/docs/api/ui.output_text_verbatim.qmd new file mode 100644 index 000000000..fe7fea05a --- /dev/null +++ b/docs/api/ui.output_text_verbatim.qmd @@ -0,0 +1,38 @@ +# ui.output_text_verbatim { #shiny.ui.output_text_verbatim } + +`ui.output_text_verbatim(id, placeholder=False)` + +Create a output container for some text. + +Place a [](:func:`~shiny.render.text`) result in the user interface. +Differs from [](:func:`~shiny.ui.output_text`) in that it wraps the text in a +fixed-width container with a gray-ish background color and border. + +## Parameters + +id: [str](`str`) + +: An output id. + +placeholder: [bool](`bool`) = False + +: If the output is empty or ``None``, should an empty rectangle be displayed to + serve as a placeholder? (This does not affect behavior when the output + is nonempty.) + +## Returns + +| Type | Description | +|------------------------|---------------| +| [Tag](`htmltools.Tag`) | A UI element | + +## See Also + +* [](:func:`~shiny.render.text`) +* [](:func:`~shiny.ui.output_text`) + + + +## Example + +See [](:func:`~shiny.ui.output_text`) \ No newline at end of file diff --git a/docs/api/ui.output_ui.qmd b/docs/api/ui.output_ui.qmd new file mode 100644 index 000000000..5a7c70c63 --- /dev/null +++ b/docs/api/ui.output_ui.qmd @@ -0,0 +1,76 @@ +# ui.output_ui { #shiny.ui.output_ui } + +`ui.output_ui(id, inline=False, container=None, fill=False, fillable=False, **kwargs)` + +Create a output container for a UI (i.e., HTML) element. + +## Parameters + +id: [str](`str`) + +: An output id. + +inline: [bool](`bool`) = False + +: If ``True``, the result is displayed inline. + +container: [Optional](`typing.Optional`)\[[TagFunction](`htmltools.TagFunction`)\] = None + +: A Callable that returns the output container. + +fill: [bool](`bool`) = False + +: Whether or not to allow the UI output to grow/shrink to fit a fillable container + with an opinionated height (e.g., [](:func:`~shiny.ui.page_fillable`)). + +fillable: [bool](`bool`) = False + +: Whether or not the UI output area should be considered a fillable (i.e., + flexbox) container. + +**kwargs: [TagAttrValue](`htmltools.TagAttrValue`) = {} + +: Attributes to be applied to the output container. + +## Returns + +| Type | Description | +|------------------------|---------------| +| [Tag](`htmltools.Tag`) | A UI element | + +## See Also + +* [](:func:`~shiny.render.ui`) +* [](:func:`~shiny.ui.output_text`) + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +from shiny import App, Inputs, Outputs, Session, reactive, render, ui + +app_ui = ui.page_fluid( + ui.input_action_button("add", "Add more controls"), + ui.output_ui("moreControls"), +) + + +def server(input: Inputs, output: Outputs, session: Session): + @render.ui + @reactive.event(input.add) + def moreControls(): + return ui.TagList( + ui.input_slider("n", "N", min=1, max=1000, value=500), + ui.input_text("label", "Label"), + ) + + +app = App(app_ui, server) + +``` + diff --git a/docs/api/ui.page_auto.qmd b/docs/api/ui.page_auto.qmd new file mode 100644 index 000000000..f501aba9a --- /dev/null +++ b/docs/api/ui.page_auto.qmd @@ -0,0 +1,58 @@ +# ui.page_auto { #shiny.ui.page_auto } + +`ui.page_auto(*args, title=MISSING, lang=MISSING, fillable=MISSING, full_width=False, page_fn=None, **kwargs)` + +A page container which automatically decides which page function to use. + +If there is a top-level nav, this will use [](:func:`~shiny.ui.page_navbar`). If not, +and there is a top-level sidebar, this will use [](:func:`~shiny.ui.page_sidebar`). + +If there are neither top-level navs nor sidebars, this will use the ``fillable`` and +``full_width`` arguments to determine which page function to use. + +## Parameters + +*args: [TagChild](`htmltools.TagChild`) \| [TagAttrs](`htmltools.TagAttrs`) = () + +: UI elements. These are used to determine which page function to use, and they + are also passed along to that page function. + +title: [str](`str`) \| [MISSING_TYPE](`shiny.types.MISSING_TYPE`) = MISSING + +: The browser window title (defaults to the host URL of the page). + +lang: [str](`str`) \| [MISSING_TYPE](`shiny.types.MISSING_TYPE`) = MISSING + +: ISO 639-1 language code for the HTML page, such as ``"en"`` or ``"ko"``. This + will be used as the lang in the ```` tag, as in ````. The + default, `None`, results in an empty string. + +fillable: [bool](`bool`) \| [MISSING_TYPE](`shiny.types.MISSING_TYPE`) = MISSING + +: If there is a top-level sidebar or nav, then the value is passed through to the + [](:func:`~shiny.ui.page_sidebar`) or [](:func:`~shiny.ui.page_navbar`) function. + Otherwise, if ``True``, use [](:func:`~shiny.ui.page_fillable`), where the content + fills the window; if ``False`` (the default), the value of ``full_width`` will + determine which page function is used. + +full_width: [bool](`bool`) = False + +: This has an effect only if there are no sidebars or top-level navs, and + ``fillable`` is ``False``. If this is ``False`` (the default), use use + [](:func:`~shiny.ui.page_fixed`); if ``True``, use [](:func:`~shiny.ui.page_fillable`). + +page_fn: [Callable](`typing.Callable`)\[..., [Tag](`htmltools.Tag`)\] \| None = None + +: The page function to use. If ``None`` (the default), will automatically choose + one based on the arguments provided. If not ``None``, this will override all + heuristics for choosing page functions. + +**kwargs: [object](`object`) = {} + +: Additional arguments, which are passed to the page function. + +## Returns + +| Type | Description | +|------------------------|---------------| +| [Tag](`htmltools.Tag`) | A UI element. | \ No newline at end of file diff --git a/docs/api/ui.page_bootstrap.qmd b/docs/api/ui.page_bootstrap.qmd new file mode 100644 index 000000000..0b1bf094b --- /dev/null +++ b/docs/api/ui.page_bootstrap.qmd @@ -0,0 +1,37 @@ +# ui.page_bootstrap { #shiny.ui.page_bootstrap } + +`ui.page_bootstrap(*args, title=None, lang=None, **kwargs)` + +Create a Bootstrap UI page container. + +## Parameters + +*args: [TagChild](`htmltools.TagChild`) \| [TagAttrs](`htmltools.TagAttrs`) = () + +: UI elements. + +title: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: The browser window title (defaults to the host URL of the page). Can also be set + as a side effect via [](:func:`~shiny.ui.panel_title`). + +lang: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: ISO 639-1 language code for the HTML page, such as ``"en"`` or ``"ko"``. This + will be used as the lang in the ```` tag, as in ````. The + default, `None`, results in an empty string. + +**kwargs: [TagAttrValue](`htmltools.TagAttrValue`) = {} + +: Attributes on the the `` tag. + +## Returns + +| Type | Description | +|------------------------|---------------| +| [Tag](`htmltools.Tag`) | A UI element. | + +## See Also + +[](:func:`~shiny.ui.page_fluid`) +[](:func:`~shiny.ui.page_navbar`) \ No newline at end of file diff --git a/docs/api/ui.page_fillable.qmd b/docs/api/ui.page_fillable.qmd new file mode 100644 index 000000000..76c389a5b --- /dev/null +++ b/docs/api/ui.page_fillable.qmd @@ -0,0 +1,48 @@ +# ui.page_fillable { #shiny.ui.page_fillable } + +`ui.page_fillable(*args, padding=None, gap=None, fillable_mobile=False, title=None, lang=None, **kwargs)` + +Create a fillable page. + +## Parameters + +*args: [TagChild](`htmltools.TagChild`) \| [TagAttrs](`htmltools.TagAttrs`) = () + +: UI elements. + +padding: [Optional](`typing.Optional`)\[[CssUnit](`shiny.ui.css.CssUnit`) \| [list](`list`)\[[CssUnit](`shiny.ui.css.CssUnit`)\]\] = None + +: Padding to use for the body. See [](:func:`~shiny.ui.css_unit.as_css_padding`) + for more details. + +fillable_mobile: [bool](`bool`) = False + +: Whether or not the page should fill the viewport's height on mobile devices + (i.e., narrow windows). + +gap: [Optional](`typing.Optional`)\[[CssUnit](`shiny.ui.css.CssUnit`)\] = None + +: A CSS length unit passed through [](:func:`~shiny.ui.css_unit.as_css_unit`) + defining the `gap` (i.e., spacing) between elements provided to `*args`. + +title: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: The browser window title (defaults to the host URL of the page). Can also be set + as a side effect via [](:func:`~shiny.ui.panel_title`). + +lang: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: ISO 639-1 language code for the HTML page, such as ``"en"`` or ``"ko"``. This + will be used as the lang in the ```` tag, as in ````. The + default, `None`, results in an empty string. + +## Returns + +| Type | Description | +|------------------------|---------------| +| [Tag](`htmltools.Tag`) | A UI element. | + +## See Also + +* [](:func:`~shiny.ui.page_fluid`) +* [](:func:`~shiny.ui.page_fixed`) \ No newline at end of file diff --git a/docs/api/ui.page_fixed.qmd b/docs/api/ui.page_fixed.qmd new file mode 100644 index 000000000..a3ce7349a --- /dev/null +++ b/docs/api/ui.page_fixed.qmd @@ -0,0 +1,80 @@ +# ui.page_fixed { #shiny.ui.page_fixed } + +`ui.page_fixed(*args, title=None, lang=None, **kwargs)` + +Create a fixed page. + +## Parameters + +*args: [TagChild](`htmltools.TagChild`) \| [TagAttrs](`htmltools.TagAttrs`) = () + +: UI elements. + +title: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: The browser window title (defaults to the host URL of the page). Can also be set + as a side effect via [](:func:`~shiny.ui.panel_title`). + +lang: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: ISO 639-1 language code for the HTML page, such as ``"en"`` or ``"ko"``. This + will be used as the lang in the ```` tag, as in ````. The + default, `None`, results in an empty string. + +**kwargs: [str](`str`) = {} + +: Attributes on the page level container. + +## Returns + +| Type | Description | +|------------------------|---------------| +| [Tag](`htmltools.Tag`) | A UI element. | + +## See Also + +[](:func:`~shiny.ui.page_fluid`) +[](:func:`~shiny.ui.page_bootstrap`) +[](:func:`~shiny.ui.page_navbar`) + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +import matplotlib.pyplot as plt +import numpy as np + +from shiny import App, Inputs, Outputs, Session, render, ui + +app_ui = ui.page_fixed( + ui.layout_sidebar( + ui.panel_sidebar( + ui.input_slider("n", "N", min=0, max=100, value=20), + ), + ui.panel_main( + ui.output_plot("plot"), + ), + ), +) + + +def server(input: Inputs, output: Outputs, session: Session): + @render.plot(alt="A histogram") + def plot() -> object: + np.random.seed(19680801) + x = 100 + 15 * np.random.randn(437) + + fig, ax = plt.subplots() + ax.hist(x, input.n(), density=True) + return fig + + +app = App(app_ui, server) + +``` + diff --git a/docs/api/ui.page_fluid.qmd b/docs/api/ui.page_fluid.qmd new file mode 100644 index 000000000..9c1a720e1 --- /dev/null +++ b/docs/api/ui.page_fluid.qmd @@ -0,0 +1,80 @@ +# ui.page_fluid { #shiny.ui.page_fluid } + +`ui.page_fluid(*args, title=None, lang=None, **kwargs)` + +Create a fluid page. + +## Parameters + +*args: [TagChild](`htmltools.TagChild`) \| [TagAttrs](`htmltools.TagAttrs`) = () + +: UI elements. + +title: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: The browser window title (defaults to the host URL of the page). Can also be set + as a side effect via [](:func:`~shiny.ui.panel_title`). + +lang: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: ISO 639-1 language code for the HTML page, such as ``"en"`` or ``"ko"``. This + will be used as the lang in the ```` tag, as in ````. The + default, `None`, results in an empty string. + +**kwargs: [str](`str`) = {} + +: Attributes on the page level container. + +## Returns + +| Type | Description | +|------------------------|---------------| +| [Tag](`htmltools.Tag`) | A UI element. | + +## See Also + +[](:func:`~shiny.ui.page_fixed`) +[](:func:`~shiny.ui.page_bootstrap`) +[](:func:`~shiny.ui.page_navbar`) + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +import matplotlib.pyplot as plt +import numpy as np + +from shiny import App, Inputs, Outputs, Session, render, ui + +app_ui = ui.page_fluid( + ui.layout_sidebar( + ui.panel_sidebar( + ui.input_slider("n", "N", min=0, max=100, value=20), + ), + ui.panel_main( + ui.output_plot("plot"), + ), + ), +) + + +def server(input: Inputs, output: Outputs, session: Session): + @render.plot(alt="A histogram") + def plot() -> object: + np.random.seed(19680801) + x = 100 + 15 * np.random.randn(437) + + fig, ax = plt.subplots() + ax.hist(x, input.n(), density=True) + return fig + + +app = App(app_ui, server) + +``` + diff --git a/docs/api/ui.page_navbar.qmd b/docs/api/ui.page_navbar.qmd new file mode 100644 index 000000000..24824c62b --- /dev/null +++ b/docs/api/ui.page_navbar.qmd @@ -0,0 +1,101 @@ +# ui.page_navbar { #shiny.ui.page_navbar } + +`ui.page_navbar(*args, title=None, id=None, selected=None, sidebar=None, fillable=False, fillable_mobile=False, gap=None, padding=None, position='static-top', header=None, footer=None, bg=None, inverse=False, underline=True, collapsible=True, fluid=True, window_title=MISSING, lang=None)` + +Create a page with a navbar and a title. + +## Parameters + +*args: [NavSetArg](`shiny.types.NavSetArg`) \| [MetadataNode](`htmltools.MetadataNode`) \| [Sequence](`typing.Sequence`)\[[MetadataNode](`htmltools.MetadataNode`)\] = () + +: UI elements. + +title: [Optional](`typing.Optional`)\[[str](`str`) \| [Tag](`htmltools.Tag`) \| [TagList](`htmltools.TagList`)\] = None + +: The browser window title (defaults to the host URL of the page). Can also be set + as a side effect via [](:func:`~shiny.ui.panel_title`). + +id: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: If provided, will create an input value that holds the currently selected nav + item. + +selected: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: Choose a particular nav item to select by default value (should match its + ``value``). + +sidebar: [Optional](`typing.Optional`)\[[Sidebar](`shiny.ui._sidebar.Sidebar`)\] = None + +: A [](:func:`~shiny.ui.sidebar`) component to display on every page. + +fillable: [bool](`bool`) \| [list](`list`)\[[str](`str`)\] = False + +: Whether or not the main content area should be considered a fillable + (i.e., flexbox) container. + +fillable_mobile: [bool](`bool`) = False + +: Whether or not ``fillable`` should apply on mobile devices. + +position: [Literal](`typing.Literal`)\['static-top', 'fixed-top', 'fixed-bottom'\] = 'static-top' + +: Determines whether the navbar should be displayed at the top of the page with + normal scrolling behavior ("static-top"), pinned at the top ("fixed-top"), or + pinned at the bottom ("fixed-bottom"). Note that using "fixed-top" or + "fixed-bottom" will cause the navbar to overlay your body content, unless you + add padding (e.g., ``tags.style("body {padding-top: 70px;}")``). + +header: [Optional](`typing.Optional`)\[[TagChild](`htmltools.TagChild`)\] = None + +: UI to display above the selected content. + +footer: [Optional](`typing.Optional`)\[[TagChild](`htmltools.TagChild`)\] = None + +: UI to display below the selected content. + +bg: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: Background color of the navbar (a CSS color). + +inverse: [bool](`bool`) = False + +: Either ``True`` for a light text color or ``False`` for a dark text color. + +collapsible: [bool](`bool`) = True + +: ``True`` to automatically collapse the elements into an expandable menu on mobile devices or narrow window widths. + +fluid: [bool](`bool`) = True + +: ``True`` to use fluid layout; ``False`` to use fixed layout. + +window_title: [str](`str`) \| [MISSING_TYPE](`shiny.types.MISSING_TYPE`) = MISSING + +: The browser's window title (defaults to the host URL of the page). Can also be + set as a side effect via [](:func:`~shiny.ui.panel_title`). + +lang: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: ISO 639-1 language code for the HTML page, such as ``"en"`` or ``"ko"``. This + will be used as the lang in the ```` tag, as in ````. The + default, `None`, results in an empty string. + +## Returns + +| Type | Description | +|------------------------|---------------| +| [Tag](`htmltools.Tag`) | A UI element. | + +## See Also + +* [](:func:`~shiny.ui.nav`) +* [](:func:`~shiny.ui.nav_menu`) +* [](:func:`~shiny.ui.navset_bar`) +* [](:func:`~shiny.ui.page_fluid`) + + + +## Example + +See [](:func:`~shiny.ui.nav`). \ No newline at end of file diff --git a/docs/api/ui.page_output.qmd b/docs/api/ui.page_output.qmd new file mode 100644 index 000000000..de395e760 --- /dev/null +++ b/docs/api/ui.page_output.qmd @@ -0,0 +1,17 @@ +# ui.page_output { #shiny.ui.page_output } + +`ui.page_output(id)` + +Create a page container where the entire body is a UI output. + +## Parameters + +id: [str](`str`) + +: An output id. + +## Returns + +| Type | Description | +|------------------------|-------------------------------------------------------------| +| [Tag](`htmltools.Tag`) | A UI element which is meant to be used as a page container. | \ No newline at end of file diff --git a/docs/api/ui.page_sidebar.qmd b/docs/api/ui.page_sidebar.qmd new file mode 100644 index 000000000..8aa42556c --- /dev/null +++ b/docs/api/ui.page_sidebar.qmd @@ -0,0 +1,90 @@ +# ui.page_sidebar { #shiny.ui.page_sidebar } + +`ui.page_sidebar(sidebar, *args, title=None, fillable=False, fillable_mobile=False, window_title=MISSING, lang=None, **kwargs)` + +Create a page with a sidebar and a title. + +## Parameters + +sidebar: [Sidebar](`shiny.ui._sidebar.Sidebar`) + +: Content to display in the sidebar. + +*args: [TagChild](`htmltools.TagChild`) \| [TagAttrs](`htmltools.TagAttrs`) = () + +: UI elements. + +title: [Optional](`typing.Optional`)\[[str](`str`) \| [Tag](`htmltools.Tag`) \| [TagList](`htmltools.TagList`)\] = None + +: A title to display at the top of the page. + +fillable: [bool](`bool`) = False + +: Whether or not the main content area should be considered a fillable + (i.e., flexbox) container. + +fillable_mobile: [bool](`bool`) = False + +: Whether or not ``fillable`` should apply on mobile devices. + +window_title: [str](`str`) \| [MISSING_TYPE](`shiny.types.MISSING_TYPE`) = MISSING + +: The browser's window title (defaults to the host URL of the page). Can also be + set as a side effect via [](:func:`~shiny.ui.panel_title`). + +lang: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: ISO 639-1 language code for the HTML page, such as ``"en"`` or ``"ko"``. This + will be used as the lang in the ```` tag, as in ````. The + default, `None`, results in an empty string. + +**kwargs: [TagAttrValue](`htmltools.TagAttrValue`) = {} + +: Additional attributes passed to [](:func:`~shiny.ui.layout_sidebar`). + +## Returns + +| Type | Description | +|------------------------|---------------| +| [Tag](`htmltools.Tag`) | A UI element. | + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +import matplotlib.pyplot as plt +import numpy as np + +from shiny import App, Inputs, Outputs, Session, render, ui + +app_ui = ui.page_sidebar( + ui.sidebar( + ui.input_slider("n", "N", min=0, max=100, value=20), + ), + ui.card( + ui.output_plot("plot"), + ), +) + + +def server(input: Inputs, output: Outputs, session: Session): + @output + @render.plot(alt="A histogram") + def plot() -> object: + np.random.seed(19680801) + x = 100 + 15 * np.random.randn(437) + + fig, ax = plt.subplots() + ax.hist(x, input.n(), density=True) + return fig + + +app = App(app_ui, server) + +``` + diff --git a/docs/api/ui.panel_absolute.qmd b/docs/api/ui.panel_absolute.qmd new file mode 100644 index 000000000..658e15ab6 --- /dev/null +++ b/docs/api/ui.panel_absolute.qmd @@ -0,0 +1,122 @@ +# ui.panel_absolute { #shiny.ui.panel_absolute } + +`ui.panel_absolute(*args, top=None, left=None, right=None, bottom=None, width=None, height=None, draggable=False, fixed=False, cursor='auto', **kwargs)` + +Create a panel of absolutely positioned content. + +Creates a `
` tag whose CSS position is set to absolute (or fixed if ``fixed = +True``). In HTML, absolute coordinates are specified relative to an element's +nearest parent element whose position is not set to static (the default). +If no such parent is found, the coordinates are relative to the page borders. +If you're not sure what that means, just keep in mind that you may get +strange results if you use this function from inside of certain types of panels. + +## Parameters + +*args: [TagChild](`htmltools.TagChild`) \| [TagAttrs](`htmltools.TagAttrs`) = () + +: UI elements to include inside the panel. + +top: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: Distance between the top of the panel and the top of the page or parent + container. + +left: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: Distance between the left side of the panel and the left of the page or parent + container. + +right: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: Distance between the right side of the panel and the right of the page or + parent container. + +bottom: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: Distance between the bottom of the panel and the bottom of the page or parent + container. + +width: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: Width of the panel. + +height: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: Height of the panel. + +draggable: [bool](`bool`) = False + +: If ``True``, allows the user to move the panel by clicking and dragging. + +fixed: [bool](`bool`) = False + +: Positions the panel relative to the browser window and prevents it from being + scrolled with the rest of the page. + +cursor: [Literal](`typing.Literal`)\['auto', 'move', 'default', 'inherit'\] = 'auto' + +: The type of cursor that should appear when the user mouses over the panel. Use + ``"move"`` for a north-east-south-west icon, ``"default"`` for the usual cursor + arrow, or ``"inherit"`` for the usual cursor behavior (including changing to an + I-beam when the cursor is over text). The default is ``"auto"``, which is + equivalent to ``"move" if draggable else "inherit"``. + +**kwargs: [TagAttrValue](`htmltools.TagAttrValue`) = {} + +: Attributes added to the content's container tag. + +## Returns + +| Type | Description | +|--------------------------------|---------------| +| [TagList](`htmltools.TagList`) | A UI element | + +## Tip + +The position (``top``, ``left``, ``right``, ``bottom``) and size (``width``, +``height``) parameters are all optional, but you should specify exactly two of top, +bottom, and height and exactly two of left, right, and width for predictable +results. + +Like most other distance parameters in Shiny, the position and size parameters take +a number (interpreted as pixels) or a valid CSS size string, such as `"100px"` +(100 pixels) or `"25%"`. + +For arcane HTML reasons, to have the panel fill the page or parent, +specify 0 for ``top``, ``left``, ``right``, and ``bottom`` rather than the more +obvious `width = "100%"` and `height = "100%"`. + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +from shiny import App, Inputs, Outputs, Session, ui + +app_ui = ui.page_fluid( + ui.panel_title("A basic absolute panel example", "Demo"), + ui.panel_absolute( + ui.panel_well( + "Drag me around!", ui.input_slider("n", "N", min=0, max=100, value=20) + ), + draggable=True, + width="300px", + right="50px", + top="50%", + ), +) + + +def server(input: Inputs, output: Outputs, session: Session): + pass + + +app = App(app_ui, server) + +``` + diff --git a/docs/api/ui.panel_conditional.qmd b/docs/api/ui.panel_conditional.qmd new file mode 100644 index 000000000..838defa9b --- /dev/null +++ b/docs/api/ui.panel_conditional.qmd @@ -0,0 +1,91 @@ +# ui.panel_conditional { #shiny.ui.panel_conditional } + +`ui.panel_conditional(condition, *args, **kwargs)` + +Create a conditional panel. + +Show UI elements only if a ``JavaScript`` condition is ``true``. + +## Parameters + +condition: [str](`str`) + +: A JavaScript expression that will be evaluated repeatedly to determine whether + the panel should be displayed. + +*args: [TagChild](`htmltools.TagChild`) \| [TagAttrs](`htmltools.TagAttrs`) = () + +: UI elements to include inside the panel. + +**kwargs: [TagAttrValue](`htmltools.TagAttrValue`) = {} + +: Attributes to place on the panel tag. + +## Returns + +| Type | Description | +|------------------------|---------------| +| [Tag](`htmltools.Tag`) | A UI element. | + +## Note + +In the JS expression, you can refer to input and output JavaScript objects that +contain the current values of input and output. For example, if you have an input +with an ``id`` of ``foo``, then you can use ``input.foo`` to read its value. +(Be sure not to modify the input/output objects, as this may cause unpredictable +behavior.) + +You are not recommended to use special JavaScript characters such as a period . in +the input id's, but if you do use them anyway, for example, `id = "foo.bar"`, you +will have to use `input["foo.bar"]` instead of ``input.foo.bar`` to read the input +value. + + + +## Tip + +A more powerful (but slower) way to conditionally show UI content is to use +[](:func:`~shiny.render.ui`). + + + +## See Also + +[](:func:`~shiny.render.ui`) +[](:func:`~shiny.ui.output_ui`) + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +from shiny import App, Inputs, Outputs, Session, ui + +app_ui = ui.page_fluid( + ui.input_checkbox("show", "Show radio buttons", False), + ui.panel_conditional( + "input.show", ui.input_radio_buttons("radio", "Choose ", ["slider", "select"]) + ), + ui.panel_conditional( + "input.show && input.radio === 'slider'", + ui.input_slider("slider", None, min=0, max=100, value=50), + ), + ui.panel_conditional( + "input.show && input.radio === 'select'", + ui.input_select("slider", None, ["A", "B", "C"]), + ), +) + + +def server(input: Inputs, output: Outputs, session: Session): + pass + + +app = App(app_ui, server) + +``` + diff --git a/docs/api/ui.panel_fixed.qmd b/docs/api/ui.panel_fixed.qmd new file mode 100644 index 000000000..b7b6af6e3 --- /dev/null +++ b/docs/api/ui.panel_fixed.qmd @@ -0,0 +1,29 @@ +# ui.panel_fixed { #shiny.ui.panel_fixed } + +`ui.panel_fixed(*args, top=None, left=None, right=None, bottom=None, width=None, height=None, draggable=False, cursor='auto', **kwargs)` + +Create a panel of absolutely positioned content. + +This function is equivalent to calling [](:func:`~shiny.ui.panel_absolute`) with +``fixed=True`` (i.e., the panel does not scroll with the rest of the page). See +[](:func:`~shiny.ui.panel_absolute`) for more information. + +## Parameters + +*args: [TagChild](`htmltools.TagChild`) \| [TagAttrs](`htmltools.TagAttrs`) = () + +: UI elements to include inside the panel. + +**kwargs: [TagAttrValue](`htmltools.TagAttrValue`) = {} + +: Arguments passed along to [](:func:`~shiny.ui.panel_absolute`). + +## Returns + +| Type | Description | +|--------------------------------|---------------| +| [TagList](`htmltools.TagList`) | A UI element. | + +## See Also + +[](:func:`~shiny.ui.panel_absolute`) \ No newline at end of file diff --git a/docs/api/ui.panel_main.qmd b/docs/api/ui.panel_main.qmd new file mode 100644 index 000000000..4bfb6078f --- /dev/null +++ b/docs/api/ui.panel_main.qmd @@ -0,0 +1,5 @@ +# ui.panel_main { #shiny.ui.panel_main } + +`ui.panel_main(*args, width=8, **kwargs)` + +Deprecated. Please supply the `*args` of [](:func:`~shiny.ui.panel_main`) directly to [](:func:`~shiny.ui.layout_sidebar`). \ No newline at end of file diff --git a/docs/api/ui.panel_sidebar.qmd b/docs/api/ui.panel_sidebar.qmd new file mode 100644 index 000000000..dfb13a7d3 --- /dev/null +++ b/docs/api/ui.panel_sidebar.qmd @@ -0,0 +1,5 @@ +# ui.panel_sidebar { #shiny.ui.panel_sidebar } + +`ui.panel_sidebar(*args, width=4, **kwargs)` + +Deprecated. Please use [](:func:`~shiny.ui.sidebar`) instead. \ No newline at end of file diff --git a/docs/api/ui.panel_title.qmd b/docs/api/ui.panel_title.qmd new file mode 100644 index 000000000..39ee0f6a1 --- /dev/null +++ b/docs/api/ui.panel_title.qmd @@ -0,0 +1,51 @@ +# ui.panel_title { #shiny.ui.panel_title } + +`ui.panel_title(title, window_title=MISSING)` + +Create title(s) for the application. + +## Parameters + +title: [str](`str`) \| [Tag](`htmltools.Tag`) \| [TagList](`htmltools.TagList`) + +: A title to display in the app's UI. + +window_title: [str](`str`) \| [MISSING_TYPE](`shiny.types.MISSING_TYPE`) = MISSING + +: A title to display on the browser tab. + +## Returns + +| Type | Description | +|--------------------------------|---------------| +| [TagList](`htmltools.TagList`) | A UI element. | + +## Note + +This result of this function causes a side effect of adding a title tag to the head +of the document (this is necessary for the browser to display the title in the +browser window). You can also specify a page title explicitly using the title +parameter of the top-level page function (e.g., [](:func:`~shiny.ui.page_fluid`)). + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +from shiny import App, Inputs, Outputs, Session, ui + +app_ui = ui.page_fluid(ui.panel_title("Page title", "Window title")) + + +def server(input: Inputs, output: Outputs, session: Session): + pass + + +app = App(app_ui, server) + +``` + diff --git a/docs/api/ui.panel_well.qmd b/docs/api/ui.panel_well.qmd new file mode 100644 index 000000000..bed74b00e --- /dev/null +++ b/docs/api/ui.panel_well.qmd @@ -0,0 +1,29 @@ +# ui.panel_well { #shiny.ui.panel_well } + +`ui.panel_well(*args, **kwargs)` + +Create a well panel. + +Creates a panel with a slightly inset border and gray background. Equivalent to +Bootstrap's ``well`` CSS class. + +## Parameters + +*args: [TagChild](`htmltools.TagChild`) \| [TagAttrs](`htmltools.TagAttrs`) = () + +: UI elements to include inside the panel. + +**kwargs: [TagAttrValue](`htmltools.TagAttrValue`) = {} + +: Attributes to place on the panel tag. + +## Returns + +| Type | Description | +|------------------------|---------------| +| [Tag](`htmltools.Tag`) | A UI element. | + +## See Also + +[](:func:`~shiny.ui.panel_sidebar`) +[](:func:`~shiny.ui.panel_main`) \ No newline at end of file diff --git a/docs/api/ui.popover.qmd b/docs/api/ui.popover.qmd new file mode 100644 index 000000000..be115df8d --- /dev/null +++ b/docs/api/ui.popover.qmd @@ -0,0 +1,172 @@ +# ui.popover { #shiny.ui.popover } + +`ui.popover(trigger, *args, title=None, id=None, placement='auto', options=None, **kwargs)` + +Add a popover to a UI element. + +Display additional information when clicking on a UI element (typically a +button). + +## Parameters + +trigger: [TagChild](`htmltools.TagChild`) + +: The UI element to serve as the popover trigger (typically a + [](:func:`~shiny.ui.input_action_button`) or similar). If `trigger` renders as + multiple HTML elements (e.g., it's a [](:func:`~shiny.ui.tags.TagList`)), the last + HTML element is used for the trigger. If the `trigger` should contain all of + those elements, wrap the object in a [](:func:`~shiny.ui.tags.div`) or + [](:func:`~shiny.ui.tags.span`). + +*args: [TagChild](`htmltools.TagChild`) \| [TagAttrs](`htmltools.TagAttrs`) = () + +: UI elements for the popover's body. Character strings are + automatically escaped unless marked as [](:func:`~shiny.html`). + +title: [Optional](`typing.Optional`)\[[TagChild](`htmltools.TagChild`)\] = None + +: A title (header) for the popover. + +id: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: A character string. Required to re-actively respond to the visibility of the + popover (via the `input.()` value) and/or update the visibility/contents of + the popover. + +placement: [Literal](`typing.Literal`)\['auto', 'top', 'right', 'bottom', 'left'\] = 'auto' + +: The placement of the popover relative to its trigger. + +options: [Optional](`typing.Optional`)\[[dict](`dict`)\[[str](`str`), [Any](`typing.Any`)\]\] = None + +: A list of additional + `options `_. + + + + +## Closing Popovers + + +In addition to clicking the `close_button`, popovers can be closed by pressing the +Esc/Space key when the popover (and/or its trigger) is focused. + + + +## Accessibility Of Popover Triggers + + +Because the user needs to interact with the `trigger` element to see the `popover`, +it's best practice to use an element that is typically accessible via keyboard +interactions, like a button or a link. + +If you use a non-interactive element, like a `` or text, `popover()` will +automatically add the `tabindex="0"` attribute to the trigger element to make sure +that users can reach the element with the keyboard. This means that in most cases +you can use any element you want as the trigger. + +One place where it's important to consider the accessibility of the trigger is when +using an icon without any accompanying text. In these cases, many icon elements are +created with the assumption that the icon is decorative, which will make it +inaccessible to users of assistive technologies. + +When using an icon as the primary trigger, ensure that the icon does not have +`aria-hidden="true"` or `role="presentation"` attributes. Icon packages typically +provide a way to specify a title for the icon, as well as a way to specify that the +icon is not decorative. The title should be a short description of the purpose of +the trigger, rather than a description of the icon itself. + +For example: + +```python +icon_title = "Settings" +def bs_gear_icon(title: str): + # Enhanced from https://rstudio.github.io/bsicons/ via `bsicons::bs_icon("gear", title = icon_title)` + return ui.HTML(f'') + +ui.popover( + bs_gear_icon(icon_title), + title = icon_title, + ui.input_slider("n", "Number of points", 1, 100, 50) +) +``` + +```python +icon_title = "Settings" +def fa_gear_icon(title: str): + # Enhanced from https://rstudio.github.io/fontawesome/ via `fontawesome::fa("gear", a11y = "sem", title = icon_title)` + return ui.HTML(f'{title}') +ui.popover( + fa_gear_icon(icon_title), + title = icon_title, + ui.input_slider("n", "Number of points", 1, 100, 50) +) +``` + + + +## See Also + +* +* [](:func:`~shiny.ui.update_popover`) +* [](:func:`~shiny.ui.tooltip`) + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +from icons import gear_fill + +from shiny import App, Inputs, Outputs, Session, render, ui + +app_ui = ui.page_fluid( + ui.popover( + ui.input_action_button("btn", "A button", class_="mt-3"), + "A popover with more context and information than should be used in a tooltip.", + "You can even have multiple DOM elements in a popover!", + id="btn_popover", + ), + ui.hr(), + ui.card( + ui.card_header( + "Plot title (Click the gear to change variables)", + ui.popover( + ui.span( + gear_fill, + style="position:absolute; top: 5px; right: 7px;", + ), + "Put dropdowns here to alter your plot!", + ui.input_selectize("x", "X", ["x1", "x2", "x3"]), + ui.input_selectize("y", "Y", ["y1", "y2", "y3"]), + placement="right", + id="card_popover", + ), + ), + ui.output_text_verbatim("plot_txt", placeholder=True), + ), +) + + +def server(input: Inputs, output: Outputs, session: Session): + @render.text + def plot_txt(): + return f"" + + +app = App(app_ui, server=server) + +## file: icons.py +from shiny import ui + +# https://icons.getbootstrap.com/icons/gear-fill/ +gear_fill = ui.HTML( + '' +) + +``` + diff --git a/docs/api/ui.remove_accordion_panel.qmd b/docs/api/ui.remove_accordion_panel.qmd new file mode 100644 index 000000000..20d754c8f --- /dev/null +++ b/docs/api/ui.remove_accordion_panel.qmd @@ -0,0 +1,94 @@ +# ui.remove_accordion_panel { #shiny.ui.remove_accordion_panel } + +`ui.remove_accordion_panel(id, target, session=None)` + +Remove an [](:func:`~shiny.ui.accordion_panel`). + +## Parameters + +id: [str](`str`) + +: A string that matches an existing [](:func:`~shiny.ui.accordion`)'s `id`. + +target: [str](`str`) \| [list](`list`)\[[str](`str`)\] + +: The `value` of an existing panel to remove. + +session: [Optional](`typing.Optional`)\[[Session](`shiny.session.Session`)\] = None + +: A Shiny session object (the default should almost always be used). + +## References + +[Bootstrap Accordion](https://getbootstrap.com/docs/5.3/components/accordion/) + + + +## See Also + +* [](:func:`~shiny.ui.accordion`) +* [](:func:`~shiny.ui.accordion_panel`) +* [](:func:`~shiny.ui.update_accordion`) +* [](:func:`~shiny.ui.insert_accordion_panel`) +* [](:func:`~shiny.ui.update_accordion_panel`) + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +import random + +from shiny import App, Inputs, Outputs, Session, reactive, ui + + +def make_panel(letter: str) -> ui.AccordionPanel: + return ui.accordion_panel( + f"Section {letter}", f"Some narrative for section {letter}" + ) + + +items = [make_panel(letter) for letter in "ABCDE"] + +choices = ["A", "B", "C", "D", "E"] +random.shuffle(choices) + +app_ui = ui.page_fluid( + ui.input_action_button( + "remove_panel", + f"Remove Section {choices[-1]}", + class_="mt-3 mb-3", + ), + " (Sections randomly picked at server start)", + ui.accordion(*items, id="acc", multiple=True), +) + + +def server(input: Inputs, output: Outputs, session: Session): + # Copy the list for user + user_choices = [choice for choice in choices] + + @reactive.Effect + @reactive.event(input.remove_panel) + def _(): + if len(user_choices) == 0: + ui.notification_show("No more panels to remove!") + return + + # Remove panel + ui.remove_accordion_panel("acc", f"Section { user_choices.pop() }") + + label = "No more panels to remove!" + if len(user_choices) > 0: + label = f"Remove Section {user_choices[-1]}" + ui.update_action_button("remove_panel", label=label) + + +app = App(app_ui, server) + +``` + diff --git a/docs/api/ui.remove_ui.qmd b/docs/api/ui.remove_ui.qmd new file mode 100644 index 000000000..7d0b1f025 --- /dev/null +++ b/docs/api/ui.remove_ui.qmd @@ -0,0 +1,67 @@ +# ui.remove_ui { #shiny.ui.remove_ui } + +`ui.remove_ui(selector, multiple=False, immediate=False, session=None)` + +Remove UI objects. + +## Parameters + +selector: [str](`str`) + +: A string that is accepted by jQuery's selector (i.e. the string ``x`` to be + placed in a ``$(x)`` jQuery call), which determines the element(s) to remove. If + you want to remove a Shiny input or output, note that many of these are wrapped + in ``
``s, so you may need to use a somewhat complex selector — see the + Examples below. (Alternatively, you could also wrap the inputs/outputs that you + want to be able to remove easily in a ``
`` with an id.) + +multiple: [bool](`bool`) = False + +: In case your selector matches more than one element, ``multiple`` determines + whether Shiny should insert the UI object relative to all matched elements + or just relative to the first matched element (default). + +immediate: [bool](`bool`) = False + +: Whether the UI object should be immediately inserted or removed, or whether + Shiny should wait until all outputs have been updated and all effects have been + run (default). + +session: [Optional](`typing.Optional`)\[[Session](`shiny.session.Session`)\] = None + +: A [](:class:`~shiny.Session`) instance. If not provided, it is inferred via + [](:func:`~shiny.session.get_current_session`). + +## See Also + +[](:func:`~shiny.ui.insert_ui`) +[](:func:`~shiny.render.ui`) + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +from shiny import App, Inputs, Outputs, Session, reactive, ui + +app_ui = ui.page_fluid( + ui.input_action_button("rmv", "Remove UI"), + ui.input_text("txt", "Click button above to remove me"), +) + + +def server(input: Inputs, output: Outputs, session: Session): + @reactive.Effect + @reactive.event(input.rmv) + def _(): + ui.remove_ui(selector="div:has(> #txt)") + + +app = App(app_ui, server) + +``` + diff --git a/docs/api/ui.row.qmd b/docs/api/ui.row.qmd new file mode 100644 index 000000000..4dd5dd4a8 --- /dev/null +++ b/docs/api/ui.row.qmd @@ -0,0 +1,71 @@ +# ui.row { #shiny.ui.row } + +`ui.row(*args, **kwargs)` + +Responsive row-column based layout + +Layout UI components using Bootstrap's grid layout system. Use ``row()`` to group +elements that should appear on the same line (if the browser has adequate width) and +[](:func:`~shiny.ui.column`) to define how much horizontal space within a 12-unit wide +grid each on of these elements should occupy. See the [layout +guide](https://shiny.posit.co/articles/layout-guide.html) for more context and +examples. +(The article is about Shiny for R, but the general principles are the same.) + +## Parameters + +*args: [TagChild](`htmltools.TagChild`) \| [TagAttrs](`htmltools.TagAttrs`) = () + +: Any number of child elements. + +**kwargs: [TagAttrValue](`htmltools.TagAttrValue`) = {} + +: Attributes to place on the row tag. + +## Returns + +| Type | Description | +|------------------------|---------------| +| [Tag](`htmltools.Tag`) | A UI element. | + +## See Also + +[](:func:`~shiny.ui.column`) + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +import matplotlib.pyplot as plt +import numpy as np + +from shiny import App, Inputs, Outputs, Session, render, ui + +app_ui = ui.page_fluid( + ui.row( + ui.column(4, ui.input_slider("n", "N", min=0, max=100, value=20)), + ui.column(8, ui.output_plot("plot")), + ) +) + + +def server(input: Inputs, output: Outputs, session: Session): + @render.plot(alt="A histogram") + def plot() -> object: + np.random.seed(19680801) + x = 100 + 15 * np.random.randn(437) + + fig, ax = plt.subplots() + ax.hist(x, input.n(), density=True) + return fig + + +app = App(app_ui, server) + +``` + diff --git a/docs/api/ui.showcase_bottom.qmd b/docs/api/ui.showcase_bottom.qmd new file mode 100644 index 000000000..c6adbfb67 --- /dev/null +++ b/docs/api/ui.showcase_bottom.qmd @@ -0,0 +1,83 @@ +# ui.showcase_bottom { #shiny.ui.showcase_bottom } + +`ui.showcase_bottom(width='100%', width_full_screen=None, height='auto', height_full_screen='2fr', max_height='100px', max_height_full_screen=None)` + +Showcase bottom + +A [](:func:`~shiny.ui.showcase_bottom`) is a [](:class:`~shiny.ui.ShowcaseLayout`) with +the following default properties: + +* `width` is `"100%"` +* `width_full_screen` is `None` +* `height` is `"auto"` +* `height_full_screen` is `"2fr"` +* `max_height` is `"100px"` +* `max_height_full_screen` is `None` + + + +## See Also + +* [](:func:`~shiny.ui.showcase_left_center`) +* [](:func:`~shiny.ui.showcase_top_right`) +* [](:func:`~shiny.ui.value_box`) + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +from icons import arrow_up, piggy_bank + +from shiny import App, ui + +app_ui = ui.page_fluid( + ui.layout_column_wrap( + ui.value_box( + "KPI Title", + ui.h1(ui.HTML("$1 Billion Dollars")), + ui.span(arrow_up, " 30% VS PREVIOUS 30 DAYS"), + showcase=piggy_bank, + theme="bg-gradient-orange-cyan", + full_screen=True, + ), + ui.value_box( + "KPI Title", + ui.h1(ui.HTML("$1 Billion Dollars")), + ui.span(arrow_up, " 30% VS PREVIOUS 30 DAYS"), + showcase=piggy_bank, + theme="text-green", + showcase_layout="top right", + full_screen=True, + ), + ui.value_box( + "KPI Title", + ui.h1(ui.HTML("$1 Billion Dollars")), + ui.span(arrow_up, " 30% VS PREVIOUS 30 DAYS"), + showcase=piggy_bank, + theme="purple", + showcase_layout="bottom", + full_screen=True, + ), + ) +) + + +app = App(app_ui, server=None) + +## file: icons.py +from shiny import ui + +piggy_bank = ui.HTML( + '' +) +arrow_up = ui.HTML( + '' +) + +``` + diff --git a/docs/api/ui.showcase_left_center.qmd b/docs/api/ui.showcase_left_center.qmd new file mode 100644 index 000000000..ceac70196 --- /dev/null +++ b/docs/api/ui.showcase_left_center.qmd @@ -0,0 +1,81 @@ +# ui.showcase_left_center { #shiny.ui.showcase_left_center } + +`ui.showcase_left_center(width='30%', width_full_screen='1fr', max_height='100px', max_height_full_screen='67%')` + +Showcase left center + +A [](:func:`~shiny.ui.showcase_left_center`) is a [](:class:`~shiny.ui.ShowcaseLayout`) with +the following default properties: + +* `width` is `"30%"` +* `width_full_screen` is `"1fr"` +* `max_height` is `"100px"` +* `max_height_full_screen` is `"67%"` + + + +## See Also + +* [](:func:`~shiny.ui.showcase_top_right`) +* [](:func:`~shiny.ui.showcase_bottom`) +* [](:func:`~shiny.ui.value_box`) + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +from icons import arrow_up, piggy_bank + +from shiny import App, ui + +app_ui = ui.page_fluid( + ui.layout_column_wrap( + ui.value_box( + "KPI Title", + ui.h1(ui.HTML("$1 Billion Dollars")), + ui.span(arrow_up, " 30% VS PREVIOUS 30 DAYS"), + showcase=piggy_bank, + theme="bg-gradient-orange-cyan", + full_screen=True, + ), + ui.value_box( + "KPI Title", + ui.h1(ui.HTML("$1 Billion Dollars")), + ui.span(arrow_up, " 30% VS PREVIOUS 30 DAYS"), + showcase=piggy_bank, + theme="text-green", + showcase_layout="top right", + full_screen=True, + ), + ui.value_box( + "KPI Title", + ui.h1(ui.HTML("$1 Billion Dollars")), + ui.span(arrow_up, " 30% VS PREVIOUS 30 DAYS"), + showcase=piggy_bank, + theme="purple", + showcase_layout="bottom", + full_screen=True, + ), + ) +) + + +app = App(app_ui, server=None) + +## file: icons.py +from shiny import ui + +piggy_bank = ui.HTML( + '' +) +arrow_up = ui.HTML( + '' +) + +``` + diff --git a/docs/api/ui.showcase_top_right.qmd b/docs/api/ui.showcase_top_right.qmd new file mode 100644 index 000000000..f3ef54a62 --- /dev/null +++ b/docs/api/ui.showcase_top_right.qmd @@ -0,0 +1,81 @@ +# ui.showcase_top_right { #shiny.ui.showcase_top_right } + +`ui.showcase_top_right(width='40%', width_full_screen='1fr', max_height='75px', max_height_full_screen='67%')` + +Showcase top right + +A [](:func:`~shiny.ui.showcase_top_right`) is a [](:class:`~shiny.ui.ShowcaseLayout`) with +the following default properties: + +* `width` is `"40%"` +* `width_full_screen` is `"1fr"` +* `max_height` is `"75px"` +* `max_height_full_screen` is `"67%"` + + + +## See Also + +* [](:func:`~shiny.ui.showcase_left_center`) +* [](:func:`~shiny.ui.showcase_bottom`) +* [](:func:`~shiny.ui.value_box`) + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +from icons import arrow_up, piggy_bank + +from shiny import App, ui + +app_ui = ui.page_fluid( + ui.layout_column_wrap( + ui.value_box( + "KPI Title", + ui.h1(ui.HTML("$1 Billion Dollars")), + ui.span(arrow_up, " 30% VS PREVIOUS 30 DAYS"), + showcase=piggy_bank, + theme="bg-gradient-orange-cyan", + full_screen=True, + ), + ui.value_box( + "KPI Title", + ui.h1(ui.HTML("$1 Billion Dollars")), + ui.span(arrow_up, " 30% VS PREVIOUS 30 DAYS"), + showcase=piggy_bank, + theme="text-green", + showcase_layout="top right", + full_screen=True, + ), + ui.value_box( + "KPI Title", + ui.h1(ui.HTML("$1 Billion Dollars")), + ui.span(arrow_up, " 30% VS PREVIOUS 30 DAYS"), + showcase=piggy_bank, + theme="purple", + showcase_layout="bottom", + full_screen=True, + ), + ) +) + + +app = App(app_ui, server=None) + +## file: icons.py +from shiny import ui + +piggy_bank = ui.HTML( + '' +) +arrow_up = ui.HTML( + '' +) + +``` + diff --git a/docs/api/ui.sidebar.qmd b/docs/api/ui.sidebar.qmd new file mode 100644 index 000000000..f031a1335 --- /dev/null +++ b/docs/api/ui.sidebar.qmd @@ -0,0 +1,164 @@ +# ui.sidebar { #shiny.ui.sidebar } + +`ui.sidebar(*args, width=250, position='left', open='desktop', id=None, title=None, bg=None, fg=None, class_=None, max_height_mobile=None, gap=None, padding=None)` + +Sidebar element + +Create a collapsing sidebar layout by providing a `sidebar()` object to the +`sidebar=` argument of: + +* [](:func:`~shiny.ui.layout_sidebar`) + * Creates a sidebar layout component which can be dropped inside any Shiny UI page method (e.g. [](:func:`~shiny.ui.page_fillable`)) or [](:func:`~shiny.ui.card`) context. +* [](:func:`~shiny.ui.navset_bar`), [](:func:`~shiny.ui.navset_card_tab`), and [](:func:`~shiny.ui.navset_card_pill`) + * Creates a multi page/tab UI with a singular `sidebar()` (which is + shown on every page/tab). + +## Parameters + +*args: [TagChild](`htmltools.TagChild`) \| [TagAttrs](`htmltools.TagAttrs`) = () + +: Contents to the sidebar. Or tag attributes that are supplied to the + resolved [](:class:`~htmltools.Tag`) object. + +width: [CssUnit](`shiny.ui.css.CssUnit`) = 250 + +: A valid CSS unit used for the width of the sidebar. + +position: [Literal](`typing.Literal`)\['left', 'right'\] = 'left' + +: Where the sidebar should appear relative to the main content. + +open: [Literal](`typing.Literal`)\['desktop', 'open', 'closed', 'always'\] = 'desktop' + +: The initial state of the sidebar. + + * `"desktop"`: the sidebar starts open on desktop screen, closed on mobile + * `"open"` or `True`: the sidebar starts open + * `"closed"` or `False`: the sidebar starts closed + * `"always"` or `None`: the sidebar is always open and cannot be closed + + In [](:func:`~shiny.ui.update_sidebar`), `open` indicates the desired state of the + sidebar. Note that [](:func:`~shiny.ui.update_sidebar`) can only open or close the + sidebar, so it does not support the `"desktop"` and `"always"` options. + +id: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: A character string. Required if wanting to re-actively read (or update) the + `collapsible` state in a Shiny app. + +title: [TagChild](`htmltools.TagChild`) \| [str](`str`) = None + +: A character title to be used as the sidebar title, which will be wrapped in a + `
` element with class `sidebar-title`. You can also provide a custom + [](:class:`~htmltools.Tag`) for the title element, in which case you'll + likely want to give this element `class = "sidebar-title"`. + +bg: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: A background or foreground color. + +class_: [Optional](`typing.Optional`)\[[str](`str`)\] = None + +: CSS classes for the sidebar container element, in addition to the fixed + `.sidebar` class. + +max_height_mobile: [Optional](`typing.Optional`)\[[str](`str`) \| [float](`float`)\] = None + +: A CSS length unit (passed through [](:func:`~shiny.ui.css.as_css_unit`)) defining + the maximum height of the horizontal sidebar when viewed on mobile devices. Only + applies to always-open sidebars that use `open = "always"`, where by default the + sidebar container is placed below the main content container on mobile devices. + +gap: [Optional](`typing.Optional`)\[[CssUnit](`shiny.ui.css.CssUnit`)\] = None + +: A CSS length unit defining the vertical `gap` (i.e., spacing) between elements + provided to `*args`. + +padding: [Optional](`typing.Optional`)\[[CssUnit](`shiny.ui.css.CssUnit`) \| [list](`list`)\[[CssUnit](`shiny.ui.css.CssUnit`)\]\] = None + +: Padding within the sidebar itself. This can be a numeric vector (which will be + interpreted as pixels) or a character vector with valid CSS lengths. `padding` + may be one to four values. + + * If a single value, then that value will be used for all four sides. + * If two, then the first value will be used for the top and bottom, while + the second value will be used for left and right. + * If three values, then the first will be used for top, the second will be left + and right, and the third will be bottom. + * If four, then the values will be interpreted as top, right, bottom, and left + respectively. + +## Returns + +| Type | Description | +|----------------------------------------|--------------------------------------| +| [Sidebar](`shiny.ui._sidebar.Sidebar`) | A [](:class:`~shiny.ui.Sidebar`) object. | + +## See Also + +* [](:func:`~shiny.ui.layout_sidebar`) +* [](:func:`~shiny.ui.navset_bar`) +* [](:func:`~shiny.ui.navset_card_tab`) +* [](:func:`~shiny.ui.navset_card_pill`) + +## Examples + + +```{shinylive-python} +#| standalone: true +#| components: [editor, viewer] +#| layout: vertical +#| viewerHeight: 400 +## file: app.py +from shiny import App, Inputs, Outputs, Session, render, ui + +app_ui = ui.page_fluid( + ui.card( + ui.layout_sidebar( + ui.sidebar("Left sidebar content", id="sidebar_left"), + ui.output_text_verbatim("state_left"), + ) + ), + ui.card( + ui.layout_sidebar( + ui.sidebar("Right sidebar content", id="sidebar_right", position="right"), + ui.output_text_verbatim("state_right"), + ), + ), + ui.card( + ui.layout_sidebar( + ui.sidebar("Closed sidebar content", id="sidebar_closed", open="closed"), + ui.output_text_verbatim("state_closed"), + ) + ), + ui.card( + ui.layout_sidebar( + ui.sidebar("Always sidebar content", id="sidebar_always", open="always"), + ui.output_text_verbatim("state_always"), + ) + ), +) + + +def server(input: Inputs, output: Outputs, session: Session): + @render.text + def state_left(): + return f"input.sidebar_left(): {input.sidebar_left()}" + + @render.text + def state_right(): + return f"input.sidebar_right(): {input.sidebar_right()}" + + @render.text + def state_closed(): + return f"input.sidebar_closed(): {input.sidebar_closed()}" + + @render.text + def state_always(): + return f"input.sidebar_always(): {input.sidebar_always()}" + + +app = App(app_ui, server) + +``` + diff --git a/docs/api/ui.tags.qmd b/docs/api/ui.tags.qmd new file mode 100644 index 000000000..9ba8846dc --- /dev/null +++ b/docs/api/ui.tags.qmd @@ -0,0 +1,3819 @@ +# ui.tags { #shiny.ui.tags } + +`ui.tags` + +Functions for creating HTML tags. + +## Functions + +| Name | Description | +| --- | --- | +| [a](#shiny.ui.tags.a) | Create a tag. The HTML element (or anchor element), with its href attribute, creates a hyperlink to web pages, files, email addresses, locations in the same page, or anything else a URL can address. Learn more at https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a | +| [abbr](#shiny.ui.tags.abbr) | Create a tag. The HTML element represents an abbreviation or acronym; the optional title attribute can provide an expansion or description for the abbreviation. If present, title must contain this full description and nothing else. Learn more at https://developer.mozilla.org/en-US/docs/Web/HTML/Element/abbr | +| [address](#shiny.ui.tags.address) | Create a
tag. The
HTML element indicates that the enclosed HTML provides contact information for a person or people, or for an organization. Learn more at https://developer.mozilla.org/en-US/docs/Web/HTML/Element/address | +| [area](#shiny.ui.tags.area) | Create a tag. The HTML element defines an area inside an image map that has predefined clickable areas. An image map allows geometric areas on an image to be associated with Hyperlink. Learn more at https://developer.mozilla.org/en-US/docs/Web/HTML/Element/area | +| [article](#shiny.ui.tags.article) | Create a
tag. The
HTML element represents a self-contained composition in a document, page, application, or site, which is intended to be independently distributable or reusable (e.g., in syndication). Examples include: a forum post, a magazine or newspaper article, or a blog entry, a product card, a user-submitted comment, an interactive widget or gadget, or any other independent item of content. Learn more at https://developer.mozilla.org/en-US/docs/Web/HTML/Element/article | +| [aside](#shiny.ui.tags.aside) | Create a