feat: using react-select

This commit is contained in:
원더 2021-02-01 20:49:02 +09:00
parent b283853e92
commit 7a900f6a12
3 changed files with 50 additions and 56 deletions

View File

@ -1,18 +1,28 @@
import { Field } from 'formik' import ReactSelect from 'react-select'
const Select = ({ name, options }:SelectProps):JSX.Element => { const Select = ({ placeholder, options, handleChange, handleTouch }:SelectProps):JSX.Element => {
return <Field as='select' name={name} className='text-black w-full h-10 border border-grey-light rounded px-3 relative focus:shadow outline-none'> return <ReactSelect styles={{
{ control: (provided) => {
options.map(o => ( return { ...provided, border: 'none' }
<option key={o}>{o}</option> },
)) option: (provided) => {
return { ...provided, cursor: 'pointer', ':hover': {
opacity: '0.7'
} }
} }
</Field> }} className='border border-grey-light dark:border-transparent' classNamePrefix='outline-none text-black dark:bg-very-black dark:text-white ' placeholder={placeholder || '선택해주세요.'} options={options} onChange={handleChange} onBlur={handleTouch} noOptionsMessage={() => '검색 결과가 없습니다.'}/>
} }
interface SelectProps { interface SelectProps {
name: string placeholder?: string
options: string[] handleChange: (value: Option) => void
handleTouch: () => void
options: Option[]
}
interface Option {
value: string
label: string
} }
export default Select export default Select

View File

@ -1,47 +1,28 @@
import Tag from '@components/Tag' import ReactSelect from 'react-select'
import { FieldArray, useFormik } from 'formik'
const Selects = ({ name, value, options }:SelectsProps):JSX.Element => { const Select = ({ placeholder, options, handleChange, handleTouch }:SelectProps):JSX.Element => {
const formik = useFormik({ return <ReactSelect styles={{
initialValues: { control: (provided) => {
search: '' return { ...provided, border: 'none' }
}, },
onSubmit: () => { console.log('Submit') } option: (provided) => {
}) return { ...provided, cursor: 'pointer', ':hover': {
return <div className='w-full'> opacity: '0.7'
<input name='search' className='text-black w-full h-10 border border-grey-light rounded px-3 focus:shadow outline-none' value={formik.values.search} onChange={formik.handleChange}/> } }
<FieldArray name={name} >
{
({ insert, remove, push }) => (
<>
<div className='rounded shadow-md my-2 pin-t pin-l dark:bg-very-black h-60 overflow-y-scroll w-full'>
<ul>
{
options.filter(el => el.includes(formik.values.search) && !value.includes(el)).length !== 0 ? options.filter(el => el.includes(formik.values.search) && !value.includes(el)).map(el=> (
<li key={el} className='cursor-pointer px-3 py-3.5 hover:bg-discord-dark-hover' onClick={()=> push(el)} onKeyPress={()=> push(el)} >{el}</li>
)) : <li className='px-3 py-3.5'> .</li>
} }
</ul> }} isMulti className='border border-grey-light dark:border-transparent' classNamePrefix='outline-none text-black dark:bg-very-black dark:text-white cursor-pointer ' placeholder={placeholder || '선택해주세요.'} options={options} onChange={handleChange} onBlur={handleTouch} noOptionsMessage={() => '검색 결과가 없습니다.'}/>
</div>
<div className='flex flex-wrap'>
{
value.map(el => (
<Tag key={el} text={<>{el} <i className='fas fa-times' /></>} className='cursor-pointer' onClick={() => remove(value.indexOf(el))} />
))
}
</div>
</>
)
}
</FieldArray>
</div>
} }
interface SelectsProps { interface SelectProps {
name: string placeholder?: string
value: string[] handleChange: (value: Option[]) => void
options: string[] handleTouch: () => void
options: Option[]
} }
export default Selects interface Option {
value: string
label: string
}
export default Select

View File

@ -2,7 +2,7 @@ import { NextPage, NextPageContext } from 'next'
import { useRouter } from 'next/router' import { useRouter } from 'next/router'
import dynamic from 'next/dynamic' import dynamic from 'next/dynamic'
import Link from 'next/link' import Link from 'next/link'
import { Form, Formik } from 'formik' import { FieldArray, Form, Formik } from 'formik'
import { get } from '@utils/Query' import { get } from '@utils/Query'
import { parseCookie, redirectTo } from '@utils/Tools' import { parseCookie, redirectTo } from '@utils/Tools'
@ -47,7 +47,7 @@ const AddBot:NextPage<AddBotProps> = ({ logged }) => {
}} }}
validationSchema={AddBotSubmitSchema} validationSchema={AddBotSubmitSchema}
onSubmit={() => { alert('Submit') }}> onSubmit={() => { alert('Submit') }}>
{({ errors, touched, values }) => ( {({ errors, touched, values, setFieldTouched, setFieldValue }) => (
<Form> <Form>
{JSON.stringify(errors)} {JSON.stringify(errors)}
{JSON.stringify(touched)} {JSON.stringify(touched)}
@ -81,10 +81,13 @@ const AddBot:NextPage<AddBotProps> = ({ logged }) => {
<Input name='prefix' placeholder='!' /> <Input name='prefix' placeholder='!' />
</Label> </Label>
<Label For='library' label='라이브러리' labelDesc='봇에 사용된 라이브러리를 선택해주세요. 해당되는 라이브러리가 없다면 기타를 선택해주세요.' short required error={errors.library && touched.library ? errors.library : null}> <Label For='library' label='라이브러리' labelDesc='봇에 사용된 라이브러리를 선택해주세요. 해당되는 라이브러리가 없다면 기타를 선택해주세요.' short required error={errors.library && touched.library ? errors.library : null}>
<Select name='library' options={library} /> <Select options={library.map(el=> ({ label: el, value: el }))} handleChange={(value) => setFieldValue('library', value.value)} handleTouch={() => setFieldTouched('library', true)} />
</Label> </Label>
<Label For='category' label='카테고리' labelDesc='봇에 해당되는 카테고리를 선택해주세요' required error={errors.category && touched.category ? errors.category : null}> <Label For='category' label='카테고리' labelDesc='봇에 해당되는 카테고리를 선택해주세요' required error={errors.category as string}>
<Selects name='category' value={values.category} options={categories} /> <Selects options={categories.map(el=> ({ label: el, value: el }))} handleChange={(value) => {
console.log(value)
setFieldValue('category', value.map(v=> v.value))
}} handleTouch={() => setFieldTouched('category', true)} />
</Label> </Label>
<Divider /> <Divider />
<Label For='website' label='웹사이트' labelDesc='봇의 웹사이트를 작성해주세요.' error={errors.website && touched.website ? errors.website : null}> <Label For='website' label='웹사이트' labelDesc='봇의 웹사이트를 작성해주세요.' error={errors.website && touched.website ? errors.website : null}>