-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat(timer): <Timer /> 컴포넌트 추가 * feat(timer): Hooks 추가 * fix: Timer 타입 수정 & size default: "small" * fix: 시간 예외처리 추가 --------- Co-authored-by: baegofda <[email protected]>
- Loading branch information
Showing
17 changed files
with
334 additions
and
13 deletions.
There are no files selected for viewing
43 changes: 43 additions & 0 deletions
43
packages/travelmakers-design-core/src/components/Timer/Timer.style.ts
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,43 @@ | ||
import { TmFontSizes, createStyles } from "@travelmakers-design-v2/styles"; | ||
import { Props, TIMER_COLOR } from "./Timer"; | ||
import { TimerSize } from "./Timer.type"; | ||
|
||
const TIMER_TEXT_FONT: Record<TimerSize, TmFontSizes> = { | ||
small: "body3", | ||
large: "body2", | ||
}; | ||
|
||
const TIMER_TIME_FONT: Record<TimerSize, TmFontSizes> = { | ||
small: "body3", | ||
large: "subhead2", | ||
}; | ||
|
||
export default createStyles( | ||
(theme, { type, size }: Pick<Props, "type" | "size">) => { | ||
const { colors, typography, spacing } = theme; | ||
|
||
return { | ||
root: { | ||
display: "flex", | ||
alignItems: "center", | ||
justifyContent: "space-between", | ||
color: colors[TIMER_COLOR[type]], | ||
}, | ||
title: { | ||
display: "flex", | ||
alignItems: "center", | ||
}, | ||
icon: { | ||
marginRight: spacing.spacing5, | ||
}, | ||
text: { | ||
...typography[TIMER_TEXT_FONT[size]], | ||
fontWeight: 400, | ||
}, | ||
time: { | ||
...typography[TIMER_TIME_FONT[size]], | ||
fontWeight: 700, | ||
}, | ||
}; | ||
} | ||
); |
78 changes: 78 additions & 0 deletions
78
packages/travelmakers-design-core/src/components/Timer/Timer.tsx
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,78 @@ | ||
"use client"; | ||
|
||
import { useRemainingTimer } from "@travelmakers-design-v2/hooks"; | ||
import { | ||
PolymorphicRef, | ||
TmColor, | ||
useTmTheme, | ||
} from "@travelmakers-design-v2/styles"; | ||
import dayjs from "dayjs"; | ||
import { forwardRef } from "react"; | ||
import { Icon } from "../Icon"; | ||
import { View } from "../View"; | ||
import useStyles from "./Timer.style"; | ||
import { TimerComponent, TimerProps, TimerSize, TimerType } from "./Timer.type"; | ||
|
||
export interface Props { | ||
type: TimerType; | ||
size?: TimerSize; | ||
text: "string"; | ||
time: dayjs.ConfigType; | ||
dateTime?: string; | ||
} | ||
|
||
const TIMER_ICON_SIZE: Record<TimerSize, number> = { | ||
small: 12, | ||
large: 16, | ||
}; | ||
|
||
export const TIMER_COLOR: Record<TimerType, TmColor> = { | ||
navy: "primary1", | ||
white: "white", | ||
}; | ||
|
||
export const Timer: TimerComponent & { | ||
displayName?: string; | ||
} = forwardRef( | ||
<C extends React.ElementType = "div">( | ||
{ | ||
type, | ||
size = "small", | ||
text, | ||
time, | ||
dateTime, | ||
className, | ||
...props | ||
}: TimerProps<C>, | ||
ref: PolymorphicRef<C> | ||
) => { | ||
const { colors } = useTmTheme(); | ||
const { classes, cx } = useStyles({ type, size }); | ||
const { remainingTime } = useRemainingTimer(time); | ||
|
||
return ( | ||
<View<React.ElementType> | ||
component={"div"} | ||
ref={ref} | ||
className={cx(classes.root, className)} | ||
{...props} | ||
> | ||
<div className={classes.title}> | ||
<Icon | ||
src={"IcClock"} | ||
className={classes.icon} | ||
width={TIMER_ICON_SIZE[size]} | ||
height={TIMER_ICON_SIZE[size]} | ||
color={colors[TIMER_COLOR[type]]} | ||
/> | ||
<strong className={classes.text}>{text}</strong> | ||
</div> | ||
<time className={classes.time} dateTime={dateTime}> | ||
{remainingTime} | ||
</time> | ||
</View> | ||
); | ||
} | ||
); | ||
|
||
Timer.displayName = "Timer"; |
23 changes: 23 additions & 0 deletions
23
packages/travelmakers-design-core/src/components/Timer/Timer.type.ts
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,23 @@ | ||
import { | ||
ClassNames, | ||
PolymorphicComponentProps, | ||
TmComponentProps, | ||
} from "@travelmakers-design-v2/styles"; | ||
import { Props } from "./Timer"; | ||
import useStyles from "./Timer.style"; | ||
|
||
export type TimerType = "navy" | "white"; | ||
export type TimerSize = "small" | "large"; | ||
|
||
type TimerStylesNames = ClassNames<typeof useStyles>; | ||
|
||
interface SharedTimerProps extends Props, TmComponentProps<TimerStylesNames> {} | ||
|
||
export type TimerProps<C extends React.ElementType> = PolymorphicComponentProps< | ||
C, | ||
SharedTimerProps | ||
>; | ||
|
||
export type TimerComponent = <C extends React.ElementType = "div">( | ||
props: TimerProps<C> | ||
) => React.ReactElement; |
2 changes: 2 additions & 0 deletions
2
packages/travelmakers-design-core/src/components/Timer/index.ts
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,2 @@ | ||
export { Timer } from "./Timer"; | ||
export type { TimerProps } from "./Timer.type"; |
78 changes: 78 additions & 0 deletions
78
packages/travelmakers-design-core/src/components/Timer/stories/Timer.stories.tsx
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,78 @@ | ||
import { Meta } from "@storybook/react"; | ||
import { getDayjs } from "@travelmakers-design-v2/utils"; | ||
import { Timer } from "../Timer"; | ||
|
||
export default { | ||
title: "@travelmakers-design-v2/core/General/Timer", | ||
component: Timer, | ||
argTypes: { | ||
type: { | ||
control: { type: "radio", options: ["navy", "white"], default: "navy" }, | ||
description: "Timer의 색상 타입", | ||
table: { | ||
type: { | ||
summary: "string", | ||
}, | ||
}, | ||
}, | ||
size: { | ||
control: { type: "radio", options: ["small", "large"], default: "small" }, | ||
defaultValue: "small", | ||
description: "Timer의 사이즈", | ||
table: { | ||
type: { | ||
summary: "string", | ||
}, | ||
}, | ||
}, | ||
text: { | ||
control: { type: "text" }, | ||
defaultValue: "타임세일 워딩", | ||
description: "타임 세일에 대한 워딩", | ||
table: { | ||
type: { | ||
summary: "string", | ||
}, | ||
}, | ||
}, | ||
time: { | ||
control: { type: "text" }, | ||
description: | ||
"타임 세일 기간 ex) Thu Apr 06 2023 10:52:19 GMT+0900 (한국 표준시)", | ||
table: { | ||
type: { | ||
summary: "dayjs.ConfigType", | ||
}, | ||
}, | ||
}, | ||
// https://developer.mozilla.org/ko/docs/Web/HTML/Element/time | ||
dateTime: { | ||
control: { type: "text" }, | ||
defaultValue: "2011-11-18", | ||
description: "검색 엔진에서 필요한 날짜 데이터 입니다.", | ||
table: { | ||
type: { | ||
summary: "string", | ||
}, | ||
}, | ||
}, | ||
}, | ||
} as Meta; | ||
|
||
export const Default = (props) => { | ||
const { time, type, size, text, dateTime } = props; | ||
const dayjs = getDayjs(); | ||
const now = dayjs(); | ||
|
||
return ( | ||
<div style={{ backgroundColor: props.type === "white" && "gray" }}> | ||
<Timer | ||
time={time || now} | ||
type={type} | ||
size={size} | ||
text={text} | ||
dateTime={dateTime} | ||
/> | ||
</div> | ||
); | ||
}; |
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
2 changes: 1 addition & 1 deletion
2
packages/travelmakers-design-hooks/src/useRafState/stories/useRafState.stories.tsx
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
1 change: 1 addition & 0 deletions
1
packages/travelmakers-design-hooks/src/useRemainingTimer/index.ts
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 @@ | ||
export * from "./useRemainingTimer"; |
12 changes: 12 additions & 0 deletions
12
...ges/travelmakers-design-hooks/src/useRemainingTimer/stories/useRemainingTimer.stories.tsx
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,12 @@ | ||
import dayjs from "dayjs"; | ||
import { useRemainingTimer } from "../useRemainingTimer"; | ||
|
||
export default { | ||
title: "@travelmakers-design-v2/hooks/useRemainingTimer", | ||
}; | ||
|
||
export const Default = () => { | ||
const { remainingTime } = useRemainingTimer(dayjs()); | ||
|
||
return <div>{remainingTime}</div>; | ||
}; |
26 changes: 26 additions & 0 deletions
26
packages/travelmakers-design-hooks/src/useRemainingTimer/useRemainingTimer.ts
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,26 @@ | ||
import { getRemainingTime } from "@travelmakers-design-v2/utils"; | ||
import dayjs from "dayjs"; | ||
import { useLayoutEffect, useState } from "react"; | ||
|
||
export const useRemainingTimer = ( | ||
targetDate: dayjs.ConfigType, | ||
format?: string, | ||
delay?: 1000 | ||
) => { | ||
const [remainingTime, setRemainingTime] = useState(""); | ||
|
||
useLayoutEffect(() => { | ||
let timer: NodeJS.Timeout | null = null; | ||
|
||
timer = setInterval( | ||
() => setRemainingTime(getRemainingTime(targetDate, format)), | ||
delay | ||
); | ||
|
||
return () => { | ||
timer && clearInterval(timer); | ||
}; | ||
}, []); | ||
|
||
return { remainingTime }; | ||
}; |
4 changes: 2 additions & 2 deletions
4
packages/travelmakers-design-hooks/src/useTimeoutFn/useTimeoutFn.ts
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
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 |
---|---|---|
@@ -1,8 +1,9 @@ | ||
export * from "./getDate"; | ||
export * from "./getPayMethod"; | ||
export * from "./getReservationsCallable"; | ||
export * from "./getTimeLineFunc"; | ||
export * from "./getTimeLineStateFunc"; | ||
export * from "./getTimeLineStateDetailFunc"; | ||
export * from "./getReservationsCallable"; | ||
export * from "./getPayMethod"; | ||
export * from "./getDate"; | ||
export * from "./getTimeLineStateFunc"; | ||
export * from "./utils/getCountDown"; | ||
export * from "./utils/getRemainingTime"; | ||
export * from "./utils/getTimeStamp"; |
39 changes: 39 additions & 0 deletions
39
packages/travelmakers-design-utils/src/utils/getRemainingTime.ts
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,39 @@ | ||
import dayjs from "dayjs"; | ||
import duration from "dayjs/plugin/duration"; | ||
import timezone from "dayjs/plugin/timezone"; | ||
import utc from "dayjs/plugin/utc"; | ||
|
||
dayjs.extend(duration); | ||
dayjs.extend(utc); | ||
dayjs.extend(timezone); | ||
dayjs.tz.setDefault("Asia/Seoul"); | ||
|
||
/** | ||
* 현재 시간부터 목표 시간까지의 남은 시간을 구합니다. | ||
* | ||
* ex) | ||
* now: "Sat Feb 25 2023 02:27:29 GMT+0900" | ||
* targetDate: "2023-02-28 23:59:00" | ||
* format: "DD일 HH:mm:ss" | ||
* | ||
* return "05일 06:31:30" | ||
*/ | ||
export const getRemainingTime = ( | ||
targetDate: dayjs.ConfigType, | ||
format = "DD일 HH:mm:ss" | ||
) => { | ||
const target = dayjs(targetDate); | ||
const now = dayjs(); | ||
const diff = target.diff(now); | ||
const isReachedTime = now.isSame(target) || diff <= 0; | ||
if (isReachedTime) return "00:00:00"; | ||
|
||
const days = dayjs.duration(diff).days(); | ||
|
||
// NOTE: 당일이라면 일자는 표시x | ||
if (days === 0) { | ||
return dayjs(diff).format("HH:mm:ss"); | ||
} | ||
|
||
return dayjs(diff).format(format); | ||
}; |