Preview: http://dashboards.webkom.co/react/airframe
This commit is contained in:
Tomasz Owczarczyk
2019-08-15 00:54:44 +02:00
parent f975443095
commit 37092d1d6c
626 changed files with 56691 additions and 0 deletions

View File

@@ -0,0 +1,25 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Consumer } from './ThemeContext';
const ThemeClass = ({ children, color, style }) => {
const layoutThemeClass = `layout--theme--${ style }--${ color }`;
return children(layoutThemeClass);
};
ThemeClass.propTypes = {
children: PropTypes.func.isRequired,
color: PropTypes.string,
style: PropTypes.string,
};
const ContextThemeClass = (otherProps) =>
<Consumer>
{
(themeState) => <ThemeClass {...{ ...themeState, ...otherProps }}/>
}
</Consumer>;
export { ContextThemeClass as ThemeClass };

View File

@@ -0,0 +1,5 @@
import React from 'react';
const { Provider, Consumer } = React.createContext();
export { Provider, Consumer };

View File

@@ -0,0 +1,51 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Provider } from './ThemeContext';
export class ThemeProvider extends React.Component {
static propTypes = {
children: PropTypes.node,
initialStyle: PropTypes.string,
initialColor: PropTypes.string,
};
constructor(props) {
super(props);
this.state = {
style: 'light',
color: 'primary',
};
}
componentDidMount() {
const { initialStyle, initialColor } = this.props;
if (initialStyle) {
this.setState({ style: initialStyle });
}
if (initialColor) {
this.setState({ color: initialColor });
}
}
onChangeTheme(themeState) {
this.setState(themeState);
}
render() {
const { children } = this.props;
return (
<Provider
value={{
...this.state,
onChangeTheme: this.onChangeTheme.bind(this)
}}
>
{ children }
</Provider>
);
}
}

View File

@@ -0,0 +1,166 @@
import React from 'react';
import _ from 'lodash';
import classNames from 'classnames';
import PropTypes from 'prop-types';
import {
Card,
CardBody,
Button,
FormGroup,
CustomInput
} from 'reactstrap';
import './../../styles/components/theme-selector.scss';
import { Consumer } from './ThemeContext';
class ThemeSelector extends React.Component {
static propTypes = {
style: PropTypes.string.isRequired,
color: PropTypes.string.isRequired,
styleOptions: PropTypes.array,
styleDisabled: PropTypes.bool,
colorOptions: PropTypes.array,
onChangeTheme: PropTypes.func,
};
static defaultProps = {
styleOptions: [
{ name: 'Light', value: 'light' },
{ name: 'Dark', value: 'dark' },
{ name: 'Color', value: 'color' }
],
colorOptions: [
{ name: 'Primary', value: 'primary' },
{ name: 'Success', value: 'success' },
{ name: 'Info', value: 'info' },
{ name: 'Danger', value: 'danger' },
{ name: 'Warning', value: 'warning' },
{ name: 'Indigo', value: 'indigo' },
{ name: 'Purple', value: 'purple' },
{ name: 'Pink', value: 'pink' },
{ name: 'Yellow', value: 'yellow' }
]
};
constructor(props) {
super(props);
this.state = {
isActive: false,
initialStyle: '',
initialColor: '',
};
}
componentDidMount() {
this.setState({
initialColor: this.props.color,
initialStyle: this.props.style
});
}
render() {
const rootClass = classNames('theme-config', {
'theme-config--active': this.state.isActive,
});
return (
<div className={ rootClass }>
<Button
color="primary"
className="theme-config__trigger"
onClick={() => { this.setState({isActive: !this.state.isActive}) }}
>
<i className="fa fa-paint-brush fa-fw"></i>
</Button>
<Card className="theme-config__body">
<CardBody>
<h6 className="text-center mb-3">
Configurator
</h6>
<FormGroup>
<span className="h6 small mb-2 d-block">
Nav Color
</span>
{
_.map(this.props.colorOptions, (option, index) => (
<CustomInput
key={ index }
type="radio"
name="sidebarColor"
id={ `sidebarStyle--${option.value}` }
value={ option.value }
checked={ this.props.color === option.value }
onChange={(ev) => {
if (ev.target.checked) {
this.props.onChangeTheme({
color: option.value
});
}
}}
label={(
<span className="d-flex align-items-center">
{ option.name }
<i className={`fa fa-circle ml-auto text-${option.value}`} />
</span>
)}
/>
))
}
</FormGroup>
<FormGroup>
<span className="h6 small mb-2 d-block">
Nav Style
</span>
{
_.map(this.props.styleOptions, (option, index) => (
<CustomInput
key={ index }
type="radio"
name="sidebarStyle"
id={ `sidebarStyle--${option.value}` }
value={ option.value }
disabled={ this.props.styleDisabled }
checked={ this.props.style === option.value }
onChange={(ev) => {
if (ev.target.checked) {
this.props.onChangeTheme({
style: option.value
});
}
}}
label={ option.name }
/>
))
}
</FormGroup>
<FormGroup className="mb-0">
<Button
color="secondary"
outline
className="d-block w-100"
onClick={() => {
this.props.onChangeTheme({
color: this.state.initialColor,
style: this.state.initialStyle
});
}}
>
Reset Options
</Button>
</FormGroup>
</CardBody>
</Card>
</div>
);
}
}
const ContextThemeSelector = (props) =>
<Consumer>
{
(themeState) => <ThemeSelector { ...themeState } { ...props } />
}
</Consumer>
export { ContextThemeSelector as ThemeSelector };

4
app/components/Theme/index.js Executable file
View File

@@ -0,0 +1,4 @@
export * from './ThemeClass';
export * from './ThemeSelector';
export * from './ThemeProvider';
export { Consumer as ThemeConsumer } from './ThemeContext';