Buttons give people a way to trigger an action. They’re typically found in forms, dialog panels, and dialogs. Some buttons are specialized for particular tasks, such as navigation, repeated actions, or presenting menus.
For more details and examples visit the official docs. The R package cannot handle each and every case, so for advanced use cases you need to work using the original docs to achieve the desired result.
Usage
ActionButton(...)
CommandBarButton(...)
CommandButton(...)
CompoundButton(...)
DefaultButton(...)
IconButton(...)
PrimaryButton(...)
ActionButton.shinyInput(inputId, ...)
updateActionButton.shinyInput(
session = shiny::getDefaultReactiveDomain(),
inputId,
...
)
CommandBarButton.shinyInput(inputId, ...)
updateCommandBarButton.shinyInput(
session = shiny::getDefaultReactiveDomain(),
inputId,
...
)
CommandButton.shinyInput(inputId, ...)
updateCommandButton.shinyInput(
session = shiny::getDefaultReactiveDomain(),
inputId,
...
)
CompoundButton.shinyInput(inputId, ...)
updateCompoundButton.shinyInput(
session = shiny::getDefaultReactiveDomain(),
inputId,
...
)
DefaultButton.shinyInput(inputId, ...)
updateDefaultButton.shinyInput(
session = shiny::getDefaultReactiveDomain(),
inputId,
...
)
IconButton.shinyInput(inputId, ...)
updateIconButton.shinyInput(
session = shiny::getDefaultReactiveDomain(),
inputId,
...
)
PrimaryButton.shinyInput(inputId, ...)
updatePrimaryButton.shinyInput(
session = shiny::getDefaultReactiveDomain(),
inputId,
...
)
Arguments
- ...
Props to pass to the component. The allowed props are listed below in the Details section.
- inputId
ID of the component.
- session
Object passed as the
session
argument to Shiny server.
Value
Object with shiny.tag
class suitable for use in the UI of a Shiny app.
The update functions return nothing (called for side effects).
Details
baseClassName
string
variantClassName
string
allowDisabledFocus
boolean
Whether the button can have focus in disabled modeariaDescription
string
Detailed description of the button for the benefit of screen readers.
Besides the compound button, other button types will need more information provided to screen reader.
ariaHidden
boolean
If provided and is true it adds an 'aria-hidden' attribute instructing screen readers to ignore the element.ariaLabel
string
The aria label of the button for the benefit of screen readers.buttonType
ButtonType
Deprecated at v1.2.3, to be removed at \>= v2.0.0. Use specific button component instead.checked
boolean
Whether the button is checkedclassName
string
If provided, additional class name to provide on the root element.componentRef
IRefObject<IButton>
Optional callback to access the IButton interface. Use this instead of ref for accessing the public methods and properties of the component.data
any
Any custom data the developer wishes to associate with the menu item.defaultRender
any
yet unknown docsdescription
IStyle
Style for the description text if applicable (for compound buttons.) Deprecated, usesecondaryText
instead.disabled
boolean
Whether the button is disabledgetClassNames
(theme: ITheme, className: string, variantClassName: string, iconClassName: string | undefined, menuIconClassName: string | undefined, disabled: boolean, checked: boolean, expanded: boolean, hasMenu: boolean, isSplit: boolean | undefined, allowDisabledFocus: boolean) => IButtonClassNames
Method to provide the classnames to style a button. The default value for this prop is the getClassnames func defined in BaseButton.classnames.getSplitButtonClassNames
(disabled: boolean, expanded: boolean, checked: boolean, allowDisabledFocus: boolean) => ISplitButtonClassNames
Method to provide the classnames to style a button. The default value for this prop is the getClassnames func defined in BaseButton.classnames.href
string
If provided, this component will be rendered as an anchor.iconProps
IIconProps
The props for the icon shown in the button.keytipProps
IKeytipProps
Optional keytip for this buttonmenuAs
IComponentAs<IContextualMenuProps>
Render a custom menu in place of the normal one.menuIconProps
IIconProps
The props for the icon shown when providing a menu dropdown.menuProps
IContextualMenuProps
Props for button menu. Providing this will default to showing the menu icon. See menuIconProps for overriding how the default icon looks. Providing this in addition of onClick and setting the split property to true will render a SplitButton.menuTriggerKeyCode
KeyCodes | null
Provides a custom KeyCode that can be used to open the button menu. The default KeyCode is the down arrow. A value of null can be provided to disable the key codes for opening the button menu.onAfterMenuDismiss
() => void
Callback that runs after Button's contextualmenu was closed (removed from the DOM)onMenuClick
(ev?: React.MouseEvent<HTMLElement> | React.KeyboardEvent<HTMLElement>, button?: IButtonProps) => void
Optional callback when menu is clicked.onRenderAriaDescription
IRenderFunction<IButtonProps>
Custom render function for the aria description element.onRenderChildren
IRenderFunction<IButtonProps>
Custom render function for rendering the button children.onRenderDescription
IRenderFunction<IButtonProps>
Custom render function for the desciption text.onRenderIcon
IRenderFunction<IButtonProps>
Custom render function for the icononRenderMenu
IRenderFunction<IContextualMenuProps>
Deprecated at v6.3.2, to be removed at \>= v7.0.0. UsemenuAs
instead.onRenderMenuIcon
IRenderFunction<IButtonProps>
Custom render function for button menu icononRenderText
IRenderFunction<IButtonProps>
Custom render function for the label text.persistMenu
boolean
Menu will not be created or destroyed when opened or closed, instead it will be hidden. This will improve perf of the menu opening but could potentially impact overall perf by having more elements in the dom. Should only be used when perf is important. Note: This may increase the amount of time it takes for the button itself to mount.primary
boolean
Changes the visual presentation of the button to be emphasized (if defined)primaryActionButtonProps
IButtonProps
Optional props to be applied only to the primary action button of SplitButton and not to the overall SplitButton containerprimaryDisabled
boolean
If set to true and if this is a splitButton (split == true) then the primary action of a split button is disabled.renderPersistedMenuHiddenOnMount
boolean
If true, the persisted menu is rendered hidden when the button initially mounts. Non-persisted menus will not be in the component tree unless they are being shown
Note: This increases the time the button will take to mount, but can improve perceived menu open perf. when the user opens the menu.
rootProps
React.ButtonHTMLAttributes<HTMLButtonElement> | React.AnchorHTMLAttributes<HTMLAnchorElement>
Deprecated at v0.56.2, to be removed at \>= v1.0.0. Just pass in button props instead. they will be mixed into the button/anchor element rendered by the component.secondaryText
string
Description of the action this button takes. Only used for compound buttonssplit
boolean
If set to true, and if menuProps and onClick are provided, the button will render as a SplitButton.splitButtonAriaLabel
string
Accessible label for the dropdown chevron button if this button is split.splitButtonMenuProps
IButtonProps
Experimental prop that get passed into the menuButton that's rendered as part of split button. Anything passed in will likely need to have accompanying style changes.styles
IButtonStyles
Custom styling for individual elements within the button DOM.text
string
Text to render button label. If text is supplied, it will override any string in button children. Other children components will be passed through after the text.theme
ITheme
Theme provided by HOC.toggle
boolean
Whether button is a toggle button with distinct on and off states. This should be true for buttons that permanently change state when a press event finishes, such as a volume mute button.toggled
boolean
Any custom data the developer wishes to associate with the menu item. Deprecated, usechecked
if setting state.uniqueId
string | number
Unique id to identify the item. Typically a duplicate of key value.
Best practices
Layout
For dialog boxes and panels, where people are moving through a sequence of screens, right-align buttons with the container.
For single-page forms and focused tasks, left-align buttons with the container.
Always place the primary button on the left, the secondary button just to the right of it.
Show only one primary button that inherits theme color at rest state. If there are more than two buttons with equal priority, all buttons should have neutral backgrounds.
Don't use a button to navigate to another place; use a link instead. The exception is in a wizard where "Back" and "Next" buttons may be used.
Don't place the default focus on a button that destroys data. Instead, place the default focus on the button that performs the "safe act" and retains the content (such as "Save") or cancels the action (such as "Cancel").
Content
Use sentence-style capitalization—only capitalize the first word. For more info, see Capitalization in the Microsoft Writing Style Guide.
Make sure it's clear what will happen when people interact with the button. Be concise; usually a single verb is best. Include a noun if there is any room for interpretation about what the verb means. For example, "Delete folder" or "Create account".
Examples
# Example 1
library(shiny)
library(shiny.fluent)
tokens <- list(childrenGap = 20)
ui <- function(id) {
ns <- NS(id)
tags$div(
Stack(
DefaultButton.shinyInput(
ns("button1"),
text = "Default Button",
styles = list("background: green")
),
PrimaryButton.shinyInput(
ns("button2"),
text = "Primary Button"
),
CompoundButton.shinyInput(
ns("button3"),
secondaryText = "Compound Button has additional text",
text = "Compound Button"
),
ActionButton.shinyInput(
ns("button4"),
iconProps = list("iconName" = "AddFriend"),
text = "Action Button"
),
horizontal = TRUE,
tokens = tokens
),
textOutput(ns("text"))
)
}
server <- function(id) {
moduleServer(id, function(input, output, session) {
clicks <- reactiveVal(0)
addClick <- function() { clicks(isolate(clicks() + 1)) }
observeEvent(input$button0, addClick())
observeEvent(input$button1, addClick())
observeEvent(input$button2, addClick())
observeEvent(input$button3, addClick())
observeEvent(input$button4, addClick())
output$text <- renderText({
paste0("Clicks:", clicks())
})
})
}
if (interactive()) {
shinyApp(ui("app"), function(input, output) server("app"))
}
# Example 2
library(shiny)
library(shiny.fluent)
# Split button with menu
menuProps <- list(
items = list(
list(
key = "emailMessage",
text = "Email message",
onClick = JS("() => alert('Email message clicked')"),
iconProps = list(
iconName = "Mail"
)
),
list(
key = "calendarEvent",
text = "Calendar event",
onClick = JS("() => alert('Calendar event clicked')"),
iconProps = list(
iconName = "Calendar"
)
)
)
)
ui <- function(id) {
ns <- NS(id)
fluentPage(
Stack(
horizontal = TRUE,
wrap = TRUE,
tokens = list(
childrenGap = 40
),
DefaultButton.shinyInput(
inputId = ns("button_1"),
text = "Standard",
primary = FALSE,
split = TRUE,
splitButtonAriaLabel = "See 2 options",
`aria-roledescription` = "split button",
menuProps = menuProps,
disabled = FALSE,
checked = FALSE
),
DefaultButton.shinyInput(
inputId = ns("button_2"),
text = "Primary",
primary = TRUE,
split = TRUE,
splitButtonAriaLabel = "See 2 options",
`aria-roledescription` = "split button",
menuProps = menuProps,
disabled = FALSE,
checked = FALSE
),
DefaultButton.shinyInput(
inputId = ns("button_3"),
text = "Main action disabled",
primaryDisabled = NA,
split = TRUE,
splitButtonAriaLabel = "See 2 options",
`aria-roledescription` = "split button",
menuProps = menuProps,
checked = FALSE
),
DefaultButton.shinyInput(
inputId = ns("button_4"),
text = "Disabled",
disabled = TRUE,
split = TRUE,
splitButtonAriaLabel = "See 2 options",
`aria-roledescription` = "split button",
menuProps = menuProps,
checked = FALSE
)
),
uiOutput(ns("text"))
)
}
server <- function(id) {
moduleServer(id, function(input, output, session) {
output$text <- renderUI({
lapply(seq_len(4), function(i) {
paste0("button_", i, ": ", input[[paste0("button_", i)]])
})
})
})
}
if (interactive()) {
shinyApp(ui("app"), function(input, output) server("app"))
}
# Example 3
library(shiny)
library(shiny.fluent)
library(shinyjs)
#>
#> Attaching package: ‘shinyjs’
#> The following object is masked from ‘package:shiny’:
#>
#> runExample
#> The following object is masked from ‘package:shiny.fluent’:
#>
#> runExample
#> The following objects are masked from ‘package:methods’:
#>
#> removeClass, show
# This example app shows how to use a Fluent UI Button to trigger a file upload.
# File upload is not natively supported by shiny.fluent so shinyjs is used
# to trigger the file upload input.
ui <- function(id) {
ns <- NS(id)
fluentPage(
useShinyjs(),
Stack(
tokens = list(
childrenGap = 10L
),
horizontal = TRUE,
DefaultButton.shinyInput(
inputId = ns("uploadFileButton"),
text = "Upload File",
iconProps = list(iconName = "Upload")
),
div(
style = "
visibility: hidden;
height: 0;
width: 0;
",
fileInput(
inputId = ns("uploadFile"),
label = NULL
)
)
),
textOutput(ns("file_path"))
)
}
server <- function(id) {
moduleServer(id, function(input, output, session) {
observeEvent(input$uploadFileButton, {
click("uploadFile")
})
output$file_path <- renderText({
input$uploadFile$name
})
})
}
if (interactive()) {
shinyApp(ui("app"), function(input, output) server("app"))
}
# Example 4
library(shiny)
library(shiny.fluent)
library(shinyjs)
# This example app shows how to use a Fluent UI Button to trigger a file download.
# File download is not natively supported by shiny.fluent so shinyjs is used
# to trigger the file download.
ui <- function(id) {
ns <- NS(id)
fluentPage(
useShinyjs(),
DefaultButton.shinyInput(
inputId = ns("downloadButton"),
text = "Download",
iconProps = list(iconName = "Download")
),
div(
style = "visibility: hidden;",
downloadButton(ns("download"), label = "")
)
)
}
server <- function(id) {
moduleServer(id, function(input, output, session) {
observeEvent(input$downloadButton, {
click("download")
})
output$download <- downloadHandler(
filename = function() {
paste("data-", Sys.Date(), ".csv", sep="")
},
content = function(file) {
write.csv(iris, file)
}
)
})
}
if (interactive()) {
shinyApp(ui("app"), function(input, output) server("app"))
}