diff options
author | sanine-a <sanine.not@pm.me> | 2021-04-13 11:37:51 -0500 |
---|---|---|
committer | sanine-a <sanine.not@pm.me> | 2021-04-13 11:37:51 -0500 |
commit | c9c1b78ed805371615d3ca8b54c86da9a35db8ce (patch) | |
tree | 1af9063f2e30392fc039738105f86461dddec576 | |
parent | bc594a2d3839d1d0a3cc76eed23ec8535c72f6bf (diff) |
implement basic user input and button styling
-rw-r--r-- | App.js | 49 | ||||
-rw-r--r-- | InputBox.js | 18 | ||||
-rw-r--r-- | StyleButton.js | 15 | ||||
-rw-r--r-- | characters.js | 2 | ||||
-rw-r--r-- | index.html | 9 | ||||
-rw-r--r-- | main.js | 10 | ||||
-rw-r--r-- | style.css | 57 |
7 files changed, 148 insertions, 12 deletions
@@ -1,6 +1,8 @@ let state = {}; let internalState = {}; +const KEY_ENTER = 13; + state.currentChar = '你'; function setState(key, value) @@ -18,19 +20,48 @@ const CurrentCharacter = function({character}) character ); } - + +function shakeInputBox() +{ + setState('inputShaking', true); + setTimeout(() => setState('inputShaking', false), 300); +} + const App = function() { - const { currentChar } = state; + const { currentChar, inputValue, inputShaking } = state; return h( 'div', {}, [ - h( - CurrentCharacter, - {character: currentChar} - ), - ] - ); -} + h(CurrentCharacter, + { character: currentChar + }), + + h(InputBox, + { value: inputValue, + shouldGrabFocus: true, + shaking: inputShaking, + handleKeyDown: (e) => + { + if (e.keyCode == KEY_ENTER) { + console.log(inputValue); + } + else { + setTimeout(() => setState('inputValue', e.target.value), 0); + } + } + }), + + h(StyleButton, + { + text: 'hello, world', + enabled: true, + handleClick: () => { + console.log('hi there'); + }, + }), + ] + ); + } diff --git a/InputBox.js b/InputBox.js new file mode 100644 index 0000000..61158e0 --- /dev/null +++ b/InputBox.js @@ -0,0 +1,18 @@ +const linkEvent = Inferno.linkEvent; + + +function InputBox(props) +{ + const { shaking, handleKeyDown } = props; + + const className = shaking ? '.shake' : ''; + + return h( + `input${className}`, + { + type: 'text', + value: props.value, + onKeyDown: handleKeyDown, + } + ); +} diff --git a/StyleButton.js b/StyleButton.js new file mode 100644 index 0000000..806ece6 --- /dev/null +++ b/StyleButton.js @@ -0,0 +1,15 @@ +function StyleButton(props) +{ + const { enabled, handleClick } = props; + + const className = enabled ? 'StyleButtonEnabled' : 'StyleButtonDisabled'; + + + return h( + `div.unselectable.StyleButton.${className}`, + { + onClick: handleClick, + }, + props.text + ); +} diff --git a/characters.js b/characters.js index 0ed41aa..a4fb49f 100644 --- a/characters.js +++ b/characters.js @@ -79,7 +79,7 @@ let characters = [['的','de'], ['同','tong2'], ['道','dao4'], ['地','di4'], - ['发','fa3'], + ['发','fa1'], ['法','fa3'], ['无','wu2'], ['然','ran2'], @@ -2,16 +2,21 @@ <html> <head> <meta charset="utf-8"> - <title>学汉字</title> + <title>学汉字 | sanine.net</title> <!-- inferno scripts --> <script src="https://unpkg.com/inferno@7.4.8/dist/inferno.min.js"></script> <script src="https://unpkg.com/inferno-hyperscript@7.4.8/dist/inferno-hyperscript.min.js"></script> <!-- local scripts --> + <script src="./main.js"></script> <script src="./characters.js"></script> + <script src="./InputBox.js"></script> + <script src="./StyleButton.js"></script> <script src="./App.js"></script> - <script src="./main.js"></script> + + <!-- styling --> + <link href="./style.css" rel="stylesheet"> </head> <body> @@ -2,6 +2,16 @@ const h = Inferno.h; +function useState(initial) { + let state = initial; + let setState = (value) => { + state = value; + render(); + } + return [state, setState]; +} + + function render() { Inferno.render( @@ -21,3 +21,60 @@ body { font-size: 200px; } +@-webkit-keyframes shake +{ + 0%, 100% { transform: translateX(0); } + 25%, 75% { transform: translateX(10px); } + 50% { transform: translateX(-10px); } +} + +@keyframes shake +{ + 0%, 100% { transform: translateX(0); } + 25%, 75% { transform: translateX(10px); } + 50% { transform: translateX(-10px); } +} + + +.shake +{ + animation-name: shake; + animation-duration: 0.3s; + animation-iteration-count: 1; +} + +.unselectable +{ + -webkit-user-select: none; /* Safari */ + -moz-user-select: none; /* Firefox */ + -ms-user-select: none; /* IE10+/Edge */ + user-select: none; /* Standard */ +} + +.StyleButton +{ + padding: 10px; + border-radius: 8px; + border-style: solid; + border-width: 2px; + display: inline; +} + + +.StyleButtonEnabled +{ + color: white; + background-color: #2af; +} + +.StyleButtonEnabled:hover +{ + background-color: #6af; +} + + +.StyleButtonDisabled +{ + color: white; + background-color: #444; +} |