Restructuring folders [ Broken ]

This commit is contained in:
2018-10-22 17:21:29 +11:00
parent 36b7b8629e
commit 776395520d
148 changed files with 238 additions and 198 deletions

View File

@ -0,0 +1,185 @@
// Copyright (c) 2018 Dominic Masters
//
// MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
import React from 'react';
import Button from './button/Button';
import ButtonGroup from './button/ButtonGroup';
import Form, { FormManager } from './form/Form';
import InputGroup from './group/InputGroup';
import Label from './label/Label';
import Keyboard from './../keyboard/Keyboard';
export default class Input extends React.Component {
constructor(props) {
super(props);
this.state = {
value: props.value,
focused: false
};
}
isFocused() {
return this.state && this.state.focused === true;
}
componentDidMount() {
if(this.props.manager) this.props.manager.addInput(this);
Keyboard.addListener(this);
}
componentWillUnmount() {
if(this.props.manager) this.props.manager.removeInput(this);
Keyboard.removeListener(this);
}
onKeyUp(e, k) {
if(!this.props.manager) return;
if(!this.isFocused()) return;
if(!k.isSubmit()) return;
this.props.manager.submit();
}
onChange(e, a, b) {
//Try my props
if(this.props.onChange && this.props.onChange(e) === false) return false;
//Try the form manager
if(this.props.manager && this.props.manager.onChange(this, e) === false) {
return false;
}
//Try something else?
this.setState({
value: e.target.value
});
}
onFocus() {
this.setState({ focused: true });
}
onBlur() {
this.setState({ focused: false });
}
render() {
let ElementType = "input";
let type = "text";
let value;
let clazzes = "o-input";
let innerClazzes = "o-input__inner";
let style;
let props = Object.assign({}, this.props);
//Determining
if(props.type) type = props.type;
//Values
if(props.value) {
value = props.value;
} else {
value = props.children;
}
//Style
if(props.style) {
style = props.style;
} else if(props.error || props.danger) {
style = "danger";
} else if(props.warning) {
style = "warning";
} else if(props.primary) {
style = "primary";
}
//Classes
clazzes += " is-"+type;
if(style) {
clazzes += " o-input--style-"+style;
innerClazzes += " o-input--style-"+style+"__inner";
}
if(props.className) {
clazzes += " " + props.className;
innerClazzes += " " + props.className + "-element";
}
//Clear junk props
delete props.manager;
//Now create the element
let element;
//First we need to switch things like submit and reset
if(type == "submit" || type == "reset" || type == "button") {
return (<Button
{...props}
className={props.className}
value={this.state.value}
/>);
} else if(type == "textarea") {
element = (<textarea
{...props}
className={innerClazzes}
onChange={this.onChange.bind(this)}
onFocus={this.onFocus.bind(this)}
onBlur={this.onBlur.bind(this)}
>{ this.state.value }</textarea>
);
} else {
element = (<ElementType
{...props}
onChange={this.onChange.bind(this)}
onFocus={this.onFocus.bind(this)}
onBlur={this.onBlur.bind(this)}
type={type}
value={ this.state.value }
className={innerClazzes}
/>);
}
return (
<div className={clazzes}>
{ element }
</div>
)
}
}
const TextArea = props => {
return <Input {...props} type="textarea" />
}
export {
Button,
ButtonGroup,
Form,
FormManager,
InputGroup,
TextArea,
Label
};

View File

@ -0,0 +1,104 @@
// Copyright (c) 2018 Dominic Masters
//
// MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
import React from 'react';
import { NavLink } from 'react-router-dom';
export default class Button extends React.Component {
constructor(props) {
super(props);
}
render() {
let ElementType = "button";//Upper Camel-Case because of react requriements
let clazzes = "o-btn";
let type = "button";
let contents;
let href;
let to;
let activeClassName;
let style;
//Basic Element Determining
if(this.props.type) {
//Buttons and Input Buttons
type = this.props.type;
clazzes += " is-button";
} else if(this.props.href) {
//Anchor Tags1
ElementType = "a";
href = this.props.href;
clazzes += " is-link is-anchor";
} else if(this.props.to) {
//React NavLink/Link
to = this.props.to;
ElementType = NavLink;
clazzes += " is-link is-nav-link";
activeClassName = "is-active";
} else {
//Everything Else (button without a type);
clazzes += " is-not-button";
}
if(this.props.value) {
contents = this.props.value;
} else {
contents = this.props.children;
}
//Determine Style
if(this.props.primary) {
style = "primary"
} else if(this.props.secondary) {
style = "secondary";
} else if(this.props.danger) {
style = "danger";
} else if(this.props.warning) {
style = "warning";
} else if(this.props.style) {
style = this.props.style;
}
//Style Clazzes
if(style) {
clazzes += " o-btn--style-"+style;
}
//Determine extra clazzes
if(this.props.className) this.clazzes += " "+this.props.className;
return (
<ElementType
{...this.props}
type={type}
className={clazzes}
href={href}
to={to}
>
<span className={ "o-btn__inner" + (style ? " o-btn--style-" + style + "__inner" : "") }>
{contents}
</span>
</ElementType>
);
}
}

View File

@ -0,0 +1,32 @@
// Copyright (c) 2018 Dominic Masters
//
// MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
import React from 'react';
export default function(props) {
return (
<div {...props} className={"o-btn-group" + (props.className ? " "+props.className : "")}>
{props.children}
</div>
);
}

View File

@ -0,0 +1,239 @@
// Copyright (c) 2018 Dominic Masters
//
// MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
import React from 'react';
import Loader, { LoaderBackdrop } from './../../loading/Loader';
import Input, { InputGroup, TextArea } from './../Input';
export default class Form extends React.Component {
constructor(props) {
super(props);
//Prepare our initial state
let s = {
ajax: props.ajax || false,
loader: props.loader || false,
loading: false,
onSubmit: props.onSubmit,
contentType: props.contentType || props.encType || "application/x-www-form-urlencoded",
manager: props.manager
};
//Determine action and method based off the internals
if(props.action) s.action = props.action;
if(props.method) s.method = props.method;
if(props.get) {
s.action = props.get;
s.method = "GET";
}
if(props.post) {
s.action = props.post;
s.method = "POST";
}
//Write our state to the component
this.state = s;
}
componentDidMount() {
if(this.props.manager) this.props.manager.addForm(this);
}
componentWillUnmount() {
if(this.props.manager) this.props.manager.removeForm(this);
}
submit() {
this.onSubmit();
}
onSubmit(e) {
//Is Ajax?
if(!this.state.ajax) {
return this.state.onSubmit ? this.state.onSubmit(e) : true;
}
if(e) e.preventDefault();
if(!this.state.action) return console.warning("This form has no action.");
if(this.state.submitting) return false;//Already submitting?
//Start submitting!
this.setState({
loading: true,
submitting: true
});
//Prepare our data
let data;
if(this.props.manager) {
data = this.props.manager.getFormData();
}
if(this.state.contentType == "application/json") {
let dataJson = {};
data.forEach(function(value, key) {
dataJson[key] = value;
});
data = JSON.stringify(dataJson);
}
//Prepare our request.
fetch(this.state.action, {
method: this.state.method,
mode: this.state.mode,
body: data,
headers: {
"Content-Type": this.state.contentType
}
})
.then(this.onSubmitted.bind(this))
.catch(this.onError.bind(this))
;
return false;
}
onSubmitted(response) {
let method = 'text';
let isJson = response.headers.get("Content-Type").toLowerCase().indexOf("application/json") !== -1;
if(isJson) method = 'json';
if(!response.ok) {
let is4xx = Math.floor(response.status / 400) === 1;
if(is4xx) {
return response[method]()
.then(this.onErrorText.bind(this))
.catch(this.onError.bind(this))
;
} else {
throw Error(response.statusText);
}
}
if(this.props.onData) return this.props.onData(response);
//Handle the old fashioned way (expect json)
response[method]()
.then(this.onData.bind(this))
.catch(this.onError.bind(this))
;
}
onData(response) {
if(this.props.onSuccess) return this.props.onSuccess(response);
console.log(response);
}
onErrorText(e,a,b) {
this.onError(e,a,b);
}
onError(e, a, b) {
this.setState({
loading: false,
submitting: false
});
if(this.props.onError) return this.props.onError(e, a, b);
if(e) console.error(e);
if(a) console.error(a);
if(b) console.error(b);
}
render() {
let clazz = "o-form";
if(this.props.className) clazz += " " + this.props.className;
//Do I need a loader?
let loader;
if(this.state.loader && this.state.loading) {
loader = (
<LoaderBackdrop className="o-form__loader">
<Loader className="o-form__loader-spinner" />
</LoaderBackdrop>
);
}
return (
<form
ref="formDOM"
className={clazz}
method={ this.state.method }
autoComplete={ this.props.autoComplete }
target={ this.props.target }
onSubmit={ this.onSubmit.bind(this) }
>
{ this.props.children }
{ loader }
</form>
);
}
}
//FormManager
class FormManager {
constructor() {
this.forms = [];
this.inputs = [];
}
addForm(form) { this.forms.push(form); }
addInput(input) { this.inputs.push(input); }
removeForm(form) {
let i = this.forms.indexOf(form);
if(i === -1) return;
this.forms.splice(i, 1);
}
removeInput(input) {
let i = this.inputs.indexOf(input);
if(i === -1) return;
this.inputs.splice(i, 1);
}
onChange(input, event) {}
submit() {
for(let i = 0; i < this.forms.length; i++) {
this.forms[i].submit();
}
}
getFormData() {
let data = new FormData();
for(let i = 0; i < this.inputs.length; i++) {
let input = this.inputs[i];
data.append(input.props.name, input.state.value);
}
return data;
}
}
export {
FormManager
};

View File

@ -0,0 +1,36 @@
// Copyright (c) 2018 Dominic Masters
//
// MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
import React from 'react';
export default function(props) {
let clazzes = "o-form__group";
if(props.className) clazzes += " " + props.className;
return (
<div className={clazzes}>
{ props.children }
</div>
);
}

View File

@ -0,0 +1,35 @@
// Copyright (c) 2018 Dominic Masters
//
// MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
import React from 'react';
export default function(props) {
let clazz = "o-label";
if(props.className) clazz += " " + props.className;
return (
<label htmlFor={ props.htmlFor } className={clazz}>
{ props.children }
</label>
);
}