---
title: "List View"
date: "`r Sys.Date()`"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{List View}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r setup, echo=FALSE, message=FALSE}
library(bslib)
```

## Creating Different Types of Lists

Lists are a great way to organize information in a structured way. And Framework7 provides a number of different list types to choose from, ranging from simple text lists to more complex lists with icons, groups, headers and footers. In `{shinyMobile}`, all these possibilities are available through the `f7List()` and `f7ListItem()` functions.

### Styling options

There are 4 styling options available for lists:

- __inset__: to make list block inset, which will make the list block appear indented. If used in combination with strong, it will also have rounded corners.
- __outline__: to add outline (borders) around the list block
- __dividers__: to add dividers (borders) between list items
- __strong__: to add extra highlighting to list block

### Available mode options

There are 4 different modes available for lists:

- __simple__: to create a simple list
- __links__: to create a list with links
- __media__: to create a list with media elements
- __contacts__: to create a grouped list

## Examples

As you can imagine, there are a lot of possible combinations of these options. Below we will show some examples of how to create different types of lists.

### List items

There are two different ways in which you can create items belonging in `f7List()`:

1. Using `tags$li()`, which is the most simple way to create a list item. Within this tag you can add any HTML content you like.
2. Using `f7ListItem()`, which gives you plenty of options to configure your list item. This is the recommended method.

For example, the following code creates a simple list with 5 items using the first method:

```{r eval = FALSE}
f7List(
  mode = "simple",
  lapply(1:5, function(j) {
    tags$li(
      paste("Item", j)
    )
  })
)
```

<br>

Using the second method, the code would look like:

```{r eval = FALSE}
f7List(
  mode = "simple",
  lapply(1:5, function(j) {
    f7ListItem(
      title = paste("Item", j)
    )
  })
)
```

<br>

The styling of these two methods might differ slightly, because in the second method some CSS classes are added to the list items. However, in the case of a simple item like above, there's no difference.

### Simple list

The most simple list has `mode` set to `"simple"` and no other options set:

```{r, eval=TRUE, echo=FALSE}
card(
  shinyMobile:::create_app_link(
    " ", # nolint
    "app",
    header = FALSE
  ),
  full_screen = TRUE,
  style = "width: 393px; margin: 0 auto; float: none;"
)
```
<div class="text-center mt-4">
<a class="btn btn-primary" data-bs-toggle="collapse" href="#simpleList" role="button" aria-expanded="false" aria-controls="singleLayout">
Code
</a>
</div>

<div class="collapse" id="simpleList">
```{r, eval=FALSE}
library(shiny)
library(shinyMobile)

shinyApp(
  ui = f7Page(
    title = "My app",
    options = list(dark = FALSE, theme = "ios"),
    f7SingleLayout(
      navbar = f7Navbar(title = "f7List"),
      f7List(
        mode = "simple",
        lapply(1:5, function(j) {
          f7ListItem(
            title = paste("Item", j)
          )
        })
      )
    )
  ),
  server = function(input, output) {
  }
)
```
</div>

<br>

Note that you need to use `title = ...` in `f7ListItem()` when using `f7List(mode = "simple", ...)`. Other arguments in `f7ListItem()` will be ignored when `mode` is `"simple"`.

<br>

Using the styling options, you can already drastically change the appearance of the list:

```{r, eval=TRUE, echo=FALSE}
card(
  shinyMobile:::create_app_link(
    " ", # nolint
    "app",
    header = FALSE
  ),
  full_screen = TRUE,
  style = "width: 393px; margin: 0 auto; float: none;"
)
```
<div class="text-center mt-4">
<a class="btn btn-primary" data-bs-toggle="collapse" href="#simpleListStyling" role="button" aria-expanded="false" aria-controls="singleLayout">
Code
</a>
</div>

<div class="collapse" id="simpleListStyling">
```{r, eval=FALSE}
library(shiny)
library(shinyMobile)

shinyApp(
  ui = f7Page(
    title = "My app",
    options = list(dark = FALSE, theme = "ios"),
    f7SingleLayout(
      navbar = f7Navbar(title = "f7List"),
      f7List(
        mode = "simple",
        outline = TRUE,
        dividers = TRUE,
        strong = TRUE,
        lapply(1:5, function(j) {
          f7ListItem(
            title = paste("Item", j)
          )
        })
      )
    )
  ),
  server = function(input, output) {
  }
)
```
</div>

### Simple link list

When setting `mode` to `"links"`, the list items will be displayed as links:

```{r, eval=TRUE, echo=FALSE}
card(
  shinyMobile:::create_app_link(
    " ", # nolint
    "app",
    header = FALSE
  ),
  full_screen = TRUE,
  style = "width: 393px; margin: 0 auto; float: none;"
)
```
<div class="text-center mt-4">
<a class="btn btn-primary" data-bs-toggle="collapse" href="#simpleLinkList" role="button" aria-expanded="false" aria-controls="singleLayout">
Code
</a>
</div>

<div class="collapse" id="simpleLinkList">
```{r, eval=FALSE}
library(shiny)
library(shinyMobile)

shinyApp(
  ui = f7Page(
    title = "My app",
    options = list(dark = FALSE, theme = "ios"),
    f7SingleLayout(
      navbar = f7Navbar(title = "f7List"),
      f7List(
        mode = "links",
        outline = TRUE,
        dividers = TRUE,
        strong = TRUE,
        lapply(1:5, function(j) {
          tags$li(
            f7Link(label = paste("Item", j), href = "https://www.google.com")
          )
        })
      )
    )
  ),
  server = function(input, output) {
  }
)
```
</div>

<br>

In the example above, we're using `f7Link()` to create the links. This will automatically make sure that the links are opened in a new tab. 

### Link list with header and footer

To add some complexity to the link list, we can add a header and footer. In this case, we will use `f7ListItem()` to create the list items. It is important to set `mode` to `NULL` in `f7List()`:   

```{r, eval=TRUE, echo=FALSE}
card(
  shinyMobile:::create_app_link(
    " ", # nolint
    "app",
    header = FALSE
  ),
  full_screen = TRUE,
  style = "width: 393px; margin: 0 auto; float: none;"
)
```
<div class="text-center mt-4">
<a class="btn btn-primary" data-bs-toggle="collapse" href="#linkedListHF" role="button" aria-expanded="false" aria-controls="singleLayout">
Code
</a>
</div>

<div class="collapse" id="linkedListHF">
```{r, eval=FALSE}
library(shiny)
library(shinyMobile)

shinyApp(
  ui = f7Page(
    title = "My app",
    options = list(dark = FALSE, theme = "ios"),
    f7SingleLayout(
      navbar = f7Navbar(title = "f7List"),
      f7List(
        mode = NULL,
        outline = TRUE,
        dividers = TRUE,
        strong = TRUE,
        lapply(1:5, function(j) {
          f7ListItem(
            title = paste("Item", j),
            header = paste("Header", j),
            footer = paste("Footer", j),
            href = "https://www.google.com"
          )
        })
      )
    )
  ),
  server = function(input, output) {
  }
)
```
</div>

### Grouped list

A grouped list can be generated by using `f7ListGroup()`. The `mode` argument should be set to `"contacts"` in `f7List()`:

```{r, eval=TRUE, echo=FALSE}
card(
  shinyMobile:::create_app_link(
    " ", # nolint
    "app",
    header = FALSE
  ),
  full_screen = TRUE,
  style = "width: 393px; margin: 0 auto; float: none;"
)
```
<div class="text-center mt-4">
<a class="btn btn-primary" data-bs-toggle="collapse" href="#groupedList" role="button" aria-expanded="false" aria-controls="singleLayout">
Code
</a>
</div>

<div class="collapse" id="groupedList">
```{r, eval=FALSE}
library(shiny)
library(shinyMobile)

shinyApp(
  ui = f7Page(
    title = "My app",
    options = list(dark = FALSE, theme = "ios"),
    f7SingleLayout(
      navbar = f7Navbar(title = "f7List"),
      f7List(
        mode = "contacts",
        outline = TRUE,
        dividers = TRUE,
        strong = TRUE,
        lapply(4:6, function(i) {
          f7ListGroup(
            title = LETTERS[i],
            lapply(1:10, function(j) {
              f7ListItem(title = paste("Person", j),
                         media = tags$img(
                         src = paste0("https://cdn.framework7.io/placeholder/people-160x160-", j, ".jpg")
                         ),
                         # Random phone number as text
                         paste0("+42 6 ", sample(10000000:99999999, 1))
                         )
            })
          )
        })
      )
    )
  ),
  server = function(input, output) {
  }
)
```
</div>

By adding `media` to the `f7ListItem()`, you can display an image next to the list item, thereby making a pretty fancy contact list!

<br>

If desired, you can also use `f7Icon()`:

```{r, eval=TRUE, echo=FALSE}
card(
  shinyMobile:::create_app_link(
    " ", # nolint
    "app",
    header = FALSE
  ),
  full_screen = TRUE,
  style = "width: 393px; margin: 0 auto; float: none;"
)
```
<div class="text-center mt-4">
<a class="btn btn-primary" data-bs-toggle="collapse" href="#groupedListIcon" role="button" aria-expanded="false" aria-controls="singleLayout">
Code
</a>
</div>

<div class="collapse" id="groupedListIcon">
```{r, eval=FALSE}
library(shiny)
library(shinyMobile)

shinyApp(
  ui = f7Page(
    title = "My app",
    options = list(dark = FALSE, theme = "ios"),
    f7SingleLayout(
      navbar = f7Navbar(title = "f7List"),
      f7List(
        mode = "contacts",
        outline = TRUE,
        dividers = TRUE,
        strong = TRUE,
        lapply(4:6, function(i) {
          f7ListGroup(
            title = LETTERS[i],
            lapply(1:10, function(j) {
              f7ListItem(title = paste("Person", j),
                         media = f7Icon("person_fill"),
                         # Random phone number as text
                         paste0("+31 6 ", sample(10000000:99999999, 1))
                         )
            })
          )
        })
      )
    )
  ),
  server = function(input, output) {
  }
)
```
</div>

### Media list

With `mode` set to `"media"`, you can create a list with media objects, and you have the option to add a `subtitle` to the list items. Note that `header` and `footer` can't be used in a media list.

```{r, eval=TRUE, echo=FALSE}
card(
  shinyMobile:::create_app_link(
    " ", # nolint
    "app",
    header = FALSE
  ),
  full_screen = TRUE,
  style = "width: 393px; margin: 0 auto; float: none;"
)
```
<div class="text-center mt-4">
<a class="btn btn-primary" data-bs-toggle="collapse" href="#mediaList" role="button" aria-expanded="false" aria-controls="singleLayout">
Code
</a>
</div>

<div class="collapse" id="mediaList">
```{r, eval=FALSE}
library(shiny)
library(shinyMobile)

shinyApp(
  ui = f7Page(
    title = "My app",
    options = list(dark = FALSE, theme = "ios"),
    f7SingleLayout(
      navbar = f7Navbar(title = "f7List"),
      f7List(
        mode = "media",
        outline = TRUE,
        dividers = TRUE,
        strong = TRUE,
        lapply(1:10, function(i) {
          f7ListItem(
            title = paste("Title", i),
            subtitle = paste("Subtitle", i),
            media = tags$img(
              style = "border-radius: 8px;",
              src = paste0("https://cdn.framework7.io/placeholder/people-160x160-", i, ".jpg"),
              width = "70"
            ),
            right = paste("Right", i),
            paste("Some longer text about this particular item that has the magical number", i),
            href = "#"
          )
        })
      )
    )
  ),
  server = function(input, output) {
  }
)
```
</div>

The default media width is `50`. If you want to override this, you can add `width` to the `img` tag.

## Other Types of Lists

The list view can be used in other cases as well:

- To create a __virtual list__ with `f7VirtualList()` for displaying a list with a large number of items.
- To create an inputs layout, where inputs can be nicely grouped and styled together inside an `f7List()`. You can read more about this in the [Inputs Layout](inputs-layout.html) vignette.
- Swipeout is an extension of the list view that allows you to swipe over list elements to reveal a hidden menu with available actions. You can use `f7Swipeout()` and `f7SwipeOutItem()` for this.
