Lots of different changes, mostly to convert to InfernoJS and to work on updating to Bulma structure.

This commit is contained in:
Robbie Antenesse 2017-01-14 12:55:42 -07:00
parent d4f4dd62c8
commit 91d4d5b5da
20 changed files with 289 additions and 131 deletions

View File

@ -1,3 +1,4 @@
{ {
"presets": [ "es2015", "react" ] "presets": [ "es2015" ],
"plugins": [ "inferno" ]
} }

View File

@ -23,6 +23,8 @@
"dependencies": { "dependencies": {
"babel-polyfill": "^6.13.0", "babel-polyfill": "^6.13.0",
"bulma": "^0.2.3", "bulma": "^0.2.3",
"inferno": "^1.0.3",
"inferno-component": "^1.0.3",
"json-query": "^2.2.0", "json-query": "^2.2.0",
"marked": "^0.3.6", "marked": "^0.3.6",
"papaparse": "^4.1.2", "papaparse": "^4.1.2",
@ -33,6 +35,7 @@
"devDependencies": { "devDependencies": {
"babel-core": "^6.14.0", "babel-core": "^6.14.0",
"babel-loader": "^6.2.5", "babel-loader": "^6.2.5",
"babel-plugin-inferno": "^1.4.0",
"babel-preset-es2015": "^6.14.0", "babel-preset-es2015": "^6.14.0",
"babel-preset-react": "^6.11.1", "babel-preset-react": "^6.11.1",
"css-loader": "^0.25.0", "css-loader": "^0.25.0",

View File

@ -1,7 +1,10 @@
import React from 'react'; // import React from 'react';
import Inferno from 'inferno';
import Component from 'inferno-component';
// Creates a clickable <span> tag with an onclick action. // Creates a clickable <span> tag with an onclick action.
export class Button extends React.Component { // export class Button extends React.Component {
export class Button extends Component {
constructor(props) { constructor(props) {
super(props); super(props);
} }

View File

@ -1,4 +1,5 @@
import React from 'react'; // import React from 'react';
import Inferno from 'inferno';
import {Input} from './Input'; import {Input} from './Input';
export class Checkbox extends Input { export class Checkbox extends Input {
@ -25,7 +26,7 @@ export class Checkbox extends Input {
{this.props.name} {this.props.name}
{this.showHelperLink()} {this.showHelperLink()}
</span> </span>
<input type="checkbox" onChange={this.handleOnChange} checked={(this.state.value) ? 'checked' : null} disabled={(this.state.isDisabled) ? 'disabled' : null} /> <input type="checkbox" onInput={this.handleOnChange} checked={(this.state.value) ? 'checked' : null} disabled={(this.state.isDisabled) ? 'disabled' : null} />
</label> </label>
); );
} }

View File

@ -1,9 +1,12 @@
import React from 'react'; // import React from 'react';
import Inferno from 'inferno';
import Component from 'inferno-component';
import {Word} from './Word'; import {Word} from './Word';
// A component for showing just the list of words provided to it as a prop. // A component for showing just the list of words provided to it as a prop.
export class Dictionary extends React.Component { // export class Dictionary extends React.Component {
export class Dictionary extends Component {
constructor(props) { constructor(props) {
super(props); super(props);
} }
@ -33,7 +36,7 @@ export class Dictionary extends React.Component {
render() { render() {
return ( return (
<div id="theDictionary"> <div className='container' id="theDictionary">
{this.showWords()} {this.showWords()}
</div> </div>
); );

View File

@ -1,4 +1,5 @@
import React from 'react'; // import React from 'react';
import Inferno from 'inferno';
import {Input} from './Input'; import {Input} from './Input';
import {htmlEntities} from '../js/helpers'; import {htmlEntities} from '../js/helpers';
@ -39,11 +40,15 @@ export class Dropdown extends Input {
render() { render() {
return ( return (
<label> <label className='control'>
<span> <div className='level'>
{this.props.name} <span className='label level-item'>
{this.showHelperLink()} {this.props.name}
</span> </span>
<span className='level-item'>
{this.showHelperLink()}
</span>
</div>
<select value={this.state.value} onChange={this.handleOnChange} disabled={(this.state.isDisabled) ? 'disabled' : null}> <select value={this.state.value} onChange={this.handleOnChange} disabled={(this.state.isDisabled) ? 'disabled' : null}>
<option value=" "></option> <option value=" "></option>
{this.parseOptions(this.props.optionsList)} {this.parseOptions(this.props.optionsList)}

View File

@ -1,4 +1,6 @@
import React from 'react'; // import React from 'react';
import Inferno from 'inferno';
import Component from 'inferno-component';
import {Input} from './Input'; import {Input} from './Input';
import {TextArea} from './TextArea'; import {TextArea} from './TextArea';
@ -7,7 +9,8 @@ import {Button} from './Button';
import {FixedPage} from './FixedPage'; import {FixedPage} from './FixedPage';
// A component that allows you to edit the dictionary's details and settings. // A component that allows you to edit the dictionary's details and settings.
export class EditDictionaryForm extends React.Component { // export class EditDictionaryForm extends React.Component {
export class EditDictionaryForm extends Component {
constructor(props) { constructor(props) {
super(props); super(props);

View File

@ -1,4 +1,6 @@
import React from 'react'; // import React from 'react';
import Inferno from 'inferno';
import Component from 'inferno-component';
import {Input} from './Input'; import {Input} from './Input';
import {TextArea} from './TextArea'; import {TextArea} from './TextArea';
@ -6,7 +8,8 @@ import {TextArea} from './TextArea';
import {WordForm} from './WordForm'; import {WordForm} from './WordForm';
// A component that allows you to edit a word // A component that allows you to edit a word
export class EditWordForm extends React.Component { // export class EditWordForm extends React.Component {
export class EditWordForm extends Component {
constructor(props) { constructor(props) {
super(props); super(props);
} }

View File

@ -1,9 +1,12 @@
import React from 'react'; // import React from 'react';
import Inferno from 'inferno';
import Component from 'inferno-component';
import {Button} from './Button'; import {Button} from './Button';
// Creates a page that floats above other elements when a connected button is clicked. // Creates a page that floats above other elements when a connected button is clicked.
export class FixedPage extends React.Component { // export class FixedPage extends React.Component {
export class FixedPage extends Component {
constructor(props) { constructor(props) {
super(props); super(props);

View File

@ -1,10 +1,13 @@
import React from 'react'; // import React from 'react';
import Inferno from 'inferno';
import Component from 'inferno-component';
import marked from 'marked'; import marked from 'marked';
import {FixedPage} from './FixedPage'; import {FixedPage} from './FixedPage';
// A component for the site footer // A component for the site footer
export class Footer extends React.Component { // export class Footer extends React.Component {
export class Footer extends Component {
constructor(props) { constructor(props) {
super(props); super(props);

View File

@ -1,11 +1,14 @@
import React from 'react'; // import React from 'react';
import Inferno from 'inferno';
import Component from 'inferno-component';
import marked from 'marked'; import marked from 'marked';
import {Button} from './Button'; import {Button} from './Button';
import {FixedPage} from './FixedPage'; import {FixedPage} from './FixedPage';
// A component for the site header // A component for the site header
export class Header extends React.Component { // export class Header extends React.Component {
export class Header extends Component {
constructor(props) { constructor(props) {
super(props); super(props);
@ -49,10 +52,12 @@ export class Header extends React.Component {
buttons = [ buttons = [
<Button key='accountbutton1' <Button key='accountbutton1'
id='accountSettings' id='accountSettings'
classes='level-item'
action={() => this.lockUserOut()} action={() => this.lockUserOut()}
label='Account Settings' />, label='Account Settings' />,
<Button key='accountbutton2' <Button key='accountbutton2'
id='logoutLink' id='logoutLink'
classes='level-item'
action={() => this.logUserOut()} action={() => this.logUserOut()}
label='Log Out' /> label='Log Out' />
]; ];
@ -60,6 +65,7 @@ export class Header extends React.Component {
buttons = [ buttons = [
<Button key='accountbutton3' <Button key='accountbutton3'
id='logoutLink' id='logoutLink'
classes='level-item'
action={() => this.unlockUser()} action={() => this.unlockUser()}
label='Can&apos;t Log In' /> label='Can&apos;t Log In' />
]; ];
@ -67,34 +73,41 @@ export class Header extends React.Component {
buttons = [ buttons = [
<Button key='accountbutton4' <Button key='accountbutton4'
id='loginLink' id='loginLink'
classes='level-item'
action={() => this.logUserIn()} action={() => this.logUserIn()}
label='Log In/Create Account' /> label='Log In/Create Account' />
]; ];
} }
return <div className='button-group'>{buttons}</div>; return buttons;
} }
render() { render() {
return ( return (
<header className='header'> <header className='header'>
<div className='hero'>
<nav className='level' id="headerPadder">
<div id="headerPadder"> <div className='level-left'>
<a className='level-item' href="/" id="siteLogo">
Lexiconga Dictionary Builder
</a>
</div>
<a href="/" id="siteLogo">Lexiconga Dictionary Builder</a> <div className='level-right'>
<div className='button-group'> {this.showAccountButtons()}
<FixedPage id='aboutButton' buttonText='About Lexiconga'> <div className='level-item'>
<div dangerouslySetInnerHTML={{__html: marked(this.aboutText)}} /> <FixedPage id='aboutButton' buttonText='About Lexiconga'>
</FixedPage> <div dangerouslySetInnerHTML={{__html: marked(this.aboutText)}} />
</FixedPage>
</div>
</div> </div>
{this.showAccountButtons()}
</nav>
</div> </div>
</header> </header>
); );
} }

View File

@ -1,4 +1,6 @@
import React from 'react'; // import React from 'react';
import Inferno from 'inferno';
import Component from 'inferno-component';
import marked from 'marked'; import marked from 'marked';
import {WordForm} from './WordForm'; import {WordForm} from './WordForm';
@ -8,7 +10,8 @@ const saveIcon = <i>&#128190;</i>;
const editIcon = <i>&#128393;</i>; const editIcon = <i>&#128393;</i>;
// A component to show dictionary information in a tabbed interface. // A component to show dictionary information in a tabbed interface.
export class InfoDisplay extends React.Component { // export class InfoDisplay extends React.Component {
export class InfoDisplay extends Component {
constructor(props) { constructor(props) {
super(props); super(props);

View File

@ -1,8 +1,19 @@
import React from 'react'; // import React from 'react';
import Inferno, {linkEvent} from 'inferno';
import Component from 'inferno-component';
import {Button} from './Button'; import {Button} from './Button';
export class Input extends React.Component { function handleOnChange(instance, event) {
console.log('changing');
instance.setState({
isValid: !(instance.props.doValidate && event.currentTarget.value === ''),
value: event.currentTarget.value
});
}
// export class Input extends React.Component {
export class Input extends Component {
constructor(props) { constructor(props) {
super(props); super(props);
@ -12,27 +23,29 @@ export class Input extends React.Component {
// doValidate: props.doValidate || true // doValidate: props.doValidate || true
// }; // };
this.generatedId = 'input' + props.idManager.nextStr;
this.state = { this.state = {
value: props.value || '', value: props.value || '',
isDisabled: props.isDisabled || false isDisabled: props.isDisabled || false
}; };
// Bind listeners // Bind listeners
this.handleOnChange = this.handleOnChange.bind(this); // this.handleOnChange = this.handleOnChange.bind(this);
this.handleOnKeyDown = this.handleOnKeyDown.bind(this); this.handleOnKeyDown = this.handleOnKeyDown.bind(this);
} }
// Whenever the input changes we update the value state of this component // Whenever the input changes we update the value state of this component
handleOnChange(event) { handleOnChange(instance, event) {
this.setState({ instance.setState({
isValid: !(this.props.doValidate && event.currentTarget.value === ''), isValid: !(instance.props.doValidate && event.currentTarget.value === ''),
value: event.currentTarget.value value: event.currentTarget.value
}); });
} }
handleOnKeyDown(event) { handleOnKeyDown(instance, event) {
if (this.props.onKeyDown) { if (instance.props.onKeyDown) {
this.props.onKeyDown(event); instance.props.onKeyDown(event);
} }
} }
@ -46,9 +59,9 @@ export class Input extends React.Component {
); );
} else { } else {
return ( return (
<Button classes='inline-button' <Button classes='inline-button'
action={this.props.helperLink.action} action={this.props.helperLink.action}
label={this.props.helperLink.label || '?'} /> label={this.props.helperLink.label || '?'} />
); );
} }
} }
@ -66,18 +79,38 @@ export class Input extends React.Component {
render() { render() {
return ( return (
<label> <div>
<span>
{this.props.name} <div className='level is-marginless'>
{this.showHelperLink()}
</span> <div className='level-item'>
<input type="text" onChange={this.handleOnChange} onKeyDown={this.handleOnKeyDown} disabled={(this.state.isDisabled) ? 'disabled' : null} value={this.state.value} /> <label className='label' for={this.generatedId}>
</label> {this.props.name}
</label>
</div>
<div className='level-item'>
{this.showHelperLink()}
</div>
</div>
<p className='control'>
<input
className='input'
id={this.generatedId}
type="text"
onInput={linkEvent(this, this.handleOnChange)}
onKeyDown={linkEvent(this, this.handleOnKeyDown)}
disabled={(this.state.isDisabled) ? 'disabled' : null} />
</p>
</div>
); );
} }
} }
Input.defaultProps = { Input.defaultProps = {
name: '', name: '',
doValidate: true doValidate: false
}; };

View File

@ -1,4 +1,5 @@
import React from 'react'; // import React from 'react';
import Inferno, {linkEvent} from 'inferno';
import {Input} from './Input'; import {Input} from './Input';
import {getInputSelection, setSelectionRange} from '../js/helpers'; import {getInputSelection, setSelectionRange} from '../js/helpers';
@ -8,26 +9,50 @@ import {FixedPage} from './FixedPage';
export class TextArea extends Input { export class TextArea extends Input {
constructor(props) { constructor(props) {
super(props); super(props);
this.mainTextarea = null;
this.maximizedTextarea = null;
}
handleMaximizedTextboxClose (instance, event) {
instance.mainTextarea.value = event.currentTarget.value;
}
handleMaximizedTextboxOpen (instance, event) {
instance.maximizedTextarea.value = event.currentTarget.value;
} }
// Use a FixedPage for TextArea's fullscreen mode. // Use a FixedPage for TextArea's fullscreen mode.
render() { render() {
return ( return (
<label> <div className='control'>
<span> <div className='level'>
{this.props.name} <div className='level-item'>
<label className='label' for={this.generatedId}>
{this.props.name}
</label>
</div>
<FixedPage id={this.props.id + '_textbox'} contentClass='no-scroll' buttonClasses='maximize-button' buttonText='Maximize'> <div className='level-item'>
<label><span>{this.props.name}</span></label> <FixedPage id={this.generatedId + '_textbox'} contentClass='no-scroll' buttonClasses='maximize-button' buttonText='Maximize'>
<label><span>{this.props.name}</span></label>
<textarea id={this.props.id} className='fullscreen-textbox' onChange={this.handleOnChange} onKeyDown={this.handleOnKeyDown} value={this.state.value} /> <textarea id={this.generatedId} className='fullscreen-textbox'
</FixedPage> onChange={linkEvent(this, this.handleMaximizedTextboxClose)}
onKeyDown={linkEvent(this, this.handleOnKeyDown)}
ref={(textarea) => {this.maximizedTextarea = textarea}} />
</FixedPage>
</div>
</span> </div>
<textarea id={this.props.id} onChange={this.handleOnChange} onKeyDown={this.handleOnKeyDown} disabled={(this.state.isDisabled) ? 'disabled' : null} value={this.state.value} /> <textarea className='textarea' id={this.generatedId}
onInput={linkEvent(this, this.handleOnChange)}
onChange={linkEvent(this, this.handleMaximizedTextboxOpen)}
onKeyDown={linkEvent(this, this.handleOnChange)} disabled={(this.state.isDisabled) ? 'disabled' : null}
ref={(textarea) => {this.mainTextarea = textarea}} />
</label> </div>
); );
} }
} }

View File

@ -1,4 +1,6 @@
import React from 'react'; // import React from 'react';
import Inferno from 'inferno';
import Component from 'inferno-component';
import marked from 'marked'; import marked from 'marked';
import {WordForm} from './WordForm'; import {WordForm} from './WordForm';
@ -7,7 +9,8 @@ import {Button} from './Button';
const saveIcon = <i>&#128190;</i>; const saveIcon = <i>&#128190;</i>;
const editIcon = <i>&#128393;</i>; const editIcon = <i>&#128393;</i>;
export class Word extends React.Component { // export class Word extends React.Component {
export class Word extends Component {
constructor(props) { constructor(props) {
super(props); super(props);
@ -34,7 +37,7 @@ export class Word extends React.Component {
showName() { showName() {
return ( return (
<div className='title is-4 name'> <div className='title is-4 name is-inline'>
{this.props.name} {this.props.name}
</div> </div>
); );
@ -43,7 +46,7 @@ export class Word extends React.Component {
showPronunciation() { showPronunciation() {
if (this.props.pronunciation !== '') { if (this.props.pronunciation !== '') {
return ( return (
<div className='pronunciation'> <div className='pronunciation is-inline'>
{this.props.pronunciation} {this.props.pronunciation}
</div> </div>
); );
@ -53,7 +56,7 @@ export class Word extends React.Component {
showPartOfSpeech() { showPartOfSpeech() {
if (this.props.partOfSpeech !== '') { if (this.props.partOfSpeech !== '') {
return ( return (
<div className='part-of-speech'> <div className='part-of-speech is-inline'>
{this.props.partOfSpeech} {this.props.partOfSpeech}
</div> </div>
); );
@ -89,18 +92,23 @@ export class Word extends React.Component {
); );
} else { } else {
return ( return (
<div> <div className='content'>
{this.showName()} <div className='hero'>
{this.showName()}
{this.showPronunciation()} {this.showPronunciation()}
{this.showPartOfSpeech()} {this.showPartOfSpeech()}
<br /> </div>
{this.showSimpleDefinition()} <div className='section'>
{this.showLongDefinition()} {this.showSimpleDefinition()}
{this.showLongDefinition()}
</div>
</div> </div>
); );
} }
@ -148,7 +156,7 @@ export class Word extends React.Component {
render() { render() {
return ( return (
<div id={'entry' + this.props.wordId} className='word'> <div id={'entry' + this.props.wordId} className='box word'>
{this.showWordOrEdit()} {this.showWordOrEdit()}

View File

@ -1,4 +1,6 @@
import React from 'react'; // import React from 'react';
import Inferno from 'inferno';
import Component from 'inferno-component';
import {keyCodeFor} from '../js/helpers' import {keyCodeFor} from '../js/helpers'
@ -7,7 +9,8 @@ import {Dropdown} from './Dropdown';
import {TextArea} from './TextArea'; import {TextArea} from './TextArea';
import {Button} from './Button'; import {Button} from './Button';
export class WordForm extends React.Component { // export class WordForm extends React.Component {
export class WordForm extends Component {
constructor(props) { constructor(props) {
super(props); super(props);
@ -91,14 +94,15 @@ export class WordForm extends React.Component {
let partOfSpeechDefaultValue = (this.props.wordValues) ? this.props.wordValues.partOfSpeech : ' '; let partOfSpeechDefaultValue = (this.props.wordValues) ? this.props.wordValues.partOfSpeech : ' ';
let simpleDefinitionDefaultValue = (this.props.wordValues) ? this.props.wordValues.simpleDefinition : ''; let simpleDefinitionDefaultValue = (this.props.wordValues) ? this.props.wordValues.simpleDefinition : '';
let longDefinitionDefaultValue = (this.props.wordValues) ? this.props.wordValues.longDefinition : ''; let longDefinitionDefaultValue = (this.props.wordValues) ? this.props.wordValues.longDefinition : '';
return ( return (
<form> <div className='form'>
<Input name='Word' <Input name='Word' idManager={this.props.idManager}
value={nameDefaultValue} value={nameDefaultValue}
onKeyDown={(event) => this.submitWordOnCtrlEnter(event)} onKeyDown={(event) => this.submitWordOnCtrlEnter(event)}
ref={(inputComponent) => this.wordField = inputComponent} /> ref={(inputComponent) => this.wordField = inputComponent} />
<Input name='Pronunciation' <Input name='Pronunciation' idManager={this.props.idManager}
helperLink={{ helperLink={{
url: "http://r12a.github.io/pickers/ipa/", url: "http://r12a.github.io/pickers/ipa/",
label: "IPA Characters", label: "IPA Characters",
@ -108,17 +112,17 @@ export class WordForm extends React.Component {
onKeyDown={(event) => this.submitWordOnCtrlEnter(event)} onKeyDown={(event) => this.submitWordOnCtrlEnter(event)}
ref={(inputComponent) => this.pronunciationField = inputComponent} /> ref={(inputComponent) => this.pronunciationField = inputComponent} />
<Dropdown name='Part of Speech' <Dropdown name='Part of Speech' idManager={this.props.idManager}
optionsList={this.props.partsOfSpeech} optionsList={this.props.partsOfSpeech}
value={partOfSpeechDefaultValue} value={partOfSpeechDefaultValue}
ref={(inputComponent) => this.partOfSpeechField = inputComponent} /> ref={(inputComponent) => this.partOfSpeechField = inputComponent} />
<Input name={<div style={{display: 'inline'}}>Definition/<wbr /><b className="wbr"></b>Equivalent Word(s)</div>} <Input name={<div style={{display: 'inline'}}>Definition/<wbr /><b className="wbr"></b>Equivalent Word(s)</div>} idManager={this.props.idManager}
value={simpleDefinitionDefaultValue} value={simpleDefinitionDefaultValue}
onKeyDown={(event) => this.submitWordOnCtrlEnter(event)} onKeyDown={(event) => this.submitWordOnCtrlEnter(event)}
ref={(inputComponent) => this.simpleDefinitionField = inputComponent} /> ref={(inputComponent) => this.simpleDefinitionField = inputComponent} />
<TextArea id='newWordForm' <TextArea id='newWordForm' idManager={this.props.idManager}
name={<div style={{display: 'inline'}}>Explanation/<wbr /><b className="wbr"></b>Long Definition</div>} name={<div style={{display: 'inline'}}>Explanation/<wbr /><b className="wbr"></b>Long Definition</div>}
value={longDefinitionDefaultValue} value={longDefinitionDefaultValue}
onKeyDown={(event) => this.submitWordOnCtrlEnter(event)} onKeyDown={(event) => this.submitWordOnCtrlEnter(event)}
@ -129,7 +133,7 @@ export class WordForm extends React.Component {
<Button classes={(this.props.updateWord) ? 'edit-button' : 'add-button'} action={() => this.handleSubmit()} label={this.props.submitLabel} /> <Button classes={(this.props.updateWord) ? 'edit-button' : 'add-button'} action={() => this.handleSubmit()} label={this.props.submitLabel} />
<div id="updateConflict">{this.state.updateConflictMessage}</div> <div id="updateConflict">{this.state.updateConflictMessage}</div>
</form> </div>
); );
} }
} }

View File

@ -3,8 +3,10 @@ import './index.html';
import './sass/main.scss'; import './sass/main.scss';
// Import React for the React.Component class and ReactDOM for rendering. // Import React for the React.Component class and ReactDOM for rendering.
import React from 'react'; // import React from 'react';
import ReactDOM from 'react-dom'; // import ReactDOM from 'react-dom';
import Inferno from 'inferno';
import Component from 'inferno-component';
// Import the necessary components. // Import the necessary components.
import {Header} from './components/Header'; import {Header} from './components/Header';
@ -17,6 +19,7 @@ import {Dictionary} from './components/Dictionary';
// Import the helper functions needed for this file. // Import the helper functions needed for this file.
import {dynamicSort} from './js/helpers'; import {dynamicSort} from './js/helpers';
import {IDManager} from './js/IDManager';
// Declare the values of the default empty dictionary. // Declare the values of the default empty dictionary.
const defaultDictionaryName = 'New' const defaultDictionaryName = 'New'
@ -27,13 +30,16 @@ const defaultDictionaryName = 'New'
; ;
// Create the Lexiconga component just for rendering the whole site. // Create the Lexiconga component just for rendering the whole site.
class Lexiconga extends React.Component { // class Lexiconga extends React.Component {
class Lexiconga extends Component {
constructor(props) { constructor(props) {
super(props); super(props);
// This could probably be a global constant instead. // This could probably be a global constant instead.
this.showConsoleMessages = this.props.showConsoleMessages || false; this.showConsoleMessages = this.props.showConsoleMessages || false;
this.idManager = new IDManager();
// Put the dictionary details, settings, and words into the state so modifications will affect display. // Put the dictionary details, settings, and words into the state so modifications will affect display.
this.state = { this.state = {
scroll: { scroll: {
@ -246,47 +252,69 @@ class Lexiconga extends React.Component {
return ( return (
<div> <div>
<Header /> <Header />
<section className='section columns'>
<div className='column is-one-third'> <section className='section'>
<div className='floating-form'> <div className='columns'>
<WordForm
partsOfSpeech={this.state.settings.partsOfSpeech} <div className='column is-one-quarter'>
addWord={(wordObject) => this.addWord(wordObject)} <div className='box'>
submitLabel='Add Word' />
<WordForm
idManager={this.idManager}
partsOfSpeech={this.state.settings.partsOfSpeech}
addWord={(wordObject) => this.addWord(wordObject)}
submitLabel='Add Word' />
</div>
</div> </div>
</div>
<div className='column is-half'> <div className='column is-half'>
<Button
action={() => this.saveLocalDictionary()}
label='Save Dictionary' />
<Button <div className='hero'>
action={() => this.loadLocalDictionary()} <div className='container is-fluid'>
label='Load Dictionary' />
<EditDictionaryForm <Button
details={this.state.details} action={() => this.saveLocalDictionary()}
settings={this.state.settings} label='Save Dictionary' />
saveChanges={(changesObject) => this.saveChanges(changesObject)} />
<h1 className="title is-1 dictionary-name"> <Button
{this.state.details.name} {this.state.details.listTypeName} action={() => this.loadLocalDictionary()}
</h1> label='Load Dictionary' />
<InfoDisplay <EditDictionaryForm
details={this.state.details} details={this.state.details}
numberOfWords={this.state.words.length} settings={this.state.settings}
isComplete={this.state.settings.isComplete} /> saveChanges={(changesObject) => this.saveChanges(changesObject)} />
<Dictionary <h1 className="title is-1 dictionary-name">
details={this.state.details} {this.state.details.name} {this.state.details.listTypeName}
words={this.state.words} </h1>
settings={this.state.settings}
updateWord={(wordId, wordObject) => this.updateWord(wordId, wordObject)} />
</div>
<div className='column ad-column'> <InfoDisplay
details={this.state.details}
numberOfWords={this.state.words.length}
isComplete={this.state.settings.isComplete} />
</div>
</div>
<div className='section'>
<Dictionary
details={this.state.details}
words={this.state.words}
settings={this.state.settings}
updateWord={(wordId, wordObject) => this.updateWord(wordId, wordObject)} />
</div>
</div>
<div className='column is-one-quarter ad-column'>
<div className='box'>
Advertisements or something.
</div>
</div>
</div> </div>
</section> </section>
@ -298,4 +326,5 @@ class Lexiconga extends React.Component {
} }
// Put the app on the screen. // Put the app on the screen.
ReactDOM.render(<Lexiconga showConsoleMessages={true} />, document.getElementById('site')); // ReactDOM.render(<Lexiconga showConsoleMessages={true} />, document.getElementById('site'));
Inferno.render(<Lexiconga showConsoleMessages={true} />, document.getElementById('site'));

13
src/js/IDManager.js Normal file
View File

@ -0,0 +1,13 @@
export class IDManager {
constructor () {
this.nextId = 0;
}
get next () {
return this.nextId++;
}
get nextStr () {
return this.next.toString();
}
}

View File

@ -1,6 +1,6 @@
@import 'variables'; @import 'variables';
@import '../../node_modules/bulma/bulma'; @import '../../node_modules/bulma/bulma';
@import 'styles'; // @import 'styles';
@import 'lexiconga'; // @import 'lexiconga';
@import 'mobile'; // @import 'mobile';
@import '../../node_modules/react-select/dist/react-select'; @import '../../node_modules/react-select/dist/react-select';

View File

@ -30,7 +30,9 @@ const APP_DIR = path.resolve(__dirname, 'src');
exclude: /node_modules/, exclude: /node_modules/,
loader: 'babel', loader: 'babel',
query: { query: {
presets: ['react', 'es2015'] // presets: ['react', 'es2015']
presets: ['es2015'],
plugins: ['inferno']
} }
} }
] ]