Quellcode durchsuchen

Expand truncated sidebar items on hover/focus

Thibaut vor 12 Jahren
Ursprung
Commit
7ab4352405

+ 2 - 4
assets/javascripts/templates/sidebar_tmpl.coffee

@@ -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>"""
 
 templates.sidebarEntry = (entry) ->
-  name = $.escape(entry.name)
-  """<a href="#{entry.fullPath()}" class="_list-item" title="#{name}">#{name}</a>"""
+  """<a href="#{entry.fullPath()}" class="_list-item _list-hover">#{$.escape entry.name}</a>"""
 
 templates.sidebarResult = (entry) ->
-  name = $.escape(entry.name)
-  """<a href="#{entry.fullPath()}" class="_list-item _list-result _icon-#{entry.doc.slug}" title="#{entry.doc.name}: #{name}">#{name}</a>"""
+  """<a href="#{entry.fullPath()}" class="_list-item _list-hover _list-result _icon-#{entry.doc.slug}">#{$.escape entry.name}</a>"""
 
 templates.sidebarPageLink = (count) ->
   """<span class="_list-item _list-pagelink">Show more… (#{count})</span>"""

+ 2 - 0
assets/javascripts/views/sidebar/sidebar.coffee

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

+ 100 - 0
assets/javascripts/views/sidebar/sidebar_hover.coffee

@@ -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'

+ 46 - 1
assets/stylesheets/components/_sidebar.scss

@@ -64,7 +64,9 @@
   line-height: 1.75rem;
   font-size: .875rem;
   white-space: nowrap;
+  word-wrap: normal;
   text-overflow: ellipsis;
+  text-shadow: 0 1px rgba(white, .3);
   border: solid transparent;
   border-width: 1px 1px 1px 0;
   cursor: default;
@@ -83,7 +85,7 @@
     background: -webkit-linear-gradient(top,       #bfc6dd, #949eb8);
     background:         linear-gradient(to bottom, #bfc6dd, #949eb8);
     border-color: #96a1c6 #8e99b7 #7f87a4;
-    box-shadow: inset 0 1px rgba(white, .15),      // top inner glow
+    box-shadow: inset 0 1px rgba(white, .15),     // top inner glow
                 inset 0 0 0 1px rgba(white, .08), // inner glow
                 0 1px rgba(black, .05);           // drop shadow
   }
@@ -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
 //

+ 0 - 1
assets/stylesheets/global/_base.scss

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

+ 1 - 0
assets/stylesheets/global/_variables.scss

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