-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
* feat: ProgressBar 컴포넌트 구현 - 스토리북 작성 * refactor: 모임 생성 > 상세 정보 스텝에 heading 문구 추가 * feat: stroke 조절이 가능한 check icon 추가 * feat: Stepper 컴포넌트 구현 * feat: Stepper 스토리북 작성 * feat: 모임 생성 퍼널에 stepper 적용 * fix: stepper 애니메이션 수정, 라벨 추가 * fix: useRemoveVerticalScroll hook enabled option이 없는 경우 바로 scroll 제거하도록 수정 * fix: 모임 생성 퍼널 > 이름 작성 스텝에서 scroll 제거 * feat: focus일 때 scroll을 제거하는 withScrollLockOnFocus hoc 구현 * feat: 모임 생성 퍼널 > 모임 정보 설정 스텝에 input, textarea focus 시 scroll 제거 기능 구현 - withScrollLockOnFoucs hoc 적용 * feat: 모임 생성 퍼널 > 가입 유형 스텝 input focus시 scroll 제거 * refactor: stepper 컴포넌트 첫 스텝에서 opacity animation 제거 * fix: nextconfig next image kakaocdn hostname *로 수정 * fix: label이 없는 경우 width 애니메이션 제거
- Loading branch information
Showing
15 changed files
with
260 additions
and
13 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
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
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,25 @@ | ||
import { forwardRef, Ref, useState } from 'react'; | ||
|
||
import useRemoveVerticalScroll from '@/hooks/useRemoveVerticalScroll'; | ||
|
||
const withScrollLockOnFocus = <P extends object>( | ||
WrappedComponent: React.ComponentType<P> | ||
) => { | ||
const Component = (props: P, ref: Ref<HTMLElement>) => { | ||
const [focus, setFocus] = useState(false); | ||
useRemoveVerticalScroll({ enabled: focus }); | ||
|
||
return ( | ||
<WrappedComponent | ||
{...props} | ||
onFocus={() => setFocus(true)} | ||
onBlur={() => setFocus(false)} | ||
ref={ref} | ||
/> | ||
); | ||
}; | ||
|
||
return forwardRef(Component); | ||
}; | ||
|
||
export default withScrollLockOnFocus; |
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,16 @@ | ||
import { Meta, StoryObj } from '@storybook/react'; | ||
import ProgressBar from '@/v1/base/ProgressBar'; | ||
|
||
const meta: Meta<typeof ProgressBar> = { | ||
title: 'Base/ProgressBar', | ||
component: ProgressBar, | ||
tags: ['autodocs'], | ||
}; | ||
|
||
export default meta; | ||
|
||
type Story = StoryObj<typeof ProgressBar>; | ||
|
||
export const Default: Story = { | ||
args: { value: 30 }, | ||
}; |
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,24 @@ | ||
import { Meta, StoryObj } from '@storybook/react'; | ||
import Stepper from '@/v1/base/Stepper'; | ||
|
||
const meta: Meta<typeof Stepper> = { | ||
title: 'Base/Stepper', | ||
component: Stepper, | ||
tags: ['autodocs'], | ||
}; | ||
|
||
export default meta; | ||
|
||
type Story = StoryObj<typeof Stepper>; | ||
|
||
export const Default: Story = { | ||
args: { activeIndex: 0 }, | ||
|
||
render: args => ( | ||
<Stepper {...args}> | ||
<Stepper.Step /> | ||
<Stepper.Step /> | ||
<Stepper.Step /> | ||
</Stepper> | ||
), | ||
}; |
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,29 @@ | ||
/** | ||
* @param value percentage | ||
*/ | ||
const ProgressBar = ({ | ||
value, | ||
className, | ||
}: { | ||
value: number; | ||
className?: string; | ||
}) => { | ||
return ( | ||
<div | ||
className={ | ||
'absolute inset-x-0 h-[0.2rem] w-full overflow-hidden ' + className | ||
} | ||
> | ||
<div className="absolute h-full w-full bg-main-500" /> | ||
<div | ||
className="absolute h-full w-full bg-main-900" | ||
style={{ | ||
transform: `translateX(-${100 - value}%)`, | ||
transition: 'transform 0.4s ease-in-out', | ||
}} | ||
/> | ||
</div> | ||
); | ||
}; | ||
|
||
export default ProgressBar; |
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,113 @@ | ||
import { | ||
Children, | ||
createContext, | ||
PropsWithChildren, | ||
ReactNode, | ||
useContext, | ||
} from 'react'; | ||
|
||
import { IconCheckStroke } from '@public/icons'; | ||
import ProgressBar from '@/v1/base/ProgressBar'; | ||
|
||
type StepStatus = 'complete' | 'incomplete' | 'active'; | ||
|
||
type StepContextValues = { | ||
index: number; | ||
status: StepStatus; | ||
count: number; | ||
}; | ||
|
||
const StepperContext = createContext<StepContextValues>( | ||
{} as StepContextValues | ||
); | ||
|
||
const Stepper = ({ | ||
activeIndex, | ||
children, | ||
}: PropsWithChildren<{ activeIndex: number }>) => { | ||
const stepElements = Children.toArray(children); | ||
const stepCount = stepElements.length; | ||
|
||
const progressPercent = | ||
activeIndex === 0 ? 0 : Math.ceil((activeIndex / (stepCount - 1)) * 100); | ||
|
||
const getStepStatus = (step: number): StepStatus => { | ||
if (step < activeIndex) return 'complete'; | ||
if (step > activeIndex) return 'incomplete'; | ||
return 'active'; | ||
}; | ||
|
||
return ( | ||
<div className="relative z-[1] flex w-full items-center justify-between"> | ||
<ProgressBar value={progressPercent} className="-z-[1]" /> | ||
{stepElements.map((child, index) => ( | ||
<StepperContext.Provider | ||
key={index} | ||
value={{ index, status: getStepStatus(index), count: stepCount }} | ||
> | ||
{child} | ||
</StepperContext.Provider> | ||
))} | ||
</div> | ||
); | ||
}; | ||
|
||
const getStepClasses = (status: StepStatus, label?: string) => { | ||
switch (status) { | ||
case 'complete': | ||
return 'bg-main-900'; | ||
// TODO: label text width 계산 로직 추가 | ||
case 'active': | ||
return `bg-main-900 ${label ? 'w-[7.4rem]' : ''}`; | ||
case 'incomplete': | ||
default: | ||
return 'bg-main-500'; | ||
} | ||
}; | ||
|
||
const Step = ({ | ||
label, | ||
children, | ||
}: { | ||
label?: string; | ||
children?: ReactNode; | ||
}) => { | ||
const { status, index } = useContext(StepperContext); | ||
|
||
const statusClasses = getStepClasses(status, label); | ||
const labelPositionClass = label | ||
? 'self-baseline px-[1.2rem]' | ||
: 'self-center'; | ||
|
||
// 첫번째 스텝이 아니고, 라벨 text가 있는 경우만 opacity transition 적용 | ||
const activeAnimationClasses = | ||
index !== 0 && label ? 'opacity-0 animate-stepper-transition' : 'opacity-1'; | ||
|
||
const stepNumberToRender = index + 1; | ||
const labelToRender = label ? label : stepNumberToRender; | ||
|
||
return ( | ||
<div | ||
className={`relative flex h-[3rem] w-[3rem] shrink-0 flex-col items-center justify-center rounded-full duration-500 ${statusClasses} overflow-hidden`} | ||
> | ||
{status === 'complete' ? ( | ||
<IconCheckStroke className="h-auto w-[1rem]" /> | ||
) : status === 'active' ? ( | ||
<p | ||
className={`relative whitespace-nowrap text-white font-body2-bold ${activeAnimationClasses} ${labelPositionClass}`} | ||
> | ||
{labelToRender} | ||
</p> | ||
) : ( | ||
<p className="relative text-white font-body2-bold"> | ||
{stepNumberToRender} | ||
</p> | ||
)} | ||
{children} | ||
</div> | ||
); | ||
}; | ||
|
||
Stepper.Step = Step; | ||
|
||
export default Stepper; |
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
Oops, something went wrong.