Input R Shiny: Shiny Input Examples with shiny.fluent
Creating a beautiful, professional, and user-approved UI plays a vital role in the success of any project. Applications developed using Shiny are no exception. The Shiny package comes with its own <a href="https://shiny.rstudio.com/gallery/widget-gallery.html" target="_blank" rel="noopener">collection of inputs</a> available for the user interface. But sometimes you need a little extra. A dash of the familiar to give your app that little push towards perfection. Luckily, Appsilon has created <a href="https://shiny.tools/" target="_blank" rel="noopener">several packages</a> to extend the look and functionalities of inputs in Shiny applications.
<blockquote>Want to build an elegant dashboard? See how with our <a href="https://appsilon.com/shiny-fluent-tutorial/" target="_blank" rel="noopener">shiny.fluent tutorial</a>.</blockquote>
In this article, we’ll explore one such package - <a href="https://appsilon.github.io/shiny.fluent/" target="_blank" rel="noopener">shiny.fluent</a>. We’ll cover what makes it exceptional and input examples, showcasing some of the inputs with code.
<ul><li style="list-style-type: none;"><ul><li><a href="#combobox">ComboBox</a></li><li><a href="#datepicker">DatePicker</a></li><li><a href="#doccard">DocumentCard</a></li><li><a href="#detaillist">DetailsList</a></li><li><a href="#stack">Stack</a></li><li><a href="#checkbox">Checkbox</a></li><li><a href="#nav">Nav Input</a></li></ul>
</li>
</ul>
<hr />
<h2><b>Introducing shiny.fluent package </b></h2>
Shiny.fluent is a package that opens up a rich set of easy-to-use components that are familiar to your users. It allows you to build Shiny apps using <a href="https://developer.microsoft.com/en-us/fluentui#/controls/web" target="_blank" rel="noopener">Microsoft’s Fluent UI</a> which is built in React, a javascript library. This is possible because shiny.fluent is based on another Appsilon package called <a href="https://github.com/Appsilon/shiny.react" target="_blank" rel="noopener">shiny.react</a>. This package makes it easy to port React libraries in Shiny apps development.
<blockquote>Want to try out a Fomantic (Semantic) UI wrapper for Shiny? Watch our <a href="https://www.youtube.com/watch?v=LRTK3Q0pb9c" target="_blank" rel="noopener">guide to shiny.semantic</a>.</blockquote>
<h2><b>Why use shiny.fluent for R Shiny inputs</b></h2>
Let’s take a look at some unique features of shiny.fluent controls that set it apart from traditional Shiny package controls.
<h3><b>Ease of use for input control</b></h3>
The easy-to-use controls that come with shiny.fluent make it widely accepted by Shiny developers. The complexity of working with React components in Shiny applications is taken care of by shiny.react - the bridge that opens up access to libraries like Fluent UI with professional and intuitive building blocks.
<img class="alignnone size-full wp-image-14490" src="https://webflow-prod-assets.s3.amazonaws.com/6525256482c9e9a06c7a9d3c%2F65b01dcbaebaad0dba422847_image-1-shiny-react-calendar-input.webp" alt="image 1 - shiny react calendar input" width="1418" height="600" />
<h3><b>Simple and uniform R Shiny input styling</b></h3>
Working with controls in the shiny.fluent package is quite simple. If you have experience working with traditional Shiny controls you’ll notice that it conforms as expected.
<img class="alignnone size-full wp-image-14492" src="https://webflow-prod-assets.s3.amazonaws.com/6525256482c9e9a06c7a9d3c%2F65b01dcc2c0171ee6e5c1cbe_image-2-simplicity-and-uniformity-r-shiny-inputs.webp" alt="image 2 - simplicity and uniformity r shiny inputs" width="1600" height="592" />
<h3><b>User accepted inputs in Shiny apps</b></h3>
<b></b>Shiny.fluent gives your users a professional-looking interface that is readily accepted because it’s familiar. Why reinvent the wheel, when you can use the collective work of Microsoft’s Fluent UI? The look and feel of Shiny applications created using shiny.fluent is straightforward and appealing to end-users because Fluent UI was designed to build cohesive experiences.
<h3><b>Reduced development time for inputs in Shiny</b></h3>
<b></b>For product owners, shiny.fluent provides a fast speed of development for development teams. Ultimately, this leads to reduced time getting to market. Incorporating shiny.fluent in your project makes it easy with so many <a href="https://templates.appsilon.com/" target="_blank" rel="noopener">readily available templates</a> and examples provided by Appsilon. Explore the <a href="https://appsilon.github.io/shiny.fluent/articles/shiny-fluent.html">tutorials</a> to speed up the learning pace for adoption and understanding of the package.
<blockquote>Want to create a Shiny app like a full-stack software engineer? <a href="https://appsilon.github.io/rhino/" target="_blank" rel="noopener">Build high-quality, enterprise-grade Shiny apps quickly with Appsilon's Rhino</a>.</blockquote>
<h2><b>Examples of Shiny inputs in shiny.fluent</b></h2>
Let’s take a look at some of the input controls available in the shiny.fluent package. We’ll demonstrate each input with simple code samples to get you started.
Before we get started, you'll want to install a few packages. You can install the latest development versions on Github via {remotes}:
<pre>remotes::install_github("Appsilon/shiny.react")
remotes::install_github("Appsilon/shiny.fluent")
devtools::install_github("tidyverse/tidyverse")
remotes::install_github("plotly/plotly")
remotes::install_github("allisonhorst/palmerpenguins")</pre>
<h3 id="combobox"><b>ComboBox Input</b></h3>
ComboBox is handy when you need a functionality that gives users the power to type in text or select from dropdown options. A combo box (ComboBox) combines a text field and a drop-down menu, giving people a way to select an option from a list or enter their own choice. It also gives users suggestions based on the list of values or types in a new text. Let’s see how to get this done using the ComboBox in shiny.fluent:
<img class="alignnone size-full wp-image-14494" src="https://webflow-prod-assets.s3.amazonaws.com/6525256482c9e9a06c7a9d3c%2F65b01dcdec1e575073de65d4_image-3-shinyfluent-combobox-input.webp" alt="image 3 - shinyfluent combobox input" width="1524" height="494" />
Try typing one of the penguins’ names.
<img class="alignnone size-full wp-image-14496" src="https://webflow-prod-assets.s3.amazonaws.com/6525256482c9e9a06c7a9d3c%2F65b01dce48b83fcd2e54dc20_image-4-combox-input-name.webp" alt="image 4 - combobox input name" width="1507" height="681" />
Check out the codes below:
<pre>library(shiny)
library(shiny.fluent)
library(tidyverse)
library(palmerpenguins)
library(plotly)
penguins_options <- list(
list(key = "Adelie", text = "Adelie"),
list(key = "Chinstrap", text = "Chinstrap"),
list(key = "Gentoo", text = "Gentoo")
)
shinyApp(
ui = fluentPage(
tags$style('
body {
background-color: #379be6;
}
div{
background-color: white;
color: #f8f8f8;
border-radius: 5px;
margin: 0px;
padding: 5px;
}'
),
div(
Text(
variant = "xLarge",
"Examples Using shiny.fluent ComboBox input",
block = TRUE
),
Separator(),
Text(
variant = "large",
"Select your favorite penguin",
block = TRUE
),
tags$br(),
ComboBox.shinyInput(
"combo",
value = list(text = "add some text or select"),
options = penguins_options,
allowFreeform = TRUE
),
textOutput("comboValue")
)
),
server = function(input, output) {
output$comboValue <- renderText({
sprintf("Value: %s", input$combo$text)
})
}
)
</pre>
<h3 id="datepicker"><b>DatePicker Input</b></h3>
The DatePicker is another interesting input control in the shiny.fluent package. It allows users to select a date value in terms of the day, month, and year of their choice using a simple control.
DatePicker can be particularly useful for any app requiring scheduling and intuitive inputs.
Its documentation further reads, a “date picker (DatePicker) offers a drop-down control that’s optimized for picking a single date from a calendar view where contextual information like the day of the week or fullness of the calendar is important. You can modify the calendar to provide additional context or to limit available dates.”
<img class="alignnone size-full wp-image-14498" src="https://webflow-prod-assets.s3.amazonaws.com/6525256482c9e9a06c7a9d3c%2F65b01dd048b83fcd2e54ddc0_image-5-calendar-contextual-input.webp" alt="image 5 - calendar contextual input" width="1600" height="735" />
This input can be added to a Shiny application using the code below.
<pre>library(shiny)
library(shiny.fluent)
library(tidyverse)
library(palmerpenguins)
library(plotly)
penguins_options <- list(
list(key = "Adelie", text = "Adelie"),
list(key = "Chinstrap", text = "Chinstrap"),
list(key = "Gentoo", text = "Gentoo")
)
shinyApp(
ui = fluentPage(
tags$style('
body {
background-color: #379be6;
}
div{
background-color: white;
color: #f8f8f8;
border-radius: 5px;
margin: 0px;
padding: 5px;
}'
),
div(
Text(
variant = "xLarge",
"Examples Using shiny.fluent DatePicker input control",
block = TRUE
),
Separator(),
Text(
variant = "large",
"Select registration date:",
block = TRUE
),
tags$br(),
DatePicker.shinyInput("regDate",
value = as.Date('2022/05/01'),
label = "Registration date"),
textOutput("dateValue")
)
),
server = function(input, output) {
output$dateValue <- renderText({
sprintf("Value: %s", input$regDate$text)
})
}
)
</pre>
Check out other arguments that can be added like isRequired, showWeekNumbers, and so on.
<img class="alignnone size-full wp-image-14500" src="https://webflow-prod-assets.s3.amazonaws.com/6525256482c9e9a06c7a9d3c%2F65b01dd1a516965e74b62101_image-6-isreequired-and-other-arguments.webp" alt="image 6 - isreequired and other arguments" width="1600" height="732" />
<h3 id="doccard"><b>DocumentCard Input</b></h3>
This is one exciting input control that can be useful to display data of different types at the same time. DocumentCard is used to represent a file and contains additional metadata or actions. It offers users a richer view of a file compared to a common grid view.
<img class="alignnone size-full wp-image-14502" src="https://webflow-prod-assets.s3.amazonaws.com/6525256482c9e9a06c7a9d3c%2F65b01dd3051092b3b542c4b6_image-7-documentcard-input.webp" alt="image 7 - documentcard input" width="1600" height="496" />
<pre>library(shiny)
library(shiny.fluent)
library(tidyverse)
library(palmerpenguins)
library(plotly)
title <- "Palmer penguins"
previewImages <- list(
list(
previewImageSrc = "images/lter_penguins.png",
width = 300,
height = 150
)
)
shinyApp(
ui = fluentPage(
tags$style('
body {
background-color: #379be6;
}
div{
background-color: white;
color: #f8f8f8;
border-radius: 5px;
margin: 0px;
padding: 5px;
}'
),
div(
Text(
variant = "xLarge",
"Examples Using shiny.fluent DocumentCard input control",
block = TRUE
),
Separator(),
Text(
variant = "large",
"Palmer penguins document:",
block = TRUE
),
tags$br(),
DocumentCard(
DocumentCardPreview(previewImages = previewImages),
DocumentCardTitle(
title = title,
shouldTruncate = TRUE
),
DocumentCardActivity(
activity = "Created by",
people = list(list(name = "Bilikisu"))
)
),
textOutput("dateValue")
)
),
server = function(input, output) {
}
)
</pre>
<h3 id="detaillist"><b>DetailsList Input</b></h3>
Looking for a simple and robust way to present a critical and information-rich collection of items, which also gives users the freedom to sort, group, and filter the content? Then, DetailsList is your best choice for presenting a full view of information in a condensed and complete fashion.
In the example below, we’ll use the DetailsList input to present the data.
<img class="alignnone size-full wp-image-14504" src="https://webflow-prod-assets.s3.amazonaws.com/6525256482c9e9a06c7a9d3c%2F65b01dd4265abcdac60a4534_image-8-detailslist-input.webp" alt="image 8 - detailslist input" width="1600" height="716" />
<pre>library(shiny)
library(shiny.fluent)
library(tidyverse)
library(palmerpenguins)
library(plotly)
details_list_columns <- tibble(
fieldName = c("species", "island", "bill_length_mm", "bill_depth_mm",
"flipper_length_mm", "body_mass_g", "sex","year"),
name = c("Species", "Island", "Bill Length (mm)", "Bill Depth (mm)",
"Flipper Length (mm)", "Body Mass (g)", "Gender", "Year"),
key = fieldName)
shinyApp(
ui = fluentPage(
tags$style('
#penguins_tbl {
background-color: #379be6;
color: black;
}
div{
background-color: white;
color: black;
border-radius: 5px;
margin: 0px;
padding: 5px;
}'
),
div(
Text(
variant = "xLarge",
"Examples Using shiny.fluent DetailsList input control",
block = TRUE
),
Separator(),
Text(
variant = "large",
"Palmer penguins dataset:",
block = TRUE
),
tags$br()
),
uiOutput("penguins_tbl")
),
server = function(input, output) {
penguins_data <- reactive({
palmerpenguins::penguins
})
output$penguins_tbl <- renderUI({
items_list <- if(nrow(penguins_data()) > 0){
DetailsList(items = penguins_data(), columns = details_list_columns)
} else {
p("No data.")
}
Stack(
tokens = list(childrenGap = 5),
div(style="max-height: 500px; overflow: auto", items_list)
)
})
}
)
</pre>
<h3 id="stack"><b>Stack Input</b></h3>
The layout of inputs within the application or dashboard interface is key to user acceptance and the success of the project. The documentation on shiny.fluent package, mentions Stack as a container-type component that abstracts the implementation of a flexbox - assisting in defining the layout of its children components. The stacks can be nested to give the design of the Shiny application a readable, and professional-looking feel which attracts users, ensures usability, and is intuitive. Let’s show an example using the code below.
<pre>library(shiny)
library(shiny.fluent)
library(tidyverse)
library(palmerpenguins)
library(plotly)
shinyApp(
ui = fluentPage(
tags$style('
body {
background-color: #379be6;
color: black;
}
div{
background-color: white;
color: black;
border-radius: 5px;
margin: 0px;
padding: 5px;
}'
),
div(
Text(
variant = "xLarge",
"Examples Using shiny.fluent Stack input",
block = TRUE
),
tags$br()
),
uiOutput("info"),
uiOutput("uiplot")
),
server = function(input, output) {
penguins_data <- reactive({
palmerpenguins::penguins
})
output$info <- renderUI({
Stack(
tokens = list(childrenGap = 15),
Text(variant = "xLarge",
"Visualizing the penguins dataset",
block = TRUE),
Separator(""))
})
output$plot1 <- renderPlotly({
p1 <- ggplot(data = penguins_data(), aes(x = flipper_length_mm)) +
geom_histogram(aes(fill = species), alpha = 0.5, position = "identity") +
scale_fill_manual(values = c("darkorange","darkorchid","cyan4"))
ggplotly(p1,height = 400, width=600)
})
output$plot2 <- renderPlotly({
p2 <- ggplot(data = penguins_data(), aes(x = bill_length_mm, y = bill_depth_mm)) +
geom_point(aes(color = species,
shape = species),
size = 2) +
scale_color_manual(values = c("darkorange","darkorchid","cyan4"))
ggplotly(p2,height = 400, width=600)
})
output$plot3 <- renderPlotly({
p2 <- ggplot(penguins_data(), aes(x = flipper_length_mm,
y = body_mass_g)) +
geom_point(aes(color = sex)) +
scale_color_manual(values = c("darkorange","cyan4"),
na.translate = FALSE) +
facet_wrap(~species)
ggplotly(p2,height = 400, width=600)
})
output$uiplot <- renderUI({
Stack(
tokens = list(childrenGap = 10), horizontal = TRUE,
Stack(
tokens = list(childrenGap = 5),
Text(variant = "large",
"Histogram example: flipper length by species",
block = TRUE),
plotlyOutput("plot1")
),
Stack(
tokens = list(childrenGap = 5),
Text(variant = "large",
"Scatterplot example 2: penguin bill length versus bill depth",
block = TRUE),
plotlyOutput("plot2")
),
Stack(
tokens = list(childrenGap = 5),
Text(variant = "large",
"Scatterplot using facet_wrap() example 3: penguin bill length versus bill depth",
block = TRUE),
plotlyOutput("plot3")
)
)
})
}
)
</pre>
<img class="alignnone size-full wp-image-14506" src="https://webflow-prod-assets.s3.amazonaws.com/6525256482c9e9a06c7a9d3c%2F65b01dd6687eb4992e574bdc_image-9-stack-input.webp" alt="image 9 - stack input" width="1600" height="525" />
<h3 id="checkbox"><strong>Checkbox Input</strong></h3>
The Checkbox input enables users to select one or more items from a group, or switch between two mutually exclusive options (checked or unchecked - on or off) while interacting with a Shiny app. Below is an example showing the checkbox input in a Shiny application:
<img class="alignnone size-full wp-image-14508" src="https://webflow-prod-assets.s3.amazonaws.com/6525256482c9e9a06c7a9d3c%2F65b01dd7afc0ff7c6578fd89_image-10-checkbox-input.webp" alt="image 10 - checkbox input" width="1600" height="201" />
<pre>library(shiny)
library(shiny.fluent)
library(tidyverse)
shinyApp(
ui = fluentPage(
tags$style('
body {
background-color: #379be6;
}
div{
background-color: white;
color: black;
border-radius: 5px;
margin: 0px;
padding: 5px;
}'
),
div(
Text(
variant = "xLarge",
"Examples Using shiny.fluent Checkbox input",
block = TRUE
),
Separator(),
tags$br(),
Checkbox.shinyInput("checkbox", value = FALSE, label="Are you ready?"),
textOutput("chkValue")
)
),
server = function(input, output) {
output$chkValue <- renderText({
sprintf("Value returned from the checkbox: %s", input$checkbox)
})
}
)
</pre>
<h3 id="nav"><strong>Nav input</strong></h3>
The shiny.fluent’s nav control, also called "left nav" or "navigation pane" provide a means of navigating through the application through links to the main areas of an app or a site. Nav control remains on-screen and on the left of the view in larger configurations. In smaller configurations, it may be collapsed into a skinnier version or completely hidden until the user taps an icon. More aesthetics and usability can be added to the control using icons available in the Microsoft Fluent UI documentation.
<img class="alignnone wp-image-14510" src="https://webflow-prod-assets.s3.amazonaws.com/6525256482c9e9a06c7a9d3c%2F65b01dd83b68120d131c339d_image-11-nav-input-open-and-closed.webp" alt="image 11 - nav input open and closed" width="300" height="230" />
<pre>library(shiny.fluent)
if (interactive()) {
navigation_styles <- list(
root = list(
height = "100%",
boxSizing = "border-box",
border = "1px solid #eee",
overflowY = "auto"
)
)
link_groups <- list(
list(
links = list(
list(
name = "Home",
expandAriaLabel = "Expand Home section",
collapseAriaLabel = "Collapse Home section",
links = list(
list(
name = "Admin",
url = "http://msn.com",
icon = "Admin",
key = "key1",
target = "_blank"
),
list(
name = "Users",
url = "http://appsilon.com",
icon = "Contact",
key = "key2",
target = "_blank"
),
list(
name = "Data",
url = "http://msn.com",
icon = "Database",
disabled = TRUE,
key = "key3",
target = "_blank"
)
),
isExpanded = TRUE
),
list(
name = "Documents",
url = "http://example.com",
key = "key4",
icon = "Document",
isExpanded = TRUE
),
list(
name = "Pages",
url = "http://msn.com",
key = "key5"
),
list(
name = "Notebook",
url = "http://msn.com",
key = "key5",
disabled = TRUE
),
list(
name = "Communication and Media",
icon = "DocLibrary",
url = "http://msn.com",
key = "key6"
),
list(
name = "News",
url = "http://cnn.com",
icon = "News",
key = "key7",
target = "_blank",
iconProps = list(
iconName = "News",
styles = list(
root = list(
fontSize = 20,
color = "#106ebe"
)
)
)
)
)
)
)
shinyApp(
ui = Nav(
groups = link_groups,
selectedKey = "key1",
styles = navigation_styles
),
server = function(input, output) {}
)
}
</pre>
<h2>Summary - R Shiny Inputs with shiny.fluent</h2>
Appsilon's shiny.fluent package input provides professional and familiar user interface design for your Shiny applications. The ease of see of the input components allows for faster development. No need to sacrifice timely deployment and market launch for quality inputs and UI in your Shiny application.
In some cases, you may need to work using the official <a href="https://developer.microsoft.com/en-us/fluentui#/controls/web/" target="_blank" rel="noopener">MS Fluent UI docs</a> to achieve the desired result.
You can also reach out to the team at Appsilon or start a discussion on the <a href="https://github.com/Appsilon/shiny.fluent" target="_blank" rel="noopener">shiny.fluent Github page</a>.