1
0
mirror of https://github.com/kremalicious/blog.git synced 2025-01-03 10:25:07 +01:00

tweaks to search usability

This commit is contained in:
Matthias Kretschmann 2018-11-18 16:41:37 +01:00
parent b149811eaa
commit 2a95ffebb9
Signed by: m
GPG Key ID: 606EEEF3C479A91F
11 changed files with 113 additions and 71 deletions

View File

@ -1,3 +0,0 @@
All post content under `./content/posts` is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
http://creativecommons.org/licenses/by-nc-sa/4.0/.

View File

@ -1,6 +0,0 @@
All photos & image assets under `./content/media`, `./src/images`, and `assets sheet.psd` are plain ol' copyright.
Copyright (c) 20082018 Matthias Kretschmann
Don't care if you fork & play with it, but you're not allowed to publish
anything from it as a whole without my written permission.

View File

@ -20,6 +20,7 @@
- [🎆 EXIF extraction](#-exif-extraction) - [🎆 EXIF extraction](#-exif-extraction)
- [💰 Cryptocurrency donation via Web3/MetaMask](#-cryptocurrency-donation-via-web3metamask) - [💰 Cryptocurrency donation via Web3/MetaMask](#-cryptocurrency-donation-via-web3metamask)
- [🕸 Related Posts](#-related-posts) - [🕸 Related Posts](#-related-posts)
- [🔍 Search](#-search)
- [🐝 Coinhive](#-coinhive) - [🐝 Coinhive](#-coinhive)
- [🏆 SEO component](#-seo-component) - [🏆 SEO component](#-seo-component)
- [📈 Matomo (formerly Piwik) analytics tracking](#-matomo-formerly-piwik-analytics-tracking) - [📈 Matomo (formerly Piwik) analytics tracking](#-matomo-formerly-piwik-analytics-tracking)
@ -83,6 +84,10 @@ If you want to know how this works, have a look at the respective component unde
- [`src/components/molecules/RelatedPosts.jsx`](src/components/molecules/RelatedPosts.jsx) - [`src/components/molecules/RelatedPosts.jsx`](src/components/molecules/RelatedPosts.jsx)
### 🔍 Search
[gatsby-plugin-lunr](https://github.com/humanseelabs/gatsby-plugin-lunr)
### 🐝 Coinhive ### 🐝 Coinhive
Includes a component for mining Monero with JavaScript via [Coinhive](https://coinhive.com). Includes a component for mining Monero with JavaScript via [Coinhive](https://coinhive.com).
@ -198,20 +203,18 @@ The deploymeng script can be used locally too, the branch checks are only happen
The MIT License (MIT) The MIT License (MIT)
except for: EXCEPT FOR:
### Posts ### Posts
<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/"> [![Creative Commons License](https://i.creativecommons.org/l/by-nc-sa/4.0/80x15.png)](http://creativecommons.org/licenses/by-nc-sa/4.0/)
<img alt="Creative Commons License" style="border-width:0;" src="https://i.creativecommons.org/l/by-nc-sa/4.0/80x15.png" />
</a>
All post content under `./content/posts` is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>. All post content under `./content/posts` is licensed under a [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License](http://creativecommons.org/licenses/by-nc-sa/4.0/).
### Photos & images ### Photos & images
All photos & image assets under `./content/media`, `./src/images`, and `assets sheet.psd` are plain ol' copyright. All photos & image assets are plain ol' copyright.
Copyright (c) 20082018 Matthias Kretschmann Copyright (c) 20082018 Matthias Kretschmann
Don't care if you fork & play with it, but you're not allowed to publish anything from it as a whole without my written permission. Don't care if you fork & play with it, but you're not allowed to publish anything from it as a whole without my written permission. Also please be aware, the combination of typography, colors & layout makes up my brand identity. So please don't just clone everything, but rather do a remix!

View File

@ -100,8 +100,9 @@ module.exports = {
// Attributes for custom indexing logic. See https://lunrjs.com/docs/lunr.Builder.html for details // Attributes for custom indexing logic. See https://lunrjs.com/docs/lunr.Builder.html for details
fields: [ fields: [
{ name: 'title', store: true, attributes: { boost: 20 } }, { name: 'title', store: true, attributes: { boost: 20 } },
{ name: 'tags', attributes: { boost: 15 } },
{ name: 'slug', store: true },
{ name: 'excerpt', attributes: { boost: 10 } }, { name: 'excerpt', attributes: { boost: 10 } },
{ name: 'tags', store: true, attributes: { boost: 5 } },
{ name: 'content' } { name: 'content' }
], ],
// How to resolve each field's value for a supported node type // How to resolve each field's value for a supported node type
@ -111,7 +112,8 @@ module.exports = {
title: node => node.frontmatter.title, title: node => node.frontmatter.title,
excerpt: node => node.excerpt, excerpt: node => node.excerpt,
tags: node => node.frontmatter.tags, tags: node => node.frontmatter.tags,
content: node => node.rawMarkdownBody content: node => node.rawMarkdownBody,
slug: node => node.fields.slug
} }
} }
} }

View File

@ -1,4 +1,4 @@
import React, { PureComponent, Fragment } from 'react' import React, { PureComponent } from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import Helmet from 'react-helmet' import Helmet from 'react-helmet'
import { CSSTransition } from 'react-transition-group' import { CSSTransition } from 'react-transition-group'
@ -25,16 +25,6 @@ export default class Search extends PureComponent {
})) }))
} }
closeSearch = () => {
this.setState({
searchOpen: false,
query: '',
results: []
})
}
isSearchOpen = () => this.state.searchOpen === true
getSearchResults(query) { getSearchResults(query) {
if (!query || !window.__LUNR__) return [] if (!query || !window.__LUNR__) return []
const lunrIndex = window.__LUNR__[this.props.lng] const lunrIndex = window.__LUNR__[this.props.lng]
@ -55,34 +45,32 @@ export default class Search extends PureComponent {
const { searchOpen, query, results } = this.state const { searchOpen, query, results } = this.state
return ( return (
<Fragment> <>
<Helmet>
<body className={this.isSearchOpen() ? 'has-search-open' : null} />
</Helmet>
<SearchButton onClick={this.toggleSearch} /> <SearchButton onClick={this.toggleSearch} />
{searchOpen && ( {searchOpen && (
<CSSTransition <>
appear={searchOpen} <Helmet>
in={searchOpen} <body className="hasSearchOpen" />
timeout={200} </Helmet>
classNames={styles} <CSSTransition
> appear={searchOpen}
<section className={styles.search}> in={searchOpen}
<SearchInput timeout={200}
value={query} classNames={styles}
onChange={this.search} >
onToggle={this.closeSearch} <section className={styles.search}>
/> <SearchInput
</section> value={query}
</CSSTransition> onChange={this.search}
onToggle={this.toggleSearch}
/>
</section>
</CSSTransition>
<SearchResults results={results} onClose={this.toggleSearch} />
</>
)} )}
</>
{query && (
<SearchResults results={results} onClose={this.closeSearch} />
)}
</Fragment>
) )
} }
} }

View File

@ -4,7 +4,7 @@
position: absolute; position: absolute;
left: $spacer / 2; left: $spacer / 2;
right: $spacer / 2; right: $spacer / 2;
top: 0; top: -($spacer / 4);
z-index: 10; z-index: 10;
input { input {
@ -40,3 +40,13 @@
transform: translate3d(0, -100px, 0); transform: translate3d(0, -100px, 0);
} }
} }
:global(.hasSearchOpen) {
overflow: hidden;
// more cross-browser backdrop-filter
main > div:first-child {
transition: filter .85s ease-out;
filter: blur(5px);
}
}

View File

@ -1,14 +1,24 @@
import React, { Fragment } from 'react' import React from 'react'
import Input from '../atoms/Input' import Input from '../atoms/Input'
import styles from './SearchInput.module.scss' import styles from './SearchInput.module.scss'
const SearchInput = props => ( const SearchInput = ({ onToggle, ...props }) => (
<Fragment> <>
<Input type="search" placeholder="Search everything" {...props} /> <Input
<button className={styles.searchInputClose} onClick={props.onToggle}> className={styles.searchInput}
type="search"
placeholder="Search everything"
autoFocus // eslint-disable-line
{...props}
/>
<button
className={styles.searchInputClose}
onClick={onToggle}
title="Close search"
>
&times; &times;
</button> </button>
</Fragment> </>
) )
export default SearchInput export default SearchInput

View File

@ -1,7 +1,27 @@
@import 'variables'; @import 'variables';
.searchInput {
composes: input from '../atoms/Input.module.scss';
background: $input-bg-focus;
&::-webkit-search-cancel-button {
display: none;
}
&:hover {
background: $input-bg-focus;
}
}
.searchInputClose { .searchInputClose {
position: absolute; position: absolute;
right: $spacer / 4; right: $spacer / 2;
top: $spacer / 4; top: $spacer / 4;
font-size: $font-size-h3;
color: $brand-grey-light;
&:hover,
&:focus {
color: $link-color;
}
} }

View File

@ -10,13 +10,14 @@ const SearchResults = ({ results, onClose }) =>
<div className={styles.searchResults}> <div className={styles.searchResults}>
<Container> <Container>
<ul> <ul>
{results.map(page => ( {results.length > 0 &&
<li key={page.url}> results.map(page => (
<Link to={page.url} onClick={onClose}> <li key={page.slug}>
{page.title} <Link to={page.slug} onClick={onClose}>
</Link> {page.title}
</li> </Link>
))} </li>
))}
</ul> </ul>
</Container> </Container>
</div>, </div>,

View File

@ -8,12 +8,19 @@
z-index: 10; z-index: 10;
top: 0; top: 0;
bottom: 0; bottom: 0;
background: $body-background-color; background: rgba($body-background-color, .95);
// backdrop-filter: blur(5px);
animation: fadein .3s;
ul { ul {
@include breakoutviewport; @include breakoutviewport;
margin-top: $spacer; padding-top: $spacer;
padding-bottom: $spacer;
margin-bottom: 0;
overflow: scroll;
-webkit-overflow-scrolling: touch;
max-height: 81vh;
li { li {
margin-left: $spacer; margin-left: $spacer;
@ -31,3 +38,13 @@
display: inline-block; display: inline-block;
} }
} }
@keyframes fadein {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}

View File

@ -14,7 +14,7 @@
border-radius: $input-border-radius; border-radius: $input-border-radius;
box-shadow: none; box-shadow: none;
transition: all ease-in-out .15s; transition: all ease-in-out .15s;
-webkit-appearance: none; // screw you, iOS default inset box-shadow appearance: none;
&:hover { &:hover {
background: lighten($input-bg, 30%); background: lighten($input-bg, 30%);