Expand truncated sidebar items on hover/focus

pull/15/head
Thibaut 11 years ago
parent 480c8b5062
commit 7ab4352405

@ -12,12 +12,10 @@ templates.sidebarType = (type) ->
"""<a href="#{type.fullPath()}" class="_list-item _list-dir" data-slug="#{type.slug}"><span class="_list-arrow"></span><span class="_list-count">#{type.count}</span>#{type.name}</a>""" """<a href="#{type.fullPath()}" class="_list-item _list-dir" data-slug="#{type.slug}"><span class="_list-arrow"></span><span class="_list-count">#{type.count}</span>#{type.name}</a>"""
templates.sidebarEntry = (entry) -> templates.sidebarEntry = (entry) ->
name = $.escape(entry.name) """<a href="#{entry.fullPath()}" class="_list-item _list-hover">#{$.escape entry.name}</a>"""
"""<a href="#{entry.fullPath()}" class="_list-item" title="#{name}">#{name}</a>"""
templates.sidebarResult = (entry) -> templates.sidebarResult = (entry) ->
name = $.escape(entry.name) """<a href="#{entry.fullPath()}" class="_list-item _list-hover _list-result _icon-#{entry.doc.slug}">#{$.escape entry.name}</a>"""
"""<a href="#{entry.fullPath()}" class="_list-item _list-result _icon-#{entry.doc.slug}" title="#{entry.doc.name}: #{name}">#{name}</a>"""
templates.sidebarPageLink = (count) -> templates.sidebarPageLink = (count) ->
"""<span class="_list-item _list-pagelink">Show more… (#{count})</span>""" """<span class="_list-item _list-pagelink">Show more… (#{count})</span>"""

@ -8,6 +8,7 @@ class app.views.Sidebar extends app.View
escape: 'onEscape' escape: 'onEscape'
init: -> init: ->
@addSubview @hover = new app.views.SidebarHover @el unless $.isTouchScreen()
@addSubview @search = new app.views.Search @addSubview @search = new app.views.Search
@search @search
@ -24,6 +25,7 @@ class app.views.Sidebar extends app.View
show: (view) -> show: (view) ->
unless @view is view unless @view is view
@hover?.hide()
@saveScrollPosition() @saveScrollPosition()
@view?.deactivate() @view?.deactivate()
@html @view = view @html @view = view

@ -0,0 +1,100 @@
class app.views.SidebarHover extends app.View
@itemClass: '_list-hover'
@events:
focus: 'onFocus'
blur: 'onBlur'
mouseover: 'onMouseover'
mouseout: 'onMouseout'
scroll: 'onScroll'
click: 'onClick'
@routes:
after: 'onRoute'
constructor: (@el) ->
unless isPointerEventsSupported()
delete @constructor.events.mouseover
super
init: ->
@offsetTop = @el.offsetTop
return
show: (el) ->
unless el is @cursor
@hide()
if @isTarget(el) and @isTruncated(el)
@cursor = el
@clone = @makeClone @cursor
$.append document.body, @clone
@position()
return
hide: ->
if @cursor
$.remove @clone
@cursor = @clone = null
return
position: =>
if @cursor
top = $.rect(@cursor).top
if top > @offsetTop
@clone.style.top = top + 'px'
else
@hide()
return
makeClone: (el) ->
clone = el.cloneNode()
clone.textContent = el.textContent
clone.classList.add 'clone'
clone
isTarget: (el) ->
el.classList.contains @constructor.itemClass
isTruncated: (el) ->
el.scrollWidth >= el.offsetWidth
onFocus: (event) =>
@focusTime = Date.now()
@show event.target
return
onBlur: =>
@hide()
return
onMouseover: (event) =>
if @isTarget(event.target) and @mouseActivated()
@show event.target
return
onMouseout: (event) =>
if @isTarget(event.target) and @mouseActivated()
@hide()
return
mouseActivated: ->
# Skip mouse events caused by focus events scrolling the sidebar.
not @focusTime or Date.now() - @focusTime > 500
onScroll: =>
@position()
return
onClick: (event) =>
if event.target is @clone
$.click @cursor
return
onRoute: =>
@hide()
return
isPointerEventsSupported = ->
el = document.createElement 'div'
el.style.cssText = 'pointer-events: auto'
el.style.pointerEvents is 'auto'

@ -64,7 +64,9 @@
line-height: 1.75rem; line-height: 1.75rem;
font-size: .875rem; font-size: .875rem;
white-space: nowrap; white-space: nowrap;
word-wrap: normal;
text-overflow: ellipsis; text-overflow: ellipsis;
text-shadow: 0 1px rgba(white, .3);
border: solid transparent; border: solid transparent;
border-width: 1px 1px 1px 0; border-width: 1px 1px 1px 0;
cursor: default; cursor: default;
@ -178,6 +180,49 @@
} }
} }
//
// List hover clone
//
._list-hover.clone {
position: fixed;
z-index: $hoverZ;
left: 0;
overflow: visible;
background-color: #e5eaf4;
pointer-events: none;
-webkit-font-smoothing: subpixel-antialiased;
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
&:not(._list-result) {
padding-left: 2.75rem;
&:before { content: none; }
}
&:not(.focus):not(.active):after {
content: '';
position: absolute;
top: -1px;
bottom: -1px;
left: $sidebarWidth;
right: -2px;
margin-left: -1px;
border: 1px solid #bbc1cc;
border-left-width: 0;
border-radius: 0 2px 2px 0;
box-shadow: inset -1px 0 rgba(white, .15), // right inner glow
inset 0 1px rgba(white, .15), // top inner glow
inset 0 -1px rgba(white, .15), // bottom inner glow
1px 0 rgba(black, .04), // right shadow
0 1px rgba(black, .04), // bottom shadow
0 -1px rgba(black, .02); // top shadow
@media #{$mediumScreen} { left: $sidebarMediumWidth; }
}
}
// //
// List picker // List picker
// //

@ -11,7 +11,6 @@ body {
height: 100%; height: 100%;
font: normal 1em/1.7 $baseFont; font: normal 1em/1.7 $baseFont;
color: $textColor; color: $textColor;
overflow-wrap: break-word;
word-wrap: break-word; word-wrap: break-word;
-webkit-tap-highlight-color: rgba(black, 0); -webkit-tap-highlight-color: rgba(black, 0);
-webkit-touch-callout: none; -webkit-touch-callout: none;

@ -19,3 +19,4 @@ $headerZ: 1;
$sidebarZ: 2; $sidebarZ: 2;
$contentZ: 3; $contentZ: 3;
$noticeZ: 4; $noticeZ: 4;
$hoverZ: 5;

Loading…
Cancel
Save