feat: rewrite search

This commit is contained in:
Cory Dransfeldt 2024-03-18 14:55:55 -07:00
parent ebcaa0d175
commit 6e81e47122
No known key found for this signature in database
13 changed files with 174 additions and 198 deletions

View file

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

View file

@ -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
View file

@ -0,0 +1,6 @@
---
layout: null
eleventyExcludeFromCollections: true
permalink: /api/search
---
{{ collections.searchIndex | json }}

View 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')
}
}
})();

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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 %}

View file

@ -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" }}

View file

@ -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 %}