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

@ -1,6 +1,7 @@
import React from 'react'
import enhanceWithClickOutside from 'react-click-outside'
import { TwitterPicker } from 'react-color'
import WindowPointer from './WindowPointer'
import { PALETTE } from '../lib/constants'
class ColorPicker extends React.Component {
@ -20,7 +21,6 @@ class ColorPicker extends React.Component {
}
handlePickColor(color) {
this.setState({ isVisible: false })
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>
<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>
<style jsx>{`
.colorpicker-container {
@ -69,8 +70,8 @@ class ColorPicker extends React.Component {
.colorpicker-picker {
position: absolute;
margin-left: 32px;
margin-top: 10px;
margin-left: 36px;
margin-top: 4px;
}
`}</style>
</div>

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

@ -52,9 +52,13 @@ export default () => (
border-bottom: solid 1px ${PALETTE.SECONDARY};
}
.settings-settings > div:first-child {
border-bottom: none;
}
.selected svg {
border-radius: 3px;
border: solid 2px #fff;
border: solid 2px ${PALETTE.SECONDARY};
}
.CodeMirror__container.dropshadow {
@ -71,6 +75,14 @@ export default () => (
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 {
padding-top: 40px;
}
@ -78,6 +90,33 @@ export default () => (
.cm-s-dracula .CodeMirror-cursor {
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>
</div>
)

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

@ -1,12 +1,13 @@
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 {
constructor(props) {
super()
this.state = { selected: props.selected || THEME_IMGS[0] }
this.state = { selected: props.selected || WINDOW_THEMES[0] }
this.select = this.select.bind(this)
}
@ -18,27 +19,34 @@ export default class extends React.Component {
}
renderThemes() {
return THEME_IMGS.map((Img, i) => (
<div className={`theme ${this.state.selected === Img ? "selected" : ""}`}
key={i} onClick={this.select.bind(null, Img)}>
<Img/>
<style jsx>{`
.theme {
margin-right: 8px;
}
return WINDOW_THEMES.map((theme, i) => {
const Img = WINDOW_THEMES_MAP[theme]
return (
<div
className={`theme ${this.state.selected === theme ? "selected" : ""}`}
key={i}
onClick={this.select.bind(null, theme)}
>
<Img />
<style jsx>{`
.theme {
cursor: pointer;
margin-right: 8px;
}
.theme:last-of-type {
margin-right: 0px;
}
`}</style>
</div>
))
.theme:last-of-type {
margin-right: 0px;
}
`}</style>
</div>
)
})
}
render() {
return (
<div className="window-theme">
<span className="label">Theme</span>
<span className="label">Window Theme</span>
<div className="themes">
{ this.renderThemes() }
</div>

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

@ -1,6 +1,6 @@
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">
<defs>
<rect id="a" width="81" height="81" rx="3"/>
@ -10,11 +10,11 @@ export const Hyper = () => (
<use xlinkHref="#a"/>
</mask>
<use fill="#616161" xlinkHref="#a"/>
<g transform="translate(17 33)" 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"/>
<g fillRule="nonzero" strokeWidth=".5" transform="translate(18.96 14.27)">
<ellipse cx="7.045" cy="7.048" fill="#FF5E55" stroke="#E0443E" rx="7.045" ry="7.048"/>
<ellipse cx="30.526" cy="7.048" fill="#FFC02C" stroke="#DEA123" rx="7.045" ry="7.048"/>
<g transform="translate(16 32)" mask="url(#b)">
<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 transform="translate(19.96 15.27)">
<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" fillRule="nonzero" stroke="#DEA123" strokeWidth=".5" rx="7.045" ry="7.048"/>
</g>
</g>
</g>

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

Loading…
Cancel
Save