Przeglądaj źródła

Add link to reveal the selected search result in the sidebar list

Thibaut 12 lat temu
rodzic
commit
2b20c09f17

+ 1 - 1
assets/javascripts/templates/sidebar_tmpl.coffee

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

+ 27 - 17
assets/javascripts/views/sidebar/doc_list.coffee

@@ -35,6 +35,16 @@ class app.views.DocList extends app.View
       @append @tmpl('sidebarDoc', app.disabledDocs.all(), disabled: true)
     return
 
+  reset: ->
+    @listSelect.deselect()
+    @listFocus?.blur()
+    @listFold.reset()
+
+    if model = app.router.context.type or app.router.context.entry
+      @reveal model
+      @select model
+    return
+
   onOpen: (event) =>
     $.stopEvent(event)
     doc = app.docs.findBy 'slug', event.target.getAttribute('data-slug')
@@ -56,14 +66,15 @@ class app.views.DocList extends app.View
       delete @lists[doc.slug]
     return
 
-  revealType: (type) ->
-    @openDoc type.doc
+  select: (model) ->
+    @listSelect.selectByHref model?.fullPath()
     return
 
-  revealEntry: (entry) ->
-    @openDoc entry.doc
-    @openType entry.getType() if entry.type
-    @lists[entry.doc.slug]?.revealEntry(entry)
+  reveal: (model) ->
+    @openDoc model.doc
+    @openType model.getType() if model.type
+    @paginateTo model
+    @scrollTo model
     return
 
   openDoc: (doc) ->
@@ -74,18 +85,17 @@ class app.views.DocList extends app.View
     @listFold.open @lists[type.doc.slug].find("[data-slug='#{type.slug}']")
     return
 
-  afterRoute: (route, context) =>
-    if context.init
-      switch route
-        when 'type'  then @revealType context.type
-        when 'entry' then @revealEntry context.entry
+  paginateTo: (model) ->
+    @lists[model.doc.slug]?.paginateTo(model)
+    return
 
-    if route in ['type', 'entry']
-      @listSelect.selectByHref (context.type or context.entry).fullPath()
-    else
-      @listSelect.deselect()
+  scrollTo: (model) ->
+    $.scrollTo @find("a[href='#{model.fullPath()}']")
+    return
 
+  afterRoute: (route, context) =>
     if context.init
-      $.scrollTo @listSelect.getSelection()
-
+      @reset()
+    else
+      @select context.type or context.entry
     return

+ 0 - 4
assets/javascripts/views/sidebar/entry_list.coffee

@@ -13,7 +13,3 @@ class app.views.EntryList extends app.views.PaginatedList
 
   render: (entries) ->
     @tmpl 'sidebarEntry', entries
-
-  revealEntry: (entry) ->
-    @paginateTo entry
-    return

+ 11 - 3
assets/javascripts/views/sidebar/sidebar.coffee

@@ -3,6 +3,7 @@ class app.views.Sidebar extends app.View
 
   @events:
     focus: 'onFocus'
+    click: 'onClick'
 
   @shortcuts:
     escape: 'onEscape'
@@ -67,9 +68,11 @@ class app.views.Sidebar extends app.View
     $.scrollTo event.target, @el, 'continuous', bottomGap: 2
     return
 
-  onEscape: =>
-    @showDocList()
-    @scrollToTop()
+  onClick: (event) =>
+    if event.target.hasAttribute? 'data-reset-list'
+      $.stopEvent(event)
+      @showDocList()
+      @docList.reset()
     return
 
   onGlobalClick: (event) =>
@@ -79,3 +82,8 @@ class app.views.Sidebar extends app.View
     else if @view is @docPicker
       @showDocList() unless $.hasChild @el, event.target
     return
+
+  onEscape: =>
+    @showDocList()
+    @scrollToTop()
+    return

+ 4 - 1
assets/javascripts/views/sidebar/sidebar_hover.coffee

@@ -55,6 +55,9 @@ class app.views.SidebarHover extends app.View
   isTarget: (el) ->
     el.classList.contains @constructor.itemClass
 
+  isSelected: (el) ->
+    el.classList.contains 'active'
+
   isTruncated: (el) ->
     el.scrollWidth >= el.offsetWidth
 
@@ -68,7 +71,7 @@ class app.views.SidebarHover extends app.View
     return
 
   onMouseover: (event) =>
-    if @isTarget(event.target) and @mouseActivated()
+    if @isTarget(event.target) and not @isSelected(event.target) and @mouseActivated()
       @show event.target
     return
 

+ 3 - 3
assets/javascripts/views/sidebar/type_list.coffee

@@ -45,7 +45,7 @@ class app.views.TypeList extends app.View
       delete @lists[type.slug]
     return
 
-  revealEntry: (entry) ->
-    if entry.type
-      @lists[entry.getType().slug]?.revealEntry(entry)
+  paginateTo: (model) ->
+    if model.type
+      @lists[model.getType().slug]?.paginateTo(model)
     return

+ 36 - 0
assets/stylesheets/components/_sidebar.scss

@@ -180,6 +180,41 @@
   }
 }
 
+//
+// Search results
+//
+
+._list-result.active {
+  padding-right: 1.75rem;
+
+  > ._list-reveal { display: block; }
+}
+
+._list-reveal {
+  display: none;
+  position: absolute;
+  top: 0;
+  bottom: 0;
+  right: 0;
+  width: 1.75rem;
+  cursor: pointer;
+
+  &:before {
+    content: '';
+    position: absolute;
+    bottom: 50%;
+    left: .5rem;
+    width: .75rem;
+    height: 1px;
+    background: rgba(white, .9);
+    box-shadow: 0 -3px rgba(white, .9),  // top line
+                0 3px rgba(white, .9),   // bottom line
+                0 -2px rgba(black, .15), // top shadow
+                0 1px rgba(black, .15),  // middle shadow
+                0 4px rgba(black, .15);  // bottom shadow
+  }
+}
+
 //
 // List hover clone
 //
@@ -189,6 +224,7 @@
   z-index: $hoverZ;
   left: 0;
   overflow: visible;
+  padding: 0 .75rem;
   background-color: #e5eaf4;
   pointer-events: none;
   -webkit-font-smoothing: subpixel-antialiased;