diff --git a/web/public/locales/en/translation.json b/web/public/locales/en/translation.json index 1db3030..7ed6ad5 100644 --- a/web/public/locales/en/translation.json +++ b/web/public/locales/en/translation.json @@ -14,5 +14,6 @@ "s3": "AWS S3", "twitter": "Twitter", "slack": "Slack" - } + }, + "try": "suggestion" } diff --git a/web/public/locales/ja/translation.json b/web/public/locales/ja/translation.json index 2ad39fd..ff44243 100644 --- a/web/public/locales/ja/translation.json +++ b/web/public/locales/ja/translation.json @@ -14,5 +14,6 @@ "s3": "AWS S3", "twitter": "Twitter", "slack": "Slack" - } + }, + "try": "これはどう?" } diff --git a/web/src/App.js b/web/src/App.js index ece67ff..43d5ad3 100644 --- a/web/src/App.js +++ b/web/src/App.js @@ -3,8 +3,6 @@ import styled, { createGlobalStyle } from 'styled-components' import { Helmet } from 'react-helmet' import { useTranslation } from 'react-i18next' -import Welcome from './components/Welcome' -import Footer from './components/Footer' import { Cards, CardContainer } from './components/Cards' import GithubCard from './components/cards/GithubCard' import DomainCard from './components/cards/DomainCard' @@ -18,15 +16,19 @@ import S3Card from './components/cards/S3Card' import CratesioCard from './components/cards/CratesioCard' import RubyGemsCard from './components/cards/RubyGemsCard' import { EventReporter } from './components/Analytics' +import Welcome from './components/Welcome' +import Footer from './components/Footer' +import Suggestion from './components/Suggestion' import { useDeferredState } from './hooks/state' import { mobile } from './util/css' import { isStandalone } from './util/pwa' export default function App() { - const [query, setQuery] = useDeferredState(1000) + const [query, setQuery] = useDeferredState('', 1000) const [inputValue, setInputValue] = useState('') const inputRef = useRef() + const [suggested, setSuggested] = useState(false) const { t } = useTranslation() const queryGiven = query && query.length > 0 @@ -35,32 +37,53 @@ export default function App() { setQuery(inputValue) }, [inputValue, setQuery]) + useEffect(() => { + if (query.length === 0) { + setSuggested(false) + } + }, [query]) + + // set input value function onInputChange(e) { - setInputValue(e.target.value) + const value = e.target.value + setInputValue(value) } + // clear input form and focus on it function onLogoClick(e) { setInputValue('') inputRef.current.focus() } + // invoke when user clicked one of the suggested items + function onSuggestionCompleted(name) { + setInputValue(name) + setSuggested(true) + } + return ( <> + namaæ — {t('title')} +
namæ - + {queryGiven && !suggested ? ( + + ) : null}
+ {queryGiven ? ( @@ -155,7 +178,7 @@ const Logo = styled.div` } ` -const Input = styled.input.attrs({ +const InputView = styled.input.attrs({ type: 'text', autocomplete: 'off', autocorrect: 'off', diff --git a/web/src/components/Cards.js b/web/src/components/Cards.js index 2569bb8..09a9ee7 100644 --- a/web/src/components/Cards.js +++ b/web/src/components/Cards.js @@ -16,11 +16,15 @@ export function Card({ title, nameList = [], alternativeList = [], children }) { {title} {nameList.map((name) => ( - {children(name)} + + {children(name)} + ))} {revealAlternatives && alternativeList.map((name) => ( - {children(name)} + + {children(name)} + ))} {alternativeList.length > 0 && !revealAlternatives ? ( diff --git a/web/src/components/Suggestion.js b/web/src/components/Suggestion.js new file mode 100644 index 0000000..3e3ce7d --- /dev/null +++ b/web/src/components/Suggestion.js @@ -0,0 +1,69 @@ +import React from 'react' +import styled from 'styled-components' +import { useTranslation } from 'react-i18next' +import { capitalize } from '../util/text' + +export default function Suggestion({ query, onSubmit }) { + const { t } = useTranslation() + const capital = capitalize(query) + const lower = query.toLowerCase() + + const suggestions = [ + `${lower}ify`, + `insta${lower}`, + `lib${lower}`, + `omni${lower}`, + `${capital}Lab`, + `${capital}Kit`, + `Open${capital}`, + ] + .sort(() => Math.random() - 0.5) + .slice(0, 3) + + function applyQuery(name) { + onSubmit(name) + } + + return ( + + {t('try')} + + {suggestions.map((name) => ( + applyQuery(name)}> + {name} + + ))} + + + ) +} + +const Container = styled.div` + margin-bottom: 10px; + display: flex; + flex-direction: row; + flex-wrap: wrap; + justify-content: center; + line-height: 1em; +` + +const Title = styled.div` + margin-top: 15px; + border: 1px solid black; + padding: 1px 6px; + border-radius: 20px; + font-size: 0.6em; +` + +const Items = styled.div` + margin-top: 15px; + margin-left: 8px; + display: flex; + flex-direction: row; +` + +const Item = styled.div` + margin-right: 8px; + cursor: pointer; + font-weight: bold; +` diff --git a/web/src/components/cards/CratesioCard.js b/web/src/components/cards/CratesioCard.js index ae47895..15a0c5b 100644 --- a/web/src/components/cards/CratesioCard.js +++ b/web/src/components/cards/CratesioCard.js @@ -9,7 +9,7 @@ export default function CratesioCard({ name }) { const lowerCase = name.toLowerCase() return ( - + {(name) => ( + {(name) => ( <> + {(name) => ( {(name) => ( diff --git a/web/src/components/cards/PypiCard.js b/web/src/components/cards/PypiCard.js index 9fbb038..4dfc9f5 100644 --- a/web/src/components/cards/PypiCard.js +++ b/web/src/components/cards/PypiCard.js @@ -11,7 +11,6 @@ export default function PypiCard({ name }) { return ( {(name) => ( diff --git a/web/src/components/cards/RubyGemsCard.js b/web/src/components/cards/RubyGemsCard.js index f4799f8..081d7a9 100644 --- a/web/src/components/cards/RubyGemsCard.js +++ b/web/src/components/cards/RubyGemsCard.js @@ -10,7 +10,6 @@ export default function RubyGemsCard({ name }) { return ( {(name) => ( diff --git a/web/src/components/cards/S3Card.js b/web/src/components/cards/S3Card.js index 531e1b8..927cc86 100644 --- a/web/src/components/cards/S3Card.js +++ b/web/src/components/cards/S3Card.js @@ -9,7 +9,7 @@ export default function S3Card({ name }) { const lowerCase = name.toLowerCase() return ( - + {(name) => ( + {(name) => ( { const fn = setTimeout(() => {