Plumbing for wallpaper previews.
This commit is contained in:
parent
84961f5dad
commit
cd123ab971
@ -5,6 +5,7 @@ import { UrlStateProvider } from './UrlState';
|
||||
import ColorState from './ColorState';
|
||||
import ColorSetInputs from './ColorSetInputs';
|
||||
import TextPreviews from './TextPreviews';
|
||||
import WallpaperPreview from './WallpaperPreview';
|
||||
|
||||
export default class App extends PureComponent {
|
||||
render() {
|
||||
@ -35,7 +36,10 @@ export default class App extends PureComponent {
|
||||
<h2 className={ styles.h2 } style={{ color: getColor('shade7')}}>1. Define colors</h2>
|
||||
<ColorSetInputs />
|
||||
<h2 className={ styles.h2 } style={{ color: getColor('shade7')}}>2. Preview</h2>
|
||||
<TextPreviews />
|
||||
<div className={ styles.previewsContainer }>
|
||||
<TextPreviews />
|
||||
<WallpaperPreview />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
) }
|
||||
|
@ -23,4 +23,10 @@
|
||||
.h2 {
|
||||
font-size: var(--size-large-1);
|
||||
margin: var(--size-regular) 0;
|
||||
}
|
||||
}
|
||||
|
||||
.previewsContainer {
|
||||
display: grid;
|
||||
grid-template-columns: calc((100% - var(--size-large-1)) * 2 / 3) calc((100% - var(--size-large-1)) / 3);
|
||||
grid-column-gap: var(--size-large-1);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import { Check } from './Icons';
|
||||
import { CheckIcon } from './Icons';
|
||||
import styles from './Checkbox.module.css';
|
||||
import ColorState from './ColorState';
|
||||
|
||||
@ -18,7 +18,7 @@ export default class Checkbox extends PureComponent {
|
||||
checked={ this.props.value }
|
||||
onChange={ evt => this.props.onChange(evt.target.checked) }
|
||||
/>
|
||||
<Check
|
||||
<CheckIcon
|
||||
backgroundColor={ this.props.value ? getColor('shade7') : 'transparent' }
|
||||
outlineColor={ this.props.value ? 'transparent' : getColor('shade7') }
|
||||
checkColor={ this.props.value ? getColor('shade0') : 'transparent' }
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import ColorState from './ColorState';
|
||||
import { Droplet } from './Icons';
|
||||
import { DropletIcon } from './Icons';
|
||||
import styles from './ColorInput.module.css';
|
||||
import getBestForeground from './getBestForeground';
|
||||
|
||||
@ -36,7 +36,7 @@ export default class ColorInput extends PureComponent {
|
||||
}}
|
||||
tabIndex="0"
|
||||
>
|
||||
<Droplet />
|
||||
<DropletIcon />
|
||||
<input
|
||||
type="color"
|
||||
className={ styles.colorInput }
|
||||
|
@ -1,18 +1,18 @@
|
||||
import React from 'react';
|
||||
|
||||
export const Droplet = () => (
|
||||
export const DropletIcon = () => (
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M8 3.004c.25.386.525.772.827 1.172.297.395 1.308 1.664 1.495 1.91C11.522 7.663 12 8.802 12 10.5c0 2.002-1.613 3.5-4 3.5s-4-1.498-4-3.5c0-1.698.48-2.837 1.678-4.414.187-.246 1.198-1.515 1.495-1.91.302-.4.576-.786.827-1.172z" stroke="currentColor" strokeWidth="2" fill="none" fillRule="evenodd"/>
|
||||
</svg>
|
||||
);
|
||||
|
||||
export const Check = ({ backgroundColor, outlineColor, checkColor }) => (
|
||||
export const CheckIcon = ({ backgroundColor, outlineColor, checkColor }) => (
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" style={{ backgroundColor, boxShadow: `inset 0 0 0 1px ${outlineColor}`, borderRadius: '2px' }}>
|
||||
<path d="M4 9l2 2M6 11l6-6" stroke={ checkColor } strokeWidth="2" fill="none" fillRule="evenodd" strokeLinecap="square"/>
|
||||
</svg>
|
||||
);
|
||||
|
||||
export const Radio = ({ selected }) => (
|
||||
export const RadioIcon = ({ selected }) => (
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
|
||||
<g fill="none" fillRule="evenodd">
|
||||
<circle stroke="currentColor" cx="8" cy="8" r="7.5"/>
|
||||
|
28
web/src/Radio.js
Normal file
28
web/src/Radio.js
Normal file
@ -0,0 +1,28 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import { RadioIcon } from './Icons';
|
||||
import ColorState from './ColorState';
|
||||
import styles from './Radio.module.css';
|
||||
|
||||
export default class Radio extends PureComponent {
|
||||
render() {
|
||||
return (
|
||||
<ColorState>
|
||||
{ ({ getColor }) => (
|
||||
<label
|
||||
className={ styles.wrapper }
|
||||
style={{ color: getColor('shade7') }}
|
||||
>
|
||||
<input
|
||||
type="radio"
|
||||
className={ styles.input }
|
||||
checked={ this.props.value }
|
||||
onChange={ evt => this.props.onChange(evt.target.checked) }
|
||||
/>
|
||||
<RadioIcon selected={ this.props.value } />
|
||||
<span className={ styles.label }>{ this.props.label }</span>
|
||||
</label>
|
||||
) }
|
||||
</ColorState>
|
||||
);
|
||||
}
|
||||
}
|
13
web/src/Radio.module.css
Normal file
13
web/src/Radio.module.css
Normal file
@ -0,0 +1,13 @@
|
||||
.wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.input {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.label {
|
||||
margin-left: var(--size-small-2);
|
||||
flex-grow: 1;
|
||||
}
|
@ -17,7 +17,10 @@ export default class Tabs extends PureComponent {
|
||||
borderLeftColor: getColor('shade7'),
|
||||
}),
|
||||
contentClassName: styles.tabContent,
|
||||
contentStyle: { borderColor: getColor('shade7') },
|
||||
contentStyle: {
|
||||
borderColor: getColor('shade7'),
|
||||
backgroundColor: getColor('shade0'),
|
||||
},
|
||||
}) }
|
||||
</ColorState>
|
||||
);
|
||||
|
@ -1,5 +1,7 @@
|
||||
.tab {
|
||||
display: inline-block;
|
||||
font-size: var(--size-regular);
|
||||
line-height: var(--line-height);
|
||||
font-family: 'Fira Code', monospace;
|
||||
padding: var(--size-small-4) var(--size-small-1);
|
||||
border-width: var(--border-size);
|
||||
@ -19,4 +21,5 @@
|
||||
border-top-right-radius: var(--border-radius-size);
|
||||
border-bottom-right-radius: var(--border-radius-size);
|
||||
border-bottom-left-radius: var(--border-radius-size);
|
||||
padding: var(--size-large-1);
|
||||
}
|
||||
|
@ -2,7 +2,6 @@ import React, { PureComponent } from 'react';
|
||||
import CodePreview from './CodePreview';
|
||||
import TerminalPreview from './TerminalPreview';
|
||||
import Tabs from './Tabs';
|
||||
import styles from './TextPreviews.module.css';
|
||||
|
||||
export default class TextPreviews extends PureComponent {
|
||||
|
||||
@ -12,7 +11,7 @@ export default class TextPreviews extends PureComponent {
|
||||
return (
|
||||
<Tabs>
|
||||
{ ({ tabClassName, getTabStyle, contentClassName, contentStyle }) => (
|
||||
<>
|
||||
<div>
|
||||
<div>
|
||||
<button
|
||||
className={ tabClassName }
|
||||
@ -25,7 +24,7 @@ export default class TextPreviews extends PureComponent {
|
||||
onClick={ () => this.setState({ activePreview: 'terminal' }) }
|
||||
>Terminal</button>
|
||||
</div>
|
||||
<div className={ `${styles.previewContainer} ${contentClassName}` } style={ contentStyle }>
|
||||
<div className={ contentClassName } style={ contentStyle }>
|
||||
{ this.state.activePreview === 'code' ? (
|
||||
<CodePreview />
|
||||
) : null }
|
||||
@ -33,7 +32,7 @@ export default class TextPreviews extends PureComponent {
|
||||
<TerminalPreview />
|
||||
) : null }
|
||||
</div>
|
||||
</>
|
||||
</div>
|
||||
) }
|
||||
</Tabs>
|
||||
);
|
||||
|
@ -1,3 +0,0 @@
|
||||
.previewContainer {
|
||||
padding: var(--size-large-1);
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
import React, { Component } from 'react';
|
||||
import React, { PureComponent } from 'react';
|
||||
import qs from 'qs';
|
||||
import { merge } from 'lodash';
|
||||
import getValueOrFallback from './getValueOrFallback';
|
||||
@ -52,9 +52,10 @@ const fallbackState = {
|
||||
dark: true,
|
||||
light: true,
|
||||
},
|
||||
activeWallpaper: 'none',
|
||||
};
|
||||
|
||||
export class UrlStateProvider extends Component {
|
||||
export class UrlStateProvider extends PureComponent {
|
||||
constructor(props, ...args) {
|
||||
super(props, ...args);
|
||||
this.state = stateFromParams(props.history.location.search);
|
||||
|
28
web/src/WallpaperPreview.js
Normal file
28
web/src/WallpaperPreview.js
Normal file
@ -0,0 +1,28 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import { UrlStateConsumer } from './UrlState';
|
||||
import Tabs from './Tabs';
|
||||
import Radio from './Radio';
|
||||
|
||||
export default class WallpaperPreview extends PureComponent {
|
||||
render() {
|
||||
return (
|
||||
<UrlStateConsumer>
|
||||
{ ({ getValueOrFallback, mergeState }) => (
|
||||
<Tabs>
|
||||
{ ({ tabClassName, getTabStyle, contentClassName, contentStyle }) => (
|
||||
<div>
|
||||
<span
|
||||
className={ tabClassName }
|
||||
style={ getTabStyle(true) }
|
||||
>Wallpaper</span>
|
||||
<div className={ contentClassName } style={ contentStyle }>
|
||||
<Radio value={ getValueOrFallback([['activeWallpaper']]) === 'none' } label="None" />
|
||||
</div>
|
||||
</div>
|
||||
) }
|
||||
</Tabs>
|
||||
) }
|
||||
</UrlStateConsumer>
|
||||
);
|
||||
}
|
||||
}
|
@ -38,10 +38,12 @@ body,
|
||||
--border-size: var(--size-small-6);
|
||||
--border-radius-size: var(--size-small-3);
|
||||
|
||||
--line-height: calc(1 / var(--size-ratio));
|
||||
|
||||
height: 100%;
|
||||
font-family: 'Fira Code', monospace;
|
||||
font-size: 16px;
|
||||
line-height: calc(1 / var(--size-ratio));
|
||||
line-height: var(--line-height);
|
||||
}
|
||||
|
||||
* {
|
||||
|
Loading…
Reference in New Issue
Block a user