Add theme helpers
This commit is contained in:
parent
882248a367
commit
2d4cb2d275
@ -1,13 +1,20 @@
|
||||
import React from 'react'
|
||||
import styled from 'styled-components'
|
||||
import { getColor, ColorSchemeProps, getBorder } from '../theme'
|
||||
|
||||
export interface ButtonProps {
|
||||
// type: string
|
||||
}
|
||||
export const Button = styled.button<ColorSchemeProps>`
|
||||
padding: 0.5rem;
|
||||
background: transparent;
|
||||
color: ${getColor};
|
||||
border: ${getBorder};
|
||||
border-radius: ${props => props.theme.border.radius}px;
|
||||
cursor: pointer;
|
||||
|
||||
export class Button extends React.PureComponent<ButtonProps> {
|
||||
render() {
|
||||
return (
|
||||
<button>{this.props.children}</button>
|
||||
)
|
||||
&:hover {
|
||||
background: ${getColor};
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover:active {
|
||||
box-shadow: 0 0 3px ${getColor};
|
||||
}
|
||||
`
|
||||
|
||||
@ -1,46 +0,0 @@
|
||||
import React from 'react'
|
||||
import {connect} from 'react-redux'
|
||||
|
||||
interface ComponentProps {
|
||||
value: string
|
||||
}
|
||||
|
||||
interface StateProps {
|
||||
value: string
|
||||
}
|
||||
|
||||
export class Component
|
||||
extends React.PureComponent<ComponentProps, StateProps> {
|
||||
constructor(props: ComponentProps) {
|
||||
super(props)
|
||||
this.state = {
|
||||
value: props.value,
|
||||
}
|
||||
}
|
||||
handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
this.setState({
|
||||
value: e.target.value,
|
||||
})
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<input
|
||||
autoComplete='off'
|
||||
type='text'
|
||||
value={this.state.value}
|
||||
onChange={this.handleChange}
|
||||
/>
|
||||
<div>{this.state.value}</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
function mapStateToProps(state: {value: string}) {
|
||||
return {
|
||||
value: state.value,
|
||||
}
|
||||
}
|
||||
|
||||
export const CComponent = connect(mapStateToProps)(Component)
|
||||
@ -27,7 +27,7 @@ const Control = styled.div`
|
||||
position: relative;
|
||||
`
|
||||
|
||||
const I = styled.span`
|
||||
const Icon = styled.span`
|
||||
position: absolute;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@ -39,12 +39,18 @@ const I = styled.span`
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 2.5rem;
|
||||
|
||||
color: ${props => props.theme.grey.light};
|
||||
`
|
||||
|
||||
const TextInput = styled.input<{hasIconLeft?: boolean}>`
|
||||
padding: 0.5rem 0.75rem;
|
||||
padding-left: ${props => props.hasIconLeft ? '2.5rem' : '0.75rem'}
|
||||
width: 100%;
|
||||
|
||||
&:focus + ${Icon} {
|
||||
color: ${props => props.theme.grey.dark};
|
||||
}
|
||||
`
|
||||
|
||||
export class Input extends React.PureComponent<InputProps> {
|
||||
@ -54,7 +60,6 @@ export class Input extends React.PureComponent<InputProps> {
|
||||
}
|
||||
}
|
||||
render() {
|
||||
const {Icon} = this.props
|
||||
return (
|
||||
<Field>
|
||||
<Label>{this.props.label}</Label>
|
||||
@ -69,7 +74,7 @@ export class Input extends React.PureComponent<InputProps> {
|
||||
readOnly={!!this.props.readOnly}
|
||||
required={this.props.required}
|
||||
/>
|
||||
{Icon && <I><Icon /></I>}
|
||||
{this.props.Icon && <Icon><this.props.Icon /></Icon>}
|
||||
</Control>
|
||||
</Field>
|
||||
)
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
// export * from './Component'
|
||||
export * from './Button'
|
||||
export * from './Input'
|
||||
export * from './Link'
|
||||
|
||||
@ -5,6 +5,7 @@ export * from './csrf'
|
||||
export * from './login'
|
||||
export * from './renderer'
|
||||
export * from './test-utils'
|
||||
export * from './theme'
|
||||
|
||||
import * as team from './team'
|
||||
export { team }
|
||||
|
||||
@ -4,6 +4,7 @@ import { FaEnvelope, FaLock, FaUser } from 'react-icons/fa'
|
||||
import { Link } from 'react-router-dom'
|
||||
import { Input } from '../components/Input'
|
||||
import { Redirect } from '../components/Redirect'
|
||||
import { Button } from '../components'
|
||||
|
||||
export interface RegisterFormProps {
|
||||
error?: string
|
||||
@ -28,12 +29,12 @@ export class RegisterForm extends React.PureComponent<RegisterFormProps> {
|
||||
<p className='error has-text-danger'>{this.props.error}</p>
|
||||
<Input
|
||||
Icon={FaEnvelope}
|
||||
label='Email'
|
||||
label='Username'
|
||||
name='username'
|
||||
type='email'
|
||||
type='text'
|
||||
onChange={this.props.onChange}
|
||||
value={this.props.data.username}
|
||||
placeholder='Email'
|
||||
placeholder='Username'
|
||||
required
|
||||
/>
|
||||
<Input
|
||||
@ -46,6 +47,15 @@ export class RegisterForm extends React.PureComponent<RegisterFormProps> {
|
||||
placeholder='Password'
|
||||
required
|
||||
/>
|
||||
<Input
|
||||
Icon={FaEnvelope}
|
||||
label='Email'
|
||||
name='email'
|
||||
type='email'
|
||||
onChange={this.props.onChange}
|
||||
value={this.props.data.username}
|
||||
placeholder='Email'
|
||||
/>
|
||||
<Input
|
||||
Icon={FaUser}
|
||||
label='First Name'
|
||||
@ -54,7 +64,6 @@ export class RegisterForm extends React.PureComponent<RegisterFormProps> {
|
||||
onChange={this.props.onChange}
|
||||
value={this.props.data.firstName}
|
||||
placeholder='First name'
|
||||
required
|
||||
/>
|
||||
<Input
|
||||
Icon={FaUser}
|
||||
@ -64,15 +73,11 @@ export class RegisterForm extends React.PureComponent<RegisterFormProps> {
|
||||
onChange={this.props.onChange}
|
||||
value={this.props.data.lastName}
|
||||
placeholder='Last name'
|
||||
required
|
||||
/>
|
||||
<div className='text-center'>
|
||||
<input
|
||||
className='button is-primary'
|
||||
name='submit'
|
||||
type='submit'
|
||||
value='Register'
|
||||
/>
|
||||
<Button name='submit' type='submit'>
|
||||
Register
|
||||
</Button>
|
||||
</div>
|
||||
<p className='small center mt-1'>
|
||||
Already have an account? <Link to='/auth/login'>Log in!</Link>
|
||||
|
||||
6
packages/client/src/theme/ColorSchemeProps.ts
Normal file
6
packages/client/src/theme/ColorSchemeProps.ts
Normal file
@ -0,0 +1,6 @@
|
||||
import { DefaultTheme, ThemeProps } from 'styled-components'
|
||||
import { ColorScheme } from './theme'
|
||||
|
||||
export interface ColorSchemeProps extends ThemeProps<DefaultTheme> {
|
||||
colorScheme?: ColorScheme
|
||||
}
|
||||
9
packages/client/src/theme/getColor.ts
Normal file
9
packages/client/src/theme/getColor.ts
Normal file
@ -0,0 +1,9 @@
|
||||
import { ColorSchemeProps } from './ColorSchemeProps'
|
||||
|
||||
export function getColor(props: ColorSchemeProps) {
|
||||
return props.theme.colors[props.colorScheme || 'primary']
|
||||
}
|
||||
|
||||
export function getBorder(props: ColorSchemeProps) {
|
||||
return `${props.theme.border.width}px solid ${getColor(props)};`
|
||||
}
|
||||
3
packages/client/src/theme/index.ts
Normal file
3
packages/client/src/theme/index.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export * from './getColor'
|
||||
export * from './theme'
|
||||
export * from './ColorSchemeProps'
|
||||
42
packages/client/src/theme/theme.ts
Normal file
42
packages/client/src/theme/theme.ts
Normal file
@ -0,0 +1,42 @@
|
||||
import { DefaultTheme } from 'styled-components'
|
||||
|
||||
declare module 'styled-components' {
|
||||
export interface DefaultTheme {
|
||||
colors: {
|
||||
primary: string
|
||||
secondary: string
|
||||
warning: string
|
||||
danger: string
|
||||
info: string
|
||||
}
|
||||
grey: {
|
||||
dark: string
|
||||
light: string
|
||||
}
|
||||
border: {
|
||||
width: 1
|
||||
radius: 3
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const theme: DefaultTheme = {
|
||||
colors: {
|
||||
primary: 'indigo',
|
||||
secondary: 'green',
|
||||
warning: 'yellow',
|
||||
danger: 'red',
|
||||
info: 'lightblue',
|
||||
},
|
||||
grey: {
|
||||
dark: 'darkgrey',
|
||||
light: 'lightgrey',
|
||||
},
|
||||
border: {
|
||||
width: 1,
|
||||
radius: 3,
|
||||
},
|
||||
}
|
||||
|
||||
export type ColorScheme =
|
||||
'primary' | 'secondary' | 'warning' | 'danger' | 'info'
|
||||
Loading…
x
Reference in New Issue
Block a user