feat: rewrite search
This commit is contained in:
parent
ebcaa0d175
commit
6e81e47122
13 changed files with 174 additions and 198 deletions
|
@ -1,6 +1,6 @@
|
|||
{% assign filteredTags = tags | filterTags %}
|
||||
<div{% if hasSpace %} style="margin-bottom:var(--sizing-md)"{% endif %}>
|
||||
{% for tag in filteredTags limit: 10 %}
|
||||
<a class="tag" href="/tags/{{ tag | downcase }}" data-pagefind-filter="tags">{{ tag | formatTag }}</a>
|
||||
<a class="tag" href="/tags/{{ tag | downcase }}">{{ tag | formatTag }}</a>
|
||||
{% endfor %}
|
||||
</div>
|
|
@ -10,7 +10,7 @@ schema: blog
|
|||
{% endcapture %}
|
||||
<style>{{ css }}</style>
|
||||
<div class="default__wrapper">
|
||||
<article class="h-entry" data-pagefind-body>
|
||||
<article class="h-entry">
|
||||
<div class="flex--centered">
|
||||
<time class="dt-published" datetime="{{ date }}">
|
||||
{{ date | date: "%B %e, %Y" }}
|
||||
|
@ -18,7 +18,7 @@ schema: blog
|
|||
</time>
|
||||
{% render "partials/share-button.liquid", url:postUrl, title:title, tagMap:collections.tagMap %}
|
||||
</div>
|
||||
<h2 class="p-name" data-pagefind-meta="title">{{ title }}</h2>
|
||||
<h2 class="p-name">{{ title }}</h2>
|
||||
<div class="text--small">{% render "partials/tags.liquid", tags:tags %}</div>
|
||||
<span class="p-author h-card hidden">{{ meta.author }}</span>
|
||||
<div class="p-summary hidden">{{ post_excerpt }}</div>
|
||||
|
|
6
src/api/search.liquid
Normal file
6
src/api/search.liquid
Normal file
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
layout: null
|
||||
eleventyExcludeFromCollections: true
|
||||
permalink: /api/search
|
||||
---
|
||||
{{ collections.searchIndex | json }}
|
47
src/assets/scripts/search.js
Normal file
47
src/assets/scripts/search.js
Normal file
|
@ -0,0 +1,47 @@
|
|||
(() => {
|
||||
const miniSearch = new MiniSearch({
|
||||
fields: ['title', 'text', 'tags']
|
||||
})
|
||||
|
||||
const $form = document.querySelector('.search__form')
|
||||
const $input = document.querySelector('.search__form--input')
|
||||
const $fallback = document.querySelector('.search__form--fallback')
|
||||
const $results = document.querySelector('.search__results')
|
||||
|
||||
// remove no-js fallbacks
|
||||
$form.removeAttribute('action')
|
||||
$form.removeAttribute('method')
|
||||
$fallback.remove()
|
||||
|
||||
let resultsById = {}
|
||||
|
||||
// fetch index
|
||||
const results = fetch('/api/search').then(response => response.json())
|
||||
.then((results) => {
|
||||
resultsById = results.reduce((byId, result) => {
|
||||
byId[result.id] = result
|
||||
return byId
|
||||
}, {})
|
||||
return miniSearch.addAll(results)
|
||||
})
|
||||
|
||||
$input.addEventListener('input', (event) => {
|
||||
const query = $input.value
|
||||
const results = (query.length > 1) ? getSearchResults(query) : []
|
||||
if (query === '') renderSearchResults([])
|
||||
renderSearchResults(results)
|
||||
})
|
||||
|
||||
const getSearchResults = (query) => miniSearch.search(query, {}).map(({ id }) => resultsById[id])
|
||||
const renderSearchResults = (results) => {
|
||||
$results.innerHTML = results.map(({ title, url }) => {
|
||||
return `<li class="search__results--result"><a href="${url}">${title}</a></li>`
|
||||
}).join('\n')
|
||||
|
||||
if (results.length > 0) {
|
||||
$results.classList.remove('hidden')
|
||||
} else {
|
||||
$results.classList.add('hidden')
|
||||
}
|
||||
}
|
||||
})();
|
|
@ -1,26 +1,23 @@
|
|||
::placeholder {
|
||||
color: var(--text-color) !important;
|
||||
opacity: .5 !important;
|
||||
color: var(--text-color);
|
||||
opacity: .5;
|
||||
}
|
||||
|
||||
input[type="text"],
|
||||
input[type="email"],
|
||||
input[type="search"],
|
||||
textarea {
|
||||
/* necessary for pagefind overrides */
|
||||
font-family: var(--font-sans) !important;
|
||||
color: var(--text-color) !important;
|
||||
background-color: var(--background-color) !important;
|
||||
border: 1px solid var(--accent-color) !important;
|
||||
font-family: var(--font-sans);
|
||||
color: var(--text-color);
|
||||
background-color: var(--background-color);
|
||||
border: 1px solid var(--accent-color);
|
||||
padding: var(--sizing-sm);
|
||||
font-size: var(--font-size-base) !important;
|
||||
width: 100% !important;
|
||||
border-radius: var(--rounded-md) !important;
|
||||
/* necessary for pagefind overrides */
|
||||
|
||||
font-size: var(--font-size-base);
|
||||
width: 100%;
|
||||
border-radius: var(--rounded-md);
|
||||
outline: none;
|
||||
margin-bottom: var(--sizing-base);
|
||||
font-weight: var(--font-weight-base) !important;
|
||||
font-weight: var(--font-weight-base);
|
||||
line-height: var(--line-height-base);
|
||||
transition-property: border-color;
|
||||
transition-timing-function: var(--transition-ease-in-out);
|
||||
|
@ -31,10 +28,10 @@ input[type="text"]:focus,
|
|||
input[type="email"]:focus,
|
||||
input[type="search"]:focus,
|
||||
textarea:focus {
|
||||
border: 1px solid var(--accent-color-hover) !important;
|
||||
border: 1px solid var(--accent-color-hover);
|
||||
}
|
||||
|
||||
button:not(.theme__toggle, .share, .pagefind-ui__search-clear) {
|
||||
button:not(.theme__toggle, .share) {
|
||||
border-radius: var(--rounded-full);
|
||||
padding: var(--sizing-sm) var(--sizing-lg);
|
||||
margin: 0 var(--sizing-xs) var(--sizing-md) 0;
|
||||
|
@ -52,11 +49,22 @@ button:not(.theme__toggle, .share, .pagefind-ui__search-clear) {
|
|||
transition-property: background-color;
|
||||
}
|
||||
|
||||
button:not(.theme__toggle, .share, .pagefind-ui__search-clear):hover,
|
||||
button:not(.theme__toggle, .share, .pagefind-ui__search-clear):active,
|
||||
button:not(.theme__toggle, .share, .pagefind-ui__search-clear):focus {
|
||||
button:not(.theme__toggle, .share):hover,
|
||||
button:not(.theme__toggle, .share):active,
|
||||
button:not(.theme__toggle, .share):focus {
|
||||
color: var(--color-lightest);
|
||||
background-color: var(--accent-color-hover) !important;
|
||||
background-color: var(--accent-color-hover);
|
||||
transition-timing-function: var(--transition-ease-in-out);
|
||||
transition-duration: var(--transition-duration-default);
|
||||
}
|
||||
|
||||
.search__results {
|
||||
margin-top: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.search__results li {
|
||||
margin-top: var(--sizing-sm);
|
||||
margin-bottom: var(--sizing-sm);
|
||||
}
|
|
@ -1,115 +0,0 @@
|
|||
.pagefind-ui {
|
||||
margin-bottom: var(--sizing-base);
|
||||
--pagefind-ui-primary: var(--accent-color);
|
||||
--pagefind-ui-text: var(--text-color);
|
||||
--pagefind-ui-background: var(--color-lightest);
|
||||
--pagefind-ui-border: var(--gray-light);
|
||||
--pagefind-ui-tag: var(--gray-light);
|
||||
--pagefind-ui-border-width: 1px;
|
||||
--pagefind-ui-border-radius: 0;
|
||||
--pagefind-ui-image-border-radius: 0;
|
||||
--pagefind-ui-image-box-ratio: 3 / 2;
|
||||
--pagefind-ui-font: var(--font-sans);
|
||||
}
|
||||
|
||||
.pagefind-ui,
|
||||
.pagefind-ui__filter-name,
|
||||
.pagefind-ui__filter-label,
|
||||
.pagefind-ui__result-excerpt,
|
||||
.pagefind-ui__message,
|
||||
.pagefind-ui__button {
|
||||
font-size: var(--font-size-base) !important;
|
||||
}
|
||||
|
||||
.pagefind-ui__result-excerpt {
|
||||
word-break: break-word !important;
|
||||
}
|
||||
|
||||
.pagefind-ui__form:before {
|
||||
opacity: 1 !important;
|
||||
top: calc(19px * var(--pagefind-ui-scale)) !important;
|
||||
}
|
||||
|
||||
.pagefind-ui__result-title {
|
||||
color: var(--accent-color);
|
||||
font-size: var(--font-size-2xl);
|
||||
line-height: var(--line-height-2xl);
|
||||
font-weight: var(--font-weight-heavy);
|
||||
margin: 0;
|
||||
transition-property: color;
|
||||
transition-timing-function: var(--transition-ease-in-out);
|
||||
transition-duration: var(--transition-duration-default);
|
||||
}
|
||||
|
||||
.pagefind-ui__result-title:hover,
|
||||
.pagefind-ui__result-title:focus,
|
||||
.pagefind-ui__result-title:active {
|
||||
color: var(--accent-color-hover);
|
||||
}
|
||||
|
||||
.pagefind-ui__results-area {
|
||||
margin-bottom: var(--sizing-base);
|
||||
}
|
||||
|
||||
:is(input[type="text"], input[type="search"]).pagefind-ui__search-input {
|
||||
padding-left: 2.375rem !important;
|
||||
padding-top: 0 !important;
|
||||
padding-bottom: 0 !important;
|
||||
height: 42px !important;
|
||||
}
|
||||
|
||||
.pagefind-ui__search-clear {
|
||||
color: var(--text-color);
|
||||
background-color: transparent !important;
|
||||
}
|
||||
|
||||
.pagefind-ui__search-clear:hover,
|
||||
.pagefind-ui__search-clear:focus,
|
||||
.pagefind-ui__search-clear:active {
|
||||
color: var(--accent-color-hover) !important;
|
||||
}
|
||||
|
||||
.pagefind-ui__result-title {
|
||||
margin-bottom: var(--sizing-xs) !important;
|
||||
}
|
||||
|
||||
.pagefind-ui__result-link {
|
||||
font-size: var(--font-size-2xl) !important;
|
||||
color: var(--accent-color) !important;
|
||||
}
|
||||
|
||||
.pagefind-ui__result-link:hover,
|
||||
.pagefind-ui__result-link:focus,
|
||||
.pagefind-ui__result-link:active {
|
||||
color: var(--accent-color-hover) !important;
|
||||
}
|
||||
|
||||
.pagefind-ui__button {
|
||||
color: var(--color-lightest) !important;
|
||||
line-height: var(--line-height-base);
|
||||
border-radius: var(--rounded-full) !important;
|
||||
padding: var(--sizing-sm) var(--sizing-lg) !important;
|
||||
margin: 0 var(--sizing-xs) var(--sizing-md) 0;
|
||||
cursor: pointer !important;
|
||||
height: unset !important;
|
||||
background-color: var(--accent-color) !important;
|
||||
transition-property: background-color;
|
||||
transition-timing-function: var(--transition-ease-in-out);
|
||||
transition-duration: var(--transition-duration-default);
|
||||
}
|
||||
|
||||
.pagefind-ui__search-clear {
|
||||
height: calc(48px * var(--pagefind-ui-scale)) !important;
|
||||
}
|
||||
|
||||
.pagefind-ui__button:hover,
|
||||
.pagefind-ui__button:active,
|
||||
.pagefind-ui__button:focus {
|
||||
color: var(--color-lightest) !important;
|
||||
background-color: var(--accent-color-hover) !important;
|
||||
}
|
||||
|
||||
.pagefind__placeholder {
|
||||
height: 42px !important;
|
||||
font-weight: var(--font-weight-heavy);
|
||||
}
|
|
@ -4,19 +4,19 @@ description: "Search through and find the posts on my site."
|
|||
layout: default
|
||||
permalink: /search.html
|
||||
---
|
||||
<script type="module" src="/assets/scripts/components/pagefind-search.js"></script>
|
||||
{% capture css %}
|
||||
{% render "../assets/styles/components/forms.css" %}
|
||||
{% render "../assets/styles/components/pagefind.css" %}
|
||||
{% endcapture %}
|
||||
<style>{{ css }}</style>
|
||||
<pagefind-search _show_images="false" _show_empty_filters="false">
|
||||
<form action="https://duckduckgo.com/" method="get" style="min-height: 3.2em;">
|
||||
<label>
|
||||
<input class="pagefind__placeholder" placeholder="Search" type="search" name="q" autocomplete="off" autofocus>
|
||||
</label>
|
||||
<input type="hidden" placeholder="Search" name="sites" value="coryd.dev">
|
||||
</form>
|
||||
</pagefind-search>
|
||||
<script src="/assets/scripts/components/minisearch.js"></script>
|
||||
{% capture js %}
|
||||
{% render "../assets/scripts/search.js" %}
|
||||
{% endcapture %}
|
||||
<script type="module">{{ js }}</script>
|
||||
<form class="search__form" action="https://duckduckgo.com" method="get">
|
||||
<input class="search__form--input" placeholder="Search" type="search" name="q" autocomplete="off" autofocus>
|
||||
<input class="search__form--fallback" type="hidden" placeholder="Search" name="sites" value="coryd.dev">
|
||||
</form>
|
||||
<ul class="search__results hidden"></ul>
|
||||
{% render "partials/tags.liquid", tags:collections.tagsSortedByCount, hasSpace:true %}
|
||||
{% render "partials/addon-links.liquid", posts:collections.posts, analytics:analytics, links:links %}
|
|
@ -76,9 +76,9 @@ pagination:
|
|||
size: 8
|
||||
---
|
||||
{% for link in pagination.items %}
|
||||
<article class="h-entry" data-pagefind-body>
|
||||
<article class="h-entry">
|
||||
<a class="no-underline" href="{{ link.url }}">
|
||||
<h2 class="flex--centered" data-pagefind-meta="title">{{ link.title }}</h2>
|
||||
<h2 class="flex--centered">{{ link.title }}</h2>
|
||||
</a>
|
||||
<time class="dt-published" datetime="{{ link.date }}">
|
||||
{{ link.date | date: "%m.%Y" }}
|
||||
|
|
|
@ -51,7 +51,7 @@ The partial displays up to `10` tags:
|
|||
```liquid
|
||||
{% assign filteredTags = tags | filterTags %}
|
||||
{% for tag in filteredTags limit: 10 %}
|
||||
<a class="tag" href="/tags/{{ tag | downcase }}" data-pagefind-filter="tags">{{ tag | formatTag }}</a>
|
||||
<a class="tag" href="/tags/{{ tag | downcase }}">{{ tag | formatTag }}</a>
|
||||
{% endfor %}
|
||||
```
|
||||
{% endraw %}
|
||||
|
|
Reference in a new issue