From c9c1b78ed805371615d3ca8b54c86da9a35db8ce Mon Sep 17 00:00:00 2001
From: sanine-a <sanine.not@pm.me>
Date: Tue, 13 Apr 2021 11:37:51 -0500
Subject: implement basic user input and button styling

---
 App.js         | 49 ++++++++++++++++++++++++++++++++++++++++---------
 InputBox.js    | 18 ++++++++++++++++++
 StyleButton.js | 15 +++++++++++++++
 characters.js  |  2 +-
 index.html     |  9 +++++++--
 main.js        | 10 ++++++++++
 style.css      | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 7 files changed, 148 insertions(+), 12 deletions(-)
 create mode 100644 InputBox.js
 create mode 100644 StyleButton.js

diff --git a/App.js b/App.js
index ebfcae3..cc436b4 100644
--- a/App.js
+++ b/App.js
@@ -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'],
diff --git a/index.html b/index.html
index cb79140..bfe29d4 100644
--- a/index.html
+++ b/index.html
@@ -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>
diff --git a/main.js b/main.js
index 0ca765b..72c97a4 100644
--- a/main.js
+++ b/main.js
@@ -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(
diff --git a/style.css b/style.css
index 485a1a1..d9873ad 100644
--- a/style.css
+++ b/style.css
@@ -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;
+}
-- 
cgit v1.2.1