Componentize tabs.
This commit is contained in:
parent
036d07bc4c
commit
b89661711f
@ -4,8 +4,7 @@ import { UrlStateProvider } from './UrlState';
|
||||
|
||||
import ColorState from './ColorState';
|
||||
import ColorSetInputs from './ColorSetInputs';
|
||||
import CodePreview from './CodePreview';
|
||||
import TerminalPreview from './TerminalPreview';
|
||||
import TextPreviews from './TextPreviews';
|
||||
|
||||
export default class App extends PureComponent {
|
||||
render() {
|
||||
@ -36,8 +35,7 @@ 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>
|
||||
<CodePreview />
|
||||
<TerminalPreview />
|
||||
<TextPreviews />
|
||||
</div>
|
||||
</div>
|
||||
) }
|
||||
|
@ -5,6 +5,7 @@ import ColorState from './ColorState';
|
||||
import ColorInput from './ColorInput';
|
||||
import Checkbox from './Checkbox';
|
||||
import CalculateIntermediaryShadesState from './CalculateIntermediaryShadesState';
|
||||
import Tabs from './Tabs';
|
||||
|
||||
export default class ColorSetInputs extends PureComponent {
|
||||
render() {
|
||||
@ -13,70 +14,66 @@ export default class ColorSetInputs extends PureComponent {
|
||||
{ ({ getValueOrFallback, mergeState }) => {
|
||||
const isDark = getValueOrFallback([['activeColorSet']]) === 'dark';
|
||||
return (
|
||||
<ColorState>
|
||||
{ ({ getColor }) => {
|
||||
const getTabStyle = active => ({
|
||||
backgroundColor: active ? getColor('shade0') : getColor('shade2', 'shade0'),
|
||||
color: getColor('shade7'),
|
||||
borderTopColor: getColor('shade7'),
|
||||
borderRightColor: getColor('shade7'),
|
||||
borderBottomColor: active ? getColor('shade0') : getColor('shade7'),
|
||||
borderLeftColor: getColor('shade7'),
|
||||
});
|
||||
return (
|
||||
<>
|
||||
<div className={ styles.tabContainer }>
|
||||
<button
|
||||
style={ getTabStyle(isDark) }
|
||||
onClick={ () => mergeState({ activeColorSet: 'dark' }) }
|
||||
>Dark Variant</button>
|
||||
<button
|
||||
style={ getTabStyle(!isDark) }
|
||||
onClick={ () => mergeState({ activeColorSet: 'light' }) }
|
||||
>Light Variant</button>
|
||||
</div>
|
||||
<div className={ styles.inputContainer } style={{ borderColor: getColor('shade7') }}>
|
||||
<ColorInput className={ styles.shade0 } colorKey="shade0" help="background color" />
|
||||
<CalculateIntermediaryShadesState>
|
||||
{ ({ getValue, setValue }) => (
|
||||
<>
|
||||
{ !getValue() && (
|
||||
<>
|
||||
<ColorInput className={ styles.shade1 } colorKey="shade1" help="UI" />
|
||||
<ColorInput className={ styles.shade2 } colorKey="shade2" help="UI, text selection" />
|
||||
<ColorInput className={ styles.shade3 } colorKey="shade3" help="UI, code comments" />
|
||||
<ColorInput className={ styles.shade4 } colorKey="shade4" help="UI" />
|
||||
<ColorInput className={ styles.shade5 } colorKey="shade5" help="UI" />
|
||||
<ColorInput className={ styles.shade6 } colorKey="shade6" help="foreground text" />
|
||||
</>
|
||||
) }
|
||||
<ColorInput
|
||||
className={ [styles.shade7, getValue() ? styles.collapsed : ''].join(' ') }
|
||||
colorKey="shade7"
|
||||
help="foreground text"
|
||||
/>
|
||||
<Checkbox
|
||||
className={ styles.checkbox }
|
||||
label="calculate intermediary shades"
|
||||
value={ getValue() }
|
||||
onChange={ setValue }
|
||||
/>
|
||||
</>
|
||||
) }
|
||||
</CalculateIntermediaryShadesState>
|
||||
<ColorInput className={ styles.accent0 } colorKey="accent0" help="error, vcs deletion" />
|
||||
<ColorInput className={ styles.accent1 } colorKey="accent1" help="syntax" />
|
||||
<ColorInput className={ styles.accent2 } colorKey="accent2" help="warning, vcs modification" />
|
||||
<ColorInput className={ styles.accent3 } colorKey="accent3" help="success, vcs addition" />
|
||||
<ColorInput className={ styles.accent4 } colorKey="accent4" help="syntax" />
|
||||
<ColorInput className={ styles.accent5 } colorKey="accent5" help="syntax" />
|
||||
<ColorInput className={ styles.accent6 } colorKey="accent6" help="syntax, caret/cursor" />
|
||||
<ColorInput className={ styles.accent7 } colorKey="accent7" help="syntax, special" />
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
} }
|
||||
</ColorState>
|
||||
<Tabs>
|
||||
{ ({ tabClassName, getTabStyle, contentClassName, contentStyle }) => (
|
||||
<ColorState>
|
||||
{ ({ getColor }) => (
|
||||
<>
|
||||
<div>
|
||||
<button
|
||||
className={ tabClassName }
|
||||
style={ getTabStyle(isDark) }
|
||||
onClick={ () => mergeState({ activeColorSet: 'dark' }) }
|
||||
>Dark Variant</button>
|
||||
<button
|
||||
className={ tabClassName }
|
||||
style={ getTabStyle(!isDark) }
|
||||
onClick={ () => mergeState({ activeColorSet: 'light' }) }
|
||||
>Light Variant</button>
|
||||
</div>
|
||||
<div className={ `${styles.inputContainer} ${contentClassName}` } style={ contentStyle }>
|
||||
<ColorInput className={ styles.shade0 } colorKey="shade0" help="background color" />
|
||||
<CalculateIntermediaryShadesState>
|
||||
{ ({ getValue, setValue }) => (
|
||||
<>
|
||||
{ !getValue() && (
|
||||
<>
|
||||
<ColorInput className={ styles.shade1 } colorKey="shade1" help="UI" />
|
||||
<ColorInput className={ styles.shade2 } colorKey="shade2" help="UI, text selection" />
|
||||
<ColorInput className={ styles.shade3 } colorKey="shade3" help="UI, code comments" />
|
||||
<ColorInput className={ styles.shade4 } colorKey="shade4" help="UI" />
|
||||
<ColorInput className={ styles.shade5 } colorKey="shade5" help="UI" />
|
||||
<ColorInput className={ styles.shade6 } colorKey="shade6" help="foreground text" />
|
||||
</>
|
||||
) }
|
||||
<ColorInput
|
||||
className={ [styles.shade7, getValue() ? styles.collapsed : ''].join(' ') }
|
||||
colorKey="shade7"
|
||||
help="foreground text"
|
||||
/>
|
||||
<Checkbox
|
||||
className={ styles.checkbox }
|
||||
label="calculate intermediary shades"
|
||||
value={ getValue() }
|
||||
onChange={ setValue }
|
||||
/>
|
||||
</>
|
||||
) }
|
||||
</CalculateIntermediaryShadesState>
|
||||
<ColorInput className={ styles.accent0 } colorKey="accent0" help="error, vcs deletion" />
|
||||
<ColorInput className={ styles.accent1 } colorKey="accent1" help="syntax" />
|
||||
<ColorInput className={ styles.accent2 } colorKey="accent2" help="warning, vcs modification" />
|
||||
<ColorInput className={ styles.accent3 } colorKey="accent3" help="success, vcs addition" />
|
||||
<ColorInput className={ styles.accent4 } colorKey="accent4" help="syntax" />
|
||||
<ColorInput className={ styles.accent5 } colorKey="accent5" help="syntax" />
|
||||
<ColorInput className={ styles.accent6 } colorKey="accent6" help="syntax, caret/cursor" />
|
||||
<ColorInput className={ styles.accent7 } colorKey="accent7" help="syntax, special" />
|
||||
</div>
|
||||
</>
|
||||
) }
|
||||
</ColorState>
|
||||
) }
|
||||
</Tabs>
|
||||
);
|
||||
} }
|
||||
</UrlStateConsumer>
|
||||
|
@ -1,25 +1,5 @@
|
||||
.tabContainer button {
|
||||
font-size: var(--size-regular);
|
||||
font-family: 'Fira Code', monospace;
|
||||
padding: var(--size-small-4) var(--size-small-1);
|
||||
border-width: var(--border-size);
|
||||
border-style: solid;
|
||||
border-top-left-radius: var(--border-radius-size);
|
||||
border-top-right-radius: var(--border-radius-size);
|
||||
}
|
||||
|
||||
.tabContainer button + button {
|
||||
margin-left: calc(var(--border-size) * -1);
|
||||
}
|
||||
|
||||
.inputContainer {
|
||||
padding: var(--size-large-1);
|
||||
border-width: var(--border-size);
|
||||
border-style: solid;
|
||||
margin-top: calc(var(--border-size) * -1);
|
||||
border-top-right-radius: var(--border-radius-size);
|
||||
border-bottom-right-radius: var(--border-radius-size);
|
||||
border-bottom-left-radius: var(--border-radius-size);
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
grid-column-gap: var(--size-large-1);
|
||||
|
25
web/src/Tabs.js
Normal file
25
web/src/Tabs.js
Normal file
@ -0,0 +1,25 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import ColorState from './ColorState';
|
||||
import styles from './Tabs.module.css';
|
||||
|
||||
export default class Tabs extends PureComponent {
|
||||
render() {
|
||||
return (
|
||||
<ColorState>
|
||||
{ ({ getColor }) => this.props.children({
|
||||
tabClassName: styles.tab,
|
||||
getTabStyle: active => ({
|
||||
backgroundColor: active ? getColor('shade0') : getColor('shade2', 'shade0'),
|
||||
color: getColor('shade7'),
|
||||
borderTopColor: getColor('shade7'),
|
||||
borderRightColor: getColor('shade7'),
|
||||
borderBottomColor: active ? getColor('shade0') : getColor('shade7'),
|
||||
borderLeftColor: getColor('shade7'),
|
||||
}),
|
||||
contentClassName: styles.tabContent,
|
||||
contentStyle: { borderColor: getColor('shade7') },
|
||||
}) }
|
||||
</ColorState>
|
||||
);
|
||||
}
|
||||
}
|
22
web/src/Tabs.module.css
Normal file
22
web/src/Tabs.module.css
Normal file
@ -0,0 +1,22 @@
|
||||
.tab {
|
||||
font-size: var(--size-regular);
|
||||
font-family: 'Fira Code', monospace;
|
||||
padding: var(--size-small-4) var(--size-small-1);
|
||||
border-width: var(--border-size);
|
||||
border-style: solid;
|
||||
border-top-left-radius: var(--border-radius-size);
|
||||
border-top-right-radius: var(--border-radius-size);
|
||||
}
|
||||
|
||||
.tab + .tab {
|
||||
margin-left: calc(var(--border-size) * -1);
|
||||
}
|
||||
|
||||
.tabContent {
|
||||
border-width: var(--border-size);
|
||||
border-style: solid;
|
||||
margin-top: calc(var(--border-size) * -1);
|
||||
border-top-right-radius: var(--border-radius-size);
|
||||
border-bottom-right-radius: var(--border-radius-size);
|
||||
border-bottom-left-radius: var(--border-radius-size);
|
||||
}
|
41
web/src/TextPreviews.js
Normal file
41
web/src/TextPreviews.js
Normal file
@ -0,0 +1,41 @@
|
||||
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 {
|
||||
|
||||
state = { activePreview: 'code' };
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Tabs>
|
||||
{ ({ tabClassName, getTabStyle, contentClassName, contentStyle }) => (
|
||||
<>
|
||||
<div>
|
||||
<button
|
||||
className={ tabClassName }
|
||||
style={ getTabStyle(this.state.activePreview === 'code') }
|
||||
onClick={ () => this.setState({ activePreview: 'code' }) }
|
||||
>Code</button>
|
||||
<button
|
||||
className={ tabClassName }
|
||||
style={ getTabStyle(this.state.activePreview === 'terminal') }
|
||||
onClick={ () => this.setState({ activePreview: 'terminal' }) }
|
||||
>Terminal</button>
|
||||
</div>
|
||||
<div className={ `${styles.previewContainer} ${contentClassName}` } style={ contentStyle }>
|
||||
{ this.state.activePreview === 'code' ? (
|
||||
<CodePreview />
|
||||
) : null }
|
||||
{ this.state.activePreview === 'terminal' ? (
|
||||
<TerminalPreview />
|
||||
) : null }
|
||||
</div>
|
||||
</>
|
||||
) }
|
||||
</Tabs>
|
||||
);
|
||||
}
|
||||
}
|
3
web/src/TextPreviews.module.css
Normal file
3
web/src/TextPreviews.module.css
Normal file
@ -0,0 +1,3 @@
|
||||
.previewContainer {
|
||||
padding: var(--size-large-1);
|
||||
}
|
@ -51,7 +51,7 @@ const fallbackState = {
|
||||
calculateIntermediaryShades: {
|
||||
dark: true,
|
||||
light: true,
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export class UrlStateProvider extends Component {
|
||||
|
Loading…
Reference in New Issue
Block a user