CLLLEANED the forms, inputs, buttons, labels and form/button groups
This commit is contained in:
@ -23,12 +23,14 @@
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import Styles from './Input.scss';
|
||||
|
||||
import Keyboard from '@public/keyboard/Keyboard';
|
||||
|
||||
import Button from './button/Button';
|
||||
import ButtonGroup from './button/ButtonGroup';
|
||||
import Form, { FormManager } from './form/Form';
|
||||
import InputGroup from './group/InputGroup';
|
||||
import Form, { FormManager, FormGroup } from './form/Form';
|
||||
import Label from './label/Label';
|
||||
import Keyboard from '@public/keyboard/Keyboard';
|
||||
|
||||
export default class Input extends React.Component {
|
||||
constructor(props) {
|
||||
@ -45,7 +47,8 @@ export default class Input extends React.Component {
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
if(this.props.manager) this.props.manager.addInput(this);
|
||||
let { manager } = this.props;
|
||||
if(manager) manager.addInput(this);
|
||||
Keyboard.addListener(this);
|
||||
}
|
||||
|
||||
@ -85,49 +88,44 @@ export default class Input extends React.Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
let ElementType = "input";
|
||||
let type = "text";
|
||||
let value;
|
||||
let newProps = {...this.props};
|
||||
let {
|
||||
value, className, type, children, style, error, danger, primary,
|
||||
warning, manager
|
||||
} = newProps;
|
||||
|
||||
//Clear bad props
|
||||
[
|
||||
"error", "danger", "primary", "warning", "manager", "style", "children"
|
||||
].forEach(e => delete newProps[e]);
|
||||
|
||||
//Prop defaults
|
||||
type = type || "text";
|
||||
|
||||
//Gen classes
|
||||
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;
|
||||
}
|
||||
value = stateValue || value || 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";
|
||||
}
|
||||
if(primary) style = "primary";
|
||||
if(warning) style = "warning";
|
||||
if(error || danger) style = "danger";
|
||||
|
||||
//Classes
|
||||
clazzes += " is-"+type;
|
||||
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";
|
||||
clazzes += ` o-input--style-${style}`;
|
||||
innerClazzes += ` o-input--style-${style}__inner`;
|
||||
}
|
||||
|
||||
//Clear junk props
|
||||
delete props.manager;
|
||||
if(className) {
|
||||
clazzes += ` ${className}`;
|
||||
innerClazzes += ` ${className}-element`;
|
||||
}
|
||||
|
||||
//Now create the element
|
||||
let element;
|
||||
@ -139,27 +137,15 @@ export default class Input extends React.Component {
|
||||
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>
|
||||
);
|
||||
[ "onChange", "onFocus", "onBlur"].forEach(e => newProps[e] = this[e]);
|
||||
|
||||
//Text areas are slightly different
|
||||
if(type == "textarea") {
|
||||
element = <textarea {...newProps} className={innerClazzes} children={value} />
|
||||
} 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}
|
||||
/>);
|
||||
element = <input {...newProps} type={type} value={ value } className={innerClazzes} />;
|
||||
}
|
||||
|
||||
return (
|
||||
@ -179,7 +165,7 @@ export {
|
||||
ButtonGroup,
|
||||
Form,
|
||||
FormManager,
|
||||
InputGroup,
|
||||
FormGroup,
|
||||
TextArea,
|
||||
Label
|
||||
};
|
||||
|
@ -9,6 +9,7 @@
|
||||
* Version:
|
||||
* 1.0.0 - 2018/05/13
|
||||
*/
|
||||
@import '~@styles/global';
|
||||
|
||||
.o-input {
|
||||
@include t-input--style-dp();
|
@ -24,81 +24,61 @@
|
||||
import React from 'react';
|
||||
import { NavLink } from 'react-router-dom';
|
||||
|
||||
export default class Button extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
import Styles from './Button.scss';
|
||||
|
||||
export default props => {
|
||||
let newProps = {...props};
|
||||
let {
|
||||
className, href, to, style, type, value, children,
|
||||
error, danger, primary, warning, manager
|
||||
} = newProps;
|
||||
|
||||
[
|
||||
"style", "value", "href", "to", "children", "error", "danger", "primary",
|
||||
"warning", "manager"
|
||||
].forEach(e => delete newProps[e]);
|
||||
|
||||
type = type || "button";
|
||||
children = children || value;
|
||||
|
||||
if(primary) style = "primary";
|
||||
if(warning) style = "warning";
|
||||
if(error || danger) style = "danger";
|
||||
|
||||
|
||||
let ElementType = "button";//Upper Camel-Case because of react requriements
|
||||
let clazzes = "o-btn";
|
||||
|
||||
//Basic Element Determining
|
||||
if(type) {
|
||||
//Buttons and Input Buttons
|
||||
clazzes += " is-button";
|
||||
|
||||
} else if(href) {
|
||||
//Anchor Tags!
|
||||
ElementType = "a";
|
||||
clazzes += " is-link is-anchor";
|
||||
newProps.href = to || href;
|
||||
|
||||
} else if(to) {
|
||||
ElementType = NavLink;
|
||||
clazzes += " is-link is-nav-link";
|
||||
newProps.to = to || href;
|
||||
|
||||
} else {
|
||||
//Everything Else (button without a type);
|
||||
clazzes += " is-not-button";
|
||||
|
||||
}
|
||||
|
||||
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;
|
||||
if(style) clazzes += ` o-btn--style-${style}`;
|
||||
if(className) clazzes += ` ${className}`;
|
||||
|
||||
//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>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<ElementType {...newProps} className={clazzes}>
|
||||
<span className={"o-btn__inner"+(style?` o-btn--style-${style}__inner`:"")}>
|
||||
{contents}
|
||||
</span>
|
||||
</ElementType>
|
||||
);
|
||||
}
|
||||
|
@ -12,6 +12,8 @@
|
||||
* 1.0.1 - 2018/05/14
|
||||
*/
|
||||
|
||||
@import '~@styles/global';
|
||||
|
||||
//Default Button (applies to all styles)
|
||||
.o-btn {
|
||||
cursor: pointer;
|
@ -23,10 +23,9 @@
|
||||
|
||||
import React from 'react';
|
||||
|
||||
export default function(props) {
|
||||
export default props => {
|
||||
let { className } = props;
|
||||
return (
|
||||
<div {...props} className={"o-btn-group" + (props.className ? " "+props.className : "")}>
|
||||
{props.children}
|
||||
</div>
|
||||
<div {...props} className={"o-btn-group" + (className?` ${className}`:"")} />
|
||||
);
|
||||
}
|
||||
|
@ -22,47 +22,54 @@
|
||||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import Styles from './Form.scss';
|
||||
|
||||
import FormGroup from './group/FormGroup';
|
||||
import Loader, { LoaderBackdrop } from '@objects/loading/Loader';
|
||||
import Input, { InputGroup, TextArea } from './../Input';
|
||||
import Input, { 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
|
||||
};
|
||||
let {
|
||||
ajax, loader, onSubmit, contentType, encType, manager, action, method,
|
||||
get, post
|
||||
} = props;
|
||||
|
||||
contentType = contentType || encType || "application/x-www-form-urlencoded";
|
||||
|
||||
//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(get) {
|
||||
action = get;
|
||||
method = "GET";
|
||||
}
|
||||
|
||||
if(props.post) {
|
||||
s.action = props.post;
|
||||
s.method = "POST";
|
||||
if(post) {
|
||||
action = post;
|
||||
method = "POST";
|
||||
}
|
||||
|
||||
//Write our state to the component
|
||||
this.state = s;
|
||||
//Prepare our initial state
|
||||
this.state = {
|
||||
ajax,
|
||||
loader,
|
||||
loading: false,
|
||||
onSubmit,
|
||||
contentType,
|
||||
manager
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
if(this.props.manager) this.props.manager.addForm(this);
|
||||
let { manager } = this.props;
|
||||
if(manager) manager.addForm(this);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
if(this.props.manager) this.props.manager.removeForm(this);
|
||||
let { manager } = this.props;
|
||||
if(manager) manager.removeForm(this);
|
||||
}
|
||||
|
||||
submit() {
|
||||
@ -70,14 +77,19 @@ export default class Form extends React.Component {
|
||||
}
|
||||
|
||||
onSubmit(e) {
|
||||
let {
|
||||
ajax, onSubmit, action, submitting, method, mode, contentType
|
||||
} = this.state;
|
||||
let { manager } = this.props;
|
||||
|
||||
//Is Ajax?
|
||||
if(!this.state.ajax) {
|
||||
return this.state.onSubmit ? this.state.onSubmit(e) : true;
|
||||
if(!ajax) {
|
||||
return onSubmit ? 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?
|
||||
if(e && e.preventDefault) e.preventDefault();
|
||||
if(!action) return console.warning("This form has no action.");
|
||||
if(submitting) return false;//Already submitting?
|
||||
|
||||
//Start submitting!
|
||||
this.setState({
|
||||
@ -87,30 +99,26 @@ export default class Form extends React.Component {
|
||||
|
||||
//Prepare our data
|
||||
let data;
|
||||
if(this.props.manager) {
|
||||
data = this.props.manager.getFormData();
|
||||
}
|
||||
if(manager) data = manager.getFormData();
|
||||
data = data || {};
|
||||
|
||||
if(this.state.contentType == "application/json") {
|
||||
if(contentType == "application/json") {
|
||||
let dataJson = {};
|
||||
data.forEach(function(value, key) {
|
||||
data.forEach((value, key) => {
|
||||
dataJson[key] = value;
|
||||
});
|
||||
data = JSON.stringify(dataJson);
|
||||
}
|
||||
|
||||
//Prepare our request.
|
||||
fetch(this.state.action, {
|
||||
method: this.state.method,
|
||||
mode: this.state.mode,
|
||||
fetch(action, {
|
||||
method: method,
|
||||
mode: mode,
|
||||
body: data,
|
||||
headers: {
|
||||
"Content-Type": this.state.contentType
|
||||
"Content-Type": contentType
|
||||
}
|
||||
})
|
||||
.then(this.onSubmitted.bind(this))
|
||||
.catch(this.onError.bind(this))
|
||||
;
|
||||
}).then(resp => this.onSubmitted(resp)).catch((e,a,b) => this.onError(e,a,b));
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -124,20 +132,19 @@ export default class Form extends React.Component {
|
||||
let is4xx = Math.floor(response.status / 400) === 1;
|
||||
if(is4xx) {
|
||||
return response[method]()
|
||||
.then(this.onErrorText.bind(this))
|
||||
.catch(this.onError.bind(this))
|
||||
.then((e,a,b) => this.onErrorText(e,a,b))
|
||||
.catch((e,a,b) => this.onError(e,a,b))
|
||||
;
|
||||
} else {
|
||||
throw Error(response.statusText);
|
||||
}
|
||||
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))
|
||||
.then(resp => this.onData(resp))
|
||||
.catch((e,a,b) => this.onError(e,a,b))
|
||||
;
|
||||
}
|
||||
|
||||
@ -163,13 +170,16 @@ export default class Form extends React.Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
let { className, children } = this.props;
|
||||
let { loader, loading } = this.state;
|
||||
|
||||
let clazz = "o-form";
|
||||
if(this.props.className) clazz += " " + this.props.className;
|
||||
if(className) clazz += ` ${className}`
|
||||
|
||||
//Do I need a loader?
|
||||
let loader;
|
||||
if(this.state.loader && this.state.loading) {
|
||||
loader = (
|
||||
let loaderElement;
|
||||
if(loader && loading) {
|
||||
loaderElement = (
|
||||
<LoaderBackdrop className="o-form__loader">
|
||||
<Loader className="o-form__loader-spinner" />
|
||||
</LoaderBackdrop>
|
||||
@ -178,15 +188,14 @@ export default class Form extends React.Component {
|
||||
|
||||
return (
|
||||
<form
|
||||
{...this.props}
|
||||
ref="formDOM"
|
||||
className={clazz}
|
||||
className={ clazz }
|
||||
method={ this.state.method }
|
||||
autoComplete={ this.props.autoComplete }
|
||||
target={ this.props.target }
|
||||
onSubmit={ this.onSubmit.bind(this) }
|
||||
onSubmit={ (e) => this.onSubmit(e) }
|
||||
>
|
||||
{ this.props.children }
|
||||
{ loader }
|
||||
{ children }
|
||||
{ loaderElement }
|
||||
</form>
|
||||
);
|
||||
}
|
||||
@ -235,5 +244,6 @@ class FormManager {
|
||||
}
|
||||
|
||||
export {
|
||||
FormManager
|
||||
FormManager,
|
||||
FormGroup
|
||||
};
|
||||
|
@ -8,6 +8,7 @@
|
||||
* Version:
|
||||
* 1.0.0 - 2018/05/13
|
||||
*/
|
||||
@import '~@styles/global';
|
||||
.o-form {
|
||||
position: relative;
|
||||
}
|
@ -23,14 +23,11 @@
|
||||
|
||||
import React from 'react';
|
||||
|
||||
export default function(props) {
|
||||
export default props => {
|
||||
let clazzes = "o-form__group";
|
||||
|
||||
if(props.className) clazzes += " " + props.className;
|
||||
if(props.className) clazzes += ` ${props.className}`;
|
||||
|
||||
return (
|
||||
<div className={clazzes}>
|
||||
{ props.children }
|
||||
</div>
|
||||
<div {...props} className={clazzes} />
|
||||
);
|
||||
}
|
@ -23,13 +23,9 @@
|
||||
|
||||
import React from 'react';
|
||||
|
||||
export default function(props) {
|
||||
export default props => {
|
||||
let clazz = "o-label";
|
||||
if(props.className) clazz += " " + props.className;
|
||||
if(props.className) clazz += ` ${props.className}`;
|
||||
|
||||
return (
|
||||
<label htmlFor={ props.htmlFor } className={clazz}>
|
||||
{ props.children }
|
||||
</label>
|
||||
);
|
||||
return <label {...props} className={clazz} />;
|
||||
}
|
||||
|
@ -1,17 +1,46 @@
|
||||
// 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 (props) => {
|
||||
let height = 100;/* Percentage of width */
|
||||
import Styles from './BoxSizer.scss';
|
||||
|
||||
//TODO: Add more methods of resizing this box.
|
||||
if(props.ratioWidth && props.ratioHeight) {
|
||||
height = 100 / props.ratioWidth * props.ratioHeight;
|
||||
}
|
||||
export default props => {
|
||||
let newProps = {...props};
|
||||
let { ratioWidth, ratioHeight, className } = props;
|
||||
|
||||
let clazzes = "o-box-sizer";
|
||||
if(className) clazzes += ` ${className}`;
|
||||
|
||||
ratioWidth = parseInt(ratioWidth);
|
||||
ratioHeight = parseInt(ratioHeight);
|
||||
|
||||
//TODO: Add more methods of resizing...
|
||||
let height = 100;
|
||||
if(ratioWidth && ratioHeight) height = 100 / ratioWidth * ratioHeight;
|
||||
|
||||
//Box Sizer
|
||||
return (
|
||||
<div className="o-box-sizer" style={{
|
||||
paddingBottom: height + '%'
|
||||
}} />
|
||||
<div {...props} className={classes} style={{ paddingBottom: `${height}%` }} />
|
||||
);
|
||||
};
|
||||
|
@ -5,6 +5,7 @@
|
||||
* Version:
|
||||
* 1.0.0 - 2018/08/10
|
||||
*/
|
||||
@import '~@styles/global';
|
||||
.o-box-sizer {
|
||||
width: 100%;
|
||||
/* padding-bottom will be set my JS */
|
@ -23,9 +23,11 @@
|
||||
|
||||
import React from 'react';
|
||||
|
||||
const Loader = function(props) {
|
||||
import Styles from './Loader.scss';
|
||||
|
||||
const Loader = props => {
|
||||
return (
|
||||
<span className={"o-loader"+(props.className?" "+props.className:"")}>
|
||||
<span {...props} className={"o-loader"+(props.className?` ${props.className}`:"")}>
|
||||
<svg width="38" height="38" viewBox="0 0 38 38" xmlns="http://www.w3.org/2000/svg" className="o-loader__image">
|
||||
<g fill="none" fillRule="evenodd">
|
||||
<g transform="translate(1 1)" strokeWidth="2">
|
||||
@ -39,11 +41,9 @@ const Loader = function(props) {
|
||||
);
|
||||
}
|
||||
|
||||
const LoaderBackdrop = function(props) {
|
||||
const LoaderBackdrop = props => {
|
||||
return (
|
||||
<div className={"o-loader__backdrop"+(props.className?" "+props.className:"")}>
|
||||
{ props.children }
|
||||
</div>
|
||||
<div {...props} className={"o-loader__backdrop"+(props.className?` ${props.className}`:"")} />
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
* Version:
|
||||
* 1.0.0 - 2018/05/08
|
||||
*/
|
||||
@import '~@styles/global';
|
||||
|
||||
@include t-keyframes(o-loader--spin) {
|
||||
0% {
|
@ -25,12 +25,16 @@ import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { bindActionCreators } from 'redux';
|
||||
import { CSSTransition, TransitionGroup } from 'react-transition-group';
|
||||
import { Button } from './../input/Input';
|
||||
|
||||
import Styles from './Modal.scss';
|
||||
|
||||
import Language from '@public/language/Language';
|
||||
import { openModal, closeModal } from '@public/actions/ModalActions';
|
||||
import { Heading4 } from '@objects/typography/Typography';
|
||||
import Keyboard from '@public/keyboard/Keyboard';
|
||||
|
||||
import { Button } from './../input/Input';
|
||||
import { Heading4 } from '@objects/typography/Typography';
|
||||
|
||||
class Modal extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
@ -50,46 +54,33 @@ class Modal extends React.Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
//Add necessary buttons
|
||||
let buttons = [];
|
||||
if(this.props.buttons) {
|
||||
if(Array.isArray(buttons)) {
|
||||
buttons.concat(this.props.buttons);
|
||||
} else {
|
||||
buttons.push(this.props.buttons);
|
||||
}
|
||||
}
|
||||
let { buttons, closeModal, close, title, children, large, modal } = this.props;
|
||||
|
||||
if(this.props.close) {
|
||||
buttons.push(<Button key="close" onClick={this.props.closeModal}>{ Language.get("modal.close") }</Button>);
|
||||
//Add necessary buttons
|
||||
buttons = buttons || [];
|
||||
if(!Array.isArray(buttons)) buttons = [ buttons ];
|
||||
|
||||
if(close) {
|
||||
buttons.push(<Button key="close" onClick={closeModal}>{ Language.get("modal.close") }</Button>);
|
||||
}
|
||||
|
||||
//Inner divs
|
||||
let heading,body,footer;
|
||||
if(this.props.title) {
|
||||
|
||||
if(title) {
|
||||
heading = (
|
||||
<div className="o-modal__box-heading">
|
||||
<Heading4 className="o-modal__title">
|
||||
{ this.props.title }
|
||||
</Heading4>
|
||||
<Heading4 className="o-modal__title">\{ title }</Heading4>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if(this.props.children) {
|
||||
body = (
|
||||
<div className="o-modal__box-body">
|
||||
{ this.props.children }
|
||||
</div>
|
||||
);
|
||||
if(children) {
|
||||
body = <div className="o-modal__box-body" children={ children } />;
|
||||
}
|
||||
|
||||
if(buttons) {
|
||||
footer = (
|
||||
<div className="o-modal__box-footer">
|
||||
{ buttons }
|
||||
</div>
|
||||
);
|
||||
if(buttons && buttons.length) {
|
||||
footer = <div className="o-modal__box-footer">{ buttons }</div>;
|
||||
}
|
||||
|
||||
//Create our modal contents
|
||||
@ -97,11 +88,11 @@ class Modal extends React.Component {
|
||||
<div className="o-modal">
|
||||
<div className="o-modal__inner">
|
||||
{/* Provides both a good overlay, and a nice clickable area */}
|
||||
<div className="o-modal__backdrop" onClick={this.props.closeModal}>
|
||||
<div className="o-modal__backdrop" onClick={closeModal}>
|
||||
</div>
|
||||
|
||||
{/* Box itself, has a background and a shadow */}
|
||||
<div className={"o-modal__box" + (this.props.large ? " is-large":"")}>
|
||||
<div className={"o-modal__box"+(large ? " is-large":"")}>
|
||||
{ heading }
|
||||
{ body }
|
||||
{ footer }
|
||||
@ -113,7 +104,7 @@ class Modal extends React.Component {
|
||||
//Display?
|
||||
let displayedContents = <div></div>;
|
||||
|
||||
if(this.props.modal.open) {
|
||||
if(modal.open) {
|
||||
displayedContents = (
|
||||
<CSSTransition
|
||||
appear={true}
|
||||
|
@ -10,6 +10,7 @@
|
||||
* Version:
|
||||
* 1.0.0 - 2018/07/05
|
||||
*/
|
||||
@import '~@styles/global';
|
||||
$o-modal--backdrop: rgba(0, 0, 0, 0.7);
|
||||
$o-modal--background: white;
|
||||
|
@ -24,15 +24,15 @@
|
||||
import React from 'react';
|
||||
|
||||
const Heading = (props) => {
|
||||
let level = props.level || 1;
|
||||
let { level, size, className } = props;
|
||||
|
||||
level = level || 1;
|
||||
size = size || 1;
|
||||
|
||||
let CustomTag = "h"+level;
|
||||
let clazz = "o-heading o-heading--"+level;
|
||||
if(props.className) clazz += " " + props.className;
|
||||
|
||||
|
||||
return (
|
||||
<CustomTag {...props} className={clazz} />
|
||||
);
|
||||
let clazz = `o-heading o-heading--${size}`;
|
||||
if(className) clazz += ` ${className}`;
|
||||
return <CustomTag {...props} className={clazz} />;
|
||||
}
|
||||
export default Heading;
|
||||
|
||||
@ -44,10 +44,5 @@ const Heading5 = (props) => { return <Heading {...props} level="5" />; };
|
||||
const Heading6 = (props) => { return <Heading {...props} level="6" />; };
|
||||
|
||||
export {
|
||||
Heading1,
|
||||
Heading2,
|
||||
Heading3,
|
||||
Heading4,
|
||||
Heading5,
|
||||
Heading6
|
||||
Heading1, Heading2, Heading3, Heading4, Heading5, Heading6
|
||||
};
|
||||
|
@ -24,8 +24,6 @@
|
||||
import React from 'react';
|
||||
|
||||
export default (props) => {
|
||||
let clazz = "o-paragraph";
|
||||
if(props.className) clazz += " "+props.className;
|
||||
|
||||
return <p {...props} className={clazz} />
|
||||
let { className } = props;
|
||||
return <p {...props} className={"o-paragraph"+(className?` ${className}`: "")} />;
|
||||
};
|
||||
|
@ -24,9 +24,6 @@
|
||||
import React from 'react';
|
||||
|
||||
export default function(props) {
|
||||
return (
|
||||
<p className={ "o-subtitle" + ( props.className ? " " + props.className : "") }>
|
||||
{ props.children }
|
||||
</p>
|
||||
);
|
||||
let { className } = props;
|
||||
return <p {...props} className={"o-subtitle"+(className?` ${className}`: "")} />;
|
||||
}
|
||||
|
@ -23,10 +23,7 @@
|
||||
|
||||
import React from 'react';
|
||||
|
||||
export default function(props) {
|
||||
return (
|
||||
<h1 className={ "o-title" + ( props.className ? " " + props.className : "") }>
|
||||
{ props.children }
|
||||
</h1>
|
||||
);
|
||||
export default props => {
|
||||
let { className } = props;
|
||||
return <h1 {...props} className={"o-title"+(className?` ${className}`: "")} />
|
||||
}
|
||||
|
@ -21,6 +21,8 @@
|
||||
// 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 Styles from './Typography';
|
||||
|
||||
import Title from './Title';
|
||||
import Subtitle from './Subtitle';
|
||||
import Paragraph from './Paragraph';
|
||||
|
@ -9,6 +9,7 @@
|
||||
* Version:
|
||||
* 1.0.1 - 2018/06/05
|
||||
*/
|
||||
@import '~@styles/global';
|
||||
|
||||
//Font Sizes will scale according to
|
||||
.o-title {
|
@ -36,32 +36,30 @@ export default class Video extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
let { autoPlay, loop, controls } = props;
|
||||
if(typeof autoPlay === typeof undefined) autoPlay;
|
||||
if(typeof loop === typeof undefined) loop;
|
||||
if(typeof controls === typeof undefined) controls;
|
||||
|
||||
//Initial State
|
||||
this.state = {
|
||||
autoPlay: this.props.autoPlay,
|
||||
loop: this.props.loop,
|
||||
autoPlay: autoPlay,
|
||||
loop: loop,
|
||||
loader: false,
|
||||
controls: this.props.controls
|
||||
controls: controls
|
||||
};
|
||||
|
||||
//Bound events (for removing event listeners)
|
||||
this.onPlayingBound = this.onPlaying.bind(this);
|
||||
this.onWaitingBound = this.onWaiting.bind(this);
|
||||
this.onPauseBound = this.onPause.bind(this);
|
||||
this.onSeekedBound = this.onSeeked.bind(this);
|
||||
this.onLoadStartBound = this.onLoadStart.bind(this);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.refs.video.addEventListener('playing', this.onPlayingBound);
|
||||
this.refs.video.addEventListener('waiting', this.onWaitingBound);
|
||||
this.refs.video.addEventListener('seeked', this.onSeekedBound);
|
||||
this.refs.video.addEventListener('pause', this.onPauseBound);
|
||||
this.refs.video.addEventListener('loadstart', this.onLoadStartBound);
|
||||
let { video } = this.refs;
|
||||
video.addEventListener('playing', () => this.onPlaying() );
|
||||
video.addEventListener('waiting', () => this.onWaiting() );
|
||||
video.addEventListener('seeked', () => this.onSeeked() );
|
||||
video.addEventListener('pause', () => this.onPause() );
|
||||
video.addEventListener('loadstart',() => this.onLoadStart() );
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
|
||||
}
|
||||
|
||||
//Standard Events - https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Media_events
|
||||
@ -103,21 +101,22 @@ export default class Video extends React.Component {
|
||||
|
||||
//React Render
|
||||
render() {
|
||||
//TODO: Add state support, as well as functional controls.
|
||||
let { autoPlay, loop } = this.state;
|
||||
let newProps = {...this.props};
|
||||
let { sources, className, gif, image } = this.props;
|
||||
|
||||
//Sources
|
||||
let sources = [];
|
||||
let sourceProps = this.props.sources ? this.props.sources : this.props;
|
||||
sources = sources || [];
|
||||
let sourceElements = [];
|
||||
|
||||
for(let i = 0; i < VALID_SOURCES.length; i++) {
|
||||
let s = VALID_SOURCES[i];
|
||||
if(!sourceProps[s]) continue;
|
||||
sources.push(<source type={"video/"+s} src={sourceProps[s]} key={s} />);
|
||||
sourceElements.push(<source type={"video/"+s} src={sourceProps[s]} key={s} />);
|
||||
}
|
||||
|
||||
//Classes
|
||||
let clazz = "o-video";
|
||||
if(this.props.className) clazz += " " + this.props.className;
|
||||
if(className) clazz += ` ${className}`;
|
||||
if(sourceProps.image) clazz += " has-image";
|
||||
if(sourceProps.gif) clazz += " has-gif";
|
||||
if(this.state.autoplay) clazz += " is-autoplaying";
|
||||
|
@ -10,6 +10,8 @@
|
||||
* Version:
|
||||
* 1.0.0 - 2018/05/07
|
||||
*/
|
||||
@import '~@styles/global';
|
||||
|
||||
%o-video__media-cover {
|
||||
position: absolute;
|
||||
top: 0;
|
@ -47,7 +47,7 @@ import { Title, Heading1, Paragraph } from '@objects/typography/Typography';
|
||||
import Input, {
|
||||
Form,
|
||||
FormManager,
|
||||
InputGroup,
|
||||
FormGroup,
|
||||
TextArea,
|
||||
Label,
|
||||
ButtonGroup
|
||||
@ -109,7 +109,7 @@ class ContactPage extends React.Component {
|
||||
onError={ this.onError.bind(this) }
|
||||
manager={ this.manager }
|
||||
>
|
||||
<InputGroup test="First Group">
|
||||
<FormGroup test="First Group">
|
||||
<Label htmlFor="name">
|
||||
{ Language.get("pages.contact.name.label") }
|
||||
</Label>
|
||||
@ -121,9 +121,9 @@ class ContactPage extends React.Component {
|
||||
maxLength={ Forms.contact.name.maxLength }
|
||||
manager={ this.manager }
|
||||
/>
|
||||
</InputGroup>
|
||||
</FormGroup>
|
||||
|
||||
<InputGroup >
|
||||
<FormGroup >
|
||||
<Label htmlFor="email">
|
||||
{ Language.get("pages.contact.email.label") }
|
||||
</Label>
|
||||
@ -135,9 +135,9 @@ class ContactPage extends React.Component {
|
||||
maxLength={ Forms.contact.email.maxLength }
|
||||
manager={ this.manager }
|
||||
/>
|
||||
</InputGroup>
|
||||
</FormGroup>
|
||||
|
||||
<InputGroup>
|
||||
<FormGroup>
|
||||
<Label> htmlFor="message">
|
||||
{ Language.get("pages.contact.message.label") }
|
||||
</Label>
|
||||
@ -150,7 +150,7 @@ class ContactPage extends React.Component {
|
||||
maxLength={ Forms.contact.message.maxLength }
|
||||
manager={ this.manager }
|
||||
/>
|
||||
</InputGroup>
|
||||
</FormGroup>
|
||||
|
||||
<ButtonGroup>
|
||||
<Input type="submit" value={ Language.get("pages.contact.send") } primary="true" />
|
||||
|
@ -1,26 +0,0 @@
|
||||
/*
|
||||
* Background
|
||||
* Styles for the background of the site.
|
||||
*
|
||||
* Dependencies:
|
||||
* styles/settings/z.scss
|
||||
* styles/tools/_absolute-centering.scss
|
||||
*
|
||||
* Version:
|
||||
* 1.0.0 - 2018/05/17
|
||||
*/
|
||||
.o-background {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: $s-z--background;
|
||||
overflow: hidden;
|
||||
|
||||
&__inner {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user