The MarqueeSelection component provides a service which allows the user to drag a rectangle to be drawn around items to select them. This works in conjunction with a selection object, which can be used to generically store selection state, separate from a component that consumes the state.

MarqueeSelection also works in conjunction with the AutoScroll utility to automatically scroll the container when we drag a rectangle within the vicinity of the edges.

When a selection rectangle is dragged, we look for elements with the data-selection-index attribute populated. We get these elements' boundingClientRects and compare them with the root's rect to determine selection state. We update the selection state appropriately.

In virtualization cases where items that were once selected are dematerialized, we will keep the item in its previous state until we know definitively if it's on/off. (In other words, this works with List.)

For more details and examples visit the official docs. The R package can not handle each and every case, so for advanced use cases you need to work using the original docs to achieve the desired result.

MarqueeSelection(...)

Arguments

className

string
Additional CSS class(es) to apply to the MarqueeSelection.

componentRef

IRefObject<IMarqueeSelection>
Optional callback to access the IMarqueeSelection interface. Use this instead of ref for accessing the public methods and properties of the component.

isDraggingConstrainedToRoot

boolean
Optional flag to restrict the drag rect to the root element, instead of allowing the drag rect to start outside of the root element boundaries.

isEnabled

boolean
Optional flag to control the enabled state of marquee selection. This allows you to render it and have events all ready to go, but conditionally disable it. That way transitioning between enabled/disabled generate no difference in the DOM.

onShouldStartSelection

(ev: MouseEvent) => boolean
Optional callback that is called, when the mouse down event occurs, in order to determine if we should start a marquee selection. If true is returned, we will cancel the mousedown event to prevent upstream mousedown handlers from executing.

rootProps

React.HTMLAttributes<HTMLDivElement>
Optional props to mix into the root DIV element.

selection

ISelection
The selection object to interact with when updating selection changes.

styles

IStyleFunction<IMarqueeSelectionStyleProps, IMarqueeSelectionStyles>
Call to provide customized styling that will layer on top of the variant rules.

theme

ITheme
Theme (provided through customization.)

Examples

library(shiny)
#> 
#> Attaching package: ‘shiny’
#> The following object is masked from ‘package:shiny.fluent’:
#> 
#>     runExample
library(shiny.fluent)

# This is an advanced demo showing how you can use virtually all features of Fluent UI
# by creating custom components in JS and rendering them with shiny.react.
# This example is a translation of the example in https://developer.microsoft.com/en-us/fluentui#/controls/web/marqueeselection.

# Script showing how to:
# 1. Use mergeStyles and themes from Fluent
# 2. Define custom components
# 3. Send results back to Shiny.
script <- tags$script(HTML([1931 chars quoted with '"']))

if (interactive()) {
  MarqueeSelectionExample <- function(...) shiny.react::reactElement(
    module = "exampleApp", name = "MarqueeSelectionExample",
    props = shiny.react::asProps(...),
  )

  shinyApp(
    ui = tagList(
      script,
      div(
        textOutput("marqueeResult"),
        Label("Drag a rectangle around the items below to select them"), # Make sure Fluent dependency is loaded.
        reactOutput("marqueeSelection")
      )
    ),
    server = function(input, output) {
      photos <- lapply(1:50, function(index) {
        randomWidth <- 50 + sample.int(150, 1)
        list(
          key = index,
          url = paste0('http://placehold.it/', randomWidth, 'x100'),
          width = randomWidth,
          height = 100
        )
      })

      output$marqueeResult <- renderText({
        paste("You have selected: ", paste(input$selectedIndices, collapse = ", "))
      })

      output$marqueeSelection <- renderReact({
        MarqueeSelectionExample(
          name = "selectedIndices",
          photos = photos
        )
      })
    }
  )
}