add theme to preferences, add backbone of themes to scss
This commit is contained in:
parent
f48b872500
commit
103ebd2014
10 changed files with 195 additions and 19 deletions
|
@ -81,6 +81,7 @@ export const CLOSE_KEYBOARD_SHORTCUT_MODAL = 'CLOSE_KEYBOARD_SHORTCUT_MODAL';
|
||||||
export const SHOW_TOAST = 'SHOW_TOAST';
|
export const SHOW_TOAST = 'SHOW_TOAST';
|
||||||
export const HIDE_TOAST = 'HIDE_TOAST';
|
export const HIDE_TOAST = 'HIDE_TOAST';
|
||||||
export const SET_TOAST_TEXT = 'SET_TOAST_TEXT';
|
export const SET_TOAST_TEXT = 'SET_TOAST_TEXT';
|
||||||
|
export const SET_THEME = 'SET_THEME';
|
||||||
|
|
||||||
export const SET_UNSAVED_CHANGES = 'SET_UNSAVED_CHANGES';
|
export const SET_UNSAVED_CHANGES = 'SET_UNSAVED_CHANGES';
|
||||||
|
|
||||||
|
|
|
@ -136,3 +136,11 @@ export function setTextOutput(value) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function setTheme(value) {
|
||||||
|
return {
|
||||||
|
type: ActionTypes.SET_THEME,
|
||||||
|
value
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -165,6 +165,33 @@ class Preferences extends React.Component {
|
||||||
<label htmlFor="autosave-off" className="preference__option">Off</label>
|
<label htmlFor="autosave-off" className="preference__option">Off</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="preference">
|
||||||
|
<h4 className="preference__title">Theme</h4>
|
||||||
|
<div className="preference__options">
|
||||||
|
<input
|
||||||
|
type="radio"
|
||||||
|
onChange={() => this.props.setTheme('light')}
|
||||||
|
aria-label="light theme on"
|
||||||
|
name="light theme"
|
||||||
|
id="light-theme-on"
|
||||||
|
className="preference__radio-button"
|
||||||
|
value="light"
|
||||||
|
checked={this.props.theme === 'light'}
|
||||||
|
/>
|
||||||
|
<label htmlFor="light-theme-on" className="preference__option">Light</label>
|
||||||
|
<input
|
||||||
|
type="radio"
|
||||||
|
onChange={() => this.props.setTheme('dark')}
|
||||||
|
aria-label="dark theme on"
|
||||||
|
name="dark theme"
|
||||||
|
id="dark-theme-on"
|
||||||
|
className="preference__radio-button"
|
||||||
|
value="dark"
|
||||||
|
checked={this.props.theme === 'dark'}
|
||||||
|
/>
|
||||||
|
<label htmlFor="dark-theme-on" className="preference__option">Dark</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div className="preference">
|
<div className="preference">
|
||||||
<h4 className="preference__title">Lint Warning Sound</h4>
|
<h4 className="preference__title">Lint Warning Sound</h4>
|
||||||
<div className="preference__options">
|
<div className="preference__options">
|
||||||
|
@ -249,7 +276,9 @@ Preferences.propTypes = {
|
||||||
textOutput: PropTypes.bool.isRequired,
|
textOutput: PropTypes.bool.isRequired,
|
||||||
setTextOutput: PropTypes.func.isRequired,
|
setTextOutput: PropTypes.func.isRequired,
|
||||||
lintWarning: PropTypes.bool.isRequired,
|
lintWarning: PropTypes.bool.isRequired,
|
||||||
setLintWarning: PropTypes.func.isRequired
|
setLintWarning: PropTypes.func.isRequired,
|
||||||
|
theme: PropTypes.string.isRequired,
|
||||||
|
setTheme: PropTypes.func.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Preferences;
|
export default Preferences;
|
||||||
|
|
|
@ -27,6 +27,7 @@ import SplitPane from 'react-split-pane';
|
||||||
import Overlay from '../../App/components/Overlay';
|
import Overlay from '../../App/components/Overlay';
|
||||||
import SketchList from '../components/SketchList';
|
import SketchList from '../components/SketchList';
|
||||||
import About from '../components/About';
|
import About from '../components/About';
|
||||||
|
import classNames from 'classnames';
|
||||||
|
|
||||||
class IDEView extends React.Component {
|
class IDEView extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
|
@ -156,8 +157,13 @@ class IDEView extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
let ideClass = classNames({
|
||||||
|
ide: true,
|
||||||
|
light: this.props.preferences.theme === 'light',
|
||||||
|
dark: this.props.preferences.theme === 'dark',
|
||||||
|
});
|
||||||
return (
|
return (
|
||||||
<div className="ide">
|
<div className={ideClass}>
|
||||||
{this.props.toast.isVisible && <Toast />}
|
{this.props.toast.isVisible && <Toast />}
|
||||||
<Nav
|
<Nav
|
||||||
user={this.props.user}
|
user={this.props.user}
|
||||||
|
@ -203,6 +209,8 @@ class IDEView extends React.Component {
|
||||||
setLintWarning={this.props.setLintWarning}
|
setLintWarning={this.props.setLintWarning}
|
||||||
textOutput={this.props.preferences.textOutput}
|
textOutput={this.props.preferences.textOutput}
|
||||||
setTextOutput={this.props.setTextOutput}
|
setTextOutput={this.props.setTextOutput}
|
||||||
|
theme={this.props.preferences.theme}
|
||||||
|
setTheme={this.props.setTheme}
|
||||||
/>
|
/>
|
||||||
<div className="editor-preview-container">
|
<div className="editor-preview-container">
|
||||||
<SplitPane
|
<SplitPane
|
||||||
|
@ -432,7 +440,8 @@ IDEView.propTypes = {
|
||||||
isTabIndent: PropTypes.bool.isRequired,
|
isTabIndent: PropTypes.bool.isRequired,
|
||||||
autosave: PropTypes.bool.isRequired,
|
autosave: PropTypes.bool.isRequired,
|
||||||
lintWarning: PropTypes.bool.isRequired,
|
lintWarning: PropTypes.bool.isRequired,
|
||||||
textOutput: PropTypes.bool.isRequired
|
textOutput: PropTypes.bool.isRequired,
|
||||||
|
theme: PropTypes.string.isRequired
|
||||||
}).isRequired,
|
}).isRequired,
|
||||||
closePreferences: PropTypes.func.isRequired,
|
closePreferences: PropTypes.func.isRequired,
|
||||||
setFontSize: PropTypes.func.isRequired,
|
setFontSize: PropTypes.func.isRequired,
|
||||||
|
@ -492,7 +501,8 @@ IDEView.propTypes = {
|
||||||
setRouteLeaveHook: PropTypes.func
|
setRouteLeaveHook: PropTypes.func
|
||||||
}).isRequired,
|
}).isRequired,
|
||||||
route: PropTypes.object.isRequired,
|
route: PropTypes.object.isRequired,
|
||||||
setUnsavedChanges: PropTypes.func.isRequired
|
setUnsavedChanges: PropTypes.func.isRequired,
|
||||||
|
setTheme: PropTypes.func.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
function mapStateToProps(state) {
|
function mapStateToProps(state) {
|
||||||
|
|
|
@ -6,7 +6,8 @@ const initialState = {
|
||||||
isTabIndent: true,
|
isTabIndent: true,
|
||||||
autosave: true,
|
autosave: true,
|
||||||
lintWarning: false,
|
lintWarning: false,
|
||||||
textOutput: false
|
textOutput: false,
|
||||||
|
theme: 'light'
|
||||||
};
|
};
|
||||||
|
|
||||||
const preferences = (state = initialState, action) => {
|
const preferences = (state = initialState, action) => {
|
||||||
|
@ -31,6 +32,8 @@ const preferences = (state = initialState, action) => {
|
||||||
return Object.assign({}, state, { textOutput: action.value });
|
return Object.assign({}, state, { textOutput: action.value });
|
||||||
case ActionTypes.SET_PREFERENCES:
|
case ActionTypes.SET_PREFERENCES:
|
||||||
return action.preferences;
|
return action.preferences;
|
||||||
|
case ActionTypes.SET_THEME:
|
||||||
|
return Object.assign({}, state, { theme: action.value });
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
26
client/styles/abstracts/_functions.scss
Normal file
26
client/styles/abstracts/_functions.scss
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
@function map-fetch($map, $keys) {
|
||||||
|
$key: nth($keys, 1);
|
||||||
|
$length: length($keys);
|
||||||
|
$value: map-get($map, $key);
|
||||||
|
|
||||||
|
|
||||||
|
@if $value != null {
|
||||||
|
@if $length > 1 {
|
||||||
|
$rest: ();
|
||||||
|
|
||||||
|
@for $i from 2 through $length {
|
||||||
|
$rest: append($rest, nth($keys, $i))
|
||||||
|
}
|
||||||
|
|
||||||
|
@return map-fetch($value, $rest);
|
||||||
|
} @else {
|
||||||
|
@return $value;
|
||||||
|
}
|
||||||
|
} @else {
|
||||||
|
@return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@function getThemifyVariable($key) {
|
||||||
|
@return map-get($theme-map, $key);
|
||||||
|
}
|
20
client/styles/abstracts/_mixins.scss
Normal file
20
client/styles/abstracts/_mixins.scss
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
@mixin themify ($themes: $themes) {
|
||||||
|
@each $theme, $map in $themes {
|
||||||
|
.#{$theme} & {
|
||||||
|
// Define theme color
|
||||||
|
$theme-map : (
|
||||||
|
color-alpha: blue
|
||||||
|
) !global;
|
||||||
|
|
||||||
|
@each $key, $submap in $map {
|
||||||
|
$value: map-fetch($themes, $theme '#{$key}');
|
||||||
|
$theme-map: map-merge($theme-map, ($key: $value)) !global;
|
||||||
|
}
|
||||||
|
|
||||||
|
@content;
|
||||||
|
|
||||||
|
// reset theme color to null
|
||||||
|
$theme-map: null !global;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,6 +5,95 @@ $p5js-pink: #ed225d;
|
||||||
$white: #fff;
|
$white: #fff;
|
||||||
$black: #000;
|
$black: #000;
|
||||||
|
|
||||||
|
$themes: (
|
||||||
|
light: (
|
||||||
|
primary-text-color: #333,
|
||||||
|
secondary-text-color: #6b6b6b,
|
||||||
|
inactive-text-color: #b5b5b5,
|
||||||
|
background-color: #fdfdfd,
|
||||||
|
button-background-color: #f4f4f4,
|
||||||
|
button-color: $black,
|
||||||
|
button-border-color: #979797,
|
||||||
|
toolbar-button-color: $p5js-pink,
|
||||||
|
button-background-hover-color: $p5js-pink,
|
||||||
|
button-background-active-color: #f10046,
|
||||||
|
button-hover-color: $white,
|
||||||
|
button-active-color: $white,
|
||||||
|
modal-background-color: #f4f4f4,
|
||||||
|
modal-button-background-color: #e6e6e6,
|
||||||
|
modal-border-color: #B9D0E1,
|
||||||
|
icon-color: #8b8b8b,
|
||||||
|
icon-hover-color: #333,
|
||||||
|
shadow-color: rgba(0, 0, 0, 0.16),
|
||||||
|
console-background-color: #eee,
|
||||||
|
console-header-background-color: #d6d6d6,
|
||||||
|
ide-border-color: #f4f4f4,
|
||||||
|
),
|
||||||
|
dark: (
|
||||||
|
primary-text-color: $white,
|
||||||
|
secondary-text-color: #c2c2c2,
|
||||||
|
inactive-text-color: #7d7d7d,
|
||||||
|
background-color: #333,
|
||||||
|
button-background-color: $white,
|
||||||
|
button-color: $black,
|
||||||
|
button-border-color: #979797,
|
||||||
|
toolbar-button-color: $p5js-pink,
|
||||||
|
button-background-hover-color: $p5js-pink,
|
||||||
|
button-background-active-color: #f10046,
|
||||||
|
button-hover-color: $white,
|
||||||
|
button-active-color: $white,
|
||||||
|
modal-background-color: #444,
|
||||||
|
modal-button-background-color: #5f5f5f,
|
||||||
|
modal-border-color: #949494,
|
||||||
|
icon-color: #a9a9a9,
|
||||||
|
icon-hover-color: $white,
|
||||||
|
shadow-color: rgba(0, 0, 0, 0.16),
|
||||||
|
console-background-color: #4f4f4f,
|
||||||
|
console-header-background-color: #3f3f3f,
|
||||||
|
console-header-color: #b5b5b5,
|
||||||
|
ide-border-color: #949494,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$primary-text-color: #333;
|
||||||
|
$secondary-text-color: #6b6b6b;
|
||||||
|
$inactive-text-color: #b5b5b5;
|
||||||
|
$background-color: #fdfdfd;
|
||||||
|
$button-background-color: #f4f4f4;
|
||||||
|
$button-color: $black;
|
||||||
|
$button-border-color: #979797;
|
||||||
|
$toolbar-button-color: $p5js-pink;
|
||||||
|
$button-background-hover-color: $p5js-pink;
|
||||||
|
$button-background-active-color: #f10046;
|
||||||
|
$button-hover-color: $white;
|
||||||
|
$button-active-color: $white;
|
||||||
|
$modal-background-color: #f4f4f4;
|
||||||
|
$modal-button-background-color: #e6e6e6;
|
||||||
|
$modal-border-color: #B9D0E1;
|
||||||
|
$icon-color: #8b8b8b;
|
||||||
|
$icon-hover-color: #333;
|
||||||
|
$shadow-color: rgba(0, 0, 0, 0.16);
|
||||||
|
$console-background-color: #eee;
|
||||||
|
$console-header-background-color: #d6d6d6;
|
||||||
|
$ide-border-color: #f4f4f4;
|
||||||
|
|
||||||
|
|
||||||
|
// other variables i may or may not need later
|
||||||
|
$ide-border-color: #f4f4f4;
|
||||||
|
$editor-selected-line-color: #f3f3f3;
|
||||||
|
$input-border-color: #979797;
|
||||||
|
|
||||||
|
$console-light-background-color: #eee;
|
||||||
|
$console-header-background-color: #d6d6d6;
|
||||||
|
$console-header-color: #b1b1b1;
|
||||||
|
$console-warn-color: #ffbe05;
|
||||||
|
$console-error-color: #ff5f52;
|
||||||
|
|
||||||
|
$toast-background-color: #979797;
|
||||||
|
$toast-text-color: $white;
|
||||||
|
|
||||||
|
//light and dark colors
|
||||||
|
|
||||||
$light-primary-text-color: #333;
|
$light-primary-text-color: #333;
|
||||||
$light-secondary-text-color: #6b6b6b;
|
$light-secondary-text-color: #6b6b6b;
|
||||||
$light-inactive-text-color: #b5b5b5;
|
$light-inactive-text-color: #b5b5b5;
|
||||||
|
@ -25,9 +114,6 @@ $light-icon-color: #8b8b8b;
|
||||||
$light-icon-hover-color: $light-primary-text-color;
|
$light-icon-hover-color: $light-primary-text-color;
|
||||||
$light-shadow-color: rgba(0, 0, 0, 0.16);
|
$light-shadow-color: rgba(0, 0, 0, 0.16);
|
||||||
|
|
||||||
$toast-background-color: #979797;
|
|
||||||
$toast-text-color: $white;
|
|
||||||
|
|
||||||
$dark-primary-text-color: $white;
|
$dark-primary-text-color: $white;
|
||||||
$dark-secondary-text-color: #c2c2c2;
|
$dark-secondary-text-color: #c2c2c2;
|
||||||
$dark-inactive-color: #7d7d7d;
|
$dark-inactive-color: #7d7d7d;
|
||||||
|
@ -41,13 +127,3 @@ $dark-button-background-active-color: #f10046;
|
||||||
$dark-button-hover-color: $white;
|
$dark-button-hover-color: $white;
|
||||||
$dark-button-active-color: $white;
|
$dark-button-active-color: $white;
|
||||||
|
|
||||||
$ide-border-color: #f4f4f4;
|
|
||||||
$editor-selected-line-color: #f3f3f3;
|
|
||||||
$input-border-color: #979797;
|
|
||||||
|
|
||||||
$console-light-background-color: #eee;
|
|
||||||
$console-header-background-color: #d6d6d6;
|
|
||||||
$console-header-color: #b1b1b1;
|
|
||||||
$console-warn-color: #ffbe05;
|
|
||||||
$console-error-color: #ff5f52;
|
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
@import 'abstracts/variables';
|
@import 'abstracts/variables';
|
||||||
|
@import 'abstracts/functions';
|
||||||
|
@import 'abstracts/mixins';
|
||||||
@import 'abstracts/placeholders';
|
@import 'abstracts/placeholders';
|
||||||
|
|
||||||
@import 'base/reset';
|
@import 'base/reset';
|
||||||
|
|
|
@ -15,7 +15,8 @@ const userSchema = new Schema({
|
||||||
isTabIndent: { type: Boolean, default: false },
|
isTabIndent: { type: Boolean, default: false },
|
||||||
autosave: { type: Boolean, default: true },
|
autosave: { type: Boolean, default: true },
|
||||||
lintWarning: { type: Boolean, default: false },
|
lintWarning: { type: Boolean, default: false },
|
||||||
textOutput: { type: Boolean, default: false }
|
textOutput: { type: Boolean, default: false },
|
||||||
|
theme: { type: String, default: 'light' }
|
||||||
}
|
}
|
||||||
}, { timestamps: true });
|
}, { timestamps: true });
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue