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
+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;