Add option to search recipes by tag, tweak UI of search results

This commit is contained in:
Maël Brunet 2021-06-07 00:29:31 +02:00
parent 6b2d108c3d
commit 3c9e10dca1
5 changed files with 57 additions and 33 deletions

View file

@ -4,7 +4,8 @@
"author": "John Doe",
"primaryColor": "#ffdb70",
"secondaryColor": "#32816e",
"searchLabel": "Find recipes by name or ingredients",
"searchLabel": "Find recipes by name, tag or ingredients",
"searchContainsLabel": "Contains",
"servingsLabel": "servings",
"ingredientsLabel": "Ingredients"
}

View file

@ -2,25 +2,15 @@
<label for="{{ 'search-home' if homeSearch else 'search' }}" class="c-search__label {{ 'c-search__label--home' if homeSearch }}">{{ site.searchLabel }}&nbsp;:</label>
<div class="c-search__input-wrapper {{ 'c-search__input-wrapper--home' if homeSearch }}">
<input type="text" id="{{ 'search-home' if homeSearch else 'search' }}" class="c-search__input {{ 'c-search__input--home' if homeSearch }}" x-model="searchInput" @focus="
if (!window.searchResults) {
fetch('/search.json').then(res => res.json()).then(res => {
window.searchResults = res;
searchResults = window.searchResults;
});
} else {
searchResults = window.searchResults;
}
if (sessionStorage.getItem('searchResults')) {
searchResults = JSON.parse(sessionStorage.getItem('searchResults'));
} else {
fetch('/search.json').then(res => res.json()).then(res => {
sessionStorage.setItem('searchResults', JSON.stringify(res));
searchResults = random(res);
searchResults = JSON.stringify(res);
});
}
" @input="
console.log(searchInput);
matches = [];
if (searchInput.length < 3) { return };
@ -28,12 +18,14 @@
searchResults.forEach(recipe => {
const matchTitle = recipe.title.toLowerCase().includes(searchInput);
const matchIngredient = recipe.ingredients.find(ingredient => ingredient.toLowerCase().includes(searchInput));
const matchTag = recipe.tags.find(tag => tag.toLowerCase().includes(searchInput));
if (!matchTitle && !matchIngredient) { return };
if (!matchTitle && !matchIngredient && !matchTag) { return };
const match = {...recipe};
if (matchTitle) { match.matchTitle = matchTitle };
if (matchIngredient) { match.matchIngredient = matchIngredient };
if (matchTag) { match.matchTag = matchTag };
matches.push(match)
});
@ -49,18 +41,25 @@
</div>
<template x-if="matches.length">
<ul class="c-search__search-results">
<div class="c-search__results-wrapper">
<ul class="c-search__results {{ 'c-search__results--home' if homeSearch }}">
<template x-for="(match, index) in matches" :key="index">
<li>
<a x-bind:href="match.url" x-html="highlightText(match.title, searchInput)" class="c-search__search-result-link {{ 'c-search__search-result-link--home' if homeSearch }}"></a>
<div class="c-search__result-link {{ 'c-search__result-link--home' if homeSearch }}">
<a x-bind:href="match.url" x-html="highlightText(match.title, searchInput)"></a>
<template x-if="match.matchTag">
<div class="c-tags__tag c-tag__tag--selected" x-html="highlightText(match.matchTag, searchInput)"></div>
</template>
</div>
<template x-if="match.matchIngredient">
<p class="c-search__search-result-ingredients {{ 'c-search__search-result-ingredients--home' if homeSearch }}" >
Contains: <span x-html="highlightText(match.matchIngredient, searchInput)"></span>
<p class="c-search__result-ingredients {{ 'c-search__result-ingredients--home' if homeSearch }}" >
{{ site.searchContainsLabel }}: <span x-html="highlightText(match.matchIngredient, searchInput)"></span>
</p>
</template>
</li>
</template>
</ul>
</div>
</template>
</div>

View file

@ -42,6 +42,7 @@ collections:
- {label: "Primary color", name: "primaryColor", widget: "color", hint: "make sure to choose a color that is light enough to display as a background behind dark text"}
- {label: "Secondary color", name: "secondaryColor", widget: "color", hint: "used for links and focus styles"}
- {label: "Search (label)", name: "searchLabel", widget: "string"}
- {label: "Search \"contains\" (label)", name: "searchContainsLabel", widget: "string"}
- {label: "Servings (label)", name: "servingsLabel", widget: "string"}
- {label: "Ingredients (label)", name: "ingredientsLabel", widget: "string"}
- name: "nav"

View file

@ -27,7 +27,7 @@
background-color: var(--color-white);
padding: 24px;
border: 1px solid var(--color-grey-300);
border-radius: 6px;
border-radius: 10px;
box-shadow: var(--shadow-xl);
font-size: 1rem;
@ -101,24 +101,46 @@
}
}
.c-search__search-results {
.c-search__results-wrapper {
position: relative;
margin: 0;
}
.c-search__results {
> * + * {
margin-top: 10px;
}
}
.c-search__search-results {
margin-top: 30px;
.c-search__results.c-search__results--home {
position: absolute;
z-index: 10;
top: 10px;
left: 50%;
transform: translateX(-50%);
width: 100%;
max-width: 500px;
padding: 24px;
background-color: var(--color-white);
border: 1px solid var(--color-grey-300);
box-shadow: var(--shadow-xl);
border-radius: 10px;
}
.c-search__search-result-link--home {
.c-search__result-link {
display: flex;
flex-wrap: wrap;
gap: 10px;
}
.c-search__result-link--home {
font-size: 1.2rem;
}
.c-search__search-result-ingredients {
.c-search__result-ingredients {
font-style: italic;
}
.c-search__search-result-ingredients--home {
.c-search__result-ingredients--home {
font-size: 1rem;
}

View file

@ -7,7 +7,8 @@ permalink: search.json
{
"title" : "{{ recipe.data.title }}",
"url" : "{{ recipe.url }}",
"ingredients" : [{% for ingredient in recipe.data.ingredients %}"{{ingredient}}"{% if not loop.last %},{% endif %}{% endfor %}]
"ingredients" : [{% for ingredient in recipe.data.ingredients %}"{{ingredient}}"{% if not loop.last %},{% endif %}{% endfor %}],
"tags" : [{% for tag in recipe.data.tags %}"{{tag}}"{% if not loop.last %},{% endif %}{% endfor %}]
}{% if not loop.last %},{% endif %}
{% endfor %}
]