├── .Rbuildignore
├── .gitignore
├── DESCRIPTION
├── LICENSE
├── LICENSE.md
├── NAMESPACE
├── R
├── accordion.R
├── alerts.R
├── badge.R
├── card.R
├── carousel.R
├── close.R
├── collapse.R
├── dependencies.R
├── dropdown.R
├── gallery.R
├── group.R
├── inputs.R
├── list.R
├── modal.R
├── offcanvas.R
├── placeholders.R
├── popover.R
├── progress.R
├── toast.R
├── tooltip.R
└── utils.R
├── README.md
├── inst
├── app
│ └── app.R
└── assets
│ ├── alert.js
│ ├── carousel.js
│ ├── color.js
│ ├── modal.js
│ ├── offcanvas.js
│ ├── popover.js
│ ├── progress.js
│ ├── range.js
│ ├── text-group.js
│ ├── toast.js
│ └── tooltip.js
├── makefile
└── man
├── accordion.Rd
├── accordionItem.Rd
├── alert.Rd
├── alertHeading.Rd
├── alertServer.Rd
├── asPlaceholder.Rd
├── badge.Rd
├── buttonGroup.Rd
├── card.Rd
├── cardBody.Rd
├── cardHeader.Rd
├── cardText.Rd
├── cardTitle.Rd
├── carousel.Rd
├── carouselControls.Rd
├── carouselImg.Rd
├── carouselIndicators.Rd
├── carouselItem.Rd
├── closeButton.Rd
├── collapse.Rd
├── collapseButton.Rd
├── collapseContent.Rd
├── collapseLink.Rd
├── colorPickerInput.Rd
├── dropdownButton.Rd
├── floatingSelectInput.Rd
├── floatingTextAreaInput.Rd
├── floatingTextInput.Rd
├── gallery.Rd
├── get_dep.Rd
├── listGroup.Rd
├── listGroupItem.Rd
├── modal.Rd
├── modalBody.Rd
├── modalFooter.Rd
├── modalHeader.Rd
├── modalTitle.Rd
├── modalToggle.Rd
├── modalTrigger.Rd
├── offcanvas.Rd
├── offcanvasButton.Rd
├── offcanvasContent.Rd
├── offcanvasHeader.Rd
├── offcanvasLink.Rd
├── offcanvasServer.Rd
├── progress.Rd
├── progressBar.Rd
├── rangeInput.Rd
├── switchInput.Rd
├── textGroupInput.Rd
├── toast.Rd
├── toastContent.Rd
├── toastToggle.Rd
├── update_color_picker.Rd
├── update_progress.Rd
├── update_range.Rd
├── update_text_group.Rd
├── withPopover.Rd
└── withTooltip.Rd
/.Rbuildignore:
--------------------------------------------------------------------------------
1 | ^LICENSE\.md$
2 | ^dev$
3 | ^makefile$
4 | ^\.vscode$
5 | ^test\.R$
6 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | dev/
2 | .vscode
3 | test.R
4 |
--------------------------------------------------------------------------------
/DESCRIPTION:
--------------------------------------------------------------------------------
1 | Package: bsutils
2 | Title: 'Shiny' Utilities for 'Bootstrap 5'
3 | Version: 0.0.0.9000
4 | Authors@R:
5 | c(
6 | person(given = "John",
7 | family = "Coene",
8 | role = c("aut", "cre"),
9 | email = "jcoenep@gmail.com",
10 | comment = c(ORCID = "0000-0002-6637-4107")),
11 | person(family = "Opifex", role = c("fnd"))
12 | )
13 | Description: 'Shiny' utilities for 'Bootstrap 5' to create
14 | elements such as accordions, off-canvas, etc.
15 | License: MIT + file LICENSE
16 | Encoding: UTF-8
17 | Roxygen: list(markdown = TRUE)
18 | RoxygenNote: 7.3.1
19 | Imports:
20 | shiny,
21 | htmltools
22 | Suggests:
23 | bslib
24 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | YEAR: 2022
2 | COPYRIGHT HOLDER: Opifex
3 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | # MIT License
2 |
3 | Copyright (c) 2022 Opifex
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/NAMESPACE:
--------------------------------------------------------------------------------
1 | # Generated by roxygen2: do not edit by hand
2 |
3 | S3method(collapse,collapseTrigger)
4 | S3method(offcanvas,offcanvasTrigger)
5 | S3method(offcanvas,shiny.tag)
6 | export(accordion)
7 | export(accordionItem)
8 | export(alert)
9 | export(alertHeading)
10 | export(alert_hide)
11 | export(alert_show)
12 | export(asPlaceholder)
13 | export(badge)
14 | export(buttonGroup)
15 | export(card)
16 | export(cardBody)
17 | export(cardHeader)
18 | export(cardSubtitle)
19 | export(cardText)
20 | export(cardTitle)
21 | export(carousel)
22 | export(carouselImg)
23 | export(carouselItem)
24 | export(closeButton)
25 | export(collapse)
26 | export(collapseButton)
27 | export(collapseContent)
28 | export(collapseLink)
29 | export(colorPickerInput)
30 | export(dropdownButton)
31 | export(floatingSelectInput)
32 | export(floatingTextAreaInput)
33 | export(floatingTextInput)
34 | export(gallery)
35 | export(listGroup)
36 | export(listGroupItem)
37 | export(modal)
38 | export(modalBody)
39 | export(modalButton)
40 | export(modalFooter)
41 | export(modalHeader)
42 | export(modalLink)
43 | export(modalTitle)
44 | export(modal_hide)
45 | export(modal_show)
46 | export(modal_toggle)
47 | export(offcanvas)
48 | export(offcanvasButton)
49 | export(offcanvasButtonWithTooltip)
50 | export(offcanvasContent)
51 | export(offcanvasHeader)
52 | export(offcanvasLink)
53 | export(offcanvas_hide)
54 | export(offcanvas_show)
55 | export(offcanvas_toggle)
56 | export(progress)
57 | export(progressBar)
58 | export(rangeInput)
59 | export(switchInput)
60 | export(textGroupInput)
61 | export(toast)
62 | export(toastBody)
63 | export(toastHeader)
64 | export(toast_hide)
65 | export(toast_show)
66 | export(update_color_picker)
67 | export(update_progress)
68 | export(update_range)
69 | export(update_text_group)
70 | export(withPopover)
71 | export(withTooltip)
72 | import(shiny)
73 | importFrom(htmltools,attachDependencies)
74 | importFrom(htmltools,tagAppendAttributes)
75 | importFrom(htmltools,tagAppendChild)
76 | importFrom(htmltools,tagAppendChildren)
77 | importFrom(htmltools,tagGetAttribute)
78 | importFrom(utils,packageVersion)
79 |
--------------------------------------------------------------------------------
/R/accordion.R:
--------------------------------------------------------------------------------
1 | #' Accordion
2 | #'
3 | #' Collapsible accordion made up of [accordionItem()].
4 | #'
5 | #' @param ... Any number of [accordionItem()].
6 | #' @param .id Id of accordion.
7 | #' @param .flush remove default background color, some
8 | #' borders, some rounded corners.
9 | #'
10 | #' @examples
11 | #' library(shiny)
12 | #'
13 | #' ui <- fluidPage(
14 | #' theme = bslib::bs_theme(version = 5L),
15 | #' accordion(
16 | #' accordionItem(
17 | #' .expanded = TRUE,
18 | #' "Something",
19 | #' p("Some content")
20 | #' ),
21 | #' accordionItem(
22 | #' "Something else",
23 | #' p("Some other content")
24 | #' )
25 | #' )
26 | #' )
27 | #'
28 | #' server <- \(input, output, session){
29 | #'
30 | #' }
31 | #'
32 | #' if(interactive())
33 | #' shinyApp(ui, server)
34 | #'
35 | #' @import shiny
36 | #'
37 | #' @export
38 | accordion <- \(
39 | ...,
40 | .id = NULL,
41 | .flush = FALSE
42 | ) {
43 | fns <- list(...)
44 |
45 | if(length(fns) == 0L)
46 | stop("Must pass `accordionItem`")
47 |
48 | flush <- ifelse(.flush, "accordion-flush", "")
49 | id <- get_id(.id)
50 |
51 | fns |>
52 | lapply(\(fn) {
53 | fn(id)
54 | }) |>
55 | div(
56 | class = sprintf("accordion %s", flush),
57 | id = id
58 | )
59 | }
60 |
61 | #' AccordionItem
62 | #'
63 | #' Accordion item to place within [accordion()].
64 | #'
65 | #' @param label Label of the item.
66 | #' @param ... Elements to place in the body of the item.
67 | #' @param .id Id of item.
68 | #' @param .expanded Whether the element is initially expanded.
69 | #' @param .label_tag Tag to use for the label.
70 | #'
71 | #' @export
72 | accordionItem <- \(
73 | label,
74 | ...,
75 | .id = NULL,
76 | .expanded = FALSE,
77 | .label_tag = shiny::h2
78 | ) {
79 | if(missing(label))
80 | stop("Missing `label`")
81 |
82 | id <- get_id(.id)
83 |
84 | toggled <- ifelse(.expanded, "show", "collapse")
85 | toggled_button <- ifelse(.expanded, "", "collapsed")
86 |
87 | \(parent_id) {
88 | div(
89 | class = "accordion-item",
90 | .label_tag(
91 | class = "accordion-header",
92 | tags$button(
93 | class = sprintf("accordion-button %s", toggled_button),
94 | type = "button",
95 | `data-bs-toggle` = "collapse",
96 | `data-bs-target` = sprintf("#%s", id),
97 | `aria-expanded` = tolower(.expanded),
98 | `aria-controls` = id,
99 | label
100 | )
101 | ),
102 | div(
103 | id = id,
104 | class = sprintf("accordion-collapse collapse %s", toggled),
105 | `data-bs-parent` = sprintf("#%s", parent_id),
106 | div(
107 | class = "accordion-body",
108 | ...
109 | )
110 | )
111 | )
112 | }
113 | }
114 |
--------------------------------------------------------------------------------
/R/alerts.R:
--------------------------------------------------------------------------------
1 | #' Alert
2 | #'
3 | #' @param id ID of alert useful to toggle from server with
4 | #' [alert_show()] or [alert_hide()].
5 | #' @param ... Content of alert.
6 | #' @param class Additional classes, e.g.: `alert-success`.
7 | #'
8 | #' @examples
9 | #' alert(
10 | #' alertHeading("Header!"),
11 | #' shiny::p("Some content")
12 | #' )
13 | #'
14 | #' @export
15 | alert <- \(
16 | ...,
17 | id = NULL,
18 | class = ""
19 | ) {
20 | tagList(
21 | get_dep("alert"),
22 | div(
23 | id = id,
24 | class = sprintf("alert %s", class),
25 | role = "alert",
26 | ...
27 | )
28 | )
29 | }
30 |
31 | #' Alert Heading
32 | #'
33 | #' Alert heading to be placed in [alert()].
34 | #'
35 | #' @param heading A character string or an HTML tag.
36 | #'
37 | #' @importFrom htmltools tagAppendAttributes
38 | #'
39 | #' @export
40 | alertHeading <- \(heading){
41 | if(is.character(heading))
42 | return(h4(class = "alert-heading", heading))
43 |
44 | tagAppendAttributes(
45 | heading,
46 | class = "alert-heading"
47 | )
48 | }
49 |
50 | #' Toggle Alert
51 | #'
52 | #' Show or hide an alert.
53 | #'
54 | #' @param id ID of [alert()] to toggle.
55 | #' @param session A valid shiny session.
56 | #'
57 | #' @name alertServer
58 | #' @export
59 | alert_show <- \(
60 | id,
61 | session = shiny::getDefaultReactiveDomain()
62 | ) {
63 | session$sendCustomMessage(
64 | "alert-show",
65 | id
66 | )
67 | }
68 |
69 | #' @rdname alertServer
70 | #' @export
71 | alert_hide <- \(
72 | id,
73 | session = shiny::getDefaultReactiveDomain()
74 | ) {
75 | session$sendCustomMessage(
76 | "alert-hide",
77 | id
78 | )
79 | }
80 |
--------------------------------------------------------------------------------
/R/badge.R:
--------------------------------------------------------------------------------
1 | #' Badge
2 | #'
3 | #' Badge.
4 | #'
5 | #' @param ... Content of the badge.
6 | #' @param color Background color of the badge.
7 | #' @param pill Whether to create a rounded badge.
8 | #' @param class Additional classes to passs to the badge.
9 | #'
10 | #' @export
11 | badge <- \(
12 | ...,
13 | color = c(
14 | "primary",
15 | "secondary",
16 | "success",
17 | "danger",
18 | "warning",
19 | "info",
20 | "light",
21 | "dark"
22 | ),
23 | pill = FALSE,
24 | class = ""
25 | ) {
26 | color <- match.arg(color)
27 | pill_class <- ""
28 |
29 | if(pill)
30 | pill_class <- "rounded-pill"
31 |
32 | cl <- sprintf(
33 | "badge bg-%s %s",
34 | color,
35 | pill_class
36 | )
37 |
38 | span(
39 | class = cl,
40 | ...
41 | )
42 | }
--------------------------------------------------------------------------------
/R/card.R:
--------------------------------------------------------------------------------
1 | #' Card
2 | #'
3 | #' Card.
4 | #'
5 | #' @param ... Content, generally [cardBody()].
6 | #'
7 | #' @examples
8 | #' card(
9 | #' cardHeader("Header"),
10 | #' cardBody(
11 | #' cardTitle("Title"),
12 | #' cardSubtitle("Subtitle"),
13 | #' cardText("The content of the card")
14 | #' )
15 | #' )
16 | #'
17 | #' @export
18 | card <- \(
19 | ...
20 | ) {
21 | div(
22 | class = "card",
23 | ...
24 | )
25 | }
26 |
27 | #' Card Body
28 | #'
29 | #' Card body to be placed within [card()].
30 | #'
31 | #' @param ... Content, HTML tags, [cardText()], [cardTitle()],
32 | #' or [cardSubtitle()].
33 | #'
34 | #' @export
35 | cardBody <- \(
36 | ...
37 | ) {
38 | div(
39 | class = "card-body",
40 | ...
41 | )
42 | }
43 |
44 | #' Card Text
45 | #'
46 | #' Card text to be placed in [cardBody()].
47 | #'
48 | #' @param ... Content of the text.
49 | #'
50 | #' @export
51 | cardText <- \(
52 | ...
53 | ) {
54 | p(
55 | class = "card-text",
56 | ...
57 | )
58 | }
59 |
60 | #' Card Title & Subtitle
61 | #'
62 | #' Card title and subtitle to be placed within [cardBody()].
63 | #'
64 | #' @param content Content of the title or subtitle, either
65 | #' a character vector or an HTML header tag.
66 | #'
67 | #' @name cardTitle
68 | #' @export
69 | cardTitle <- \(
70 | content
71 | ) {
72 | if(missing(content))
73 | stop("Missing `content`")
74 |
75 | if(is.character(content))
76 | return(h5(content, class = "card-title"))
77 |
78 | tagAppendAttributes(
79 | content,
80 | class = "card-title"
81 | )
82 | }
83 |
84 | #' @rdname cardTitle
85 | #' @export
86 | cardSubtitle <- \(
87 | content
88 | ) {
89 | if(missing(content))
90 | stop("Missing `content`")
91 |
92 | if(is.character(content))
93 | return(h6(content, class = "card-subtitle"))
94 |
95 | tagAppendAttributes(
96 | content,
97 | class = "card-subtitle"
98 | )
99 | }
100 |
101 | #' Card Header
102 | #'
103 | #' Card header placed within [card()] before [cardBody()].
104 | #'
105 | #' @param content Content of the title or subtitle, either
106 | #' a character vector or an HTML header tag.
107 | #'
108 | #' @importFrom htmltools tagAppendAttributes
109 | #'
110 | #' @export
111 | cardHeader <- \(
112 | content
113 | ) {
114 | if(missing(content))
115 | stop("Missing `content`")
116 |
117 | if(is.character(content))
118 | return(h5(content, class = "card-header"))
119 |
120 | tagAppendAttributes(
121 | content,
122 | class = "card-header"
123 | )
124 | }
125 |
--------------------------------------------------------------------------------
/R/carousel.R:
--------------------------------------------------------------------------------
1 | #' Carousel
2 | #'
3 | #' Carousel element.
4 | #'
5 | #' @param ... Slides of the carousel, see [carouselItem()].
6 | #' @param id ID of carousel.
7 | #' @param class Additional class of the carousel.
8 | #' @param indicators Whether to show indicators.
9 | #' @param controls Whether to show control arrows.
10 | #'
11 | #' @examples
12 | #' library(shiny)
13 | #'
14 | #' ui <- fluidPage(
15 | #' theme = bslib::bs_theme(version = 5L),
16 | #' carousel(
17 | #' indicators = TRUE,
18 | #' controls = TRUE,
19 | #' carouselItem(
20 | #' h5("Hello"),
21 | #' class = "bg-primary rounded p-4"
22 | #' ),
23 | #' carouselItem(
24 | #' h5("World"),
25 | #' class = "bg-info rounded p-4"
26 | #' )
27 | #' )
28 | #' )
29 | #'
30 | #' server <- \(input, output, session){
31 | #' }
32 | #'
33 | #' if(interactive())
34 | #' shinyApp(ui, server)
35 | #'
36 | #' @export
37 | carousel <- \(
38 | ...,
39 | id = NULL,
40 | class = "",
41 | controls = FALSE,
42 | indicators = FALSE
43 | ) {
44 | items <- list(...)
45 | id <- get_id(id)
46 |
47 | items[[1]] <- tagAppendAttributes(
48 | items[[1]],
49 | class = "active"
50 | )
51 |
52 | inner <- div(
53 | class = "carousel-inner",
54 | items
55 | )
56 |
57 | tagList(
58 | get_dep("carousel"),
59 | div(
60 | id = id,
61 | class = sprintf("bsutils-carousel carousel slide %s", class),
62 | `data-bs-ride` = "carousel",
63 | carouselIndicators(items, id, indicators),
64 | inner,
65 | carouselControls(controls, id)
66 | )
67 | )
68 | }
69 |
70 | #' Carousel Indicators
71 | #'
72 | #' Carousel indicators
73 | #'
74 | #' @param items list of [carouselItem()].
75 | #' @param id Parent if of [carousel()].
76 | #' @param show Whether to show the indicators.
77 | #'
78 | #' @keywords internal
79 | carouselIndicators <- \(
80 | items,
81 | id,
82 | show
83 | ) {
84 | if(!show)
85 | return()
86 |
87 | n <- length(items)
88 | lapply(1:n, \(i) {
89 | tags$button(
90 | type = "button",
91 | `data-bs-target` = sprintf("#%s", id),
92 | `data-bs-slide-to` = i - 1,
93 | class = if(i == 1) "active",
94 | `aria-current` = if(i == 1) "true"
95 | )
96 | }) |>
97 | div(
98 | class = "carousel-indicators"
99 | )
100 | }
101 |
102 | #' Carousel Controls
103 | #'
104 | #' Carousel control arrows.
105 | #'
106 | #' @param show Whether to show the control arrows.
107 | #' @param id ID of parent [carousel()].
108 | #'
109 | #' @keywords internal
110 | carouselControls <- \(
111 | show,
112 | id
113 | ){
114 | if(!show)
115 | return()
116 |
117 | tagList(
118 | tags$button(
119 | class = "carousel-control-prev",
120 | type = "button",
121 | `data-bs-target` = sprintf("#%s", id),
122 | `data-bs-slide` = "prev",
123 | tags$span(
124 | class = "carousel-control-prev-icon",
125 | `aria-hidden` = "true"
126 | ),
127 | tags$span(
128 | class = "visually-hidden",
129 | "Previous"
130 | )
131 | ),
132 | tags$button(
133 | class = "carousel-control-next",
134 | type = "button",
135 | `data-bs-target` = sprintf("#%s", id),
136 | `data-bs-slide` = "next",
137 | tags$span(
138 | class = "carousel-control-next-icon",
139 | `aria-hidden` = "true"
140 | ),
141 | tags$span(
142 | class = "visually-hidden",
143 | "Next"
144 | )
145 | )
146 | )
147 | }
148 |
149 | #' Carousel Item
150 | #'
151 | #' Carousel item to use within [carousel()].
152 | #'
153 | #' @param ... Content of item.
154 | #' @param interval Number of milliseconds this item should be shown.
155 | #' @param class Additional classes.
156 | #'
157 | #' @export
158 | carouselItem <- \(
159 | ...,
160 | interval = NULL,
161 | class = ""
162 | ) {
163 | div(
164 | class = sprintf("carousel-item %s", class),
165 | `data-bs-interval` = interval,
166 | ...
167 | )
168 | }
169 |
170 | #' Carousel Image
171 | #'
172 | #' Carousel image to use within [carouselItem()].
173 | #'
174 | #' @param ... Passed to `
`.
175 | #' @param class Additional classes.
176 | #'
177 | #' @export
178 | carouselImg <- \(
179 | ...,
180 | class = ""
181 | ) {
182 | tags$img(
183 | class = sprintf("d-block w-100 %s", class),
184 | ...
185 | )
186 | }
187 |
--------------------------------------------------------------------------------
/R/close.R:
--------------------------------------------------------------------------------
1 | #' Close Button
2 | #'
3 | #' Button to dismiss or close a component.
4 | #'
5 | #' @export
6 | closeButton <- \() {
7 | tags$button(
8 | type = "button",
9 | class = "btn-close",
10 | `aria-label` = "Close"
11 | )
12 | }
--------------------------------------------------------------------------------
/R/collapse.R:
--------------------------------------------------------------------------------
1 | #' Collapse
2 | #'
3 | #' Create a collapsible.
4 | #'
5 | #' @param trigger A [collapseButton()] or [collapseLink()].
6 | #' @param content The offcanvas content as returned by
7 | #' [offcanvasContent()].
8 | #'
9 | #' @examples
10 | #' library(shiny)
11 | #'
12 | #' ui <- fluidPage(
13 | #' theme = bslib::bs_theme(version = 5L),
14 | #' collapse(
15 | #' collapseLink(
16 | #' "Reveal"
17 | #' ),
18 | #' collapseContent(
19 | #' "Some collapsed content"
20 | #' )
21 | #' )
22 | #' )
23 | #'
24 | #' server <- \(input, output, session){
25 | #'
26 | #' }
27 | #'
28 | #' if(interactive())
29 | #' shinyApp(ui, server)
30 | #'
31 | #' @importFrom htmltools tagGetAttribute
32 | #'
33 | #' @name collapse
34 | #' @export
35 | collapse <- \(trigger, content) UseMethod("collapse")
36 |
37 | #' @describeIn collapse Collapse wrapper
38 | #' @method collapse collapseTrigger
39 | #' @export
40 | collapse.collapseTrigger <- \(
41 | trigger,
42 | content
43 | ){
44 | if(missing(trigger))
45 | stop("Missing `trigger`")
46 |
47 | if(missing(content))
48 | stop("Missing `content`")
49 |
50 | target_id <- tagGetAttribute(content, "id")
51 |
52 | tagList(
53 | trigger(target_id),
54 | content
55 | )
56 | }
57 |
58 | #' Collapse Button
59 | #'
60 | #' Collapse button.
61 | #'
62 | #' @param ... Passed to the button.
63 | #' @param id Button id.
64 | #' @param class Additional classes to pass to the button.
65 | #'
66 | #' @examples
67 | #' library(shiny)
68 | #'
69 | #' ui <- fluidPage(
70 | #' theme = bslib::bs_theme(version = 5L),
71 | #' collapse(
72 | #' collapseButton(
73 | #' "Reveal"
74 | #' ),
75 | #' collapseContent(
76 | #' "Some collapsed content"
77 | #' )
78 | #' )
79 | #' )
80 | #'
81 | #' server <- \(input, output, session){
82 | #'
83 | #' }
84 | #'
85 | #' if(interactive())
86 | #' shinyApp(ui, server)
87 | #'
88 | #' @export
89 | collapseButton <- \(
90 | ...,
91 | id = NULL,
92 | class = ""
93 | ){
94 | id <- get_id(id)
95 | class <- sprintf("btn btn-default action-button %s", class)
96 |
97 | btn <- \(target_id){
98 | class <- sprintf("btn btn-default %s", class)
99 | tags$button(
100 | id = id,
101 | class = class,
102 | `data-bs-toggle` = "collapse",
103 | role = "button",
104 | `aria-expanded` = "false",
105 | `aria-controls` = target_id,
106 | href = sprintf("#%s", target_id),
107 | ...
108 | )
109 | }
110 |
111 | structure(
112 | btn,
113 | class = c("collapseTrigger", class(btn))
114 | )
115 | }
116 |
117 | #' Collapse Link
118 | #'
119 | #' Collapse link.
120 | #'
121 | #' @param ... Passed to the link.
122 | #' @param id Link id.
123 | #' @param class Additional class to pass to the link.
124 | #'
125 | #' @export
126 | #' @name collapseLink
127 | collapseLink <- \(
128 | ...,
129 | id = NULL,
130 | class = ""
131 | ){
132 | id <- get_id(id)
133 | class <- sprintf("action-button %s", class)
134 |
135 | lnk <- \(target_id){
136 | tags$a(
137 | id = id,
138 | `data-bs-toggle` = "collapse",
139 | `aria-expanded` = "false",
140 | `aria-controls` = target_id,
141 | href = sprintf("#%s", target_id),
142 | ...
143 | )
144 | }
145 |
146 | structure(
147 | lnk,
148 | class = c("collapseTrigger", class(lnk))
149 | )
150 | }
151 |
152 | #' Collapse Content
153 | #'
154 | #' Collapse content, to pass to [collapseButton()] or
155 | #' [collapseLink()].
156 | #'
157 | #' @param ... Content of the collapsible.
158 | #' @param .id Id of the element.
159 | #'
160 | #' @export
161 | collapseContent <- \(
162 | ...,
163 | .id = NULL
164 | ){
165 |
166 | id <- get_id(.id)
167 |
168 | content <- div(
169 | class = "collapse",
170 | id = id,
171 | ...
172 | )
173 |
174 | structure(
175 | content,
176 | class = c("collapseContent", class(content))
177 | )
178 | }
179 |
--------------------------------------------------------------------------------
/R/dependencies.R:
--------------------------------------------------------------------------------
1 | #' Get Dependencies
2 | #'
3 | #' Get a dependency.
4 | #'
5 | #' @param name Name of dependency.
6 | #'
7 | #' @importFrom utils packageVersion
8 | #'
9 | #' @keywords internal
10 | get_dep <- \(
11 | name
12 | ) {
13 | htmltools::htmlDependency(
14 | name = sprintf("bsutils-%s", name),
15 | version = packageVersion("bsutils"),
16 | package = "bsutils",
17 | src = "assets",
18 | script = sprintf("%s.js", name)
19 | )
20 | }
21 |
--------------------------------------------------------------------------------
/R/dropdown.R:
--------------------------------------------------------------------------------
1 | #' Dropdown Button
2 | #'
3 | #' Dropdown buttons for [shiny::actionLink()].
4 | #'
5 | #' @param label Label of the dropdown.
6 | #' @param ... [shiny::actionLink()] to place within the
7 | #' dropdown.
8 | #' @param id ID of parent dropdown.
9 | #' @param class Additional class for dropdown button.
10 | #'
11 | #' @examples
12 | #' library(shiny)
13 | #'
14 | #' ui <- fluidPage(
15 | #' theme = bslib::bs_theme(version = 5L),
16 | #' dropdownButton(
17 | #' "Buttons",
18 | #' actionLink("first", "First"),
19 | #' actionLink("second", "Second")
20 | #' )
21 | #' )
22 | #'
23 | #' server <- \(input, output, session){
24 | #'
25 | #' }
26 | #'
27 | #' if(interactive())
28 | #' shinyApp(ui, server)
29 | #'
30 | #' @importFrom htmltools tagAppendAttributes
31 | #'
32 | #' @export
33 | dropdownButton <- \(
34 | label,
35 | ...,
36 | id = NULL,
37 | class = ""
38 | ) {
39 |
40 | id <- get_id(id)
41 | class <- sprintf("btn btn-default dropdown-toggle %s", class)
42 |
43 | btns <- list(...) |>
44 | lapply(\(btn) {
45 | btn <- tagAppendAttributes(btn, class = "dropdown-item")
46 | tags$li(btn)
47 | })
48 |
49 | div(
50 | class = "dropdown",
51 | tags$button(
52 | class = class,
53 | type = "button",
54 | `data-bs-toggle` = "dropdown",
55 | `aria-expanded` = "false",
56 | id = id,
57 | label
58 | ),
59 | tags$ul(
60 | class = "dropdown-menu",
61 | `aria-labelledby` = id,
62 | btns
63 | )
64 | )
65 | }
--------------------------------------------------------------------------------
/R/gallery.R:
--------------------------------------------------------------------------------
1 | #' Gallery
2 | #'
3 | #' Demo of utilities.
4 | #'
5 | #' @export
6 | gallery <- \(){
7 | shiny::shinyAppFile(
8 | system.file("app/app.R", package = "bsutils")
9 | )
10 | }
--------------------------------------------------------------------------------
/R/group.R:
--------------------------------------------------------------------------------
1 | #' Button Group
2 | #'
3 | #' Group of buttons.
4 | #'
5 | #' @param ... Any [shiny::actionButton()].
6 | #' @param class Any additional class.
7 | #'
8 | #' @examples
9 | #' library(shiny)
10 | #'
11 | #' ui <- fluidPage(
12 | #' theme = bslib::bs_theme(version = 5L),
13 | #' buttonGroup(
14 | #' actionButton("first", "First", class = "btn-primary"),
15 | #' actionButton("second", "Second", class = "btn-warning"),
16 | #' actionButton("third", "Third", class = "btn-success")
17 | #' )
18 | #' )
19 | #'
20 | #' server <- \(input, output, session){
21 | #'
22 | #' }
23 | #'
24 | #' if(interactive())
25 | #' shinyApp(ui, server)
26 | #'
27 | #' @export
28 | buttonGroup <- \(
29 | ...,
30 | class = ""
31 | ) {
32 | div(
33 | class = sprintf("btn-group %s", class),
34 | ...
35 | )
36 | }
37 |
--------------------------------------------------------------------------------
/R/inputs.R:
--------------------------------------------------------------------------------
1 | #' Text Input Floating Label
2 | #'
3 | #' Text input with floating label.
4 | #'
5 | #' @param inputId ID of input.
6 | #' @param label Label of input.
7 | #' @param placeholder Placeholder value.
8 | #' @param value Value of input.
9 | #' @param ... Passed to input.
10 | #'
11 | #' @export
12 | floatingTextInput <- \(
13 | inputId,
14 | label,
15 | placeholder,
16 | value = "",
17 | ...
18 | ) {
19 | if(missing(inputId))
20 | stop("Missing `inputId`")
21 |
22 | if(missing(label))
23 | stop("Missing `label`")
24 |
25 | if(missing(placeholder))
26 | stop("Missing `placeholder`")
27 |
28 | div(
29 | class = "form-floating",
30 | tags$input(
31 | id = inputId,
32 | type = "text",
33 | class = "form-control",
34 | placeholder = placeholder,
35 | value = value,
36 | ...
37 | ),
38 | tags$label(
39 | `for` = inputId,
40 | label
41 | )
42 | )
43 | }
44 |
45 | #' Text Area Input Floating Label
46 | #'
47 | #' Text area input with floating label.
48 | #'
49 | #' @param inputId ID of input.
50 | #' @param label Label of input.
51 | #' @param placeholder Placeholder value.
52 | #' @param value Value of input.
53 | #' @param ... Passed to input.
54 | #'
55 | #' @export
56 | floatingTextAreaInput <- \(
57 | inputId,
58 | label,
59 | placeholder,
60 | value = "",
61 | ...
62 | ) {
63 | if(missing(inputId))
64 | stop("Missing `inputId`")
65 |
66 | if(missing(label))
67 | stop("Missing `label`")
68 |
69 | if(missing(placeholder))
70 | stop("Missing `placeholder`")
71 |
72 | div(
73 | class = "form-floating",
74 | tags$textarea(
75 | id = inputId,
76 | class = "form-control",
77 | placeholder = placeholder,
78 | value = value,
79 | ...
80 | ),
81 | tags$label(
82 | `for` = inputId,
83 | label
84 | )
85 | )
86 | }
87 |
88 | #' Select Floating Label
89 | #'
90 | #' Select input with floating label.
91 | #'
92 | #' @param inputId ID of input.
93 | #' @param label Label of input.
94 | #' @param choices Choices, named vector.
95 | #' @param ... Passed to input.
96 | #'
97 | #' @importFrom htmltools tagAppendChild
98 | #'
99 | #' @export
100 | floatingSelectInput <- \(
101 | inputId,
102 | label,
103 | choices = NULL,
104 | ...
105 | ) {
106 | if(missing(inputId))
107 | stop("Missing `inputId`")
108 |
109 | if(missing(label))
110 | stop("Missing `label`")
111 |
112 | select <- tags$select(
113 | id = inputId,
114 | class = "form-select",
115 | `aria-label` = label
116 | )
117 |
118 | if(!is.null(choices)){
119 | for(i in 1:length(choices)) {
120 | nm <- names(choices)[i]
121 | if(is.null(nm))
122 | nm <- unname(choices[i])
123 |
124 | opt <- tags$option(
125 | value = unname(choices[i]),
126 | nm
127 | )
128 | select <- tagAppendChildren(select, opt)
129 | }
130 | }
131 |
132 | div(
133 | class = "form-floating",
134 | select,
135 | tags$label(
136 | `for` = inputId,
137 | label
138 | )
139 | )
140 | }
141 |
142 | #' Switch Input
143 | #'
144 | #' Switch input, similar to checkbox.
145 | #'
146 | #' @param inputId ID of input.
147 | #' @param label Label of input.
148 | #' @param checked Whether the input is initialised checked.
149 | #' @param ... Passed to input.
150 | #'
151 | #' @export
152 | switchInput <- \(
153 | inputId,
154 | label,
155 | checked = FALSE,
156 | ...
157 | ) {
158 | if(missing(inputId))
159 | stop("Missing `inputId`")
160 |
161 | if(missing(label))
162 | stop("Missing `label`")
163 |
164 | input <- tags$input(
165 | class = "form-check-input",
166 | type = "checkbox",
167 | id = inputId,
168 | ...
169 | )
170 |
171 | if(checked)
172 | input <- tagAppendAttributes(input, checked = NA)
173 |
174 | div(
175 | class = "form-check form-switch",
176 | input,
177 | tags$label(
178 | class = "form-check-label",
179 | `for` = inputId,
180 | label
181 | )
182 | )
183 | }
184 |
185 | #' Color Picker Input
186 | #'
187 | #' Color picker input.
188 | #'
189 | #' @param inputId ID of input.
190 | #' @param value Initial value of the input.
191 | #' @param ... Passed to input.
192 | #'
193 | #' @export
194 | colorPickerInput <- \(
195 | inputId,
196 | value = NULL,
197 | ...
198 | ) {
199 | if(missing(inputId))
200 | stop("Missing `inputId`")
201 |
202 | tagList(
203 | get_dep("color"),
204 | tags$input(
205 | type = "color",
206 | class = "form-control form-control-color bsutils-color",
207 | id = inputId,
208 | value = value,
209 | ...
210 | )
211 | )
212 | }
213 |
214 | #' Update Color Picker
215 | #'
216 | #' Update a [colorPickerInput()] from the server.
217 | #'
218 | #' @param id ID of input to update.
219 | #' @param value Value to set.
220 | #' @param session A valid shiny session.
221 | #'
222 | #' @export
223 | update_color_picker <- \(
224 | id,
225 | value,
226 | session = shiny::getDefaultReactiveDomain()
227 | ){
228 | if(missing(id))
229 | stop("Missing `id`")
230 |
231 | if(missing(value))
232 | stop("Missing `value`")
233 |
234 | session$sendInputMessage(id, value)
235 | }
236 |
237 | #' Range Input
238 | #'
239 | #' A range input similar to a slider.
240 | #'
241 | #' @param id ID of input.
242 | #' @param label Label of input.
243 | #' @param value Initial value of input.
244 | #' @param min,max Minimum and maximum values of the range.
245 | #' @param step Step of range change.
246 | #' @param ... Passed to input.
247 | #'
248 | #' @export
249 | rangeInput <- \(
250 | id,
251 | label,
252 | value = 0L,
253 | ...,
254 | min = 0L,
255 | max = 100L,
256 | step = 1L
257 | ) {
258 | if(missing(id))
259 | stop("Missing `id`")
260 |
261 | if(missing(label))
262 | stop("Missing `label`")
263 |
264 | tagList(
265 | get_dep("range"),
266 | tags$label(
267 | label,
268 | `for` = id,
269 | class = "form-label"
270 | ),
271 | tags$input(
272 | type = "range",
273 | class = "form-range bsutils-range",
274 | id = id,
275 | value = value,
276 | min = min,
277 | max = max,
278 | step = step,
279 | ...
280 | )
281 | )
282 | }
283 |
284 | #' Update Range
285 | #'
286 | #' Update a [rangeInput()] from the server.
287 | #'
288 | #' @param id ID of input to update.
289 | #' @param session A valid shiny session.
290 | #' @param ... Elements to update, one or more of,
291 | #' `value`, `min`, and `max`.
292 | #'
293 | #' @export
294 | update_range <- \(
295 | id,
296 | ...,
297 | session = shiny::getDefaultReactiveDomain()
298 | ) {
299 | if(missing(id))
300 | stop("Missing `id`")
301 |
302 | session$sendInputMessage(
303 | id,
304 | list(...)
305 | )
306 | }
307 |
308 | #' Text Group Input
309 | #'
310 | #' Text group input.
311 | #'
312 | #' @param inputId ID of input.
313 | #' @param label Label of input.
314 | #' @param value Initial value of input.
315 | #' @param placeholder Placeholder for input.
316 | #' @param .position Position of the label.
317 | #'
318 | #' @importFrom htmltools tagAppendChildren attachDependencies
319 | #'
320 | #' @export
321 | textGroupInput <- \(
322 | inputId,
323 | label,
324 | value = "",
325 | placeholder = NULL,
326 | .position = c("left", "right")
327 | ) {
328 | if(missing(inputId))
329 | stop("Missing `inputId`")
330 |
331 | if(missing(label))
332 | stop("Missing `label`")
333 |
334 | .position <- match.arg(.position)
335 |
336 | input <- tags$input(
337 | id = inputId,
338 | value = value,
339 | placeholder = placeholder,
340 | class = "form-control bsutils-text-group"
341 | )
342 |
343 | label <- span(
344 | class = "input-group-text",
345 | label
346 | )
347 |
348 | wrapper <- div(
349 | class = "input-group"
350 | )
351 |
352 | if(.position == "left")
353 | div <- tagAppendChildren(
354 | wrapper,
355 | label,
356 | input
357 | )
358 |
359 | if(.position == "right")
360 | div <- tagAppendChildren(
361 | wrapper,
362 | input,
363 | label
364 | )
365 |
366 | attachDependencies(
367 | div,
368 | get_dep("text-group")
369 | )
370 | }
371 |
372 | #' Update Text Group Input
373 | #'
374 | #' Update [textGroupInput()].
375 | #'
376 | #' @param id ID of input to update.
377 | #' @param ... Items to update; `value`, and/or `label`.
378 | #' @param session Valid shiny session.
379 | #'
380 | #' @export
381 | update_text_group <- \(
382 | id,
383 | ...,
384 | session = shiny::getDefaultReactiveDomain()
385 | ) {
386 | session$sendInputMessage(
387 | id,
388 | list(
389 | ...
390 | )
391 | )
392 | }
393 |
--------------------------------------------------------------------------------
/R/list.R:
--------------------------------------------------------------------------------
1 | #' List Group
2 | #'
3 | #' List group, see [listGroupItem()].
4 | #'
5 | #' @param ... Content of the list group, see [listGroupItem()].
6 | #'
7 | #' @export
8 | listGroup <- \(
9 | ...
10 | ) {
11 | tags$ul(
12 | class = "list-group",
13 | ...
14 | )
15 | }
16 |
17 | #' List Group Item
18 | #'
19 | #' Items for [listGroup()].
20 | #'
21 | #' @param ... Content.
22 | #' @param class Additional classes.
23 | #'
24 | #' @export
25 | listGroupItem <- \(
26 | ...,
27 | class = ""
28 | ) {
29 | tags$li(
30 | class = sprintf("list-group-item %s", class),
31 | ...
32 | )
33 | }
--------------------------------------------------------------------------------
/R/modal.R:
--------------------------------------------------------------------------------
1 | #' Modal
2 | #'
3 | #' Create a modal in the UI.
4 | #' The modal is not down see [modal_show()], or
5 | #' [modal_toggle()] (from server).
6 | #'
7 | #' @param id ID of modal.
8 | #' @param ... Content of the modal, [modalBody()],
9 | #' [modalHeader()], [modalFooter()].
10 | #' @param static_backdrop When backdrop is set to static,
11 | #' the modal will not close when clicking outside it.
12 | #' @param scrollable Whether to make the content scrollable.
13 | #' @param centered Whether to make the content vertically
14 | #' centered.
15 | #' @param size Size of the modal.
16 | #'
17 | #' @examples
18 | #' library(shiny)
19 | #'
20 | #' ui <- fluidPage(
21 | #' theme = bslib::bs_theme(version = 5L),
22 | #' actionButton("show", "Show modal"),
23 | #' modal(
24 | #' id = "modal",
25 | #' modalHeader(
26 | #' modalTitle("Title")
27 | #' ),
28 | #' modalBody(
29 | #' p("The content of the modal")
30 | #' ),
31 | #' modalFooter(
32 | #' p("The footer of the modal")
33 | #' )
34 | #' )
35 | #' )
36 | #'
37 | #' server <- \(input, output, session){
38 | #' observeEvent(input$show, {
39 | #' modal_show("modal")
40 | #' })
41 | #' }
42 | #'
43 | #' if(interactive())
44 | #' shinyApp(ui, server)
45 | #'
46 | #' @export
47 | modal <- \(
48 | id,
49 | ...,
50 | static_backdrop = FALSE,
51 | scrollable = FALSE,
52 | centered = FALSE,
53 | size = c(
54 | "default",
55 | "sm",
56 | "lg",
57 | "xl",
58 | "fullscreen",
59 | "fullscreen-sm-down",
60 | "fullscreen-md-down",
61 | "fullscreen-lg-down",
62 | "fullscreen-xl-down",
63 | "fullscreen-xxl-down"
64 | )
65 | ) {
66 | if(missing(id))
67 | stop("Missing `id`")
68 |
69 | size <- match.arg(size)
70 |
71 | dialog_class <- "modal-dialog"
72 | if(scrollable)
73 | dialog_class <- sprintf("%s modal-dialog-scrollable", dialog_class)
74 |
75 | if(centered)
76 | dialog_class <- sprintf("%s modal-dialog-centered", dialog_class)
77 |
78 | dialog_class <- sprintf("%s modal-%s", dialog_class, size)
79 |
80 | modal <- div(
81 | get_dep("modal"),
82 | class = "modal fade",
83 | id = id,
84 | tabindex = "-1",
85 | `aria-hidden` = "true",
86 | div(
87 | class = dialog_class,
88 | div(
89 | class = "modal-content",
90 | ...
91 | )
92 | )
93 | )
94 |
95 | if(static_backdrop)
96 | modal <- modal |>
97 | tagAppendAttributes(
98 | `data-bs-backdrop` = "static"
99 | )
100 |
101 | modal
102 | }
103 |
104 | #' Modal Header
105 | #'
106 | #' Header of a modal, place within [modal()].
107 | #'
108 | #' @param ... Content.
109 | #' @param .close Whether to add the close button.
110 | #'
111 | #' @export
112 | modalHeader <- \(
113 | ...,
114 | .close = TRUE
115 | ) {
116 | if(!.close)
117 | return(div(class = "modal-header", ...))
118 |
119 | div(
120 | class = "modal-header",
121 | ...,
122 | tags$button(
123 | type = "button",
124 | class = "btn-close",
125 | `data-bs-dismiss` = "modal",
126 | `aria-label` = "Close"
127 | )
128 | )
129 | }
130 |
131 | #' Modal Title
132 | #'
133 | #' Modal title, place within [modalHeader()].
134 | #'
135 | #' @param title An HTML tag or a character vector of length 1.
136 | #'
137 | #' @export
138 | modalTitle <- \(
139 | title
140 | ) {
141 | if(inherits(title, "character"))
142 | return(h5(class = "modal-title", title))
143 |
144 | tagAppendAttributes(
145 | title,
146 | class = "modal-title"
147 | )
148 | }
149 |
150 | #' Modal Body
151 | #'
152 | #' Body of the modal, place within [modal()].
153 | #'
154 | #' @param ... Content of the body.
155 | #'
156 | #' @export
157 | modalBody <- \(
158 | ...
159 | ) {
160 | div(
161 | class = "modal-body",
162 | ...
163 | )
164 | }
165 |
166 | #' Modal Footer
167 | #'
168 | #' Footer of the modal, place within [modal()].
169 | #'
170 | #' @param ... Content of the footer.
171 | #'
172 | #' @export
173 | modalFooter <- \(
174 | ...
175 | ) {
176 | div(
177 | class = "modal-footer",
178 | ...
179 | )
180 | }
181 |
182 | #' Modal Toggle
183 | #'
184 | #' Show, hide, or toggle a modal from the server.
185 | #'
186 | #' @param id ID of the [modal()].
187 | #' @param session A valid shiny session.
188 | #'
189 | #' @name modalToggle
190 | #' @export
191 | modal_show <- \(
192 | id,
193 | session = shiny::getDefaultReactiveDomain()
194 | ) {
195 | if(missing(id))
196 | stop("Missing `id`")
197 |
198 | session$sendCustomMessage(
199 | "bsutils-modal",
200 | list(
201 | id = id,
202 | action = "show"
203 | )
204 | )
205 | }
206 |
207 | #' @rdname modalToggle
208 | #' @export
209 | modal_hide <- \(
210 | id,
211 | session = shiny::getDefaultReactiveDomain()
212 | ) {
213 | if(missing(id))
214 | stop("Missing `id`")
215 |
216 | session$sendCustomMessage(
217 | "bsutils-modal",
218 | list(
219 | id = id,
220 | action = "hide"
221 | )
222 | )
223 | }
224 |
225 | #' @rdname modalToggle
226 | #' @export
227 | modal_toggle <- \(
228 | id,
229 | session = shiny::getDefaultReactiveDomain()
230 | ) {
231 | if(missing(id))
232 | stop("Missing `id`")
233 |
234 | session$sendCustomMessage(
235 | "bsutils-modal",
236 | list(
237 | id = id,
238 | action = "toggle"
239 | )
240 | )
241 | }
242 |
243 | #' Modal Triggers
244 | #'
245 | #' Trigger open a modal with a button or a link,
246 | #' avoids goind through the server.
247 | #'
248 | #' @param target Target ID of the [modal()] to show.
249 | #' @param ... Content of link or button, generally a
250 | #' character vector of length 1.
251 | #' @param class Additional class to pass to the button.
252 | #'
253 | #' @name modalTrigger
254 | #' @export
255 | modalButton <- \(
256 | target,
257 | ...,
258 | class = ""
259 | ) {
260 | if(missing(target))
261 | stop("Missing `target`")
262 |
263 | tags$button(
264 | class = sprintf("btn btn-default %s", class),
265 | `data-bs-toggle` = "modal",
266 | `data-bs-target` = sprintf("#%s", target),
267 | ...
268 | )
269 | }
270 |
271 | #' @rdname modalTrigger
272 | #' @export
273 | modalLink <- \(
274 | target,
275 | ...
276 | ) {
277 | if(missing(target))
278 | stop("Missing `target`")
279 |
280 | tags$button(
281 | `data-bs-toggle` = "modal",
282 | `data-bs-target` = sprintf("#%s", target),
283 | ...
284 | )
285 | }
--------------------------------------------------------------------------------
/R/offcanvas.R:
--------------------------------------------------------------------------------
1 | #' Offcanvas
2 | #'
3 | #' Create an offcanvas element.
4 | #'
5 | #' @param trigger A [collapseButton()], [collapseLink()],
6 | #' [shiny::actionButton()], [shiny::actionLink()].
7 | #' @param content The offcanvas content as returned by
8 | #' [offcanvasContent()].
9 | #'
10 | #' @examples
11 | #' library(shiny)
12 | #'
13 | #' ui <- fluidPage(
14 | #' theme = bslib::bs_theme(version = 5L),
15 | #' offcanvas(
16 | #' offcanvasButton(
17 | #' "Open"
18 | #' ),
19 | #' offcanvasContent(
20 | #' offcanvasHeader(
21 | #' "Off canvas"
22 | #' ),
23 | #' p(
24 | #' "Hello world"
25 | #' )
26 | #' )
27 | #' )
28 | #' )
29 | #'
30 | #' server <- \(input, output, session){
31 | #'
32 | #' }
33 | #'
34 | #' if(interactive())
35 | #' shinyApp(ui, server)
36 | #'
37 | #' @importFrom htmltools tagGetAttribute
38 | #'
39 | #' @name offcanvas
40 | #' @export
41 | offcanvas <- \(trigger, content) UseMethod("offcanvas")
42 |
43 | #' @describeIn offcanvas Offcanvas wrapper for [collapseButton()], [collapseLink()].
44 | #' @method offcanvas offcanvasTrigger
45 | #' @export
46 | offcanvas.offcanvasTrigger <- \(
47 | trigger,
48 | content
49 | ){
50 | if(missing(trigger))
51 | stop("Missing `trigger`")
52 |
53 | if(missing(content))
54 | stop("Missing `content`")
55 |
56 | target_id <- tagGetAttribute(content, "id")
57 |
58 | tagList(
59 | trigger(target_id),
60 | content
61 | )
62 | }
63 |
64 | #' @describeIn offcanvas Offcanvas wrapper for [shiny::actionButton()], [shiny::actionLink()].
65 | #' @method offcanvas shiny.tag
66 | #' @export
67 | offcanvas.shiny.tag <- \(
68 | trigger,
69 | content
70 | ){
71 | if(missing(trigger))
72 | stop("Missing `trigger`")
73 |
74 | if(missing(content))
75 | stop("Missing `content`")
76 |
77 | tagList(
78 | trigger,
79 | content
80 | )
81 | }
82 |
83 | #' Offcanvas Button
84 | #'
85 | #' Offcanvas button trigger.
86 | #'
87 | #' @param ... Passed to the button.
88 | #' @param id ID of the button.
89 | #' @param class Additional class to pass to the button.
90 | #' @inheritParams withTooltip
91 | #'
92 | #' @export
93 | offcanvasButton <- \(
94 | ...,
95 | id = NULL,
96 | class = ""
97 | ) {
98 | id <- get_id(id)
99 | class <- sprintf("btn btn-default action-button %s", class)
100 |
101 | btn <- \(target_id) {
102 | tags$button(
103 | id = id,
104 | class = class,
105 | type = "button",
106 | `data-bs-toggle` = "offcanvas",
107 | `data-bs-target` = sprintf("#%s", target_id),
108 | `aria-controls` = target_id,
109 | ...
110 | )
111 | }
112 |
113 | structure(
114 | btn,
115 | class = c("offcanvasTrigger", class(btn))
116 | )
117 | }
118 |
119 | #' @rdname offcanvasButton
120 | #' @export
121 | offcanvasButtonWithTooltip <- \(
122 | ...,
123 | title,
124 | placement = c(
125 | "top",
126 | "right",
127 | "bottom",
128 | "left"
129 | ),
130 | id = NULL,
131 | class = ""
132 | ) {
133 | placement <- match.arg(placement)
134 | id <- get_id(id)
135 | class <- sprintf("btn btn-default action-button %s", class)
136 |
137 | btn <- \(target_id) {
138 | tags$span(
139 | `data-bs-toggle` = "offcanvas",
140 | `data-bs-target` = sprintf("#%s", target_id),
141 | `aria-controls` = target_id,
142 | tags$button(
143 | id = id,
144 | title = HTML(as.character(title)),
145 | class = class,
146 | type = "button",
147 | `data-bs-toggle` = "tooltip",
148 | ...
149 | )
150 | ) |>
151 | htmltools::attachDependencies(
152 | get_dep("tooltip")
153 | )
154 | }
155 |
156 | structure(
157 | btn,
158 | class = c("offcanvasTrigger", class(btn))
159 | )
160 | }
161 |
162 | #' Offcanvas Link
163 | #'
164 | #' Offcanvas link trigger.
165 | #'
166 | #' @param ... Passed to the button.
167 | #' @param id ID of the link.
168 | #' @param class Additional class to pass to the button.
169 | #'
170 | #' @export
171 | offcanvasLink <- \(
172 | ...,
173 | id = NULL,
174 | class = ""
175 | ) {
176 | id <- get_id(id)
177 | class <- sprintf("action-button %s", class)
178 |
179 | lnk <- \(target_id) {
180 | tags$a(
181 | id = id,
182 | class = class,
183 | `data-bs-toggle` = "offcanvas",
184 | `data-bs-target` = sprintf("#%s", target_id),
185 | `aria-controls` = target_id,
186 | ...
187 | )
188 | }
189 |
190 | structure(
191 | lnk,
192 | class = c("offcanvasTrigger", class(lnk))
193 | )
194 | }
195 |
196 | #' Offcanvas Content
197 | #'
198 | #' Offcanvas content.
199 | #'
200 | #' @param ... Content of the offcanvas.
201 | #' @param id Id of the canvas.
202 | #' @param class Additional classes.
203 | #' @param .position Where the canvas should open.
204 | #' @param scroll Whether to allow scrolling the body.
205 | #'
206 | #' @export
207 | offcanvasContent <- \(
208 | ...,
209 | id = NULL,
210 | class = "",
211 | .position = c("start", "end", "top", "bottom"),
212 | scroll = TRUE
213 | ) {
214 | id <- get_id(id)
215 | position <- match.arg(.position)
216 | class <- sprintf("offcanvas offcanvas-%s %s", position, class)
217 |
218 | content <- div(
219 | get_dep("offcanvas"),
220 | class = class,
221 | tabindex = "-1",
222 | id = id,
223 | `data-bs-scroll` = tolower(scroll),
224 | div(
225 | class = "offcanvas-body",
226 | ...
227 | )
228 | )
229 |
230 | structure(
231 | content,
232 | class = c("offcanvasContent", class(content))
233 | )
234 | }
235 |
236 | #' Canvas Header
237 | #'
238 | #' Header for [offcanvasContent()].
239 | #'
240 | #' @param header An HTML tag or a character string.
241 | #'
242 | #' @export
243 | offcanvasHeader <- \(
244 | header
245 | ) {
246 | if(missing(header))
247 | stop("Missing `header`")
248 |
249 | if(is.character(header))
250 | header <- h5(header)
251 |
252 | div(
253 | class = "offcanvas-header",
254 | header,
255 | tags$button(
256 | type = "button",
257 | class = "btn-close text-reset",
258 | `data-bs-dismiss` = "offcanvas",
259 | `aria-label` = "Close"
260 | )
261 | )
262 | }
263 |
264 | #' Offcanvas Server
265 | #'
266 | #' Toggle the offcanvas from the server.
267 | #'
268 | #' @param id ID of [offcanvasContent()].
269 | #' @param session Valid shiny session.
270 | #'
271 | #' @name offcanvasServer
272 | #' @export
273 | offcanvas_show <- \(
274 | id,
275 | session = shiny::getDefaultReactiveDomain()
276 | ) {
277 | if(missing(id))
278 | stop("Missing `id`")
279 |
280 | session$sendCustomMessage(
281 | "bsutils-offcanvas",
282 | list(
283 | id = id,
284 | action = "show"
285 | )
286 | )
287 | }
288 |
289 | #' @rdname offcanvasServer
290 | #' @export
291 | offcanvas_hide <- \(
292 | id,
293 | session = shiny::getDefaultReactiveDomain()
294 | ) {
295 | if(missing(id))
296 | stop("Missing `id`")
297 |
298 | session$sendCustomMessage(
299 | "bsutils-offcanvas",
300 | list(
301 | id = id,
302 | action = "hide"
303 | )
304 | )
305 | }
306 |
307 | #' @rdname offcanvasServer
308 | #' @export
309 | offcanvas_toggle <- \(
310 | id,
311 | session = shiny::getDefaultReactiveDomain()
312 | ) {
313 | if(missing(id))
314 | stop("Missing `id`")
315 |
316 | session$sendCustomMessage(
317 | "bsutils-offcanvas",
318 | list(
319 | id = id,
320 | action = "toggle"
321 | )
322 | )
323 | }
324 |
--------------------------------------------------------------------------------
/R/placeholders.R:
--------------------------------------------------------------------------------
1 | #' As Placeholder
2 | #'
3 | #' Turn an element into a placeholder.
4 | #'
5 | #' @param el Element to turn into a placeholder.
6 | #' @param glow Whether the elements should glow.
7 | #'
8 | #' @examples
9 | #' shiny::p() |>
10 | #' asPlaceholder()
11 | #'
12 | #' shiny::actionButton("id", "") |>
13 | #' asPlaceholder()
14 | #'
15 | #' @export
16 | asPlaceholder <- \(el, glow = FALSE){
17 | if(missing(el))
18 | stop("Missing `el`")
19 |
20 | cls <- "placeholder"
21 | if(glow)
22 | cls <- paste0(cls, "-glow")
23 |
24 | htmltools::tagAppendAttributes(
25 | el,
26 | class = cls
27 | )
28 | }
--------------------------------------------------------------------------------
/R/popover.R:
--------------------------------------------------------------------------------
1 | #' Popover
2 | #'
3 | #' Add a popover to an element.
4 | #'
5 | #' @param el Element to place popover on.
6 | #' @param content Content of the popover.
7 | #' @param title Optional popover title.
8 | #' @param container container of the popover.
9 | #' @param placement Position of the popover.
10 | #'
11 | #' @export
12 | withPopover <- \(
13 | el,
14 | content,
15 | title = NULL,
16 | container = "body",
17 | placement = c(
18 | "top",
19 | "right",
20 | "bottom",
21 | "left"
22 | )
23 | ) {
24 | if(missing(el))
25 | stop("Missing `el`")
26 |
27 | if(missing(content))
28 | stop("Missing `content`")
29 |
30 | placement <- match.arg(placement)
31 |
32 | el <- tagAppendAttributes(
33 | el,
34 | `data-bs-toggle` = "popover",
35 | `data-bs-content` = content,
36 | `data-bs-placement` = placement,
37 | `data-bs-container` = container
38 | )
39 |
40 | if(!is.null(title))
41 | el <- tagAppendAttributes(
42 | el,
43 | title = title
44 | )
45 |
46 | htmltools::attachDependencies(el, get_dep("popover"))
47 | }
--------------------------------------------------------------------------------
/R/progress.R:
--------------------------------------------------------------------------------
1 | #' Progress
2 | #'
3 | #' Progress bars.
4 | #'
5 | #' @param ... Progress bars as returned by [progressBar()].
6 | #' @param id Parent id.
7 | #'
8 | #' @examples
9 | #' library(shiny)
10 | #'
11 | #' ui <- fluidPage(
12 | #' theme = bslib::bs_theme(version = 5L),
13 | #' actionButton(
14 | #' "rand",
15 | #' "Randomise"
16 | #' ),
17 | #' progress(
18 | #' progressBar(15, id = "bar")
19 | #' )
20 | #' )
21 | #'
22 | #' server <- \(input, output, session){
23 | #' observeEvent(input$rand, {
24 | #' update_progress("bar", sample(10:99, 1))
25 | #' })
26 | #' }
27 | #'
28 | #' if(interactive())
29 | #' shinyApp(ui, server)
30 | #'
31 | #' @export
32 | progress <- \(
33 | ...,
34 | id = NULL
35 | ) {
36 | div(
37 | class = "progress",
38 | ...
39 | )
40 | }
41 |
42 | #' Progress Bar
43 | #'
44 | #' A progress bar to pass to [progress()].
45 | #'
46 | #' @param value Value of progress bar.
47 | #' @param min,max Minimum and maximum values.
48 | #' @param id ID of progress bar.
49 | #' @param class Additional classes.
50 | #'
51 | #' @export
52 | progressBar <- \(
53 | value = 0L,
54 | min = 0L,
55 | max = 100L,
56 | id = NULL,
57 | class = ""
58 | ) {
59 | if(value < 0L || value > 100L)
60 | stop("`value` must be between 0 and 100")
61 |
62 | id <- get_id(id)
63 | val <- round((value / max) * 100)
64 | style <- sprintf("width: %s%%;", val)
65 |
66 | tagList(
67 | get_dep("progress"),
68 | div(
69 | id = id,
70 | class = sprintf("bsutils-progress progress-bar %s", class),
71 | role = "progressbar",
72 | style = style,
73 | `aria-valuenow` = value,
74 | `aria-valuemin` = min,
75 | `aria-valuemax` = max
76 | )
77 | )
78 | }
79 |
80 | #' Update Progress
81 | #'
82 | #' Update a [progressBar()].
83 | #'
84 | #' @param id ID of progress bar to update.
85 | #' @param value Value to set the progress bar to.
86 | #' @param session A valid shiny session.
87 | #'
88 | #' @export
89 | update_progress <- \(
90 | id,
91 | value,
92 | session = shiny::getDefaultReactiveDomain()
93 | ){
94 | if(missing(id))
95 | stop("Missing `id`")
96 |
97 | if(missing(value))
98 | stop("Missing `value`")
99 |
100 | session$sendInputMessage(id, value)
101 | }
102 |
--------------------------------------------------------------------------------
/R/toast.R:
--------------------------------------------------------------------------------
1 | #' Toast
2 | #'
3 | #' Toast notifications.
4 | #'
5 | #' @param id ID of toast, used to show/hide from server.
6 | #' @param ... Content, generally [toastHeader()], [toastBody()].
7 | #' @param class Any additional classes.
8 | #' @param position Position of the toast.
9 | #'
10 | #' @examples
11 | #' library(shiny)
12 | #'
13 | #' ui <- fluidPage(
14 | #' theme = bslib::bs_theme(version = 5L),
15 | #' toast(
16 | #' "toast",
17 | #' toastHeader(
18 | #' strong(
19 | #' "Toast",
20 | #' class = "me-auto"
21 | #' )
22 | #' ),
23 | #' toastBody("The body of the toast!")
24 | #' ),
25 | #' h1("Hello"),
26 | #' actionButton("show", "Show toast"),
27 | #' actionButton("hide", "Hide toast")
28 | #' )
29 | #'
30 | #' server <- \(input, output, session){
31 | #' observeEvent(input$show, {
32 | #' toast_show("toast", auto_hide = FALSE)
33 | #' })
34 | #'
35 | #' observeEvent(input$hide, {
36 | #' toast_hide("toast")
37 | #' })
38 | #' }
39 | #'
40 | #' if(interactive())
41 | #' shinyApp(ui, server)
42 | #'
43 | #' @export
44 | toast <- \(
45 | id,
46 | ...,
47 | class = "",
48 | position = c(
49 | "top-right",
50 | "top-left",
51 | "bottom-right",
52 | "bottom-left"
53 | )
54 | ) {
55 | if(missing(id))
56 | stop("Missing `id`")
57 |
58 | style <- get_position(position)
59 |
60 | tagList(
61 | get_dep("toast"),
62 | div(
63 | class = sprintf("position-fixed %s", style),
64 | div(
65 | class = sprintf("toast %s", class),
66 | role = "alert",
67 | `aria-live` = "assertive",
68 | `aria-atomic` = "true",
69 | id = id,
70 | ...
71 | )
72 | )
73 | )
74 | }
75 |
76 | #' Toast Content
77 | #'
78 | #' Content of the toast to place within [toast()].
79 | #'
80 | #' @param ... Content.
81 | #' @param class Any additional class.
82 | #'
83 | #' @name toastContent
84 | #'
85 | #' @export
86 | toastHeader <- \(
87 | ...,
88 | class = ""
89 | ) {
90 | div(
91 | class = sprintf("toast-header %s", class),
92 | ...,
93 | tags$button(
94 | type = "button",
95 | class = "btn-close",
96 | `data-bs-dismiss` = "toast",
97 | `aria-label` = "Close"
98 | )
99 | )
100 | }
101 |
102 | #' @rdname toastContent
103 | #' @export
104 | toastBody <- \(
105 | ...,
106 | class = ""
107 | ) {
108 | div(
109 | class = sprintf("toast-body %s", class),
110 | ...
111 | )
112 | }
113 |
114 | #' Toast Toggle
115 | #'
116 | #' Show or hide a toast.
117 | #'
118 | #' @param id ID of [toast()] to toggle.
119 | #' @param animation Whether to animate the toast.
120 | #' @param auto_hide Whether to automatically hide the
121 | #' toast after `delay`.
122 | #' @param delay Milliseconds after which to hide the
123 | #' toast (if `auto_hide = TRUE`).
124 | #' @param session A valid shiny session.
125 | #' @param header,body Header and body of the toast
126 | #' to replace existing content.
127 | #'
128 | #' @name toastToggle
129 | #'
130 | #' @export
131 | toast_show <- \(
132 | id,
133 | header = NULL,
134 | body = NULL,
135 | animation = TRUE,
136 | auto_hide = TRUE,
137 | delay = 5000L,
138 | session = shiny::getDefaultReactiveDomain()
139 | ) {
140 | id <- namespace(session, id)
141 |
142 | if(!is.null(body))
143 | body <- as.character(body)
144 |
145 | if(!is.null(header))
146 | header <- as.character(header)
147 |
148 | session$sendCustomMessage(
149 | "bsutils-toast",
150 | list(
151 | id = id,
152 | action = "show",
153 | body = body,
154 | header = header,
155 | opts = list(
156 | animation = animation,
157 | autohide = auto_hide,
158 | delay = delay
159 | )
160 | )
161 | )
162 | }
163 |
164 | #' @rdname toastToggle
165 | #' @export
166 | toast_hide <- \(
167 | id,
168 | session = shiny::getDefaultReactiveDomain()
169 | ) {
170 | id <- namespace(session, id)
171 |
172 | session$sendCustomMessage(
173 | "bsutils-toast",
174 | list(
175 | id = id,
176 | action = "hide",
177 | opts = list()
178 | )
179 | )
180 | }
181 |
--------------------------------------------------------------------------------
/R/tooltip.R:
--------------------------------------------------------------------------------
1 | #' Tooltip
2 | #'
3 | #' Add a tooltip to an element.
4 | #'
5 | #' @param el Element.
6 | #' @param title HTML tag or character vector of length 1.
7 | #' @param placement Placement of the tooltip.
8 | #'
9 | #' @examples
10 | #' library(shiny)
11 | #'
12 | #' ui <- fluidPage(
13 | #' theme = bslib::bs_theme(version = 5L),
14 | #' withTooltip(
15 | #' span("plain"),
16 | #' "content"
17 | #' ),
18 | #' br(),
19 | #' withTooltip(
20 | #' span("HTML"),
21 | #' tagList(
22 | #' strong("HTML"),
23 | #' "content"
24 | #' )
25 | #' )
26 | #' )
27 | #'
28 | #' server <- \(input, output, session){
29 | #' }
30 | #'
31 | #' if(interactive())
32 | #' shinyApp(ui, server)
33 | #'
34 | #' @export
35 | withTooltip <- \(
36 | el,
37 | title,
38 | placement = c(
39 | "top",
40 | "right",
41 | "bottom",
42 | "left"
43 | )
44 | ) {
45 | placement <- match.arg(placement)
46 | tagAppendAttributes(
47 | el,
48 | title = HTML(as.character(title)),
49 | `data-bs-placement` = placement,
50 | `data-bs-toggle` = "tooltip",
51 | `data-bs-html` = "true"
52 | ) |>
53 | htmltools::attachDependencies(
54 | get_dep("tooltip")
55 | )
56 | }
--------------------------------------------------------------------------------
/R/utils.R:
--------------------------------------------------------------------------------
1 | make_id <- \(){
2 | letters |>
3 | sample(10L) |>
4 | paste0(collapse = "")
5 | }
6 |
7 | get_id <- \(id = NULL) {
8 | if(!is.null(id))
9 | return(id)
10 |
11 | make_id()
12 | }
13 |
14 | namespace <- \(
15 | session,
16 | id
17 | ) {
18 | ns <- session$ns(NULL)
19 |
20 | if(length(ns) == 0L)
21 | return(id)
22 |
23 | sprintf("%s-%s", ns, id)
24 | }
25 |
26 | get_position <- \(
27 | position = c(
28 | "top-right",
29 | "top-left",
30 | "bottom-right",
31 | "bottom-left"
32 | )
33 | ) {
34 | position <- match.arg(position)
35 |
36 | if(position == "top-right")
37 | return("top-0 end-0")
38 |
39 | if(position == "top-left")
40 | return("top-0 start-0")
41 |
42 | if(position == "bottom-right")
43 | return("bottom-0 end-0")
44 |
45 | "bottom-0 start-0"
46 | }
47 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | # bsutils
5 |
6 | UI utilities for Bootstrap 5 and Shiny.
7 |
8 | ## Installation
9 |
10 | ``` r
11 | # install.packages("devtools")
12 | devtools::install_github("JohnCoene/bsutils")
13 | ```
14 |
15 | ## Utilities
16 |
17 | - Accordion
18 | - Alerts
19 | - Badge
20 | - Card
21 | - Carousel
22 | - Collapse
23 | - Color input
24 | - Dropdown
25 | - Floating select input
26 | - Floating text input
27 | - Floating textarea input
28 | - List group
29 | - Modal
30 | - Offcanvas
31 | - Placeholder
32 | - Popover
33 | - Progress
34 | - Range input
35 | - Switch input
36 | - Text group input
37 | - Toast
38 | - Tooltip
39 |
40 | ## Example
41 |
42 | Run `bsutils::gallery()` for a demo.
43 |
44 | Make sure you use __Bootstrap version 5__.
45 |
46 | ```r
47 | library(shiny)
48 | library(bsutils)
49 |
50 | ui <- fluidPage(
51 | theme = bslib::bs_theme(version = 5L),
52 | offcanvas(
53 | offcanvasButton(
54 | "Open"
55 | ),
56 | offcanvasContent(
57 | offcanvasHeader(
58 | "Off canvas"
59 | ),
60 | p(
61 | "Hello world"
62 | )
63 | )
64 | )
65 | )
66 |
67 | server <- \(input, output, session){}
68 |
69 | shinyApp(ui, server)
70 | ```
71 |
--------------------------------------------------------------------------------
/inst/app/app.R:
--------------------------------------------------------------------------------
1 | library(shiny)
2 | library(bsutils)
3 |
4 | code <- \(code) {
5 | tags$pre(
6 | tags$code(
7 | class = "language-r",
8 | code
9 | )
10 | )
11 | }
12 |
13 | ui <- navbarPage(
14 | "bsutils",
15 | theme = bslib::bs_theme(version = 5L),
16 | header = list(
17 | tags$link(
18 | href = "https://unpkg.com/prismjs@v1.x/themes/prism.css",
19 | rel = "stylesheet"
20 | )
21 | ),
22 | tabPanel(
23 | "Accordion",
24 | fluidRow(
25 | column(
26 | 6,
27 | accordion(
28 | accordionItem(
29 | .expanded = TRUE,
30 | "Something",
31 | p("Some content")
32 | ),
33 | accordionItem(
34 | "Something else",
35 | p("Some other content")
36 | ),
37 | accordionItem(
38 | "Another thing",
39 | p("Some other item")
40 | )
41 | )
42 | ),
43 | column(
44 | 6,
45 | code(
46 | '
47 | accordion(
48 | accordionItem(
49 | .expanded = TRUE,
50 | "Something",
51 | p("Some content")
52 | ),
53 | accordionItem(
54 | "Something else",
55 | p("Some other content")
56 | ),
57 | accordionItem(
58 | "Another thing",
59 | p("Some other item")
60 | )
61 | )'
62 | )
63 | )
64 | )
65 | ),
66 | tabPanel(
67 | "Carousel",
68 | carousel(
69 | indicators = TRUE,
70 | controls = TRUE,
71 | carouselItem(
72 | h5("First"),
73 | p("First carousel slide"),
74 | class = "bg-primary rounded p-4"
75 | ),
76 | carouselItem(
77 | h5("Second"),
78 | p("Second carousel slide"),
79 | class = "bg-info rounded p-4"
80 | )
81 | ),
82 | code(
83 | '
84 | carousel(
85 | indicators = TRUE,
86 | controls = TRUE,
87 | carouselItem(
88 | h5("First"),
89 | p("First carousel slide"),
90 | class = "bg-primary rounded p-4"
91 | ),
92 | carouselItem(
93 | h5("Second"),
94 | p("Second carousel slide"),
95 | class = "bg-info rounded p-4"
96 | )
97 | )'
98 | ),
99 | tags$a(
100 | "Should I use a carousel?",
101 | href = "https://shouldiuseacarousel.com/",
102 | target = "_blank"
103 | )
104 | ),
105 | tabPanel(
106 | "Collapsible",
107 | fluidRow(
108 | column(
109 | 6,
110 | collapse(
111 | collapseButton(
112 | "Reveal",
113 | id = "x"
114 | ),
115 | collapseContent(
116 | "Some collapsed content"
117 | )
118 | )
119 | ),
120 | column(
121 | 6,
122 | code(
123 | '
124 | collapse(
125 | collapseButton(
126 | "Reveal",
127 | id = "x"
128 | ),
129 | collapseContent(
130 | "Some collapsed content"
131 | )
132 | )'
133 | )
134 | )
135 | )
136 | ),
137 | tabPanel(
138 | "Buttons",
139 | h4("Dropdown"),
140 | fluidRow(
141 | column(
142 | 6,
143 | dropdownButton(
144 | "Buttons",
145 | actionLink("first", "First"),
146 | actionLink("second", "Second"),
147 | actionLink("third", "Third")
148 | )
149 | ),
150 | column(
151 | 6,
152 | code(
153 | '
154 | dropdownButton(
155 | "Buttons",
156 | actionLink("first", "First"),
157 | actionLink("second", "Second"),
158 | actionLink("third", "Third")
159 | )'
160 | )
161 | )
162 | ),
163 | h4("Group"),
164 | buttonGroup(
165 | actionButton("first", "First", class = "btn-primary"),
166 | actionButton("second", "Second", class = "btn-warning"),
167 | actionButton("third", "Third", class = "btn-success")
168 | ),
169 | code(
170 | '
171 | buttonGroup(
172 | actionButton("first", "First", class = "btn-primary"),
173 | actionButton("second", "Second", class = "btn-warning"),
174 | actionButton("third", "Third", class = "btn-success")
175 | )'
176 | )
177 | ),
178 | tabPanel(
179 | "Offcanvas",
180 | offcanvas(
181 | offcanvasButton(
182 | "Open"
183 | ),
184 | offcanvasContent(
185 | offcanvasHeader(
186 | "Off canvas"
187 | ),
188 | p(
189 | "Hello world"
190 | ),
191 | plotOutput("plot")
192 | )
193 | ),
194 | code(
195 | '
196 | offcanvas(
197 | offcanvasButton(
198 | "Open"
199 | ),
200 | offcanvasContent(
201 | offcanvasHeader(
202 | "Off canvas"
203 | ),
204 | p(
205 | "Hello world"
206 | ),
207 | uiOutput("text")
208 | )
209 | )'
210 | ),
211 | tags$script(
212 | src = "https://unpkg.com/prismjs@v1.x/components/prism-core.min.js"
213 | ),
214 | tags$script(
215 | src = "https://unpkg.com/prismjs@v1.x/plugins/autoloader/prism-autoloader.min.js"
216 | )
217 | ),
218 | tabPanel(
219 | "Progress",
220 | actionButton(
221 | "rand",
222 | "Randomise"
223 | ),
224 | progress(
225 | progressBar(15, id = "bar")
226 | ),
227 | h4("UI"),
228 | code(
229 | '
230 | actionButton(
231 | "rand",
232 | "Randomise"
233 | ),
234 | progress(
235 | progressBar(15, id = "bar")
236 | )'
237 | ),
238 | h4("Server"),
239 | code(
240 | '
241 | observeEvent(input$rand, {
242 | update_progress("bar", sample(10:99, 1))
243 | })'
244 | )
245 | ),
246 | tabPanel(
247 | "Toast",
248 | toast(
249 | "toast",
250 | toastHeader(
251 | strong(
252 | "Toast",
253 | class = "me-auto"
254 | )
255 | ),
256 | toastBody("The body of the toast!")
257 | ),
258 | h1("Hello"),
259 | actionButton("show", "Show toast"),
260 | actionButton("hide", "Hide toast"),
261 | h4("UI"),
262 | code(
263 | '
264 | toast(
265 | "toast",
266 | toastHeader(
267 | strong(
268 | "Toast",
269 | class = "me-auto"
270 | )
271 | ),
272 | toastBody("The body of the toast!")
273 | )'
274 | ),
275 | h4("Server"),
276 | code(
277 | '
278 | observeEvent(input$show, {
279 | toast_show("toast", auto_hide = FALSE)
280 | })
281 |
282 | observeEvent(input$hide, {
283 | toast_hide("toast")
284 | })'
285 | )
286 | ),
287 | tabPanel(
288 | "Modal",
289 | actionButton("show_modal", "Show modal"),
290 | modal(
291 | id = "modal",
292 | modalHeader(
293 | modalTitle("Title")
294 | ),
295 | modalBody(
296 | p("The content of the modal")
297 | ),
298 | modalFooter(
299 | p("The footer of the modal")
300 | )
301 | ),
302 | h4("UI"),
303 | code(
304 | '
305 | modal(
306 | id = "modal",
307 | modalHeader(
308 | modalTitle("Title")
309 | ),
310 | modalBody(
311 | p("The content of the modal")
312 | ),
313 | modalFooter(
314 | p("The footer of the modal")
315 | )
316 | )'
317 | ),
318 | h4("Server"),
319 | code(
320 | '
321 | observeEvent(input$show, {
322 | modal_show("modal")
323 | })'
324 | )
325 | ),
326 | tabPanel(
327 | "Tooltips",
328 | fluidRow(
329 | column(
330 | 4,
331 | withTooltip(
332 | span("plain"),
333 | "content"
334 | )
335 | ),
336 | column(
337 | 8,
338 | code(
339 | '
340 | withTooltip(
341 | span("plain"),
342 | "content"
343 | )'
344 | )
345 | )
346 | ),
347 | fluidRow(
348 | column(
349 | 4,
350 | withTooltip(
351 | span("HTML"),
352 | tagList(
353 | strong("HTML"),
354 | "content"
355 | )
356 | )
357 | ),
358 | column(
359 | 8,
360 | code(
361 | '
362 | withTooltip(
363 | span("HTML"),
364 | tagList(
365 | strong("HTML"),
366 | "content"
367 | )
368 | )'
369 | )
370 | )
371 | )
372 | ),
373 | tabPanel(
374 | "List",
375 | fluidRow(
376 | column(
377 | 4,
378 | listGroup(
379 | listGroupItem("Item 1"),
380 | listGroupItem("Item 2"),
381 | listGroupItem("Item 3"),
382 | listGroupItem("Item 4")
383 | )
384 | ),
385 | column(
386 | 8,
387 | code(
388 | '
389 | listGroup(
390 | listGroupItem("Item 1"),
391 | listGroupItem("Item 2"),
392 | listGroupItem("Item 3"),
393 | listGroupItem("Item 4")
394 | )'
395 | )
396 | )
397 | )
398 | ),
399 | tabPanel(
400 | "Popover",
401 | withPopover(
402 | span("click me"),
403 | "The content",
404 | "The title"
405 | ),
406 | code(
407 | '
408 | withPopover(
409 | span("click me"),
410 | "The content",
411 | "The title"
412 | )'
413 | )
414 | ),
415 | tabPanel(
416 | "Inputs",
417 | fluidRow(
418 | column(
419 | 6,
420 | floatingTextInput(
421 | "text",
422 | "Text input",
423 | "placeholder text"
424 | )
425 | ),
426 | column(
427 | 6,
428 | code(
429 | '
430 | floatingTextInput(
431 | "text",
432 | "Text input",
433 | "placeholder text"
434 | )'
435 | )
436 | )
437 | ),
438 | fluidRow(
439 | column(
440 | 6,
441 | floatingTextAreaInput(
442 | "textarea",
443 | "Text input",
444 | "placeholder text",
445 | style = "height: 10rem;"
446 | )
447 | ),
448 | column(
449 | 6,
450 | code(
451 | '
452 | floatingTextAreaInput(
453 | "textarea",
454 | "Text input",
455 | "placeholder text",
456 | style = "height: 10rem;"
457 | )'
458 | )
459 | )
460 | ),
461 | fluidRow(
462 | column(
463 | 6,
464 | floatingSelectInput(
465 | "select",
466 | "Select Something",
467 | letters
468 | )
469 | ),
470 | column(
471 | 6,
472 | code(
473 | '
474 | floatingSelectInput(
475 | "select",
476 | "Select Something",
477 | letters
478 | )'
479 | )
480 | )
481 | ),
482 | fluidRow(
483 | column(
484 | 6,
485 | switchInput(
486 | "switch",
487 | "Switch input"
488 | )
489 | ),
490 | column(
491 | 6,
492 | code(
493 | '
494 | switchInput(
495 | "switch",
496 | "Switch input"
497 | )'
498 | )
499 | )
500 | ),
501 | fluidRow(
502 | column(
503 | 6,
504 | colorPickerInput(
505 | "color",
506 | value = "#000000"
507 | )
508 | ),
509 | column(
510 | 6,
511 | code(
512 | '
513 | colorPickerInput(
514 | "color",
515 | value = "#000000"
516 | )'
517 | )
518 | )
519 | ),
520 | fluidRow(
521 | column(
522 | 6,
523 | rangeInput(
524 | "range",
525 | "A range input"
526 | )
527 | ),
528 | column(
529 | 6,
530 | code(
531 | '
532 | rangeInput(
533 | "range",
534 | "A range input"
535 | )'
536 | )
537 | )
538 | ),
539 | fluidRow(
540 | column(
541 | 6,
542 | textGroupInput(
543 | "textGroup",
544 | "@",
545 | placeholder = "username"
546 | )
547 | ),
548 | column(
549 | 6,
550 | code(
551 | '
552 | textGroupInput(
553 | "textGroup",
554 | "@",
555 | placeholder = "username"
556 | )'
557 | )
558 | )
559 | )
560 | )
561 | )
562 |
563 | server <- \(input, output, session) {
564 |
565 | output$plot <- renderPlot({
566 | plot(cars)
567 | })
568 |
569 | observeEvent(input$rand, {
570 | update_progress("bar", sample(10:99, 1))
571 | })
572 |
573 | observeEvent(input$show, {
574 | toast_show("toast", auto_hide = FALSE)
575 | })
576 |
577 | observeEvent(input$hide, {
578 | toast_hide("toast")
579 | })
580 |
581 | observeEvent(input$show_modal, {
582 | modal_show("modal")
583 | })
584 |
585 | observeEvent(input$text, {
586 | print(input$text)
587 | })
588 |
589 | observeEvent(input$textarea, {
590 | print(input$textarea)
591 | })
592 |
593 | observeEvent(input$select, {
594 | print(input$select)
595 | })
596 |
597 | observeEvent(input$switch, {
598 | print(input$switch)
599 | })
600 |
601 | observeEvent(input$color, {
602 | print(input$color)
603 | })
604 |
605 | observeEvent(input$range, {
606 | print(input$range)
607 | })
608 |
609 | observeEvent(input$textGroup, {
610 | print(input$textGroup)
611 | })
612 | }
613 |
614 | shinyApp(ui, server)
615 |
--------------------------------------------------------------------------------
/inst/assets/alert.js:
--------------------------------------------------------------------------------
1 | import 'shiny';
2 |
3 | $(function() {
4 | Shiny.addCustomMessageHandler('alert-show', (msg) => {
5 | $(`#${msg}`).show();
6 | });
7 |
8 | Shiny.addCustomMessageHandler('alert-hide', (msg) => {
9 | $(`#${msg}`).hide();
10 | });
11 | });
--------------------------------------------------------------------------------
/inst/assets/carousel.js:
--------------------------------------------------------------------------------
1 | $(() => {
2 | $("body").on("slide.bs.carousel", ".bsutils-carousel", (event) => {
3 | $(event.target).trigger("shown");
4 | });
5 | });
6 |
--------------------------------------------------------------------------------
/inst/assets/color.js:
--------------------------------------------------------------------------------
1 | var color = new Shiny.InputBinding();
2 |
3 | $.extend(color, {
4 | find: function(scope) {
5 | return $(scope).find(".bsutils-color");
6 | },
7 | getValue: function(el) {
8 | return $(el).val();
9 | },
10 | setValue: function(el, value) {
11 | $(el).val(value);
12 | $(el).change();
13 | },
14 | receiveMessage: function(el, value){
15 | this.setValue(el, value);
16 | },
17 | subscribe: function (el, callback) {
18 | $(el).on("change.bsutils-color", function(){
19 | callback(true);
20 | })
21 | },
22 | unsubscribe: function(el) {
23 | $(el).off(".bsutils-color");
24 | }
25 | });
26 |
27 | Shiny.inputBindings.register(color, 'bsutils.color');
28 |
--------------------------------------------------------------------------------
/inst/assets/modal.js:
--------------------------------------------------------------------------------
1 | Shiny.addCustomMessageHandler('bsutils-modal', (msg) => {
2 | var modal = bootstrap.Modal.getOrCreateInstance(
3 | document.getElementById(msg.id),
4 | {},
5 | );
6 |
7 | if(msg.action == 'show'){
8 | modal.show();
9 | return;
10 | }
11 |
12 | if(msg.action == 'hide'){
13 | modal.hide();
14 | return;
15 | }
16 |
17 | modal.toggle();
18 | });
--------------------------------------------------------------------------------
/inst/assets/offcanvas.js:
--------------------------------------------------------------------------------
1 | Shiny.addCustomMessageHandler('bsutils-offcanvas', (msg) => {
2 | let el = document.getElementById(msg.id);
3 | let canvas = bootstrap.Offcanvas.getOrCreateInstance(el, msg.opts);
4 |
5 | if(msg.action == "show") {
6 | canvas.show();
7 | return;
8 | }
9 |
10 | if(msg.action == "hide") {
11 | canvas.hide();
12 | return;
13 | }
14 |
15 | canvas.toggle();
16 | });
17 |
--------------------------------------------------------------------------------
/inst/assets/popover.js:
--------------------------------------------------------------------------------
1 | $(document).on('shiny:connected', () => {
2 | setTimeout(() => {
3 | var popoverTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="popover"]'));
4 | var popoverList = popoverTriggerList.map(function (popoverTriggerEl) {
5 | return new bootstrap.Popover(popoverTriggerEl)
6 | });
7 | }, 250);
8 | });
--------------------------------------------------------------------------------
/inst/assets/progress.js:
--------------------------------------------------------------------------------
1 | var progress = new Shiny.InputBinding();
2 |
3 | $.extend(progress, {
4 | find: function(scope) {
5 | return $(scope).find(".bsutils-progress");
6 | },
7 | getValue: function(el) {
8 | return $(el).attr("aria-valuenow");
9 | },
10 | setValue: function(el, value) {
11 | let max = $(el).attr("aria-valuemax");
12 | let val = Math.ceil((value / max) * 100);
13 | $(el).css('width', `${val}%`);
14 | $(el).attr("aria-valuenow", value).change();
15 | },
16 | receiveMessage: function(el, value){
17 | this.setValue(el, value);
18 | },
19 | subscribe: function (el, callback) {
20 | $(el).on("change.bsutils-progress", function(){
21 | callback(true);
22 | })
23 | },
24 | unsubscribe: function(el) {
25 | $(el).off(".bsutils-progress");
26 | }
27 | });
28 |
29 | Shiny.inputBindings.register(progress, 'bsutils.progress');
30 |
--------------------------------------------------------------------------------
/inst/assets/range.js:
--------------------------------------------------------------------------------
1 | var range = new Shiny.InputBinding();
2 |
3 | $.extend(range, {
4 | find: function(scope) {
5 | return $(scope).find(".bsutils-range");
6 | },
7 | getValue: function(el) {
8 | return parseInt($(el).val());
9 | },
10 | setValue: function(el, value) {
11 | $(el).val(value);
12 | $(el).change();
13 | },
14 | receiveMessage: function(el, msg){
15 | if(msg.value)
16 | this.setValue(el, msg.value);
17 |
18 | if(msg.min)
19 | $(el).attr('min', msg.min);
20 |
21 | if(msg.max)
22 | $(el).attr('max', msg.max);
23 | },
24 | subscribe: function (el, callback) {
25 | $(el).on("change.bsutils-range", function(){
26 | callback(true);
27 | })
28 | },
29 | unsubscribe: function(el) {
30 | $(el).off(".bsutils-range");
31 | }
32 | });
33 |
34 | Shiny.inputBindings.register(range, 'bsutils.range');
35 |
36 |
--------------------------------------------------------------------------------
/inst/assets/text-group.js:
--------------------------------------------------------------------------------
1 | var textGroup = new Shiny.InputBinding();
2 |
3 | $.extend(textGroup, {
4 | find: function(scope) {
5 | return $(scope).find(".bsutils-text-group");
6 | },
7 | getValue: function(el) {
8 | return $(el).val();
9 | },
10 | setValue: function(el, value) {
11 | $(el).val(value);
12 | },
13 | receiveMessage: function(el, msg){
14 | if(msg.value)
15 | this.setValue(el, msg.value);
16 |
17 | if(msg.label)
18 | $(el).siblings('span').text(msg.label);
19 | },
20 | subscribe: function (el, callback) {
21 | $(el).on("keyup.bsutils-text-group input.bsutils-text-group", function(){
22 | callback(true);
23 | });
24 |
25 | $(el).on("change.bsutils-text-group", function(){
26 | callback(false);
27 | });
28 | },
29 | unsubscribe: function(el) {
30 | $(el).off(".bsutils-text-group");
31 | },
32 | getRatePolicy: function(){
33 | return {
34 | policy: 'debounce',
35 | delay: 250
36 | }
37 | }
38 | });
39 |
40 | Shiny.inputBindings.register(textGroup, 'bsutils.bsutils-text-group');
41 |
42 |
43 |
--------------------------------------------------------------------------------
/inst/assets/toast.js:
--------------------------------------------------------------------------------
1 | Shiny.addCustomMessageHandler("bsutils-toast", (msg) => {
2 | let el = document.getElementById(msg.id);
3 | let toast = bootstrap.Toast.getOrCreateInstance(el, msg.opts);
4 |
5 | if (msg.body) {
6 | $(el).find(".toast-body").html(msg.body);
7 | }
8 |
9 | if (msg.header) {
10 | $(el).find(".toast-header").html(msg.header);
11 | }
12 |
13 | if (msg.action == "show") {
14 | toast.show();
15 | return;
16 | }
17 |
18 | toast.hide();
19 | });
20 |
--------------------------------------------------------------------------------
/inst/assets/tooltip.js:
--------------------------------------------------------------------------------
1 | setTimeout(() => {
2 | var tooltipTriggerList = [].slice.call(
3 | document.querySelectorAll('[data-bs-toggle="tooltip"]'),
4 | );
5 | var tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) {
6 | return new bootstrap.Tooltip(tooltipTriggerEl);
7 | });
8 | }, 150);
9 |
--------------------------------------------------------------------------------
/makefile:
--------------------------------------------------------------------------------
1 | install: check
2 | Rscript -e "devtools::install()"
3 |
4 | check: document
5 | Rscript -e "devtools::check()"
6 |
7 | document:
8 | Rscript -e "devtools::document()"
9 |
10 | test:
11 | Rscript -e "devtools::test()"
12 |
13 | run:
14 | Rscript test.R
15 |
--------------------------------------------------------------------------------
/man/accordion.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/accordion.R
3 | \name{accordion}
4 | \alias{accordion}
5 | \title{Accordion}
6 | \usage{
7 | accordion(..., .id = NULL, .flush = FALSE)
8 | }
9 | \arguments{
10 | \item{...}{Any number of \code{\link[=accordionItem]{accordionItem()}}.}
11 |
12 | \item{.id}{Id of accordion.}
13 |
14 | \item{.flush}{remove default background color, some
15 | borders, some rounded corners.}
16 | }
17 | \description{
18 | Collapsible accordion made up of \code{\link[=accordionItem]{accordionItem()}}.
19 | }
20 | \examples{
21 | library(shiny)
22 |
23 | ui <- fluidPage(
24 | theme = bslib::bs_theme(version = 5L),
25 | accordion(
26 | accordionItem(
27 | .expanded = TRUE,
28 | "Something",
29 | p("Some content")
30 | ),
31 | accordionItem(
32 | "Something else",
33 | p("Some other content")
34 | )
35 | )
36 | )
37 |
38 | server <- \(input, output, session){
39 |
40 | }
41 |
42 | if(interactive())
43 | shinyApp(ui, server)
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/man/accordionItem.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/accordion.R
3 | \name{accordionItem}
4 | \alias{accordionItem}
5 | \title{AccordionItem}
6 | \usage{
7 | accordionItem(
8 | label,
9 | ...,
10 | .id = NULL,
11 | .expanded = FALSE,
12 | .label_tag = shiny::h2
13 | )
14 | }
15 | \arguments{
16 | \item{label}{Label of the item.}
17 |
18 | \item{...}{Elements to place in the body of the item.}
19 |
20 | \item{.id}{Id of item.}
21 |
22 | \item{.expanded}{Whether the element is initially expanded.}
23 |
24 | \item{.label_tag}{Tag to use for the label.}
25 | }
26 | \description{
27 | Accordion item to place within \code{\link[=accordion]{accordion()}}.
28 | }
29 |
--------------------------------------------------------------------------------
/man/alert.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/alerts.R
3 | \name{alert}
4 | \alias{alert}
5 | \title{Alert}
6 | \usage{
7 | alert(..., id = NULL, class = "")
8 | }
9 | \arguments{
10 | \item{...}{Content of alert.}
11 |
12 | \item{id}{ID of alert useful to toggle from server with
13 | \code{\link[=alert_show]{alert_show()}} or \code{\link[=alert_hide]{alert_hide()}}.}
14 |
15 | \item{class}{Additional classes, e.g.: \code{alert-success}.}
16 | }
17 | \description{
18 | Alert
19 | }
20 | \examples{
21 | alert(
22 | alertHeading("Header!"),
23 | shiny::p("Some content")
24 | )
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/man/alertHeading.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/alerts.R
3 | \name{alertHeading}
4 | \alias{alertHeading}
5 | \title{Alert Heading}
6 | \usage{
7 | alertHeading(heading)
8 | }
9 | \arguments{
10 | \item{heading}{A character string or an HTML tag.}
11 | }
12 | \description{
13 | Alert heading to be placed in \code{\link[=alert]{alert()}}.
14 | }
15 |
--------------------------------------------------------------------------------
/man/alertServer.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/alerts.R
3 | \name{alertServer}
4 | \alias{alertServer}
5 | \alias{alert_show}
6 | \alias{alert_hide}
7 | \title{Toggle Alert}
8 | \usage{
9 | alert_show(id, session = shiny::getDefaultReactiveDomain())
10 |
11 | alert_hide(id, session = shiny::getDefaultReactiveDomain())
12 | }
13 | \arguments{
14 | \item{id}{ID of \code{\link[=alert]{alert()}} to toggle.}
15 |
16 | \item{session}{A valid shiny session.}
17 | }
18 | \description{
19 | Show or hide an alert.
20 | }
21 |
--------------------------------------------------------------------------------
/man/asPlaceholder.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/placeholders.R
3 | \name{asPlaceholder}
4 | \alias{asPlaceholder}
5 | \title{As Placeholder}
6 | \usage{
7 | asPlaceholder(el, glow = FALSE)
8 | }
9 | \arguments{
10 | \item{el}{Element to turn into a placeholder.}
11 |
12 | \item{glow}{Whether the elements should glow.}
13 | }
14 | \description{
15 | Turn an element into a placeholder.
16 | }
17 | \examples{
18 | shiny::p() |>
19 | asPlaceholder()
20 |
21 | shiny::actionButton("id", "") |>
22 | asPlaceholder()
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/man/badge.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/badge.R
3 | \name{badge}
4 | \alias{badge}
5 | \title{Badge}
6 | \usage{
7 | badge(
8 | ...,
9 | color = c("primary", "secondary", "success", "danger", "warning", "info", "light",
10 | "dark"),
11 | pill = FALSE,
12 | class = ""
13 | )
14 | }
15 | \arguments{
16 | \item{...}{Content of the badge.}
17 |
18 | \item{color}{Background color of the badge.}
19 |
20 | \item{pill}{Whether to create a rounded badge.}
21 |
22 | \item{class}{Additional classes to passs to the badge.}
23 | }
24 | \description{
25 | Badge.
26 | }
27 |
--------------------------------------------------------------------------------
/man/buttonGroup.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/group.R
3 | \name{buttonGroup}
4 | \alias{buttonGroup}
5 | \title{Button Group}
6 | \usage{
7 | buttonGroup(..., class = "")
8 | }
9 | \arguments{
10 | \item{...}{Any \code{\link[shiny:actionButton]{shiny::actionButton()}}.}
11 |
12 | \item{class}{Any additional class.}
13 | }
14 | \description{
15 | Group of buttons.
16 | }
17 | \examples{
18 | library(shiny)
19 |
20 | ui <- fluidPage(
21 | theme = bslib::bs_theme(version = 5L),
22 | buttonGroup(
23 | actionButton("first", "First", class = "btn-primary"),
24 | actionButton("second", "Second", class = "btn-warning"),
25 | actionButton("third", "Third", class = "btn-success")
26 | )
27 | )
28 |
29 | server <- \(input, output, session){
30 |
31 | }
32 |
33 | if(interactive())
34 | shinyApp(ui, server)
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/man/card.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/card.R
3 | \name{card}
4 | \alias{card}
5 | \title{Card}
6 | \usage{
7 | card(...)
8 | }
9 | \arguments{
10 | \item{...}{Content, generally \code{\link[=cardBody]{cardBody()}}.}
11 | }
12 | \description{
13 | Card.
14 | }
15 | \examples{
16 | card(
17 | cardHeader("Header"),
18 | cardBody(
19 | cardTitle("Title"),
20 | cardSubtitle("Subtitle"),
21 | cardText("The content of the card")
22 | )
23 | )
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/man/cardBody.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/card.R
3 | \name{cardBody}
4 | \alias{cardBody}
5 | \title{Card Body}
6 | \usage{
7 | cardBody(...)
8 | }
9 | \arguments{
10 | \item{...}{Content, HTML tags, \code{\link[=cardText]{cardText()}}, \code{\link[=cardTitle]{cardTitle()}},
11 | or \code{\link[=cardSubtitle]{cardSubtitle()}}.}
12 | }
13 | \description{
14 | Card body to be placed within \code{\link[=card]{card()}}.
15 | }
16 |
--------------------------------------------------------------------------------
/man/cardHeader.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/card.R
3 | \name{cardHeader}
4 | \alias{cardHeader}
5 | \title{Card Header}
6 | \usage{
7 | cardHeader(content)
8 | }
9 | \arguments{
10 | \item{content}{Content of the title or subtitle, either
11 | a character vector or an HTML header tag.}
12 | }
13 | \description{
14 | Card header placed within \code{\link[=card]{card()}} before \code{\link[=cardBody]{cardBody()}}.
15 | }
16 |
--------------------------------------------------------------------------------
/man/cardText.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/card.R
3 | \name{cardText}
4 | \alias{cardText}
5 | \title{Card Text}
6 | \usage{
7 | cardText(...)
8 | }
9 | \arguments{
10 | \item{...}{Content of the text.}
11 | }
12 | \description{
13 | Card text to be placed in \code{\link[=cardBody]{cardBody()}}.
14 | }
15 |
--------------------------------------------------------------------------------
/man/cardTitle.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/card.R
3 | \name{cardTitle}
4 | \alias{cardTitle}
5 | \alias{cardSubtitle}
6 | \title{Card Title & Subtitle}
7 | \usage{
8 | cardTitle(content)
9 |
10 | cardSubtitle(content)
11 | }
12 | \arguments{
13 | \item{content}{Content of the title or subtitle, either
14 | a character vector or an HTML header tag.}
15 | }
16 | \description{
17 | Card title and subtitle to be placed within \code{\link[=cardBody]{cardBody()}}.
18 | }
19 |
--------------------------------------------------------------------------------
/man/carousel.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/carousel.R
3 | \name{carousel}
4 | \alias{carousel}
5 | \title{Carousel}
6 | \usage{
7 | carousel(..., id = NULL, class = "", controls = FALSE, indicators = FALSE)
8 | }
9 | \arguments{
10 | \item{...}{Slides of the carousel, see \code{\link[=carouselItem]{carouselItem()}}.}
11 |
12 | \item{id}{ID of carousel.}
13 |
14 | \item{class}{Additional class of the carousel.}
15 |
16 | \item{controls}{Whether to show control arrows.}
17 |
18 | \item{indicators}{Whether to show indicators.}
19 | }
20 | \description{
21 | Carousel element.
22 | }
23 | \examples{
24 | library(shiny)
25 |
26 | ui <- fluidPage(
27 | theme = bslib::bs_theme(version = 5L),
28 | carousel(
29 | indicators = TRUE,
30 | controls = TRUE,
31 | carouselItem(
32 | h5("Hello"),
33 | class = "bg-primary rounded p-4"
34 | ),
35 | carouselItem(
36 | h5("World"),
37 | class = "bg-info rounded p-4"
38 | )
39 | )
40 | )
41 |
42 | server <- \(input, output, session){
43 | }
44 |
45 | if(interactive())
46 | shinyApp(ui, server)
47 |
48 | }
49 |
--------------------------------------------------------------------------------
/man/carouselControls.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/carousel.R
3 | \name{carouselControls}
4 | \alias{carouselControls}
5 | \title{Carousel Controls}
6 | \usage{
7 | carouselControls(show, id)
8 | }
9 | \arguments{
10 | \item{show}{Whether to show the control arrows.}
11 |
12 | \item{id}{ID of parent \code{\link[=carousel]{carousel()}}.}
13 | }
14 | \description{
15 | Carousel control arrows.
16 | }
17 | \keyword{internal}
18 |
--------------------------------------------------------------------------------
/man/carouselImg.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/carousel.R
3 | \name{carouselImg}
4 | \alias{carouselImg}
5 | \title{Carousel Image}
6 | \usage{
7 | carouselImg(..., class = "")
8 | }
9 | \arguments{
10 | \item{...}{Passed to \verb{
}.}
11 |
12 | \item{class}{Additional classes.}
13 | }
14 | \description{
15 | Carousel image to use within \code{\link[=carouselItem]{carouselItem()}}.
16 | }
17 |
--------------------------------------------------------------------------------
/man/carouselIndicators.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/carousel.R
3 | \name{carouselIndicators}
4 | \alias{carouselIndicators}
5 | \title{Carousel Indicators}
6 | \usage{
7 | carouselIndicators(items, id, show)
8 | }
9 | \arguments{
10 | \item{items}{list of \code{\link[=carouselItem]{carouselItem()}}.}
11 |
12 | \item{id}{Parent if of \code{\link[=carousel]{carousel()}}.}
13 |
14 | \item{show}{Whether to show the indicators.}
15 | }
16 | \description{
17 | Carousel indicators
18 | }
19 | \keyword{internal}
20 |
--------------------------------------------------------------------------------
/man/carouselItem.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/carousel.R
3 | \name{carouselItem}
4 | \alias{carouselItem}
5 | \title{Carousel Item}
6 | \usage{
7 | carouselItem(..., interval = NULL, class = "")
8 | }
9 | \arguments{
10 | \item{...}{Content of item.}
11 |
12 | \item{interval}{Number of milliseconds this item should be shown.}
13 |
14 | \item{class}{Additional classes.}
15 | }
16 | \description{
17 | Carousel item to use within \code{\link[=carousel]{carousel()}}.
18 | }
19 |
--------------------------------------------------------------------------------
/man/closeButton.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/close.R
3 | \name{closeButton}
4 | \alias{closeButton}
5 | \title{Close Button}
6 | \usage{
7 | closeButton()
8 | }
9 | \description{
10 | Button to dismiss or close a component.
11 | }
12 |
--------------------------------------------------------------------------------
/man/collapse.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/collapse.R
3 | \name{collapse}
4 | \alias{collapse}
5 | \alias{collapse.collapseTrigger}
6 | \title{Collapse}
7 | \usage{
8 | collapse(trigger, content)
9 |
10 | \method{collapse}{collapseTrigger}(trigger, content)
11 | }
12 | \arguments{
13 | \item{trigger}{A \code{\link[=collapseButton]{collapseButton()}} or \code{\link[=collapseLink]{collapseLink()}}.}
14 |
15 | \item{content}{The offcanvas content as returned by
16 | \code{\link[=offcanvasContent]{offcanvasContent()}}.}
17 | }
18 | \description{
19 | Create a collapsible.
20 | }
21 | \section{Methods (by class)}{
22 | \itemize{
23 | \item \code{collapse(collapseTrigger)}: Collapse wrapper
24 |
25 | }}
26 | \examples{
27 | library(shiny)
28 |
29 | ui <- fluidPage(
30 | theme = bslib::bs_theme(version = 5L),
31 | collapse(
32 | collapseLink(
33 | "Reveal"
34 | ),
35 | collapseContent(
36 | "Some collapsed content"
37 | )
38 | )
39 | )
40 |
41 | server <- \(input, output, session){
42 |
43 | }
44 |
45 | if(interactive())
46 | shinyApp(ui, server)
47 |
48 | }
49 |
--------------------------------------------------------------------------------
/man/collapseButton.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/collapse.R
3 | \name{collapseButton}
4 | \alias{collapseButton}
5 | \title{Collapse Button}
6 | \usage{
7 | collapseButton(..., id = NULL, class = "")
8 | }
9 | \arguments{
10 | \item{...}{Passed to the button.}
11 |
12 | \item{id}{Button id.}
13 |
14 | \item{class}{Additional classes to pass to the button.}
15 | }
16 | \description{
17 | Collapse button.
18 | }
19 | \examples{
20 | library(shiny)
21 |
22 | ui <- fluidPage(
23 | theme = bslib::bs_theme(version = 5L),
24 | collapse(
25 | collapseButton(
26 | "Reveal"
27 | ),
28 | collapseContent(
29 | "Some collapsed content"
30 | )
31 | )
32 | )
33 |
34 | server <- \(input, output, session){
35 |
36 | }
37 |
38 | if(interactive())
39 | shinyApp(ui, server)
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/man/collapseContent.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/collapse.R
3 | \name{collapseContent}
4 | \alias{collapseContent}
5 | \title{Collapse Content}
6 | \usage{
7 | collapseContent(..., .id = NULL)
8 | }
9 | \arguments{
10 | \item{...}{Content of the collapsible.}
11 |
12 | \item{.id}{Id of the element.}
13 | }
14 | \description{
15 | Collapse content, to pass to \code{\link[=collapseButton]{collapseButton()}} or
16 | \code{\link[=collapseLink]{collapseLink()}}.
17 | }
18 |
--------------------------------------------------------------------------------
/man/collapseLink.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/collapse.R
3 | \name{collapseLink}
4 | \alias{collapseLink}
5 | \title{Collapse Link}
6 | \usage{
7 | collapseLink(..., id = NULL, class = "")
8 | }
9 | \arguments{
10 | \item{...}{Passed to the link.}
11 |
12 | \item{id}{Link id.}
13 |
14 | \item{class}{Additional class to pass to the link.}
15 | }
16 | \description{
17 | Collapse link.
18 | }
19 |
--------------------------------------------------------------------------------
/man/colorPickerInput.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/inputs.R
3 | \name{colorPickerInput}
4 | \alias{colorPickerInput}
5 | \title{Color Picker Input}
6 | \usage{
7 | colorPickerInput(inputId, value = NULL, ...)
8 | }
9 | \arguments{
10 | \item{inputId}{ID of input.}
11 |
12 | \item{value}{Initial value of the input.}
13 |
14 | \item{...}{Passed to input.}
15 | }
16 | \description{
17 | Color picker input.
18 | }
19 |
--------------------------------------------------------------------------------
/man/dropdownButton.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/dropdown.R
3 | \name{dropdownButton}
4 | \alias{dropdownButton}
5 | \title{Dropdown Button}
6 | \usage{
7 | dropdownButton(label, ..., id = NULL, class = "")
8 | }
9 | \arguments{
10 | \item{label}{Label of the dropdown.}
11 |
12 | \item{...}{\code{\link[shiny:actionButton]{shiny::actionLink()}} to place within the
13 | dropdown.}
14 |
15 | \item{id}{ID of parent dropdown.}
16 |
17 | \item{class}{Additional class for dropdown button.}
18 | }
19 | \description{
20 | Dropdown buttons for \code{\link[shiny:actionButton]{shiny::actionLink()}}.
21 | }
22 | \examples{
23 | library(shiny)
24 |
25 | ui <- fluidPage(
26 | theme = bslib::bs_theme(version = 5L),
27 | dropdownButton(
28 | "Buttons",
29 | actionLink("first", "First"),
30 | actionLink("second", "Second")
31 | )
32 | )
33 |
34 | server <- \(input, output, session){
35 |
36 | }
37 |
38 | if(interactive())
39 | shinyApp(ui, server)
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/man/floatingSelectInput.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/inputs.R
3 | \name{floatingSelectInput}
4 | \alias{floatingSelectInput}
5 | \title{Select Floating Label}
6 | \usage{
7 | floatingSelectInput(inputId, label, choices = NULL, ...)
8 | }
9 | \arguments{
10 | \item{inputId}{ID of input.}
11 |
12 | \item{label}{Label of input.}
13 |
14 | \item{choices}{Choices, named vector.}
15 |
16 | \item{...}{Passed to input.}
17 | }
18 | \description{
19 | Select input with floating label.
20 | }
21 |
--------------------------------------------------------------------------------
/man/floatingTextAreaInput.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/inputs.R
3 | \name{floatingTextAreaInput}
4 | \alias{floatingTextAreaInput}
5 | \title{Text Area Input Floating Label}
6 | \usage{
7 | floatingTextAreaInput(inputId, label, placeholder, value = "", ...)
8 | }
9 | \arguments{
10 | \item{inputId}{ID of input.}
11 |
12 | \item{label}{Label of input.}
13 |
14 | \item{placeholder}{Placeholder value.}
15 |
16 | \item{value}{Value of input.}
17 |
18 | \item{...}{Passed to input.}
19 | }
20 | \description{
21 | Text area input with floating label.
22 | }
23 |
--------------------------------------------------------------------------------
/man/floatingTextInput.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/inputs.R
3 | \name{floatingTextInput}
4 | \alias{floatingTextInput}
5 | \title{Text Input Floating Label}
6 | \usage{
7 | floatingTextInput(inputId, label, placeholder, value = "", ...)
8 | }
9 | \arguments{
10 | \item{inputId}{ID of input.}
11 |
12 | \item{label}{Label of input.}
13 |
14 | \item{placeholder}{Placeholder value.}
15 |
16 | \item{value}{Value of input.}
17 |
18 | \item{...}{Passed to input.}
19 | }
20 | \description{
21 | Text input with floating label.
22 | }
23 |
--------------------------------------------------------------------------------
/man/gallery.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/gallery.R
3 | \name{gallery}
4 | \alias{gallery}
5 | \title{Gallery}
6 | \usage{
7 | gallery()
8 | }
9 | \description{
10 | Demo of utilities.
11 | }
12 |
--------------------------------------------------------------------------------
/man/get_dep.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/dependencies.R
3 | \name{get_dep}
4 | \alias{get_dep}
5 | \title{Get Dependencies}
6 | \usage{
7 | get_dep(name)
8 | }
9 | \arguments{
10 | \item{name}{Name of dependency.}
11 | }
12 | \description{
13 | Get a dependency.
14 | }
15 | \keyword{internal}
16 |
--------------------------------------------------------------------------------
/man/listGroup.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/list.R
3 | \name{listGroup}
4 | \alias{listGroup}
5 | \title{List Group}
6 | \usage{
7 | listGroup(...)
8 | }
9 | \arguments{
10 | \item{...}{Content of the list group, see \code{\link[=listGroupItem]{listGroupItem()}}.}
11 | }
12 | \description{
13 | List group, see \code{\link[=listGroupItem]{listGroupItem()}}.
14 | }
15 |
--------------------------------------------------------------------------------
/man/listGroupItem.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/list.R
3 | \name{listGroupItem}
4 | \alias{listGroupItem}
5 | \title{List Group Item}
6 | \usage{
7 | listGroupItem(..., class = "")
8 | }
9 | \arguments{
10 | \item{...}{Content.}
11 |
12 | \item{class}{Additional classes.}
13 | }
14 | \description{
15 | Items for \code{\link[=listGroup]{listGroup()}}.
16 | }
17 |
--------------------------------------------------------------------------------
/man/modal.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/modal.R
3 | \name{modal}
4 | \alias{modal}
5 | \title{Modal}
6 | \usage{
7 | modal(
8 | id,
9 | ...,
10 | static_backdrop = FALSE,
11 | scrollable = FALSE,
12 | centered = FALSE,
13 | size = c("default", "sm", "lg", "xl", "fullscreen", "fullscreen-sm-down",
14 | "fullscreen-md-down", "fullscreen-lg-down", "fullscreen-xl-down",
15 | "fullscreen-xxl-down")
16 | )
17 | }
18 | \arguments{
19 | \item{id}{ID of modal.}
20 |
21 | \item{...}{Content of the modal, \code{\link[=modalBody]{modalBody()}},
22 | \code{\link[=modalHeader]{modalHeader()}}, \code{\link[=modalFooter]{modalFooter()}}.}
23 |
24 | \item{static_backdrop}{When backdrop is set to static,
25 | the modal will not close when clicking outside it.}
26 |
27 | \item{scrollable}{Whether to make the content scrollable.}
28 |
29 | \item{centered}{Whether to make the content vertically
30 | centered.}
31 |
32 | \item{size}{Size of the modal.}
33 | }
34 | \description{
35 | Create a modal in the UI.
36 | The modal is not down see \code{\link[=modal_show]{modal_show()}}, or
37 | \code{\link[=modal_toggle]{modal_toggle()}} (from server).
38 | }
39 | \examples{
40 | library(shiny)
41 |
42 | ui <- fluidPage(
43 | theme = bslib::bs_theme(version = 5L),
44 | actionButton("show", "Show modal"),
45 | modal(
46 | id = "modal",
47 | modalHeader(
48 | modalTitle("Title")
49 | ),
50 | modalBody(
51 | p("The content of the modal")
52 | ),
53 | modalFooter(
54 | p("The footer of the modal")
55 | )
56 | )
57 | )
58 |
59 | server <- \(input, output, session){
60 | observeEvent(input$show, {
61 | modal_show("modal")
62 | })
63 | }
64 |
65 | if(interactive())
66 | shinyApp(ui, server)
67 |
68 | }
69 |
--------------------------------------------------------------------------------
/man/modalBody.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/modal.R
3 | \name{modalBody}
4 | \alias{modalBody}
5 | \title{Modal Body}
6 | \usage{
7 | modalBody(...)
8 | }
9 | \arguments{
10 | \item{...}{Content of the body.}
11 | }
12 | \description{
13 | Body of the modal, place within \code{\link[=modal]{modal()}}.
14 | }
15 |
--------------------------------------------------------------------------------
/man/modalFooter.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/modal.R
3 | \name{modalFooter}
4 | \alias{modalFooter}
5 | \title{Modal Footer}
6 | \usage{
7 | modalFooter(...)
8 | }
9 | \arguments{
10 | \item{...}{Content of the footer.}
11 | }
12 | \description{
13 | Footer of the modal, place within \code{\link[=modal]{modal()}}.
14 | }
15 |
--------------------------------------------------------------------------------
/man/modalHeader.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/modal.R
3 | \name{modalHeader}
4 | \alias{modalHeader}
5 | \title{Modal Header}
6 | \usage{
7 | modalHeader(..., .close = TRUE)
8 | }
9 | \arguments{
10 | \item{...}{Content.}
11 |
12 | \item{.close}{Whether to add the close button.}
13 | }
14 | \description{
15 | Header of a modal, place within \code{\link[=modal]{modal()}}.
16 | }
17 |
--------------------------------------------------------------------------------
/man/modalTitle.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/modal.R
3 | \name{modalTitle}
4 | \alias{modalTitle}
5 | \title{Modal Title}
6 | \usage{
7 | modalTitle(title)
8 | }
9 | \arguments{
10 | \item{title}{An HTML tag or a character vector of length 1.}
11 | }
12 | \description{
13 | Modal title, place within \code{\link[=modalHeader]{modalHeader()}}.
14 | }
15 |
--------------------------------------------------------------------------------
/man/modalToggle.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/modal.R
3 | \name{modalToggle}
4 | \alias{modalToggle}
5 | \alias{modal_show}
6 | \alias{modal_hide}
7 | \alias{modal_toggle}
8 | \title{Modal Toggle}
9 | \usage{
10 | modal_show(id, session = shiny::getDefaultReactiveDomain())
11 |
12 | modal_hide(id, session = shiny::getDefaultReactiveDomain())
13 |
14 | modal_toggle(id, session = shiny::getDefaultReactiveDomain())
15 | }
16 | \arguments{
17 | \item{id}{ID of the \code{\link[=modal]{modal()}}.}
18 |
19 | \item{session}{A valid shiny session.}
20 | }
21 | \description{
22 | Show, hide, or toggle a modal from the server.
23 | }
24 |
--------------------------------------------------------------------------------
/man/modalTrigger.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/modal.R
3 | \name{modalTrigger}
4 | \alias{modalTrigger}
5 | \alias{modalButton}
6 | \alias{modalLink}
7 | \title{Modal Triggers}
8 | \usage{
9 | modalButton(target, ..., class = "")
10 |
11 | modalLink(target, ...)
12 | }
13 | \arguments{
14 | \item{target}{Target ID of the \code{\link[=modal]{modal()}} to show.}
15 |
16 | \item{...}{Content of link or button, generally a
17 | character vector of length 1.}
18 |
19 | \item{class}{Additional class to pass to the button.}
20 | }
21 | \description{
22 | Trigger open a modal with a button or a link,
23 | avoids goind through the server.
24 | }
25 |
--------------------------------------------------------------------------------
/man/offcanvas.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/offcanvas.R
3 | \name{offcanvas}
4 | \alias{offcanvas}
5 | \alias{offcanvas.offcanvasTrigger}
6 | \alias{offcanvas.shiny.tag}
7 | \title{Offcanvas}
8 | \usage{
9 | offcanvas(trigger, content)
10 |
11 | \method{offcanvas}{offcanvasTrigger}(trigger, content)
12 |
13 | \method{offcanvas}{shiny.tag}(trigger, content)
14 | }
15 | \arguments{
16 | \item{trigger}{A \code{\link[=collapseButton]{collapseButton()}}, \code{\link[=collapseLink]{collapseLink()}},
17 | \code{\link[shiny:actionButton]{shiny::actionButton()}}, \code{\link[shiny:actionButton]{shiny::actionLink()}}.}
18 |
19 | \item{content}{The offcanvas content as returned by
20 | \code{\link[=offcanvasContent]{offcanvasContent()}}.}
21 | }
22 | \description{
23 | Create an offcanvas element.
24 | }
25 | \section{Methods (by class)}{
26 | \itemize{
27 | \item \code{offcanvas(offcanvasTrigger)}: Offcanvas wrapper for \code{\link[=collapseButton]{collapseButton()}}, \code{\link[=collapseLink]{collapseLink()}}.
28 |
29 | \item \code{offcanvas(shiny.tag)}: Offcanvas wrapper for \code{\link[shiny:actionButton]{shiny::actionButton()}}, \code{\link[shiny:actionButton]{shiny::actionLink()}}.
30 |
31 | }}
32 | \examples{
33 | library(shiny)
34 |
35 | ui <- fluidPage(
36 | theme = bslib::bs_theme(version = 5L),
37 | offcanvas(
38 | offcanvasButton(
39 | "Open"
40 | ),
41 | offcanvasContent(
42 | offcanvasHeader(
43 | "Off canvas"
44 | ),
45 | p(
46 | "Hello world"
47 | )
48 | )
49 | )
50 | )
51 |
52 | server <- \(input, output, session){
53 |
54 | }
55 |
56 | if(interactive())
57 | shinyApp(ui, server)
58 |
59 | }
60 |
--------------------------------------------------------------------------------
/man/offcanvasButton.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/offcanvas.R
3 | \name{offcanvasButton}
4 | \alias{offcanvasButton}
5 | \alias{offcanvasButtonWithTooltip}
6 | \title{Offcanvas Button}
7 | \usage{
8 | offcanvasButton(..., id = NULL, class = "")
9 |
10 | offcanvasButtonWithTooltip(
11 | ...,
12 | title,
13 | placement = c("top", "right", "bottom", "left"),
14 | id = NULL,
15 | class = ""
16 | )
17 | }
18 | \arguments{
19 | \item{...}{Passed to the button.}
20 |
21 | \item{id}{ID of the button.}
22 |
23 | \item{class}{Additional class to pass to the button.}
24 |
25 | \item{title}{HTML tag or character vector of length 1.}
26 |
27 | \item{placement}{Placement of the tooltip.}
28 | }
29 | \description{
30 | Offcanvas button trigger.
31 | }
32 |
--------------------------------------------------------------------------------
/man/offcanvasContent.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/offcanvas.R
3 | \name{offcanvasContent}
4 | \alias{offcanvasContent}
5 | \title{Offcanvas Content}
6 | \usage{
7 | offcanvasContent(
8 | ...,
9 | id = NULL,
10 | class = "",
11 | .position = c("start", "end", "top", "bottom"),
12 | scroll = TRUE
13 | )
14 | }
15 | \arguments{
16 | \item{...}{Content of the offcanvas.}
17 |
18 | \item{id}{Id of the canvas.}
19 |
20 | \item{class}{Additional classes.}
21 |
22 | \item{.position}{Where the canvas should open.}
23 |
24 | \item{scroll}{Whether to allow scrolling the body.}
25 | }
26 | \description{
27 | Offcanvas content.
28 | }
29 |
--------------------------------------------------------------------------------
/man/offcanvasHeader.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/offcanvas.R
3 | \name{offcanvasHeader}
4 | \alias{offcanvasHeader}
5 | \title{Canvas Header}
6 | \usage{
7 | offcanvasHeader(header)
8 | }
9 | \arguments{
10 | \item{header}{An HTML tag or a character string.}
11 | }
12 | \description{
13 | Header for \code{\link[=offcanvasContent]{offcanvasContent()}}.
14 | }
15 |
--------------------------------------------------------------------------------
/man/offcanvasLink.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/offcanvas.R
3 | \name{offcanvasLink}
4 | \alias{offcanvasLink}
5 | \title{Offcanvas Link}
6 | \usage{
7 | offcanvasLink(..., id = NULL, class = "")
8 | }
9 | \arguments{
10 | \item{...}{Passed to the button.}
11 |
12 | \item{id}{ID of the link.}
13 |
14 | \item{class}{Additional class to pass to the button.}
15 | }
16 | \description{
17 | Offcanvas link trigger.
18 | }
19 |
--------------------------------------------------------------------------------
/man/offcanvasServer.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/offcanvas.R
3 | \name{offcanvasServer}
4 | \alias{offcanvasServer}
5 | \alias{offcanvas_show}
6 | \alias{offcanvas_hide}
7 | \alias{offcanvas_toggle}
8 | \title{Offcanvas Server}
9 | \usage{
10 | offcanvas_show(id, session = shiny::getDefaultReactiveDomain())
11 |
12 | offcanvas_hide(id, session = shiny::getDefaultReactiveDomain())
13 |
14 | offcanvas_toggle(id, session = shiny::getDefaultReactiveDomain())
15 | }
16 | \arguments{
17 | \item{id}{ID of \code{\link[=offcanvasContent]{offcanvasContent()}}.}
18 |
19 | \item{session}{Valid shiny session.}
20 | }
21 | \description{
22 | Toggle the offcanvas from the server.
23 | }
24 |
--------------------------------------------------------------------------------
/man/progress.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/progress.R
3 | \name{progress}
4 | \alias{progress}
5 | \title{Progress}
6 | \usage{
7 | progress(..., id = NULL)
8 | }
9 | \arguments{
10 | \item{...}{Progress bars as returned by \code{\link[=progressBar]{progressBar()}}.}
11 |
12 | \item{id}{Parent id.}
13 | }
14 | \description{
15 | Progress bars.
16 | }
17 | \examples{
18 | library(shiny)
19 |
20 | ui <- fluidPage(
21 | theme = bslib::bs_theme(version = 5L),
22 | actionButton(
23 | "rand",
24 | "Randomise"
25 | ),
26 | progress(
27 | progressBar(15, id = "bar")
28 | )
29 | )
30 |
31 | server <- \(input, output, session){
32 | observeEvent(input$rand, {
33 | update_progress("bar", sample(10:99, 1))
34 | })
35 | }
36 |
37 | if(interactive())
38 | shinyApp(ui, server)
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/man/progressBar.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/progress.R
3 | \name{progressBar}
4 | \alias{progressBar}
5 | \title{Progress Bar}
6 | \usage{
7 | progressBar(value = 0L, min = 0L, max = 100L, id = NULL, class = "")
8 | }
9 | \arguments{
10 | \item{value}{Value of progress bar.}
11 |
12 | \item{min, max}{Minimum and maximum values.}
13 |
14 | \item{id}{ID of progress bar.}
15 |
16 | \item{class}{Additional classes.}
17 | }
18 | \description{
19 | A progress bar to pass to \code{\link[=progress]{progress()}}.
20 | }
21 |
--------------------------------------------------------------------------------
/man/rangeInput.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/inputs.R
3 | \name{rangeInput}
4 | \alias{rangeInput}
5 | \title{Range Input}
6 | \usage{
7 | rangeInput(id, label, value = 0L, ..., min = 0L, max = 100L, step = 1L)
8 | }
9 | \arguments{
10 | \item{id}{ID of input.}
11 |
12 | \item{label}{Label of input.}
13 |
14 | \item{value}{Initial value of input.}
15 |
16 | \item{...}{Passed to input.}
17 |
18 | \item{min, max}{Minimum and maximum values of the range.}
19 |
20 | \item{step}{Step of range change.}
21 | }
22 | \description{
23 | A range input similar to a slider.
24 | }
25 |
--------------------------------------------------------------------------------
/man/switchInput.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/inputs.R
3 | \name{switchInput}
4 | \alias{switchInput}
5 | \title{Switch Input}
6 | \usage{
7 | switchInput(inputId, label, checked = FALSE, ...)
8 | }
9 | \arguments{
10 | \item{inputId}{ID of input.}
11 |
12 | \item{label}{Label of input.}
13 |
14 | \item{checked}{Whether the input is initialised checked.}
15 |
16 | \item{...}{Passed to input.}
17 | }
18 | \description{
19 | Switch input, similar to checkbox.
20 | }
21 |
--------------------------------------------------------------------------------
/man/textGroupInput.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/inputs.R
3 | \name{textGroupInput}
4 | \alias{textGroupInput}
5 | \title{Text Group Input}
6 | \usage{
7 | textGroupInput(
8 | inputId,
9 | label,
10 | value = "",
11 | placeholder = NULL,
12 | .position = c("left", "right")
13 | )
14 | }
15 | \arguments{
16 | \item{inputId}{ID of input.}
17 |
18 | \item{label}{Label of input.}
19 |
20 | \item{value}{Initial value of input.}
21 |
22 | \item{placeholder}{Placeholder for input.}
23 |
24 | \item{.position}{Position of the label.}
25 | }
26 | \description{
27 | Text group input.
28 | }
29 |
--------------------------------------------------------------------------------
/man/toast.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/toast.R
3 | \name{toast}
4 | \alias{toast}
5 | \title{Toast}
6 | \usage{
7 | toast(
8 | id,
9 | ...,
10 | class = "",
11 | position = c("top-right", "top-left", "bottom-right", "bottom-left")
12 | )
13 | }
14 | \arguments{
15 | \item{id}{ID of toast, used to show/hide from server.}
16 |
17 | \item{...}{Content, generally \code{\link[=toastHeader]{toastHeader()}}, \code{\link[=toastBody]{toastBody()}}.}
18 |
19 | \item{class}{Any additional classes.}
20 |
21 | \item{position}{Position of the toast.}
22 | }
23 | \description{
24 | Toast notifications.
25 | }
26 | \examples{
27 | library(shiny)
28 |
29 | ui <- fluidPage(
30 | theme = bslib::bs_theme(version = 5L),
31 | toast(
32 | "toast",
33 | toastHeader(
34 | strong(
35 | "Toast",
36 | class = "me-auto"
37 | )
38 | ),
39 | toastBody("The body of the toast!")
40 | ),
41 | h1("Hello"),
42 | actionButton("show", "Show toast"),
43 | actionButton("hide", "Hide toast")
44 | )
45 |
46 | server <- \(input, output, session){
47 | observeEvent(input$show, {
48 | toast_show("toast", auto_hide = FALSE)
49 | })
50 |
51 | observeEvent(input$hide, {
52 | toast_hide("toast")
53 | })
54 | }
55 |
56 | if(interactive())
57 | shinyApp(ui, server)
58 |
59 | }
60 |
--------------------------------------------------------------------------------
/man/toastContent.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/toast.R
3 | \name{toastContent}
4 | \alias{toastContent}
5 | \alias{toastHeader}
6 | \alias{toastBody}
7 | \title{Toast Content}
8 | \usage{
9 | toastHeader(..., class = "")
10 |
11 | toastBody(..., class = "")
12 | }
13 | \arguments{
14 | \item{...}{Content.}
15 |
16 | \item{class}{Any additional class.}
17 | }
18 | \description{
19 | Content of the toast to place within \code{\link[=toast]{toast()}}.
20 | }
21 |
--------------------------------------------------------------------------------
/man/toastToggle.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/toast.R
3 | \name{toastToggle}
4 | \alias{toastToggle}
5 | \alias{toast_show}
6 | \alias{toast_hide}
7 | \title{Toast Toggle}
8 | \usage{
9 | toast_show(
10 | id,
11 | header = NULL,
12 | body = NULL,
13 | animation = TRUE,
14 | auto_hide = TRUE,
15 | delay = 5000L,
16 | session = shiny::getDefaultReactiveDomain()
17 | )
18 |
19 | toast_hide(id, session = shiny::getDefaultReactiveDomain())
20 | }
21 | \arguments{
22 | \item{id}{ID of \code{\link[=toast]{toast()}} to toggle.}
23 |
24 | \item{header, body}{Header and body of the toast
25 | to replace existing content.}
26 |
27 | \item{animation}{Whether to animate the toast.}
28 |
29 | \item{auto_hide}{Whether to automatically hide the
30 | toast after \code{delay}.}
31 |
32 | \item{delay}{Milliseconds after which to hide the
33 | toast (if \code{auto_hide = TRUE}).}
34 |
35 | \item{session}{A valid shiny session.}
36 | }
37 | \description{
38 | Show or hide a toast.
39 | }
40 |
--------------------------------------------------------------------------------
/man/update_color_picker.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/inputs.R
3 | \name{update_color_picker}
4 | \alias{update_color_picker}
5 | \title{Update Color Picker}
6 | \usage{
7 | update_color_picker(id, value, session = shiny::getDefaultReactiveDomain())
8 | }
9 | \arguments{
10 | \item{id}{ID of input to update.}
11 |
12 | \item{value}{Value to set.}
13 |
14 | \item{session}{A valid shiny session.}
15 | }
16 | \description{
17 | Update a \code{\link[=colorPickerInput]{colorPickerInput()}} from the server.
18 | }
19 |
--------------------------------------------------------------------------------
/man/update_progress.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/progress.R
3 | \name{update_progress}
4 | \alias{update_progress}
5 | \title{Update Progress}
6 | \usage{
7 | update_progress(id, value, session = shiny::getDefaultReactiveDomain())
8 | }
9 | \arguments{
10 | \item{id}{ID of progress bar to update.}
11 |
12 | \item{value}{Value to set the progress bar to.}
13 |
14 | \item{session}{A valid shiny session.}
15 | }
16 | \description{
17 | Update a \code{\link[=progressBar]{progressBar()}}.
18 | }
19 |
--------------------------------------------------------------------------------
/man/update_range.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/inputs.R
3 | \name{update_range}
4 | \alias{update_range}
5 | \title{Update Range}
6 | \usage{
7 | update_range(id, ..., session = shiny::getDefaultReactiveDomain())
8 | }
9 | \arguments{
10 | \item{id}{ID of input to update.}
11 |
12 | \item{...}{Elements to update, one or more of,
13 | \code{value}, \code{min}, and \code{max}.}
14 |
15 | \item{session}{A valid shiny session.}
16 | }
17 | \description{
18 | Update a \code{\link[=rangeInput]{rangeInput()}} from the server.
19 | }
20 |
--------------------------------------------------------------------------------
/man/update_text_group.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/inputs.R
3 | \name{update_text_group}
4 | \alias{update_text_group}
5 | \title{Update Text Group Input}
6 | \usage{
7 | update_text_group(id, ..., session = shiny::getDefaultReactiveDomain())
8 | }
9 | \arguments{
10 | \item{id}{ID of input to update.}
11 |
12 | \item{...}{Items to update; \code{value}, and/or \code{label}.}
13 |
14 | \item{session}{Valid shiny session.}
15 | }
16 | \description{
17 | Update \code{\link[=textGroupInput]{textGroupInput()}}.
18 | }
19 |
--------------------------------------------------------------------------------
/man/withPopover.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/popover.R
3 | \name{withPopover}
4 | \alias{withPopover}
5 | \title{Popover}
6 | \usage{
7 | withPopover(
8 | el,
9 | content,
10 | title = NULL,
11 | container = "body",
12 | placement = c("top", "right", "bottom", "left")
13 | )
14 | }
15 | \arguments{
16 | \item{el}{Element to place popover on.}
17 |
18 | \item{content}{Content of the popover.}
19 |
20 | \item{title}{Optional popover title.}
21 |
22 | \item{container}{container of the popover.}
23 |
24 | \item{placement}{Position of the popover.}
25 | }
26 | \description{
27 | Add a popover to an element.
28 | }
29 |
--------------------------------------------------------------------------------
/man/withTooltip.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/tooltip.R
3 | \name{withTooltip}
4 | \alias{withTooltip}
5 | \title{Tooltip}
6 | \usage{
7 | withTooltip(el, title, placement = c("top", "right", "bottom", "left"))
8 | }
9 | \arguments{
10 | \item{el}{Element.}
11 |
12 | \item{title}{HTML tag or character vector of length 1.}
13 |
14 | \item{placement}{Placement of the tooltip.}
15 | }
16 | \description{
17 | Add a tooltip to an element.
18 | }
19 | \examples{
20 | library(shiny)
21 |
22 | ui <- fluidPage(
23 | theme = bslib::bs_theme(version = 5L),
24 | withTooltip(
25 | span("plain"),
26 | "content"
27 | ),
28 | br(),
29 | withTooltip(
30 | span("HTML"),
31 | tagList(
32 | strong("HTML"),
33 | "content"
34 | )
35 | )
36 | )
37 |
38 | server <- \(input, output, session){
39 | }
40 |
41 | if(interactive())
42 | shinyApp(ui, server)
43 |
44 | }
45 |
--------------------------------------------------------------------------------