Merge pull request #3 from dawnlabs/window-themes

- Window themes
- Better defaults
- Editor styling consistency
main
Jake Dexheimer 7 years ago committed by GitHub
commit d6d65df044

@ -2,7 +2,7 @@ import { EOL } from 'os'
import React from 'react' import React from 'react'
import domtoimage from 'dom-to-image' import domtoimage from 'dom-to-image'
import CodeMirror from 'react-codemirror' import CodeMirror from 'react-codemirror'
import WindowControls from '../components/svg/Controls' import WindowControls from '../components/WindowControls'
import Spinner from 'react-spinner' import Spinner from 'react-spinner'
const DEFAULT_SETTINGS = { const DEFAULT_SETTINGS = {
@ -15,8 +15,7 @@ const DEFAULT_SETTINGS = {
language: 'javascript' language: 'javascript'
} }
class CodeImage extends React.Component { class CodeImage extends React.Component {
constructor (props) { constructor (props) {
super(props) super(props)
@ -64,9 +63,9 @@ const DEFAULT_SETTINGS = {
if (this.state.loading === false) { if (this.state.loading === false) {
content = ( content = (
<div id="container" style={containerStyle}> <div id="container" style={containerStyle}>
{ config.windowControls ? <WindowControls /> : null } { config.windowControls ? <WindowControls theme={config.windowTheme} /> : null }
<CodeMirror <CodeMirror
className={`CodeMirror__container ${config.dropShadow ? 'dropshadow' : ''}`} className={`CodeMirror__container window-theme__${config.windowTheme} ${config.dropShadow ? 'dropshadow' : ''}`}
value={this.props.children} value={this.props.children}
options={options} options={options}
/> />

@ -1,6 +1,7 @@
import React from 'react' import React from 'react'
import enhanceWithClickOutside from 'react-click-outside' import enhanceWithClickOutside from 'react-click-outside'
import { TwitterPicker } from 'react-color' import { TwitterPicker } from 'react-color'
import WindowPointer from './WindowPointer'
import { PALETTE } from '../lib/constants' import { PALETTE } from '../lib/constants'
class ColorPicker extends React.Component { class ColorPicker extends React.Component {
@ -20,7 +21,6 @@ class ColorPicker extends React.Component {
} }
handlePickColor(color) { handlePickColor(color) {
this.setState({ isVisible: false })
this.props.onChange(color.hex) this.props.onChange(color.hex)
} }
@ -34,7 +34,8 @@ class ColorPicker extends React.Component {
<div className="bg-color" style={{background: this.props.bg}} onClick={this.toggle}></div> <div className="bg-color" style={{background: this.props.bg}} onClick={this.toggle}></div>
</div> </div>
<div className="colorpicker-picker" hidden={!this.state.isVisible}> <div className="colorpicker-picker" hidden={!this.state.isVisible}>
<TwitterPicker color={this.props.bg} onChangeComplete={this.handlePickColor} /> <WindowPointer fromLeft="15px" />
<TwitterPicker color={this.props.bg} onChangeComplete={this.handlePickColor} triangle="hide" />
</div> </div>
<style jsx>{` <style jsx>{`
.colorpicker-container { .colorpicker-container {
@ -69,8 +70,8 @@ class ColorPicker extends React.Component {
.colorpicker-picker { .colorpicker-picker {
position: absolute; position: absolute;
margin-left: 32px; margin-left: 36px;
margin-top: 10px; margin-top: 4px;
} }
`}</style> `}</style>
</div> </div>

@ -101,10 +101,6 @@ class Dropdown extends React.Component {
z-index: 1; z-index: 1;
} }
.dropdown-display:hover {
background: #131313;
}
.is-visible + .dropdown-list { .is-visible + .dropdown-list {
display: block; display: block;
} }

@ -52,9 +52,13 @@ export default () => (
border-bottom: solid 1px ${PALETTE.SECONDARY}; border-bottom: solid 1px ${PALETTE.SECONDARY};
} }
.settings-settings > div:first-child {
border-bottom: none;
}
.selected svg { .selected svg {
border-radius: 3px; border-radius: 3px;
border: solid 2px #fff; border: solid 2px ${PALETTE.SECONDARY};
} }
.CodeMirror__container.dropshadow { .CodeMirror__container.dropshadow {
@ -71,6 +75,14 @@ export default () => (
font-size: 0.7rem; font-size: 0.7rem;
} }
.window-theme__sharp > .CodeMirror {
border-radius: 0px;
}
.window-theme__bw > .CodeMirror {
border: 2px solid ${PALETTE.SECONDARY};
}
.window-controls + .CodeMirror__container > .CodeMirror { .window-controls + .CodeMirror__container > .CodeMirror {
padding-top: 40px; padding-top: 40px;
} }
@ -78,6 +90,33 @@ export default () => (
.cm-s-dracula .CodeMirror-cursor { .cm-s-dracula .CodeMirror-cursor {
border-left: solid 2px #159588; border-left: solid 2px #159588;
} }
/* Colorpicker overrides */
.twitter-picker {
width: 278px !important;
border: 0.5px solid ${PALETTE.SECONDARY} !important;
border-radius: 3px !important;
background: #1A1A1A !important;
}
.colorpicker-picker > div > div:nth-child(3) > div:nth-child(11) {
background: #1A1A1A !important;
border: 0.5px solid ${PALETTE.SECONDARY} !important;
border-right: none !important;
border-radius: 3px 0 0 3px !important;
color: ${PALETTE.SECONDARY} !important;
}
#toolbar > div.colorpicker-container > div.colorpicker-picker > div > div:nth-child(3) > div:nth-child(12) > input {
background: rgba(255, 255, 255, 0.165) !important;
height: 30px !important;
width: 108px !important;
color: #fff !important;
}
#toolbar > div.colorpicker-container > div.colorpicker-picker > div > div:nth-child(3) > span > div {
border-radius: 2px !important;
}
`}</style> `}</style>
</div> </div>
) )

@ -4,6 +4,7 @@ import SettingsIcon from './svg/Settings'
import ThemeSelect from './ThemeSelect' import ThemeSelect from './ThemeSelect'
import Slider from './Slider' import Slider from './Slider'
import Toggle from './Toggle' import Toggle from './Toggle'
import WindowPointer from './WindowPointer';
import { PALETTE } from '../lib/constants' import { PALETTE } from '../lib/constants'
class Settings extends React.Component { class Settings extends React.Component {
@ -30,7 +31,8 @@ class Settings extends React.Component {
<SettingsIcon /> <SettingsIcon />
</div> </div>
<div className="settings-settings"> <div className="settings-settings">
<ThemeSelect onChange={this.props.onChange} /> <WindowPointer fromLeft="15px" />
<ThemeSelect onChange={this.props.onChange.bind(null, 'windowTheme')} />
<Toggle label="Drop shadow" <Toggle label="Drop shadow"
enabled={this.props.enabled.dropShadow} enabled={this.props.enabled.dropShadow}
onChange={this.props.onChange.bind(null, 'dropShadow')} onChange={this.props.onChange.bind(null, 'dropShadow')}
@ -69,10 +71,6 @@ class Settings extends React.Component {
cursor: pointer; cursor: pointer;
} }
.settings-display:hover {
background: #131313;
}
.is-visible + .settings-settings { .is-visible + .settings-settings {
display: block; display: block;
} }
@ -80,7 +78,7 @@ class Settings extends React.Component {
.settings-settings { .settings-settings {
display: none; display: none;
position: absolute; position: absolute;
top: 48px; top: 44px;
left: 0; left: 0;
border: 0.5px solid ${PALETTE.SECONDARY}; border: 0.5px solid ${PALETTE.SECONDARY};
width: 184px; width: 184px;

@ -1,12 +1,13 @@
import React from 'react' import React from 'react'
import { Hyper, BW, None } from './svg/Themes' import { None, BW, Sharp } from './svg/WindowThemes'
const THEME_IMGS = [None, Hyper, BW] const WINDOW_THEMES_MAP = { none: None, sharp: Sharp, bw: BW }
export const WINDOW_THEMES = Object.keys(WINDOW_THEMES_MAP)
export default class extends React.Component { export default class extends React.Component {
constructor(props) { constructor(props) {
super() super()
this.state = { selected: props.selected || THEME_IMGS[0] } this.state = { selected: props.selected || WINDOW_THEMES[0] }
this.select = this.select.bind(this) this.select = this.select.bind(this)
} }
@ -18,27 +19,34 @@ export default class extends React.Component {
} }
renderThemes() { renderThemes() {
return THEME_IMGS.map((Img, i) => ( return WINDOW_THEMES.map((theme, i) => {
<div className={`theme ${this.state.selected === Img ? "selected" : ""}`} const Img = WINDOW_THEMES_MAP[theme]
key={i} onClick={this.select.bind(null, Img)}> return (
<Img/> <div
<style jsx>{` className={`theme ${this.state.selected === theme ? "selected" : ""}`}
.theme { key={i}
margin-right: 8px; onClick={this.select.bind(null, theme)}
} >
<Img />
<style jsx>{`
.theme {
cursor: pointer;
margin-right: 8px;
}
.theme:last-of-type { .theme:last-of-type {
margin-right: 0px; margin-right: 0px;
} }
`}</style> `}</style>
</div> </div>
)) )
})
} }
render() { render() {
return ( return (
<div className="window-theme"> <div className="window-theme">
<span className="label">Theme</span> <span className="label">Window Theme</span>
<div className="themes"> <div className="themes">
{ this.renderThemes() } { this.renderThemes() }
</div> </div>

@ -1,6 +1,6 @@
import React from 'react' import React from 'react'
import Dropdown from './Dropdown' import Dropdown from './Dropdown'
import ColorPicker from './Colorpicker' import ColorPicker from './ColorPicker'
import Settings from './Settings' import Settings from './Settings'
import Button from './Button' import Button from './Button'
import CopyButton from './CopyButton' import CopyButton from './CopyButton'

@ -0,0 +1,18 @@
import React from 'react'
import { Controls, ControlsBW } from './svg/Controls'
export default ({ theme }) => (
<div className="window-controls">
{ theme === 'bw' ? <ControlsBW /> : <Controls /> }
<style jsx>{`
div {
margin-top: -19px;
position: relative;
top: +30px;
margin-left: 18px;
z-index: 1;
}
`}
</style>
</div>
)

@ -0,0 +1,19 @@
import React from 'react'
export default ({ fromLeft }) => (
<div style={{ left: fromLeft }}>
<div className="window-pointer" />
<style jsx>{`
.window-pointer {
width: 0px;
height: 0px;
border-style: solid;
border-width: 0 4px 5px 4px;
border-color: transparent transparent #fff transparent;
position: absolute;
top: -5px;
left: 15px;
}
`}</style>
</div>
)

@ -1,23 +1,21 @@
import React from 'react' import React from 'react'
export default () => ( export const Controls = () => (
<div className="window-controls"> <svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14">
<svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"> <g fill="none" fillRule="evenodd" transform="translate(1 1)">
<g fill="none" fillRule="evenodd" transform="translate(1 1)"> <circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" strokeWidth=".5"/>
<circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" strokeWidth=".5"/> <circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" strokeWidth=".5"/>
<circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" strokeWidth=".5"/> <circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" strokeWidth=".5"/>
<circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" strokeWidth=".5"/> </g>
</g> </svg>
</svg> )
<style jsx>{`
div { export const ControlsBW = () => (
margin-top: -19px; <svg xmlns="http://www.w3.org/2000/svg" width="54" height="16" viewBox="0 0 54 14">
position: relative; <g fill="none" fillRule="evenodd" stroke="#878787" transform="translate(1 1)">
top: +30px; <circle cx="6" cy="6" r="6"/>
margin-left: 18px; <circle cx="26" cy="6" r="6"/>
z-index: 1; <circle cx="46" cy="6" r="6"/>
} </g>
`} </svg>
</style>
</div>
) )

@ -1,6 +1,6 @@
import React from 'react' import React from 'react'
export const Hyper = () => ( export const Sharp = () => (
<svg xmlns="http://www.w3.org/2000/svg" width="50" height="50" viewBox="0 0 81 81" xmlnsXlink="http://www.w3.org/1999/xlink"> <svg xmlns="http://www.w3.org/2000/svg" width="50" height="50" viewBox="0 0 81 81" xmlnsXlink="http://www.w3.org/1999/xlink">
<defs> <defs>
<rect id="a" width="81" height="81" rx="3"/> <rect id="a" width="81" height="81" rx="3"/>
@ -10,11 +10,11 @@ export const Hyper = () => (
<use xlinkHref="#a"/> <use xlinkHref="#a"/>
</mask> </mask>
<use fill="#616161" xlinkHref="#a"/> <use fill="#616161" xlinkHref="#a"/>
<g transform="translate(17 33)" mask="url(#b)"> <g transform="translate(16 32)" mask="url(#b)">
<path fill="#000000" stroke="#393939" strokeWidth="2" d="M65.0458013,49.1077029 C66.0458013,49.1077029 0.174089069,49.1077029 0.174089069,49.1077029 L0.174089069,5.16868499 C0.174089069,2.41055979 2.40986586,0.174657534 5.17268563,0.174657534 L65.0458013,0.174657534 L65.0458013,49.1077029 Z"/> <path fill="#000000" fillRule="nonzero" d="M66.0458013,46.1092762 C66.0458013,48.3193105 64.2622787,50.1077029 62.050805,50.1077029 L0.174089069,50.1077029 L0.174089069,6.16868499 C0.174089069,0.174657534 0.174089069,0.174657534 0.174089069,0.174657534 L66.0458013,0.174657534 L66.0458013,46.1092762 Z"/>
<g fillRule="nonzero" strokeWidth=".5" transform="translate(18.96 14.27)"> <g transform="translate(19.96 15.27)">
<ellipse cx="7.045" cy="7.048" fill="#FF5E55" stroke="#E0443E" rx="7.045" ry="7.048"/> <ellipse cx="7.045" cy="7.048" fill="#FF5E55" fillRule="nonzero" stroke="#E0443E" strokeWidth=".5" rx="7.045" ry="7.048"/>
<ellipse cx="30.526" cy="7.048" fill="#FFC02C" stroke="#DEA123" rx="7.045" ry="7.048"/> <ellipse cx="30.526" cy="7.048" fill="#FFC02C" fillRule="nonzero" stroke="#DEA123" strokeWidth=".5" rx="7.045" ry="7.048"/>
</g> </g>
</g> </g>
</g> </g>

@ -7,6 +7,7 @@ import domtoimage from 'dom-to-image'
import ReadFileDropContainer from '../components/ReadFileDropContainer' import ReadFileDropContainer from '../components/ReadFileDropContainer'
import Meta from '../components/Meta' import Meta from '../components/Meta'
import Toolbar from '../components/Toolbar' import Toolbar from '../components/Toolbar'
import { WINDOW_THEMES } from '../components/ThemeSelect'
import CodeImage from '../components/CodeImage' import CodeImage from '../components/CodeImage'
import Header from '../components/Header' import Header from '../components/Header'
import Footer from '../components/Footer' import Footer from '../components/Footer'
@ -30,10 +31,11 @@ class Index extends React.Component {
constructor() { constructor() {
super() super()
this.state = { this.state = {
background: '#111111', background: '#ABB8C3',
theme: THEMES[0].id, theme: THEMES[0].id,
language: 'javascript', // TODO LANGUAGES[0] language: 'javascript', // TODO LANGUAGES[0]
dropShadow: false, windowTheme: WINDOW_THEMES[0],
dropShadow: true,
windowControls: true, windowControls: true,
paddingVertical: '48px', paddingVertical: '48px',
paddingHorizontal: '32px' paddingHorizontal: '32px'
@ -41,7 +43,6 @@ class Index extends React.Component {
} }
save () { save () {
// domtoimage.toPng(document.getElementById('container'))
domtoimage.toPng(document.getElementById('container')) domtoimage.toPng(document.getElementById('container'))
.then((dataUrl) => { .then((dataUrl) => {
const link = document.createElement('a') const link = document.createElement('a')

Loading…
Cancel
Save