How to code a Sidebar collapse in shiny to show only icons

7.6k Views Asked by At

If you are familiar with the shiny website, you'll notice that when you press the button to collapse the sidebar, it's showing bigger icons (but not completely hiding the sidebar.

Do you know how is this possible to code this?

I heard that the package shinyBS could be useful or bootstrap things, but I don't understand what it is.

Before collapsing:

<body id="app" class="app ng-scope buffer-pinterest" data-custom-page="" data-off-canvas-nav="" data-ng-controller="AppCtrl">

enter image description here

And this (see highlighted text): enter image description here

After collapsing:

<body id="app" class="app ng-scope buffer-pinterest nav-collapsed-min" data-custom-page="" data-off-canvas-nav="" data-ng-controller="AppCtrl">

enter image description here

3

There are 3 best solutions below

10
On BEST ANSWER

You can accomplish that with a little help of two great libraries: shinydashboard (obtaining navbar based on AdminLTE bootstrap theme) and shinyjs (including neccessary class to the template). Working code below:

## app.R ##
library(shiny)
library(shinydashboard)
library(shinyjs)

ui <- dashboardPage(
  dashboardHeader(),
  dashboardSidebar(sidebarMenu(menuItem('Test', icon = icon('phone'), tabName = 'sampletabname'))),
  dashboardBody(h3('Test app'),
                useShinyjs())
)

server <- function(input, output) {
  runjs('
        var el2 = document.querySelector(".skin-blue");
        el2.className = "skin-blue sidebar-mini";
        ')
}

shinyApp(ui, server)

EDIT: To solve the problem mentioned in the comment I play with visibility: hidden css style. New content of server part of the app (rest remains unchanged):

  runjs({'
        var el2 = document.querySelector(".skin-blue");
        el2.className = "skin-blue sidebar-mini";
        var clicker = document.querySelector(".sidebar-toggle");
        clicker.id = "switchState";
    '})

  onclick('switchState', runjs({'
        var title = document.querySelector(".logo")
        if (title.style.visibility == "hidden") {
          title.style.visibility = "visible";
        } else {
          title.style.visibility = "hidden";
        }
  '}))
0
On

I've created collapsing sidebar using pure CSS and Bootstrap 4.

See below working snippet:

You can also check here on codepen: https://codepen.io/imharshm/pen/ZEePyyR

in codepen example, I've used SCSS.

.sidebar-wrapper {
  background: #fff;
  box-shadow: 1px 0px 4px rgba(0, 0, 0, 0.08);
  width: 60px;
  height: 100vh;
  position: absolute;
  top: 0;
  transition: all 0.35s ease;
  overflow: hidden auto;
  z-index: 9;
}

.sidebar-wrapper:hover,
.sidebar-wrapper.show {
  width: 300px;
}

@media (max-width: 599px) {
  .sidebar-wrapper {
    width: 0;
  }
}

.sidebar-wrapper #sidebar-container {
  width: 300px;
  height: 100%;
  position: absolute;
}

.sidebar-wrapper #sidebar-container .list-group .list-group-item {
  border: 0;
  border-left: 5px solid transparent;
  border-radius: 0 !important;
  color: #0c0c0c;
  padding: 0.5rem 0;
  padding-right: 0.5rem;
  min-height: 45px;
  border-top-color: rgba(206, 212, 218, 0.36) !important;
  border-bottom-color: rgba(206, 212, 218, 0.36) !important;
}

.sidebar-wrapper #sidebar-container .list-group .list-group-item.selected {
  border-left: 5px solid #196bd6;
  color: #196bd6;
}

.sidebar-wrapper #sidebar-container .list-group .list-group-item.brand-name {
  color: #1dc8cd;
  background: #26262d;
}

.sidebar-wrapper #sidebar-container .list-group .list-group-item .change-workspace-dropdown button {
  border: 1px solid #ddd d;
  border-radius: 0.5rem;
}

.sidebar-wrapper #sidebar-container .list-group .list-group-item .change-workspace-dropdown .dropdown-menu {
  padding: 0;
  width: 200px;
  border-radius: 0.5rem;
  overflow: hidden;
}

.sidebar-wrapper #sidebar-container .list-group .list-group-item .change-workspace-dropdown .dropdown-menu .dropdown-item {
  display: flex;
  align-items: center;
}

.sidebar-wrapper #sidebar-container .list-group .list-group-item .change-workspace-dropdown .dropdown-menu .dropdown-item .handler-icon {
  font-size: 20px;
  margin-right: 0.5rem;
}

.sidebar-wrapper #sidebar-container .list-group .list-group-item .edit-workspace {
  color: #296bd6;
  font-size: 10px;
}

.sidebar-wrapper #sidebar-container .list-group .list-group-item .plan-info {
  background: rgba(41, 107, 214, 0.09);
  border-radius: 15px;
  color: #296bd6;
  font-size: 10px;
  padding: 0.125rem 0.5rem;
}

.sidebar-wrapper #sidebar-container .list-group .list-group-item .menu-icon {
  font-size: 18px;
  display: inline-flex;
  justify-content: center;
  align-items: center;
  min-height: 45px;
  width: 55px;
  padding-right: 0.5rem;
}

.sidebar-wrapper #sidebar-container .list-group .list-group-item .menu-collapsed {
  display: flex;
  flex-direction: column;
  justify-content: center;
  margin-left: 0.5rem;
}

.sidebar-wrapper #sidebar-container .list-group .list-group-item .submenu-icon {
  display: inline-block;
}

.sidebar-wrapper #sidebar-container .list-group .list-group-item[aria-expanded="false"] .submenu-icon::after {
  content: "\f0d7";
  font-family: FontAwesome;
  display: inline;
  text-align: right;
}

.sidebar-wrapper #sidebar-container .list-group .list-group-item[aria-expanded="true"] .submenu-icon::after {
  content: "\f0d8";
  font-family: FontAwesome;
  display: inline;
  text-align: right;
  padding-left: 10px;
}

.sidebar-wrapper #sidebar-container .list-group .sidebar-submenu {
  font-size: 0.9rem;
}

.sidebar-wrapper #sidebar-container .list-group .sidebar-submenu .list-group-item {
  height: 45px;
  padding-left: 30px;
}

.cursor-pointer {
  cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.0/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
<link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" />
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" />


<div class="sidebar-wrapper">
  <div id="sidebar-container">
    <div class="h-100 d-flex flex-column">
      <ul class="list-group">
        <a href="#" class="list-group-item list-group-item-action brand-name">
          <div class="d-flex w-100 justify-content-start align-items-center">
            <img class="menu-icon" src="https://imharshm.github.io/logo.png" />
            <div class="menu-collapsed">
              <span>IMHARSHM </span>
            </div>
          </div>
        </a>
        <a href="#" class="list-group-item list-group-item-action">
          <div class="d-flex w-100 justify-content-start align-items-center">
            <span class="menu-icon fa fa-briefcase"></span>
            <div class="menu-collapsed">
              <span>Switch Workspace <span class="edit-workspace ml-2">Edit</span></span>
              <div class="change-workspace-dropdown">
                <button class="dropdown-toggle" data-toggle="dropdown">
                  Change workspace
                </button>
                <ul class="dropdown-menu" id="linked-handles">
                  <li class="dropdown-item" href="#"> <span class="handler-icon fa fa-facebook-square"></span>
                    <span>Handler 1</span></li>

                  <li class="dropdown-item" href="#"><span class="handler-icon fa fa-instagram"></span><span>Handler 1</span></li>
                </ul>
              </div>
            </div>
          </div>
        </a>

        <a href="#" class="list-group-item list-group-item-action analysis-list-item border-top">
          <div class="d-flex w-100 justify-content-start align-items-center">
            <span class="menu-icon fa fa-pencil"></span>
            <div class="menu-collapsed"><span>Improve Post</span> <span class="small">Optimise your
                Instagram Posts</span></div>
          </div>
        </a>

        <a href="#" class="list-group-item list-group-item-action competitor-list-item">
          <div class="d-flex w-100 justify-content-start align-items-center">
            <span class="menu-icon fa fa-line-chart"></span>
            <div class="menu-collapsed"><span>Content Analysis</span> <span class="small">Analyse your
                competitor's strategy</span></div>
          </div>
        </a>
      </ul>

      <ul class="list-group mt-auto">
        <a href="#" class="list-group-item list-group-item-action border-top" data-backdrop="static" data-toggle="modal" data-target="#newWorkspaceModal">
          <div class="d-flex w-100 justify-content-start align-items-center">
            <span class="menu-icon fa fa-plus-square"></span>
            <div class="menu-collapsed"><span>New Workspace</span> <span class="small">Use a new Instagram
                Account</span></div>
          </div>
        </a>

        <a href="#" class="list-group-item list-group-item-action pricing-list-item border-top">
          <div class="d-flex w-100 justify-content-start align-items-center">
            <span class="menu-icon fa fa-usd"></span>
            <div class="menu-collapsed">
              <span>Plan Details <span class="plan-info">Trial plan: 7 days left</span></span> <span class="small">Manage your subscriptions</span>
            </div>
          </div>
        </a>

        <a href="#" class="list-group-item list-group-item-action">
          <div class="d-flex w-100 justify-content-start align-items-center">
            <span class="menu-icon fa fa-smile-o"></span>
            <div class="menu-collapsed"><span>Apply Offer Code</span> <span class="small">Redeem your
                discount codes</span></div>
          </div>
        </a>

        <a href="#" class="list-group-item list-group-item-action border-top">
          <div class="d-flex w-100 justify-content-start align-items-center">
            <span class="menu-icon fa fa-question"></span>
            <div class="menu-collapsed"><span>Help</span> <span class="small">Let us help you use for better</span></div>
          </div>
        </a>

        <a class="list-group-item list-group-item-action">
          <div class="d-flex w-100 justify-content-start align-items-center">
            <span class="menu-icon fa fa-user"></span>
            <div class="menu-collapsed"><span class="topbar-username">Profile</span> <span class="g-signout cursor-pointer small">Logout</span></div>
            <span class="submenu-icon ml-auto"></span>
          </div>
        </a>
      </ul>
    </div>
  </div>
</div>

0
On

Or you can insert that code in the javascript file e.g. sidebar.js inside the www folder (placed on the same level as server.R and ui.R)

$( document ).ready(function() {
  $(".skin-blue").addClass("sidebar-mini");
  $(".sidebar-toggle").click(function() {
    $(".logo").toggleClass("hidden");
  });
});

Then you need to load it in the page head, namely on top of your dashboardBody:

dashboardBody(
      tags$head(
        tags$script(src = "sidebar.js")
      ),
...

And you can not care about shinyjs