-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* react-hook-form 설치 * ControlledLiveToggle 컴포넌트 추가 * react hook form 기반으로 Form 컴포넌트 추가 * debounce util 추가 * Form 컴포넌트 기반으로 페이지 로직 변경 * Form에 value type 지정
- Loading branch information
Showing
6 changed files
with
157 additions
and
101 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import React, { useEffect } from 'react'; | ||
|
||
import useToggle from 'hooks/useToggle'; | ||
|
||
import LiveToggle from 'components/LiveToggle'; | ||
import { useFormContext } from 'react-hook-form'; | ||
|
||
type Props = { | ||
name: string; | ||
}; | ||
|
||
function ControlledLiveToggle({ name }: Props) { | ||
const [isLiveMode, toggleIsLiveMode] = useToggle(true); | ||
|
||
const { setValue, register } = useFormContext(); | ||
|
||
useEffect(() => { | ||
register(name); | ||
}, [name, register]); | ||
|
||
useEffect(() => { | ||
setValue(name, isLiveMode); | ||
}, [name, isLiveMode, setValue]); | ||
|
||
return <LiveToggle value={isLiveMode} onClick={toggleIsLiveMode} />; | ||
} | ||
|
||
export default ControlledLiveToggle; |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
import React, { useEffect } from 'react'; | ||
|
||
import { debounce } from 'utils'; | ||
import { objectToQueryString } from 'utils/string'; | ||
|
||
import { FormProvider, useForm } from 'react-hook-form'; | ||
import ControlledLiveToggle from 'components/ControlledLiveToggle'; | ||
|
||
type FormValues = { | ||
liveMode: boolean; | ||
dateString: string; | ||
size: string; | ||
theme: string; | ||
rotate: string; | ||
}; | ||
|
||
type Props = { | ||
onChange: (v: string) => void; | ||
}; | ||
|
||
function MoonForm({ onChange }: Props) { | ||
const formMethods = useForm<FormValues>({ | ||
defaultValues: { | ||
liveMode: true, | ||
dateString: '', | ||
size: '', | ||
theme: 'basic', | ||
rotate: '0', | ||
}, | ||
}); | ||
|
||
const { register, watch } = formMethods; | ||
|
||
const liveMode = watch('liveMode'); | ||
|
||
useEffect(() => { | ||
const subscription = watch( | ||
debounce(({ liveMode, dateString, size, theme, rotate }: FormValues) => { | ||
const queryString = objectToQueryString({ | ||
liveMode, | ||
date: liveMode ? '' : dateString, | ||
size, | ||
theme, | ||
rotate, | ||
}); | ||
|
||
onChange(queryString); | ||
}, 100), | ||
); | ||
return () => subscription.unsubscribe(); | ||
}, [watch, onChange]); | ||
|
||
return ( | ||
<FormProvider {...formMethods}> | ||
<ControlledLiveToggle name="liveMode" /> | ||
{!liveMode && ( | ||
<div className="form-control w-full max-w-xs"> | ||
<label className="label"> | ||
<span className="label-text">Date</span> | ||
</label> | ||
<input | ||
type="date" | ||
className="input input-bordered w-full max-w-xs" | ||
{...register('dateString')} | ||
/> | ||
</div> | ||
)} | ||
<div className="form-control w-full max-w-xs"> | ||
<label className="label" htmlFor="theme"> | ||
<span className="label-text">Theme</span> | ||
</label> | ||
<select | ||
id="theme" | ||
className="select input-bordered w-full max-w-xs" | ||
{...register('theme')} | ||
> | ||
<option value="basic">Basic</option> | ||
<option value="ray">Ray</option> | ||
</select> | ||
</div> | ||
<div className="form-control w-full max-w-xs"> | ||
<label className="label"> | ||
<span className="label-text">Rotate</span> | ||
</label> | ||
<input | ||
type="range" | ||
min="0" | ||
max="360" | ||
className="range" | ||
{...register('rotate')} | ||
/> | ||
</div> | ||
<div className="form-control w-full max-w-xs"> | ||
<label className="label"> | ||
<span className="label-text">Size</span> | ||
</label> | ||
<input | ||
type="number" | ||
placeholder="100 (default)" | ||
className="input input-bordered w-full max-w-xs" | ||
{...register('size')} | ||
/> | ||
</div> | ||
</FormProvider> | ||
); | ||
} | ||
|
||
export default MoonForm; |
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
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
export const debounce = (fn: Function, ms = 100) => { | ||
let timeoutId: ReturnType<typeof setTimeout>; | ||
return function (this: any, ...args: any[]) { | ||
clearTimeout(timeoutId); | ||
timeoutId = setTimeout(() => fn.apply(this, args), ms); | ||
}; | ||
}; |
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
2fab17d
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs:
moon-svg – ./
moon-svg-hmu332233.vercel.app
moon-phase.vercel.app
moon-svg.minung.dev
moon-svg-git-main-hmu332233.vercel.app