diff --git a/app/App.js b/app/App.js index e977202..0521762 100644 --- a/app/App.js +++ b/app/App.js @@ -1,12 +1,17 @@ -import React from 'react'; +import React, {useState} from 'react'; import TermInput from './TermInput.js'; import ResultsGraph from './ResultsGraph.js'; -const App = () => ( -
- - -
-); +const App = () => +{ + const [terms, setTerms] = useState([]); + + return ( +
+ + +
+ ); +}; export default App; diff --git a/app/TermInput.js b/app/TermInput.js index 6af70cd..397667f 100644 --- a/app/TermInput.js +++ b/app/TermInput.js @@ -1,32 +1,53 @@ -import React from 'react'; +import React, {useState} from 'react'; -class TermInput extends React.Component +const enterKey = 13; + +const TermInput = ({terms, setTerms}) => { - constructor(props) - { - super(props); - this.state = { input: '' }; - this.handleInputChange = this.handleInputChange.bind(this); - } + const [value, setValue] = useState(''); - handleInputChange(ev) + const handleKeyDown = ev => { - this.setState({ - input: ev.target.value - }); - } + if (ev.keyCode === enterKey) + { + ev.preventDefault(); - render() + if (!terms.includes(value)) + { + setTerms(terms.concat([value])); + } + + setValue(''); + } + }; + + const handleChange = ev => { - return ( -
- -
- ); - } + setValue(ev.target.value); + }; + + const handleRemove = removedTerm => + { + console.log(removedTerm); + console.log(terms); + setTerms(terms.filter(term => term !== removedTerm)); + }; + + return ( +
+ {terms.map(term => + {term} + )} + +
+ ); } export default TermInput; diff --git a/app/style/style.css b/app/style/style.css index efe5044..d41761b 100644 --- a/app/style/style.css +++ b/app/style/style.css @@ -1,7 +1,18 @@ :root { + --color-accent: #D80C49; + --color-secondary: #AE1246; + --color-light: #EEEEEE; + --color-dark: #1D1D1D; + --font-family: 'Source Sans Pro'; --font-size: 18px; + --font-color: var(--color-dark); + + --base-size: 25px; + + --animation-ease-out: cubic-bezier(0.075, 0.82, 0.165, 1); + --animation-short: .3s; } body, html @@ -11,8 +22,12 @@ body, html outline: 0; height: 100%; + background-color: var(--color-light); + font-family: var(--font-family); font-size: var(--font-size); + line-height: var(--base-size); + color: var(--font-color); } body, html, #root @@ -25,6 +40,9 @@ input { font-family: var(--font-family); font-size: var(--font-size); + + padding: 0 calc(.6 * var(--base-size)); + height: calc(2 * var(--base-size)); } *, *::before, *::after @@ -32,48 +50,89 @@ input box-sizing: border-box; } +/** + * App + */ + .App { width: 100%; height: 100%; } -.TermInput +.App .TermInput { position: absolute; z-index: 2; - top: 32px; + width: 600px; + + top: calc(2 * var(--base-size)); left: 50%; transform: translateX(-50%); +} - border: 2px solid #333333; +/** + * TermInput + */ + +.TermInput +{ display: flex; + align-items: center; + + border: 2px solid var(--color-dark); + border-radius: 2px; + background: white; + + transition: box-shadow var(--animation-short) var(--animation-ease-out); } .TermInput:focus-within { - outline: 2px solid #333333; + box-shadow: + -1px -1px 0px var(--color-dark), + 1px -1px 0px var(--color-dark), + 1px 1px 0px var(--color-dark), + -1px 1px 0px var(--color-dark); +} + +.TermInput_term +{ + display: inline-block; + background: var(--color-secondary); + color: var(--color-light); + + border-radius: 2px; + padding: calc(.2 * var(--base-size)); + margin-left: calc(.3 * var(--base-size)); + cursor: pointer; + + transition: background var(--animation-short) var(--animation-ease-out); +} + +.TermInput_term:hover +{ + background: var(--color-accent); } .TermInput_input { flex: 1; - padding: 6px 12px; border: none; - width: 600px; } -.ResultsGraph, .ResultsGraph div, .ResultsGraph svg -{ - width: 100%; - height: 100%; -} +/** + * Graph + */ .Graph { position: relative; display: block; + width: 100%; + height: 100%; + overflow: hidden; user-select: none; } @@ -91,7 +150,7 @@ input .Graph_edgesContainer line { - stroke: black; + stroke: var(--color-dark); } .Graph_node