diff --git a/package.json b/package.json index 57d15c02..9f4d0007 100644 --- a/package.json +++ b/package.json @@ -52,8 +52,8 @@ "lodash.startcase": "4.4.0", "match-sorter": "2.3.0", "prop-types": "15.6.2", - "react": "16.6.1", - "react-dom": "16.6.1", + "react": "16.7.0-alpha.0", + "react-dom": "16.7.0-alpha.0", "react-emotion": "9.2.12", "react-helmet": "5.2.0", "react-icons": "3.2.2", diff --git a/src/components/header.js b/src/components/header.js index e340bcf7..b4455987 100644 --- a/src/components/header.js +++ b/src/components/header.js @@ -1,4 +1,4 @@ -import React, { Component, createRef } from 'react'; +import React, { useState, useRef } from 'react'; import PropTypes from 'prop-types'; import { Link } from 'gatsby'; import { css } from 'react-emotion'; @@ -6,143 +6,134 @@ import { IconContext } from 'react-icons'; import { MdSearch, MdZoomOut } from 'react-icons/md'; import mq from '../utils/mq'; -class Header extends Component { - state = { - searchTerm: '', - showSearch: false, - }; +function Header({ onSearchTermChange, siteTitle, withSearch }) { + const [searchTerm, setSearchTerm] = useState(''); + const [showSearch, setShowSearch] = useState(false); + const searchInput = useRef(null); - searchInput = createRef(); - - clearSearchTerm = () => { - this.setState({ searchTerm: '' }, () => { - this.props.onSearchTermChange(''); - }); - }; + function clearSearchTerm() { + setSearchTerm(''); + onSearchTermChange(''); + } - toggleSearch = () => { - this.setState(({ showSearch }) => ({ showSearch: !showSearch })); - this.clearSearchTerm(); - }; + function toggleSearch() { + setShowSearch(currentShowSearch => !currentShowSearch); + clearSearchTerm(); + } - handleSearchTermChange = ({ target: { value: searchTerm } }) => { - this.setState(() => ({ searchTerm })); - this.props.onSearchTermChange(searchTerm); - }; + function handleSearchTermChange({ target: { value } }) { + setSearchTerm(value); + onSearchTermChange(value); + } - handleSearchTermKeydown = ({ keyCode }) => { + function handleSearchTermKeydown({ keyCode }) { if (keyCode === 27 /* ESC */) { - this.searchInput.current.blur(); - this.toggleSearch(); + searchInput.current.blur(); + toggleSearch(); } - }; - - render() { - const { siteTitle, withSearch } = this.props; - const { searchTerm, showSearch } = this.state; + } - return ( - +
-
-

- +

+ {withSearch && ( +
+ + -
- )} -
- - ); - } + {showSearch ? : } + + + )} +
+
+ ); } Header.propTypes = { diff --git a/src/components/searchable-drinks-page.js b/src/components/searchable-drinks-page.js index 79174025..8d86a688 100644 --- a/src/components/searchable-drinks-page.js +++ b/src/components/searchable-drinks-page.js @@ -1,4 +1,4 @@ -import React, { Component } from 'react'; +import React, { useState } from 'react'; import PropTypes from 'prop-types'; import { css } from 'react-emotion'; import difference from 'lodash.difference'; @@ -9,58 +9,52 @@ import mq from '../utils/mq'; import Layout from './layout'; import DrinkList from './drink-list'; -class SearchableDrinksPage extends Component { - state = { searchTerm: '' }; +function SearchableDrinksPage({ children, drinks }) { + const [searchTerm, setSearchTerm] = useState(''); - handleSearchTermChange = searchTerm => this.setState({ searchTerm }); + function handleSearchTermChange(value) { + setSearchTerm(value); + } - render() { - const { children, drinks } = this.props; - const { searchTerm } = this.state; - const containsSearchTerm = new RegExp(searchTerm, 'i'); + const containsSearchTerm = new RegExp(searchTerm, 'i'); - const titleMatchedDrinks = matchSorter(drinks, searchTerm, { - keys: ['title'], - }); - const otherMatchedDrinks = orderBy( - difference(drinks, titleMatchedDrinks).filter( - drink => - containsSearchTerm.test( - get(drink, 'notes.childMarkdownRemark.rawMarkdownBody'), - ) || containsSearchTerm.test(drink.ingredients), - ), - ['rank', 'createdAt'], - ['desc', 'desc'], - ); - const filteredDrinks = [...titleMatchedDrinks, ...otherMatchedDrinks]; - const sortedDrinks = orderBy( - drinks, - ['rank', 'createdAt'], - ['desc', 'desc'], - ); + const titleMatchedDrinks = matchSorter(drinks, searchTerm, { + keys: ['title'], + }); + const otherMatchedDrinks = orderBy( + difference(drinks, titleMatchedDrinks).filter( + drink => + containsSearchTerm.test( + get(drink, 'notes.childMarkdownRemark.rawMarkdownBody'), + ) || containsSearchTerm.test(drink.ingredients), + ), + ['rank', 'createdAt'], + ['desc', 'desc'], + ); + const filteredDrinks = [...titleMatchedDrinks, ...otherMatchedDrinks]; + const sortedDrinks = orderBy(drinks, ['rank', 'createdAt'], ['desc', 'desc']); - return ( - - {children} - {filteredDrinks.length ? ( - - ) : ( - - No drinks found. - - )} - - ); - } + return ( + + {children} + {filteredDrinks.length ? ( + + ) : ( + + No drinks found. + + )} + + ); } SearchableDrinksPage.propTypes = { diff --git a/src/pages/tags.js b/src/pages/tags.js index b7bb60b5..dd2ce60d 100644 --- a/src/pages/tags.js +++ b/src/pages/tags.js @@ -1,4 +1,4 @@ -import React, { Component } from 'react'; +import React, { useState } from 'react'; import PropTypes from 'prop-types'; import Helmet from 'react-helmet'; import { Link, graphql } from 'gatsby'; @@ -12,94 +12,86 @@ import NavDivider from '../components/nav-divider'; import Tag from '../components/tag'; import mq from '../utils/mq'; -class TagsPage extends Component { - state = { - searchTerm: '', - }; +function TagsPage({ + data: { + allContentfulDrink: { group }, + }, +}) { + const [searchTerm, setSearchTerm] = useState(''); + const tags = group.map(({ fieldValue }) => fieldValue); + const filteredTags = matchSorter(tags, searchTerm); - handleSearchTermChange = searchTerm => { - this.setState(() => ({ searchTerm })); - }; - - render() { - const { - data: { - allContentfulDrink: { group }, - }, - } = this.props; - const { searchTerm } = this.state; - - const tags = group.map(({ fieldValue }) => fieldValue); - const filteredTags = matchSorter(tags, searchTerm); + function handleSearchTermChange(value) { + setSearchTerm(value); + } - return ( - - - -
- {filteredTags.length ? ( - filteredTags.map(tag => ( - - - {tag} - - - )) - ) : ( - + + +
+ {filteredTags.length ? ( + filteredTags.map(tag => ( + - No matching tags found. - - )} -
- - ); - } + + {tag} + + + )) + ) : ( + + No matching tags found. + + )} +
+
+ ); } export const query = graphql` diff --git a/yarn.lock b/yarn.lock index 6dce2762..074ecb08 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8216,7 +8216,6 @@ listr-silent-renderer@^1.1.1: listr-update-renderer@^0.4.0, "listr-update-renderer@https://github.com/okonet/listr-update-renderer/tarball/upgrade-log-update": version "0.4.0" - uid "06073fa93166277607a7814f4e1f83960081414c" resolved "https://github.com/okonet/listr-update-renderer/tarball/upgrade-log-update#06073fa93166277607a7814f4e1f83960081414c" dependencies: chalk "^1.1.3" @@ -10917,15 +10916,15 @@ react-dev-utils@^4.2.1: strip-ansi "3.0.1" text-table "0.2.0" -react-dom@16.6.1: - version "16.6.1" - resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.6.1.tgz#5476e08694ae504ae385a28b62ecc4fe3a29add9" - integrity sha512-zm+wBuEMGm009Wt1uE4Zw5KcXOW7qC4E/xW/fpJsCsbOco4U/R84u+DzzO/S4SYSdNBcqcaulcp4w3FXl8pImw== +react-dom@16.7.0-alpha.0: + version "16.7.0-alpha.0" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.7.0-alpha.0.tgz#8379158d4c76d63c989f325f45dfa5762582584f" + integrity sha512-/XUn1ldxmoV2B7ov0rWT5LMZaaHMlF9GGLkUsmPRxmWTJwRDOuAPXidSaSlmR/VOhDSI1s+v3+KzFqhhDFJxYA== dependencies: loose-envify "^1.1.0" object-assign "^4.1.1" prop-types "^15.6.2" - scheduler "^0.11.0" + scheduler "^0.11.0-alpha.0" react-emotion@9.2.12: version "9.2.12" @@ -10980,15 +10979,15 @@ react-side-effect@^1.1.0: exenv "^1.2.1" shallowequal "^1.0.1" -react@16.6.1: - version "16.6.1" - resolved "https://registry.yarnpkg.com/react/-/react-16.6.1.tgz#ee2aef4f0a09e494594882029821049772f915fe" - integrity sha512-OtawJThYlvRgm9BXK+xTL7BIlDx8vv21j+fbQDjRRUyok6y7NyjlweGorielTahLZHYIdKUoK2Dp9ByVWuMqxw== +react@16.7.0-alpha.0: + version "16.7.0-alpha.0" + resolved "https://registry.yarnpkg.com/react/-/react-16.7.0-alpha.0.tgz#e2ed4abe6f268c9b092a1d1e572953684d1783a9" + integrity sha512-V0za4H01aoAF0SdzahHepvfvzTQ1xxkgMX4z8uKzn+wzZAlVk0IVpleqyxZWluqmdftNedj6fIIZRO/rVYVFvQ== dependencies: loose-envify "^1.1.0" object-assign "^4.1.1" prop-types "^15.6.2" - scheduler "^0.11.0" + scheduler "^0.11.0-alpha.0" read-all-stream@^3.0.0: version "3.1.0" @@ -11657,10 +11656,10 @@ sax@>=0.6.0, sax@^1.2.4, sax@~1.2.1, sax@~1.2.4: resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== -scheduler@^0.11.0: - version "0.11.0" - resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.11.0.tgz#def1f1bfa6550cc57981a87106e65e8aea41a6b5" - integrity sha512-MAYbBfmiEHxF0W+c4CxMpEqMYK+rYF584VP/qMKSiHM6lTkBKKYOJaDiSILpJHla6hBOsVd6GucPL46o2Uq3sg== +scheduler@^0.11.0-alpha.0: + version "0.11.0-alpha.0" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.11.0-alpha.0.tgz#7b132c726608993471db07866f2d59a52b9e190b" + integrity sha512-0tUDHYSyni/EHkMMBysVXVwfanCWWbLsulnDB1tGrQiWWrVuRVoclWCPHCYC/1iR5Rj34EQhxh3/F36V+F+ZpA== dependencies: loose-envify "^1.1.0" object-assign "^4.1.1"