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')}
+
+
{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(() => {