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 {
|
export const Button = styled.button<ColorSchemeProps>`
|
||||||
// type: string
|
padding: 0.5rem;
|
||||||
|
background: transparent;
|
||||||
|
color: ${getColor};
|
||||||
|
border: ${getBorder};
|
||||||
|
border-radius: ${props => props.theme.border.radius}px;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: ${getColor};
|
||||||
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Button extends React.PureComponent<ButtonProps> {
|
&:hover:active {
|
||||||
render() {
|
box-shadow: 0 0 3px ${getColor};
|
||||||
return (
|
|
||||||
<button>{this.props.children}</button>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
`
|
||||||
|
|||||||
@ -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;
|
position: relative;
|
||||||
`
|
`
|
||||||
|
|
||||||
const I = styled.span`
|
const Icon = styled.span`
|
||||||
position: absolute;
|
position: absolute;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@ -39,12 +39,18 @@ const I = styled.span`
|
|||||||
top: 0;
|
top: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
width: 2.5rem;
|
width: 2.5rem;
|
||||||
|
|
||||||
|
color: ${props => props.theme.grey.light};
|
||||||
`
|
`
|
||||||
|
|
||||||
const TextInput = styled.input<{hasIconLeft?: boolean}>`
|
const TextInput = styled.input<{hasIconLeft?: boolean}>`
|
||||||
padding: 0.5rem 0.75rem;
|
padding: 0.5rem 0.75rem;
|
||||||
padding-left: ${props => props.hasIconLeft ? '2.5rem' : '0.75rem'}
|
padding-left: ${props => props.hasIconLeft ? '2.5rem' : '0.75rem'}
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
|
&:focus + ${Icon} {
|
||||||
|
color: ${props => props.theme.grey.dark};
|
||||||
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
export class Input extends React.PureComponent<InputProps> {
|
export class Input extends React.PureComponent<InputProps> {
|
||||||
@ -54,7 +60,6 @@ export class Input extends React.PureComponent<InputProps> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
render() {
|
render() {
|
||||||
const {Icon} = this.props
|
|
||||||
return (
|
return (
|
||||||
<Field>
|
<Field>
|
||||||
<Label>{this.props.label}</Label>
|
<Label>{this.props.label}</Label>
|
||||||
@ -69,7 +74,7 @@ export class Input extends React.PureComponent<InputProps> {
|
|||||||
readOnly={!!this.props.readOnly}
|
readOnly={!!this.props.readOnly}
|
||||||
required={this.props.required}
|
required={this.props.required}
|
||||||
/>
|
/>
|
||||||
{Icon && <I><Icon /></I>}
|
{this.props.Icon && <Icon><this.props.Icon /></Icon>}
|
||||||
</Control>
|
</Control>
|
||||||
</Field>
|
</Field>
|
||||||
)
|
)
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
// export * from './Component'
|
|
||||||
export * from './Button'
|
export * from './Button'
|
||||||
export * from './Input'
|
export * from './Input'
|
||||||
export * from './Link'
|
export * from './Link'
|
||||||
|
|||||||
@ -5,6 +5,7 @@ export * from './csrf'
|
|||||||
export * from './login'
|
export * from './login'
|
||||||
export * from './renderer'
|
export * from './renderer'
|
||||||
export * from './test-utils'
|
export * from './test-utils'
|
||||||
|
export * from './theme'
|
||||||
|
|
||||||
import * as team from './team'
|
import * as team from './team'
|
||||||
export { team }
|
export { team }
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import { FaEnvelope, FaLock, FaUser } from 'react-icons/fa'
|
|||||||
import { Link } from 'react-router-dom'
|
import { Link } from 'react-router-dom'
|
||||||
import { Input } from '../components/Input'
|
import { Input } from '../components/Input'
|
||||||
import { Redirect } from '../components/Redirect'
|
import { Redirect } from '../components/Redirect'
|
||||||
|
import { Button } from '../components'
|
||||||
|
|
||||||
export interface RegisterFormProps {
|
export interface RegisterFormProps {
|
||||||
error?: string
|
error?: string
|
||||||
@ -28,12 +29,12 @@ export class RegisterForm extends React.PureComponent<RegisterFormProps> {
|
|||||||
<p className='error has-text-danger'>{this.props.error}</p>
|
<p className='error has-text-danger'>{this.props.error}</p>
|
||||||
<Input
|
<Input
|
||||||
Icon={FaEnvelope}
|
Icon={FaEnvelope}
|
||||||
label='Email'
|
label='Username'
|
||||||
name='username'
|
name='username'
|
||||||
type='email'
|
type='text'
|
||||||
onChange={this.props.onChange}
|
onChange={this.props.onChange}
|
||||||
value={this.props.data.username}
|
value={this.props.data.username}
|
||||||
placeholder='Email'
|
placeholder='Username'
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
<Input
|
<Input
|
||||||
@ -46,6 +47,15 @@ export class RegisterForm extends React.PureComponent<RegisterFormProps> {
|
|||||||
placeholder='Password'
|
placeholder='Password'
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
|
<Input
|
||||||
|
Icon={FaEnvelope}
|
||||||
|
label='Email'
|
||||||
|
name='email'
|
||||||
|
type='email'
|
||||||
|
onChange={this.props.onChange}
|
||||||
|
value={this.props.data.username}
|
||||||
|
placeholder='Email'
|
||||||
|
/>
|
||||||
<Input
|
<Input
|
||||||
Icon={FaUser}
|
Icon={FaUser}
|
||||||
label='First Name'
|
label='First Name'
|
||||||
@ -54,7 +64,6 @@ export class RegisterForm extends React.PureComponent<RegisterFormProps> {
|
|||||||
onChange={this.props.onChange}
|
onChange={this.props.onChange}
|
||||||
value={this.props.data.firstName}
|
value={this.props.data.firstName}
|
||||||
placeholder='First name'
|
placeholder='First name'
|
||||||
required
|
|
||||||
/>
|
/>
|
||||||
<Input
|
<Input
|
||||||
Icon={FaUser}
|
Icon={FaUser}
|
||||||
@ -64,15 +73,11 @@ export class RegisterForm extends React.PureComponent<RegisterFormProps> {
|
|||||||
onChange={this.props.onChange}
|
onChange={this.props.onChange}
|
||||||
value={this.props.data.lastName}
|
value={this.props.data.lastName}
|
||||||
placeholder='Last name'
|
placeholder='Last name'
|
||||||
required
|
|
||||||
/>
|
/>
|
||||||
<div className='text-center'>
|
<div className='text-center'>
|
||||||
<input
|
<Button name='submit' type='submit'>
|
||||||
className='button is-primary'
|
Register
|
||||||
name='submit'
|
</Button>
|
||||||
type='submit'
|
|
||||||
value='Register'
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<p className='small center mt-1'>
|
<p className='small center mt-1'>
|
||||||
Already have an account? <Link to='/auth/login'>Log in!</Link>
|
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