Skip to content

Commit

Permalink
Sticky admin nav
Browse files Browse the repository at this point in the history
  • Loading branch information
Sinetheta committed Nov 24, 2015
1 parent 49a8072 commit 03872e3
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 6 deletions.
106 changes: 106 additions & 0 deletions backend/app/assets/javascripts/spree/backend/sticky.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
$.fn.offsetBottom = ->
$(this).offset().top + $(this).height()

class Viewport
measure: =>
@top = document.documentElement.scrollTop || document.body.scrollTop
@height = $(window).height()
@bottom = @top + @height

isScrollingUp: =>
@measure()
goingUp = @top < @lastTop
@lastTop = @top
goingUp

isAbove: (el) =>
@top < el.offset().top

isBelow: (el) =>
@bottom > el.offsetBottom()

fits: (el) =>
el.height() < @height

viewport = new Viewport()

$(window).on
resize: _.debounce(viewport.measure, 100)

class Sticky
@checkStickies: =>
for sticky in @stickies
sticky.measure()
if viewport.isScrollingUp()
if sticky.isStuckBottom
sticky.pin()
else
sticky.stick() if viewport.isAbove(sticky.el)
if sticky.tooHigh()
sticky.unstick() if sticky.isStuckTop
else
if viewport.fits(sticky.el)
sticky.stick() unless viewport.isAbove(sticky.el)
else
sticky.stick(true) if viewport.isBelow(sticky.el)
if sticky.tooLow()
sticky.pin(true)

@stickies: []

constructor: (@el) ->
@container = @el.parent()
@placeholder = $('<div>').insertBefore(@el)
@measure()
if @container.css('position') == 'static'
@container.css('position', 'relative')
Sticky.stickies.push(this)

measure: =>
@maxTop = @placeholder.offset().top
@maxBottom = @container.offsetBottom()

tooLow: =>
@el.offsetBottom() >= @maxBottom

tooHigh: =>
@el.offset().top <= @maxTop

stick: (bottom) =>
if bottom
return if @isStuckBottom
@isStuckBottom = true
else
return if @isStuckTop
@isStuckTop = true
width = @el.width()
@el.addClass(if bottom then 'sticky-bottom' else 'sticky-top')
.css
position: 'fixed'
top: ''
width: width

unstick: =>
return unless @isStuckBottom || @isStuckTop
@isStuckBottom = @isStuckTop = false
@el.removeClass('sticky-bottom sticky-top')
@el.css('position', '')

pin: (bottom) =>
top = @el.offset().top - @container.offset().top
@unstick()
@el.css('position', 'absolute')
if bottom
@el.css('bottom', 0)
else
@el.css('top', Math.max(top, @maxTop))

$(window).on
scroll: @checkStickies

$.fn.sticky = ->
$(this).each ->
new Sticky($(this))

$ ->
$('[data-sticky]').sticky()
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,12 @@ nav.menu {
}

.admin-nav {
@include display(flex);
@include flex-direction(column);
border-right: 1px solid $color-sidebar-border;
background: $color-sidebar-bg;
z-index: $z-index-navbar-flyout;
}

.admin-nav-menu {
@include flex(1);
text-transform: uppercase;

ul {
Expand Down Expand Up @@ -136,3 +133,16 @@ nav.menu {
margin-right: 0.5rem;
}
}

.sticky-top,
.sticky-bottom {
position: fixed;
}

.sticky-top {
top: 0;
}

.sticky-bottom {
bottom: 0;
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ body {
}

.admin-nav {
@include position(fixed, 0 null 0 0);
@include position(absolute, 0 null 0 0);
width: $width-sidebar;
}

Expand Down
6 changes: 4 additions & 2 deletions backend/app/views/spree/admin/shared/_navigation.html.erb
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<div class="admin-nav">
<%= render partial: 'spree/admin/shared/header' %>
<%= render partial: 'spree/admin/shared/menu' %>
<%= render partial: 'spree/admin/shared/navigation_footer' %>
<div class="admin-nav-sticky" data-sticky>
<%= render partial: 'spree/admin/shared/menu' %>
<%= render partial: 'spree/admin/shared/navigation_footer' %>
</div>
</div>

0 comments on commit 03872e3

Please sign in to comment.