Make contextual sidebar collapsible

This commit is contained in:
Annabel Dunstone Gray 2017-08-02 20:19:43 -05:00
parent 4b3011e1c2
commit d7ef168c52
8 changed files with 159 additions and 2 deletions

View file

@ -23,6 +23,7 @@ export const showSubLevelItems = (el) => {
const top = calculateTop(boundingRect, subItems.offsetHeight);
const isAbove = top < boundingRect.top;
subItems.classList.add('fly-out-list');
subItems.style.transform = `translate3d(0, ${Math.floor(top)}px, 0)`;
if (isAbove) {

View file

@ -1,23 +1,63 @@
import Cookies from 'js-cookie';
import _ from 'underscore';
/* global bp */
import './breakpoints';
export default class NewNavSidebar {
constructor() {
this.initDomElements();
this.render();
}
initDomElements() {
this.$page = $('.page-with-sidebar');
this.$sidebar = $('.nav-sidebar');
this.$overlay = $('.mobile-overlay');
this.$openSidebar = $('.toggle-mobile-nav');
this.$closeSidebar = $('.close-nav-button');
this.$sidebarToggle = $('.js-toggle-sidebar');
}
bindEvents() {
this.$openSidebar.on('click', () => this.toggleSidebarNav(true));
this.$closeSidebar.on('click', () => this.toggleSidebarNav(false));
this.$overlay.on('click', () => this.toggleSidebarNav(false));
this.$sidebarToggle.on('click', () => {
const value = !this.$sidebar.hasClass('sidebar-icons-only');
this.toggleCollapsedSidebar(value);
});
$(window).on('resize', () => _.debounce(this.render(), 100));
}
static setCollapsedCookie(value) {
if (bp.getBreakpointSize() !== 'lg') {
return;
}
Cookies.set('sidebar_collapsed', value, { expires: 365 * 10 });
}
toggleSidebarNav(show) {
this.$sidebar.toggleClass('nav-sidebar-expanded', show);
this.$overlay.toggleClass('mobile-nav-open', show);
this.$sidebar.removeClass('sidebar-icons-only');
}
toggleCollapsedSidebar(collapsed) {
this.$sidebar.toggleClass('sidebar-icons-only', collapsed);
this.$page.toggleClass('page-with-new-sidebar', !collapsed);
this.$page.toggleClass('page-with-icon-sidebar', collapsed);
NewNavSidebar.setCollapsedCookie(collapsed);
}
render() {
const breakpoint = bp.getBreakpointSize();
if (breakpoint === 'sm' || breakpoint === 'md') {
this.toggleCollapsedSidebar(true);
} else if (breakpoint === 'lg') {
const collapse = Cookies.get('sidebar_collapsed') === 'true';
this.toggleCollapsedSidebar(collapse);
}
}
}

View file

@ -12,9 +12,12 @@ $hover-background: $indigo-700;
$hover-color: $white-light;
$inactive-color: $gl-text-color-secondary;
$new-sidebar-width: 220px;
$new-sidebar-collapsed-width: 50px;
.page-with-new-sidebar {
@media (min-width: $screen-sm-min) {
padding-left: $new-sidebar-collapsed-width;
@media (min-width: $screen-lg-min) {
padding-left: $new-sidebar-width;
}
@ -29,6 +32,12 @@ $new-sidebar-width: 220px;
}
}
.page-with-icon-sidebar {
@media (min-width: $screen-sm-min) {
padding-left: $new-sidebar-collapsed-width;
}
}
.context-header {
position: relative;
@ -125,6 +134,20 @@ $new-sidebar-width: 220px;
background-color: $gray-normal;
box-shadow: inset -2px 0 0 $border-color;
// .expand-full-sidebar-button {
// display: none;
// }
&.sidebar-icons-only {
width: $new-sidebar-collapsed-width;
.nav-item-name,
.badge,
.project-title {
display: none;
}
}
&.nav-sidebar-expanded {
left: 0;
}
@ -219,6 +242,8 @@ $new-sidebar-width: 220px;
}
.sidebar-top-level-items {
margin-bottom: 60px;
> li {
> a {
@media (min-width: $screen-sm-min) {
@ -240,7 +265,7 @@ $new-sidebar-width: 220px;
@media (min-width: $screen-sm-min) {
position: fixed;
top: 0;
left: 220px;
left: $new-sidebar-width;
width: 150px;
margin-top: -1px;
padding: 8px 1px;
@ -326,6 +351,85 @@ $new-sidebar-width: 220px;
}
}
// Collapsed nav
.toggle-sidebar-button {
width: $new-sidebar-width - 2px;
position: fixed;
bottom: 0;
padding: 16px;
background-color: $gray-normal;
border-top: 2px solid $border-color;
color: $gl-text-color-secondary;
display: flex;
align-items: center;
@media (max-width: $screen-xs-max) {
display: none;
}
i {
font-size: 20px;
margin-right: 8px;
}
.fa-angle-double-right {
display: none;
}
&:hover {
background-color: $border-color;
color: $gl-text-color;
}
}
.sidebar-icons-only {
.context-header {
height: 60px;
a {
padding: 10px 4px;
}
}
li a {
padding: 12px 15px;
}
.sidebar-top-level-items > li {
&.active a {
padding-left: 12px;
}
.sidebar-sub-level-items {
@media (min-width: $screen-sm-min) {
left: $new-sidebar-collapsed-width;
}
&:not(.flyout-list) {
display: none;
}
}
}
.toggle-sidebar-button {
width: $new-sidebar-collapsed-width - 2px;
.collapse-text,
.fa-angle-double-left {
display: none;
}
.fa-angle-double-right {
display: block;
}
}
}
// Mobile nav
.toggle-mobile-nav {
display: none;
background-color: transparent;

View file

@ -149,3 +149,5 @@
= custom_icon('settings')
%span.nav-item-name
Settings
= render 'shared/sidebar_toggle_button'

View file

@ -88,3 +88,5 @@
= link_to group_settings_ci_cd_path(@group), title: 'CI / CD' do
%span
CI / CD
= render 'shared/sidebar_toggle_button'

View file

@ -83,3 +83,5 @@
= custom_icon('authentication_log')
%span.nav-item-name
Authentication log
= render 'shared/sidebar_toggle_button'

View file

@ -222,6 +222,8 @@
%span
Members
= render 'shared/sidebar_toggle_button'
-# Shortcut to Project > Activity
%li.hidden
= link_to activity_project_path(@project), title: 'Activity', class: 'shortcuts-project-activity' do

View file

@ -0,0 +1,4 @@
%a.toggle-sidebar-button.js-toggle-sidebar{ role: "button", type: "button", title: "Toggle sidebar" }
= icon('angle-double-left')
= icon('angle-double-right')
%span.collapse-text Collapse sidebar