diff options
-rw-r--r-- | app/assets/javascripts/fly_out_nav.js | 1 | ||||
-rw-r--r-- | app/assets/javascripts/new_sidebar.js | 40 | ||||
-rw-r--r-- | app/assets/stylesheets/new_sidebar.scss | 108 | ||||
-rw-r--r-- | app/views/layouts/nav/_new_admin_sidebar.html.haml | 2 | ||||
-rw-r--r-- | app/views/layouts/nav/_new_group_sidebar.html.haml | 2 | ||||
-rw-r--r-- | app/views/layouts/nav/_new_profile_sidebar.html.haml | 2 | ||||
-rw-r--r-- | app/views/layouts/nav/_new_project_sidebar.html.haml | 2 | ||||
-rw-r--r-- | app/views/shared/_sidebar_toggle_button.html.haml | 4 |
8 files changed, 159 insertions, 2 deletions
diff --git a/app/assets/javascripts/fly_out_nav.js b/app/assets/javascripts/fly_out_nav.js index 8e9a97fe207..301e82f4610 100644 --- a/app/assets/javascripts/fly_out_nav.js +++ b/app/assets/javascripts/fly_out_nav.js @@ -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) { diff --git a/app/assets/javascripts/new_sidebar.js b/app/assets/javascripts/new_sidebar.js index 5f98aff8ced..3a3e6b14ec4 100644 --- a/app/assets/javascripts/new_sidebar.js +++ b/app/assets/javascripts/new_sidebar.js @@ -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); + } } } diff --git a/app/assets/stylesheets/new_sidebar.scss b/app/assets/stylesheets/new_sidebar.scss index 3d202183c82..2a568292aba 100644 --- a/app/assets/stylesheets/new_sidebar.scss +++ b/app/assets/stylesheets/new_sidebar.scss @@ -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; diff --git a/app/views/layouts/nav/_new_admin_sidebar.html.haml b/app/views/layouts/nav/_new_admin_sidebar.html.haml index 54ea39a2d36..06cfa509ebf 100644 --- a/app/views/layouts/nav/_new_admin_sidebar.html.haml +++ b/app/views/layouts/nav/_new_admin_sidebar.html.haml @@ -149,3 +149,5 @@ = custom_icon('settings') %span.nav-item-name Settings + + = render 'shared/sidebar_toggle_button' diff --git a/app/views/layouts/nav/_new_group_sidebar.html.haml b/app/views/layouts/nav/_new_group_sidebar.html.haml index 33a83866cbf..30724543bf1 100644 --- a/app/views/layouts/nav/_new_group_sidebar.html.haml +++ b/app/views/layouts/nav/_new_group_sidebar.html.haml @@ -88,3 +88,5 @@ = link_to group_settings_ci_cd_path(@group), title: 'CI / CD' do %span CI / CD + + = render 'shared/sidebar_toggle_button' diff --git a/app/views/layouts/nav/_new_profile_sidebar.html.haml b/app/views/layouts/nav/_new_profile_sidebar.html.haml index f715d8a63f9..df869fef604 100644 --- a/app/views/layouts/nav/_new_profile_sidebar.html.haml +++ b/app/views/layouts/nav/_new_profile_sidebar.html.haml @@ -83,3 +83,5 @@ = custom_icon('authentication_log') %span.nav-item-name Authentication log + + = render 'shared/sidebar_toggle_button' diff --git a/app/views/layouts/nav/_new_project_sidebar.html.haml b/app/views/layouts/nav/_new_project_sidebar.html.haml index 673febbc798..67b27b4e165 100644 --- a/app/views/layouts/nav/_new_project_sidebar.html.haml +++ b/app/views/layouts/nav/_new_project_sidebar.html.haml @@ -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 diff --git a/app/views/shared/_sidebar_toggle_button.html.haml b/app/views/shared/_sidebar_toggle_button.html.haml new file mode 100644 index 00000000000..e70faad4894 --- /dev/null +++ b/app/views/shared/_sidebar_toggle_button.html.haml @@ -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 |