Browse Source

feat(search): add search icon to navbar to open new search dialog

* Search icon added to navbar if search enabled in config
* New search dialog added which overlays current page when searching
* The docs search box now opens the new search dialog instead of
  displaying results within the docs page itself

Close #784

BREAKING CHANGE:

Search widget is deprecated and `content/home/search.md` should be
removed
George Cushen 6 years ago
parent
commit
e95405f79a

+ 4 - 6
assets/js/academic-search.js

@@ -53,9 +53,6 @@ function initSearch(force, fuse) {
   // If query deleted, clear results.
   if ( query.length < 1) {
     $('#search-hits').empty();
-    $('.docs-content .article').show();
-  } else {
-    $('.docs-content .article').hide();
   }
 
   // Check for timer event (enter key not pressed) and query less than minimum length required.
@@ -74,10 +71,8 @@ function searchAcademic(query, fuse) {
   let results = fuse.search(query);
   // console.log({"results": results});
 
-  if ($('.docs-content').length > 0)
-    $('#search-hits').append('<h1>' + i18n.results + '</h1>');
-
   if (results.length > 0) {
+    $('#search-hits').append('<h3 class="mt-0">' + results.length + ' ' + i18n.results + '</h3>');
     parseResults(query, results);
   } else {
     $('#search-hits').append('<div class="search-no-results">' + i18n.no_results + '</div>');
@@ -159,7 +154,10 @@ if (typeof Fuse === 'function') {
 
     // On page load, check for search query in URL.
     if (query = getSearchQuery('q')) {
+      $("body").addClass('searching');
+      $('.search-results').css({opacity: 0, visibility: "visible"}).animate({opacity: 1},200);
       $("#search-query").val(query);
+      $("#search-query").focus();
       initSearch(true, fuse);
     }
 

+ 12 - 0
assets/js/academic.js

@@ -366,6 +366,18 @@
     // Print latest Academic version if necessary.
     if ($('#academic-release').length > 0)
       printLatestRelease('#academic-release', $('#academic-release').data('repo'));
+
+    // On search icon click toggle search dialog.
+    $('.js-search').click(function(e) {
+      e.preventDefault();
+      if ($('body').hasClass('searching')) {
+        $('body').removeClass('searching');
+      } else {
+        $('body').addClass('searching');
+        $('.search-results').css({opacity: 0, visibility: 'visible'}).animate({opacity: 1}, 200);
+        $('#search-query').focus();
+      }
+    });
   });
 
 })(jQuery);

+ 0 - 12
exampleSite/content/home/search.md

@@ -1,12 +0,0 @@
-+++
-# Search widget.
-widget = "search"
-active = true
-date = 2018-07-23T00:00:00
-
-title = "Search"
-subtitle = ""
-
-# Order that this section will appear in.
-weight = 66
-+++

+ 4 - 1
i18n/en.yaml

@@ -164,11 +164,14 @@
 
 # Search
 
+- id: search
+  translation: Search
+
 - id: search_placeholder
   translation: Search...
 
 - id: search_results
-  translation: Search Results
+  translation: results found
 
 - id: search_no_results
   translation: No results found

+ 63 - 2
layouts/partials/css/academic.css

@@ -239,6 +239,66 @@ small,
  *  Search.
  **************************************************/
 
+.search-results {
+  transform: scale(0);
+  background-color: {{ .Get "background" }};
+  bottom: 0;
+  left: 0;
+  right: 0;
+  top: 0;
+  overflow: scroll;
+  position: fixed;
+  visibility: hidden;
+  z-index: -99;
+}
+
+.dark .search-results {
+  background-color: rgb(40, 42, 54);
+}
+
+.searching {
+  overflow: hidden;
+}
+
+.searching .search-results {
+  transform: scale(1);
+  visibility: visible;
+  z-index: 11; /* Second highest index, after navbar. */
+}
+
+.searching #search-box #search-query {
+  width: 100%;
+}
+
+.search-results > .container {
+  padding-top: calc(70px + 2rem); /* Max responsive navbar height plus padding. */
+}
+
+.search-header {
+  background-color: {{ .Get "background" }};
+  position: sticky;
+  top: calc(70px + 2rem); /* Max responsive navbar height plus padding. */
+  padding-bottom: 1rem;
+}
+
+.dark .search-header {
+  background-color: rgb(40, 42, 54);
+}
+
+.search-header h1 {
+  margin: 0;
+  line-height: 1;
+}
+
+.col-search-close {
+  text-align: right;
+}
+
+.search-header i {
+  font-size: 2rem;
+  line-height: 1;
+}
+
 #search-box {
   position: relative; /* Required for search icon positioning. */
   margin-bottom: 0.5rem;
@@ -1788,7 +1848,7 @@ div.alert a {
       position: -webkit-sticky;
       position: sticky;
       top: 51px;
-      z-index: 1000;
+      z-index: 10;
       height: calc(100vh - 51px)
     }
   }
@@ -1803,7 +1863,7 @@ div.alert a {
       position: -webkit-sticky;
       position: sticky;
       top: 71px;
-      z-index: 1000;
+      z-index: 10;
       height: calc(100vh - 71px)
     }
   }
@@ -1989,6 +2049,7 @@ body.dark,
 .dark .form-control,
 .dark .form-control:focus {
   color: rgb(248, 248, 242);
+  background: rgb(40, 42, 54);
 }
 
 .dark .form-control {

+ 1 - 3
layouts/partials/docs_layout.html

@@ -25,9 +25,7 @@
     {{ end }}
 
     <main class="col-12 col-md-9 col-xl-8 py-md-3 pl-md-5 docs-content" role="main">
-      <div id="search-hits">
-        <!-- Search results will appear here -->
-      </div>
+
       <article class="article" itemscope itemtype="http://schema.org/Article">
 
         <div class="docs-article-container">

+ 1 - 0
layouts/partials/header.html

@@ -155,3 +155,4 @@
 
 </head>
 <body id="top" data-spy="scroll" data-target="{{ if or .IsHome .Params.widgets }}#navbar-main{{ else }}#TableOfContents{{ end }}" data-offset="71" {{ if not ($scr.Get "light") }}class="dark"{{ end }}>
+  {{ partial "search" . }}

+ 6 - 0
layouts/partials/navbar.html

@@ -91,6 +91,12 @@
 
         {{ end }}
 
+        {{ if .Site.Params.search.engine }}
+        <li class="nav-item">
+          <a class="nav-link js-search" href="#"><i class="fas fa-search" aria-hidden="true"></i></a>
+        </li>
+        {{ end }}
+
         {{ if .IsTranslated }}
         <li class="nav-item dropdown">
           <a href="#" class="nav-link dropdown-toggle" data-toggle="dropdown" aria-haspopup="true">

+ 32 - 0
layouts/partials/search.html

@@ -0,0 +1,32 @@
+<aside class="search-results" id="search">
+  <div class="container">
+    <section class="search-header fixed-top">
+
+      <div class="row no-gutters justify-content-between mb-3">
+        <div class="col-6">
+          <h1>{{ i18n "search" }}</h1>
+        </div>
+        <div class="col-6 col-search-close">
+          <a class="js-search" href="#"><i class="fas fa-times-circle text-muted" aria-hidden="true"></i></a>
+        </div>
+      </div>
+
+      <div id="search-box">
+        {{ if eq $.Site.Params.search.engine 1 }}
+        <input name="q" id="search-query" placeholder="{{i18n "search_placeholder"}}" autocapitalize="off"
+        autocomplete="off" autocorrect="off" role="textbox" spellcheck="false" type="search">
+        {{ else }}
+        <!-- Search box will appear here -->
+        {{ end }}
+      </div>
+
+    </section>
+    <section class="section-search-results">
+
+      <div id="search-hits">
+        <!-- Search results will appear here -->
+      </div>
+
+    </section>
+  </div>
+</aside>

+ 0 - 25
layouts/partials/widgets/search.html

@@ -1,25 +0,0 @@
-{{ $ := .root }}
-{{ $page := .page }}
-
-<div class="row">
-  <div class="col-xs-12 col-md-4 section-heading">
-    <h1>{{ with $page.Title }}{{ . | markdownify }}{{ end }}</h1>
-    {{ with $page.Params.subtitle }}<p>{{ . | markdownify }}</p>{{ end }}
-  </div>
-  <div class="col-xs-12 col-md-8">
-    {{ with $page.Content }}<p>{{ . | markdownify }}</p>{{ end }}
-
-    <div id="search-box">
-      {{ if eq $.Site.Params.search.engine 1 }}
-      <input name="q" id="search-query" placeholder="{{ i18n "search_placeholder" }}" autocapitalize="off" autocomplete="off" autocorrect="off" role="textbox" spellcheck="false" type="search">
-      {{ else }}
-      <!-- Search box will appear here -->
-      {{ end }}
-    </div>
-
-    <div id="search-hits">
-      <!-- Search results will appear here -->
-    </div>
-
-  </div>
-</div>