Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Card class and migrate card JavaScript to TypeScript #557

Merged
merged 78 commits into from
May 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
78 commits
Select commit Hold shift + click to select a range
c125347
Use MutationSummary to watch for new sidebars
gadenbuie Apr 24, 2023
61ff86d
Small code refactor
gadenbuie Apr 24, 2023
f013b3c
Use direct event listeners instead of event delegation
gadenbuie Apr 24, 2023
fad99e6
Switch to `arrive.js` from `mutation-summary`
gadenbuie Apr 25, 2023
c01c4c2
Add a small delay before removing transitioning class
gadenbuie Apr 25, 2023
8f0cc11
recompile components
gadenbuie Apr 25, 2023
3b5d911
Use hand-crafted DocumentObserver instead of arrive.js
gadenbuie Apr 25, 2023
cef77ac
rebuild components
gadenbuie Apr 25, 2023
b930cb2
remove debugging console.logs
gadenbuie Apr 25, 2023
6364ecc
Fold DocumentObserver into Sidebar class
gadenbuie Apr 25, 2023
041ca8f
Add delay in the `transitionend` handler
gadenbuie Apr 25, 2023
f6712ce
Remove unused argument
gadenbuie Apr 26, 2023
7a706cc
Initial setup of Card class
gadenbuie Apr 26, 2023
2c0d3ef
typescript: skipLIbCheck to avoid checking types of recursive depende…
gadenbuie Apr 27, 2023
9e819c8
esbuild: don't try to bundle bootstrap
gadenbuie Apr 27, 2023
5b5b24d
esbuild: build card.ts
gadenbuie Apr 27, 2023
cd2e113
Fix `Tooltip` and `TooltipType`
gadenbuie Apr 27, 2023
2232709
Expose Card via `window.bslib`
gadenbuie Apr 27, 2023
8a009eb
Add `card_dependency()` and remove inline init script
gadenbuie Apr 27, 2023
b75a256
`card()` needs `data-bslib-card-needs-init` attribute
gadenbuie Apr 27, 2023
3138722
Merge enter/exit full screen into Card class
gadenbuie Apr 27, 2023
ce54337
Add blur and subtle animation to full screen overlay
gadenbuie Apr 27, 2023
7048908
Remove card-full-screen.js
gadenbuie Apr 27, 2023
3453cbf
Use {bsicons} if available for full screen toggle icon
gadenbuie Apr 27, 2023
f41aec8
Remove exit fullscren event listeners after updating DOM
gadenbuie Apr 27, 2023
04daa74
Tidy up Card class code
gadenbuie Apr 27, 2023
bbddc81
Add `id` to all cards in example cards app
gadenbuie Apr 27, 2023
7bafb39
Add TODO comment for dependent shiny PR
gadenbuie Apr 27, 2023
53d121d
Build card component
gadenbuie Apr 27, 2023
f4e5bd1
Full screen buttons are direct descendants of `.bslib-card`
gadenbuie May 2, 2023
187e4fd
Add/remove body-level class when entering/exiting full screen
gadenbuie May 2, 2023
2530e08
rebuild card component js
gadenbuie May 2, 2023
a703f90
Resave distributed files (GitHub Action)
gadenbuie May 2, 2023
655a85d
Resave data (GitHub Action)
gadenbuie May 2, 2023
45649f9
Fix escape key event listener
gadenbuie May 2, 2023
019fdd6
Don't close full screen if select input has focus
gadenbuie May 2, 2023
d509234
Exit full screen when kbd Enter/Space on close anchor
gadenbuie May 2, 2023
44cbe67
Cycle focus within expanded full screen
gadenbuie May 2, 2023
46bae9c
Clean up and polish focus entrapment
gadenbuie May 2, 2023
ce77ca9
`yarn build` (GitHub Actions)
gadenbuie May 2, 2023
106b7e5
Merge commit '4a2276d3c9502e814d5f245967afa1e8dd3367f1'
gadenbuie May 10, 2023
a62f60e
Revert to initialization via `<script>` tag
gadenbuie May 10, 2023
375b3c0
Use ShinyResizeObserver
gadenbuie May 10, 2023
fd53e44
yarn build
gadenbuie May 10, 2023
75ad2be
Fix bad merge from main
gadenbuie May 10, 2023
b551a73
Apply suggestions from code review
gadenbuie May 10, 2023
3cb2908
Apply suggestions from code review
gadenbuie May 11, 2023
7426089
`devtools::document()` (GitHub Actions)
gadenbuie May 11, 2023
df9b0fc
`yarn build` (GitHub Actions)
gadenbuie May 11, 2023
68a6b02
Resave distributed files (GitHub Action)
gadenbuie May 11, 2023
3c6a43d
Resave data (GitHub Action)
gadenbuie May 11, 2023
b3b6c42
Improve focusable elements selector
gadenbuie May 11, 2023
02e8983
Remove unused event listener cleanup method
gadenbuie May 11, 2023
f26f72b
rewrite focus tracking to recalculate focusable elements on each change
gadenbuie May 11, 2023
78341b4
Refactor `_createOverlayCloseAnchor()` method
gadenbuie May 11, 2023
a97688c
move focus into card body, no need to entrap
gadenbuie May 11, 2023
cfd3b8c
yarn build
gadenbuie May 11, 2023
8b3bf57
`devtools::document()` (GitHub Actions)
gadenbuie May 11, 2023
69144b0
`yarn build` (GitHub Actions)
gadenbuie May 11, 2023
aa43e18
always move focus to the card on fullscreen
gadenbuie May 11, 2023
37fcf62
yarn build
gadenbuie May 11, 2023
a910b3e
Add NEWS item
gadenbuie May 11, 2023
7a06c30
remove comment
gadenbuie May 11, 2023
76577e4
`yarn build` (GitHub Actions)
gadenbuie May 11, 2023
920a67a
trapFocusExit handles all the logic for trapping focus
gadenbuie May 12, 2023
6bcb9a8
Use keydown for all keyboard events
gadenbuie May 12, 2023
81704a7
Don't exit when select input is open and focused
gadenbuie May 12, 2023
f9a5ada
yarn build
gadenbuie May 12, 2023
874feb1
rename CardFullScreenOverlay
gadenbuie May 12, 2023
950c789
Add Card documentation with jsdoc
gadenbuie May 12, 2023
f98505a
yarn build
gadenbuie May 12, 2023
8ed4e45
five cases not four
gadenbuie May 12, 2023
c6dd7f9
simplify focus trap handling logic
gadenbuie May 12, 2023
35d9037
Use stopEvent() closure
gadenbuie May 12, 2023
45115de
Move overlay click handler to the overlay onclick attribute
gadenbuie May 12, 2023
8c8df3f
Merge 'origin/main' into 'card/js-deps'
gadenbuie May 12, 2023
1bd9c8d
`yarn build` (GitHub Actions)
gadenbuie May 12, 2023
9123f8a
Resave distributed files (GitHub Action)
gadenbuie May 12, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 7 additions & 6 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,21 @@

This significant release adds [sidebar layouts](https://rstudio.github.io/bslib/articles/sidebars.html), [accordions](https://rstudio.github.io/bslib/articles/sidebars.html#sidebar-accordions), and makes many improvements to make dashboard-like filling layouts easier to create.

Although `{bslib}` is still maturing, and will continue to receiving new UI features, we now see it as a viable replacement for `{shinydashboard}`.
Although `{bslib}` is still maturing, and will continue to receiving new UI features, we now see it as a viable replacement for `{shinydashboard}`.

## Breaking changes

* `card_body()` now provides the same behavior as `card_body_fill()` (i.e., it is both a fillable container and fill item) by default. And, now, since `card_body()` can do everything `card_body_fill()` can do, `card_body_fill()` has been deprecated. The main benefit of this change is that `card(full_screen = TRUE, ...)` with output(s) passed to `...` "just works" in an intuitive way. To revert to the previous behavior, set `fillable = FALSE` and `fill = FALSE` in calls to `card_body()` and set `wrapper = function(x) card_body(x, fillable = FALSE, fill = FALSE)` in calls to `card()`. (#498)
* Closed #375: `margin-top` is no longer included on header tags that aren't created via pandoc. If this negatively impacts spacing above headers, consider adding a suitable [utility class](https://rstudio.github.io/bslib/articles/utility-classes.html) (for example, change `shiny::titlePanel("My title")` to `tagAppendAttributes(titlePanel("My title"), class = "mt-3", .selector = "h2")`). (#396)
* `layout_column_wrap()`'s `fill` argument now controls whether or not the _layout container_ is allowed to grow/shrink to fit a fillable container (e.g., `page_fillable()`). It also gains a new `fillable` argument for controlling whether _UI elements_ are allowed to fill their row height. This is more consistent with the meaning of `fill` in other functions, like `card()`, `card_body()`, `layout_sidebar()`, etc. (#498)
* `page_fill()` (now called `page_fillable()`) had several breaking changes (listed below). If this breaks existing behavior, consider using `shiny::fillPage(theme = bslib::bs_theme(), ...)` instead of `page_fill()`.
* `page_fill()` (now called `page_fillable()`) had several breaking changes (listed below). If this breaks existing behavior, consider using `shiny::fillPage(theme = bslib::bs_theme(), ...)` instead of `page_fill()`.
* `page_fill()` now produces a `<body>` tag with `display:flex` (instead of `display:block`).
* `page_fill()` no longer fills the windows height on mobile (i.e., narrow screens) by default (set `fill_mobile = TRUE` to restore the old behavior).
* `page_fill()` no longer fills the windows height on mobile (i.e., narrow screens) by default (set `fill_mobile = TRUE` to restore the old behavior).
* `page_fill()` now adds `padding` and `gap` by default, set `padding = 0` and `gap = 0` to restore the old behavior.
* `page_navbar()` (and consequently `shiny::navbarPage()`) no longer implicitly wrap `header` and `footer` in an additional `shiny::fluidRow()` container for Bootstrap 5+ (i.e., `theme = bs_theme()`) usage. Similarly, `navs_bar()` no longer does this (for any version of Bootstrap). If this breaks existing behavior, consider wrapping the `header` and `footer` value(s) with `shiny::fluidRow()`). (#479)
* Closed #510: `card()` no longer includes `margin-bottom`. To revert the old behavior, add `class = "mb-3` to `card()`. (#542)
* Defaults for the following Bootstrap 5 Sass variables were changed to `null`: `$accordion-button-active-bg`, `$accordion-button-active-color`, and `$accordion-icon-active-color`. To restore the old behavior, do `bs_add_variables(theme, "accordion-button-active-bg" = "tint-color($component-active-bg, 90%)", "accordion-button-active-color" = "shade-color($primary, 10%)", "accordion-icon-active-color" = "$accordion-button-active-color", .where = "declarations")`. (#475)
* Closed #558: nested cards with `fullscreen = TRUE` now correctly and individually expand to fill the window. Tab focus behavior while in full screen mode has also been improved. (#557)

## New features

Expand Down Expand Up @@ -45,8 +46,8 @@ Although `{bslib}` is still maturing, and will continue to receiving new UI feat

* Adds a new `card()` API as well as `value_box()` and `layout_column_wrap()`. To learn more about this new functionality, refer to these new pkgdown articles:

* https://rstudio.github.io/bslib/articles/cards.html
* https://rstudio.github.io/bslib/articles/value-boxes.html
* https://rstudio.github.io/bslib/articles/cards.html
* https://rstudio.github.io/bslib/articles/value-boxes.html
* https://rstudio.github.io/bslib/articles/column-layout.html

# bslib 0.4.1
Expand Down Expand Up @@ -123,7 +124,7 @@ Small patch release to fix failing test on Solaris.

## Bug fixes

* Closed #236, #230, #242, #187, #215, #250: Addressed various cosmetic issues with CSS (#249).
* Closed #236, #230, #242, #187, #215, #250: Addressed various cosmetic issues with CSS (#249).
* Closed #289: collapsed navbar toggle now correctly floats to the right (#290).
* Closed [rstudio/flexdashboard#316](https://github.com/rstudio/flexdashboard/issues/316): fixed an issue with navbar nav spacing/alignment (#286).

Expand Down
73 changes: 21 additions & 52 deletions R/card.R
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,12 @@ card <- function(..., full_screen = FALSE, height = NULL, max_height = NULL, fil
height = validateCssUnit(height),
max_height = validateCssUnit(max_height)
),
"data-bslib-card-init" = NA,
!!!attribs,
!!!children,
if (full_screen) full_screen_toggle(),
card_js_init()
card_dependency(),
card_init_js()
)

tag <- bindFillRole(tag, container = TRUE, item = fill)
Expand Down Expand Up @@ -271,64 +273,31 @@ full_screen_toggle <- function() {
"data-bs-toggle" = "tooltip",
"data-bs-placement" = "bottom",
title = "Expand",
full_screen_toggle_icon(),
htmlDependency(
name = "bslib-card-full-screen",
version = get_package_version("bslib"),
package = "bslib",
src = "components",
script = "card-full-screen.js"
)
full_screen_toggle_icon()
)
}

card_dependency <- function() {
htmlDependency(
name = "bslib-card",
version = get_package_version("bslib"),
package = "bslib",
src = "components",
script = "card.min.js"
)
}

card_js_init <- function() {
tags$script("data-bslib-card-needs-init" = NA, HTML(
"
var thisScript = document.querySelector('script[data-bslib-card-needs-init]');
if (!thisScript) throw new Error('Failed to register card() resize observer');

thisScript.removeAttribute('data-bslib-card-needs-init');

var card = $(thisScript).parents('.card').last();
if (!card) throw new Error('Failed to register card() resize observer');

// Let Shiny know to trigger resize when the card size changes
// TODO: shiny could/should do this itself (rstudio/shiny#3682)
var resizeEvent = window.document.createEvent('UIEvents');
resizeEvent.initUIEvent('resize', true, false, window, 0);
var ro = new ResizeObserver(() => { window.dispatchEvent(resizeEvent); });
ro.observe(card[0]);

// Enable tooltips (for the expand icon)
var tooltipList = card[0].querySelectorAll('[data-bs-toggle=\"tooltip\"]');
tooltipList.forEach(function(x) { new bootstrap.Tooltip(x); });

// In some complex fill-based layouts with multiple outputs (e.g., plotly),
// shiny initializes with the correct sizing, but in-between the 1st and last
// renderValue(), the size of the output containers can change, meaning every
// output but the 1st gets initialized with the wrong size during their
// renderValue(); and then after the render phase, shiny won't know trigger a
// resize since all the widgets will return to their original size
// (and thus, Shiny thinks there isn't any resizing to do).
// We workaround that situation by manually triggering a resize on the binding
// when the output container changes (this way, if the size is different during
// the render phase, Shiny will know about it)
$(document).on('shiny:value', function(x) {
var el = x.binding.el;
if (card[0].contains(el) && !$(el).data('bslib-output-observer')) {
var roo = new ResizeObserver(x.binding.onResize);
roo.observe(el);
$(el).data('bslib-output-observer', true);
}
});
"
))
card_init_js <- function() {
tags$script(
`data-bslib-card-init` = NA,
HTML("bslib.Card.initializeAllCards();")
)
}

# via bsicons::bs_icon("arrows-fullscreen")
full_screen_toggle_icon <- function() {
if (is_installed("bsicons")) {
return(bsicons::bs_icon("arrows-fullscreen"))
}
HTML('<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" class="bi bi-arrows-fullscreen " style="height:1em;width:1em;fill:currentColor;" aria-hidden="true" role="img" ><path fill-rule="evenodd" d="M5.828 10.172a.5.5 0 0 0-.707 0l-4.096 4.096V11.5a.5.5 0 0 0-1 0v3.975a.5.5 0 0 0 .5.5H4.5a.5.5 0 0 0 0-1H1.732l4.096-4.096a.5.5 0 0 0 0-.707zm4.344 0a.5.5 0 0 1 .707 0l4.096 4.096V11.5a.5.5 0 1 1 1 0v3.975a.5.5 0 0 1-.5.5H11.5a.5.5 0 0 1 0-1h2.768l-4.096-4.096a.5.5 0 0 1 0-.707zm0-4.344a.5.5 0 0 0 .707 0l4.096-4.096V4.5a.5.5 0 1 0 1 0V.525a.5.5 0 0 0-.5-.5H11.5a.5.5 0 0 0 0 1h2.768l-4.096 4.096a.5.5 0 0 0 0 .707zm-4.344 0a.5.5 0 0 1-.707 0L1.025 1.732V4.5a.5.5 0 0 1-1 0V.525a.5.5 0 0 1 .5-.5H4.5a.5.5 0 0 1 0 1H1.732l4.096 4.096a.5.5 0 0 1 0 .707z"></path></svg>')
}

Expand Down
2 changes: 1 addition & 1 deletion inst/components/accordion.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading