ES6 initial setup

This commit is contained in:
Francisco Hodge
2018-04-20 16:34:02 -04:00
commit df42db3b95
35 changed files with 14071 additions and 0 deletions
+31
View File
@@ -0,0 +1,31 @@
#root {
font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif;
max-width: 1000px;
margin: 0 auto;
padding-top: 20px;
}
#root .simple-keyboard-preview {
background: rgba(0,0,0,0.8);
border: 20px solid;
height: 300px;
border-top-right-radius: 5px;
border-top-left-radius: 5px;
padding: 10px;
box-sizing: border-box;
}
#root .input {
color: white;
background: transparent;
border: none;
outline: none;
font-family: monospace;
width: 100%;
height: 100%;
}
.simple-keyboard.hg-layout-custom {
border-top-left-radius: 0px;
border-top-right-radius: 0px;
}
+49
View File
@@ -0,0 +1,49 @@
import Keyboard from '../lib';
import './App.css';
class App {
constructor(){
document.addEventListener('DOMContentLoaded', this.onDOMLoaded);
this.layoutName = "default";
}
onDOMLoaded = () => {
this.keyboard = new Keyboard({
debug: true,
layoutName: this.layoutName,
onChange: input => this.onChange(input),
onKeyPress: button => this.onKeyPress(button)
});
this.keyboard.setInput("Hello World!");
console.log(this.keyboard);
}
handleShiftButton = () => {
let layoutName = this.layoutName;
let shiftToggle = this.layoutName = layoutName === "default" ? "shift" : "default";
this.keyboard.setOptions({
layoutName: shiftToggle
});
}
onChange = input => {
document.querySelector('.input').value = input;
}
onKeyPress = button => {
console.log("Button pressed", button);
/**
* Shift functionality
*/
if(button === "{lock}" || button === "{shift}")
this.handleShiftButton();
}
}
export default App;
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

+15
View File
@@ -0,0 +1,15 @@
import App from './App';
/**
* Initializing demo
*/
new App();
/**
* Adding preview (demo only)
*/
document.querySelector('.simple-keyboard').insertAdjacentHTML('beforebegin', `
<div class="simple-keyboard-preview">
<textarea class="input" readonly>Hello World!</textarea>
</div>
`);
+66
View File
@@ -0,0 +1,66 @@
body, html {
margin: 0;
padding: 0;
}
.simple-keyboard {
font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif;
width: 100%;
user-select: none;
box-sizing: border-box;
overflow: hidden;
}
.simple-keyboard .hg-row {
display: flex;
}
.simple-keyboard .hg-row:not(:last-child) {
margin-bottom: 5px;
}
.simple-keyboard .hg-row .hg-button:not(:last-child) {
margin-right: 5px;
}
.simple-keyboard .hg-button {
display: inline-block;
flex-grow: 1;
cursor: pointer;
}
.simple-keyboard.hg-layout-default .hg-button.hg-standardBtn {
max-width: 100px;
}
/**
* hg-theme-default theme
*/
.simple-keyboard.hg-theme-default {
background-color: rgba(0,0,0,0.2);
padding: 5px;
border-radius: 5px;
}
.simple-keyboard.hg-theme-default .hg-button {
box-shadow: 0px 0px 3px -1px rgba(0,0,0,0.3);
height: 40px;
border: 1px solid rgba(0,0,0,0.25);
border-radius: 5px;
box-sizing: border-box;
padding: 5px;
background: white;
border-bottom: 1px solid gray;
}
.simple-keyboard.hg-theme-default .hg-button:active {
background: #e4e4e4;
}
.simple-keyboard.hg-theme-default.hg-layout-numeric .hg-button {
width: 33.3%;
height: 60px;
align-items: center;
display: flex;
justify-content: center;
}
+165
View File
@@ -0,0 +1,165 @@
import './Keyboard.css';
// Services
import KeyboardLayout from '../services/KeyboardLayout';
import Utilities from '../services/Utilities';
class SimpleKeyboard {
constructor(...params){
let keyboardDOMQuery = typeof params[0] === "string" ? params[0] : '.simple-keyboard';
let options = typeof params[0] === "object" ? params[0] : params[1];
if(!options)
options = {};
/**
* Processing options
*/
this.keyboardDOM = document.querySelector(keyboardDOMQuery);
this.options = options;
this.input = '';
this.options.layoutName = this.options.layoutName || "default";
this.options.theme = this.options.theme || "hg-theme-default";
/**
* Rendering keyboard
*/
if(this.keyboardDOM)
this.render();
else
console.error(`"${keyboardDOMQuery}" was not found in the DOM.`);
}
handleButtonClicked = (button) => {
let debug = this.options.debug;
/**
* Ignoring placeholder buttons
*/
if(button === '{//}')
return false;
/**
* Calling onKeyPress
*/
if(typeof this.options.onKeyPress === "function")
this.options.onKeyPress(button);
/**
* Updating input
*/
let options = {
newLineOnEnter: (this.options.newLineOnEnter === true)
}
let updatedInput = Utilities.getUpdatedInput(button, this.input, options);
if(this.input !== updatedInput){
this.input = updatedInput;
if(debug)
console.log('Input changed:', this.input);
/**
* Calling onChange
*/
if(typeof this.options.onChange === "function")
this.options.onChange(this.input);
}
if(debug){
console.log("Key pressed:", button);
}
}
clearInput = () => {
this.input = '';
}
getInput = () => {
return this.input;
}
setInput = input => {
this.input = input;
}
setOptions = option => {
option = option || {};
this.options = Object.assign(this.options, option);
this.render();
}
clear = () => {
this.keyboardDOM.innerHTML = '';
}
render = () => {
/**
* Clear keyboard
*/
this.clear();
let layoutClass = this.options.layout ? "hg-layout-custom" : `hg-layout-${this.options.layoutName}`;
let layout = this.options.layout || KeyboardLayout.getLayout(this.options.layoutName);
/**
* Adding themeClass, layoutClass to keyboardDOM
*/
this.keyboardDOM.className += ` ${this.options.theme} ${layoutClass}`;
/**
* Iterating through each row
*/
layout[this.options.layoutName].forEach((row, index) => {
let rowArray = row.split(' ');
/**
* Creating empty row
*/
var rowDOM = document.createElement('div');
rowDOM.className += "hg-row";
/**
* Iterating through each button in row
*/
rowArray.forEach((button, index) => {
let fctBtnClass = Utilities.getButtonClass(button);
let buttonDisplayName = Utilities.getButtonDisplayName(button, this.options.display);
/**
* Creating button
*/
var buttonDOM = document.createElement('div');
buttonDOM.className += `hg-button ${fctBtnClass}`;
buttonDOM.onclick = () => this.handleButtonClicked(button);
/**
* Adding button label to button
*/
var buttonSpanDOM = document.createElement('span');
buttonSpanDOM.innerHTML = buttonDisplayName;
buttonDOM.appendChild(buttonSpanDOM);
/**
* Appending button to row
*/
rowDOM.appendChild(buttonDOM);
/**
* Calling onInit
*/
if(typeof this.options.onInit === "function")
this.options.onInit();
});
/**
* Appending row to keyboard
*/
this.keyboardDOM.appendChild(rowDOM);
});
}
}
export default SimpleKeyboard;
+8
View File
@@ -0,0 +1,8 @@
import React from 'react';
import ReactDOM from 'react-dom';
import Keyboard from './Keyboard';
it('Keyboard renders without crashing', () => {
const div = document.createElement('div');
ReactDOM.render(<Keyboard />, div);
});
+2
View File
@@ -0,0 +1,2 @@
import SimpleKeyboard from './components/Keyboard';
export default SimpleKeyboard;
+37
View File
@@ -0,0 +1,37 @@
class KeyboardLayout {
static getLayout = layout => {
if(layout === "qwerty"){
return {
'default': [
'` 1 2 3 4 5 6 7 8 9 0 - = {bksp}',
'{tab} q w e r t y u i o p [ ] \\',
'{lock} a s d f g h j k l ; \' {enter}',
'{shift} z x c v b n m , . / {shift}',
'.com @ {space}'
],
'shift': [
'~ ! @ # $ % ^ & * ( ) _ + {bksp}',
'{tab} Q W E R T Y U I O P { } |',
'{lock} A S D F G H J K L : " {enter}',
'{shift} Z X C V B N M < > ? {shift}',
'.com @ {space}'
]
};
} else if(layout === "numeric"){
return {
'default': [
'1 2 3',
'4 5 6',
'7 8 9',
'{//} 0 {bksp}'
]
};
} else {
return KeyboardLayout.getLayout("qwerty");
}
}
}
export default KeyboardLayout;
+92
View File
@@ -0,0 +1,92 @@
class Utilities {
static normalizeString(string){
let output;
if(string === "@")
output = 'at';
else if(string === ",")
output = 'comma';
else if(string === ".")
output = 'dot';
else if(string === "\\")
output = 'backslash';
else if(string === "/")
output = 'fordardslash';
else if(string === "*")
output = 'asterisk';
else if(string === "&")
output = 'ampersand';
else if(string === "$")
output = 'dollarsign';
else if(string === "=")
output = 'equals';
else if(string === "+")
output = 'plus';
else if(string === "-")
output = 'minus';
else if(string === "'")
output = 'apostrophe';
else if(string === ";")
output = 'colon';
else if(string === "[")
output = 'openbracket';
else if(string === "]")
output = 'closebracket';
else if(string === "//")
output = 'emptybutton';
else
output = '';
return output ? ` hg-button-${output}` : '';
}
static getButtonClass = button => {
let buttonTypeClass = (button.includes("{") && button !== '{//}') ? "functionBtn" : "standardBtn";
let buttonWithoutBraces = button.replace("{", "").replace("}", "");
let buttonNormalized =
buttonTypeClass === "standardBtn" ?
Utilities.normalizeString(buttonWithoutBraces) : ` hg-button-${buttonWithoutBraces}`;
return `hg-${buttonTypeClass}${buttonNormalized}`;
}
static getDefaultDiplay(){
return {
'{bksp}': 'delete',
'{enter}': '< enter',
'{shift}': 'shift',
'{s}': 'shift',
'{tab}': 'tab',
'{lock}': 'caps',
'{accept}': 'Submit',
'{space}': ' ',
'{//}': ' '
};
}
static getButtonDisplayName = (button, display) => {
display = display || Utilities.getDefaultDiplay();
return display[button] || button;
}
static getUpdatedInput = (button, input, options) => {
let output = input;
let newLineOnEnter = options.newLineOnEnter;
if(button === "{bksp}" && output.length > 0)
output = output.slice(0, -1);
else if(button === "{space}")
output = output + ' ';
else if(button === "{tab}")
output = output + "\t";
else if(button === "{enter}" && newLineOnEnter)
output = output + "\n";
else if(!button.includes("{") && !button.includes("{"))
output = output + button;
return output;
}
}
export default Utilities;