Created
October 17, 2018 06:35
-
-
Save rhostem/8d82fd50711ea66d532cb20c5e80f1c3 to your computer and use it in GitHub Desktop.
[React] form components set
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import * as React from 'react' | |
import styled from 'styled-components' | |
import { color, mixin } from 'styles' | |
const CheckBoxGroup = styled.div` | |
display: inline-flex; | |
align-items: center; | |
& > input { | |
display: none; | |
} | |
& > input + label { | |
display: inline-block; | |
position: relative; | |
padding-left: 30px; | |
height: 20px; | |
font-size: 12px; | |
color: ${color.text}; | |
margin-bottom: 0; | |
&:hover { | |
cursor: pointer; | |
} | |
&:before { | |
${mixin.centeredY()}; | |
left: 0; | |
display: block; | |
width: 20px; | |
height: 20px; | |
content: ' '; | |
background-image: url('${ | |
process.env.REACT_APP_CDN_URL | |
}/admin/btn-check-off.svg'); | |
background-repeat: no-repeat; | |
background-position: center; | |
background-size: contain; | |
} | |
} | |
& > input:checked + label { | |
&:before { | |
background-image: url('${ | |
process.env.REACT_APP_CDN_URL | |
}/admin/btn-check-on.svg'); | |
} | |
} | |
` | |
type Props = { | |
id: string, | |
onChange: Function, | |
children: any, | |
checked: boolean, | |
disabled?: boolean, | |
name?: string, | |
} | |
class CheckBox extends React.Component<Props, any> { | |
static defaultProps = { | |
checked: false, | |
disabled: false, | |
} | |
render() { | |
const { children, id, onChange, checked, disabled, name } = this.props | |
return ( | |
<CheckBoxGroup> | |
<input | |
id={id} | |
type="checkbox" | |
onChange={onChange} | |
checked={checked} | |
disabled={disabled} | |
name={name} | |
/> | |
<label | |
htmlFor={id} | |
style={{ | |
opacity: disabled ? 0.6 : 1, | |
}} | |
> | |
{children || name} | |
</label> | |
</CheckBoxGroup> | |
) | |
} | |
} | |
export default CheckBox |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// import React, { Fragment } from 'react' | |
import styled from 'styled-components' | |
import { clearFix } from 'polished' | |
export const FormContainer = styled.div` | |
margin: 12px 0; | |
/* FormGroup */ | |
& > * { | |
&:last-child { | |
border-bottom: 1px solid #dee0e4; | |
} | |
} | |
` | |
export const FormGroup = styled.div` | |
${clearFix()}; | |
display: flex; | |
font-size: 14px; | |
border-top: 1px solid #dee0e4; | |
` | |
/** | |
* label, input의 wrapper | |
* FormGroup을 같은 넓이로 나눈다. FormGroup에 한 세트의 label, input만 사용된다면 필요없다. | |
*/ | |
export const FormContent = styled.div` | |
${clearFix()}; | |
flex: 1; | |
` | |
const labelWidth = '135px' | |
export const FormLabel = styled.label` | |
float: left; | |
padding: 12px 10px; | |
width: ${labelWidth}; | |
margin-bottom: 0; | |
` | |
/** | |
* input, form, select, texteditor, ... | |
*/ | |
export const FormInput = styled.div` | |
padding: 12px 10px; | |
float: left; | |
width: calc(100% - ${labelWidth}); | |
display: inline-flex; | |
align-items: center; | |
justify-content: flex-start; | |
flex-flow: row wrap; | |
` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from 'react' | |
import styled from 'styled-components' | |
const Wrap = styled.div` | |
position: relative; | |
display: block; | |
width: 100%; | |
height: 40px; | |
background-color: #ffffff; | |
border: solid 1px #dee0e4; | |
padding: 0 12px; | |
font-size: 14px; | |
display: flex; | |
align-items: center; | |
& > input { | |
flex: 1; | |
border: none; | |
background-color: transparent; | |
font-size: inherit; | |
&::placeholder { | |
color: #dee0e4; | |
} | |
} | |
` | |
// const Input = styled.input`` | |
type IconType = 'PASSWORD' | 'ID' | 'PHONE' | |
const getIconUrl = (icon: IconType) => { | |
const iconUrl = { | |
PASSWORD: `${process.env.REACT_APP_CDN_URL}/admin/icon-login-password.png`, | |
ID: `${process.env.REACT_APP_CDN_URL}/admin/icon-login-id.png`, | |
PHONE: `${process.env.REACT_APP_CDN_URL}/admin/icon-input-phone.png`, | |
} | |
return iconUrl[icon] | |
} | |
const Icon = styled.img` | |
display: inline-block; | |
width: 20px; | |
height: 20px; | |
margin-right: 10px; | |
` | |
type Props = { | |
style?: Object, | |
icon: IconTypes, | |
value: string, | |
onChange: Function, | |
placeholder: string, | |
type: string, | |
} | |
export default ({ | |
style, // css style | |
icon, // 아이콘 타입 | |
iconSize = '20px', // 좌측 아이콘 크기 | |
value, | |
onChange, | |
placeholder, | |
type, // html type | |
children, // 인풋 오른쪽 영역, 검색 | |
}: Props) => { | |
return ( | |
<Wrap style={style}> | |
{!!icon ? ( | |
<Icon | |
src={getIconUrl(icon)} | |
style={{ width: iconSize, height: iconSize }} | |
/> | |
) : null} | |
<input | |
type={type} | |
value={value} | |
onChange={onChange} | |
placeholder={placeholder} | |
/> | |
{children} | |
</Wrap> | |
) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { Component, Fragment } from 'react' | |
import Select from 'react-select' // https://react-select.com/ | |
import chroma from 'chroma-js' | |
type Option = { | |
value: string, // 실제 값 | |
label: string, // 표시 값 | |
} | |
type Props = { | |
name: string, // name property of input tag | |
placeholder: string, // input placeholder | |
options: Option[], // options array | |
onChange: ( | |
option: Object | Array<Object> | null | undefined, | |
action: Object | |
) => undefined, | |
} | |
type State = { | |
isClearable: boolean, | |
isDisabled: boolean, | |
isLoading: boolean, | |
isRtl: boolean, | |
isSearchable: boolean, | |
} | |
const optionBgColor = chroma('#ff9e03') | |
const customStyles = { | |
control: (base, state) => ({ | |
...base, | |
borderColor: 'blue', | |
}), | |
option: (base, state) => ({ | |
...base, | |
padding: '1rem', | |
fontWeight: state.isSelected ? 700 : 400, | |
backgroundColor: state.isSelected | |
? optionBgColor.css() | |
: optionBgColor.alpha(0.2).css(), | |
'&:hover': { | |
backgroundColor: 'hotpink', | |
}, | |
}), | |
singleValue: (base, state) => { | |
const opacity = state.isDisabled ? 0.5 : 1 | |
const transition = 'opacity 300ms' | |
return { ...base, opacity, transition } | |
}, | |
} | |
export default class SingleSelect extends Component<Props, State> { | |
static defaultProps = { | |
name: 'select-name', | |
options: [], | |
placeholder: 'Select', | |
className: 'reactSelect--single', | |
} | |
state = { | |
isClearable: true, | |
isDisabled: false, | |
isLoading: false, | |
isRtl: false, | |
isSearchable: true, | |
} | |
toggleClearable = () => | |
this.setState(state => ({ isClearable: !state.isClearable })) | |
toggleDisabled = () => | |
this.setState(state => ({ isDisabled: !state.isDisabled })) | |
toggleLoading = () => | |
this.setState(state => ({ isLoading: !state.isLoading })) | |
toggleRtl = () => this.setState(state => ({ isRtl: !state.isRtl })) | |
toggleSearchable = () => | |
this.setState(state => ({ isSearchable: !state.isSearchable })) | |
render() { | |
const { | |
isClearable, | |
isSearchable, | |
isDisabled, | |
isLoading, | |
isRtl, | |
} = this.state | |
const { options, name, placeholder, onChange, className } = this.props | |
return ( | |
<Fragment>å | |
<Select | |
name={name} | |
options={options} | |
defaultValue={options[0]} | |
placeholder={placeholder} | |
onChange={onChange} | |
styles={customStyles} | |
className={className} | |
classNamePrefix="select" | |
isDisabled={isDisabled} | |
isLoading={isLoading} | |
isClearable={isClearable} | |
isRtl={isRtl} | |
isSearchable={isSearchable} | |
/> | |
</Fragment> | |
) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment