)
-}
+})
-function Title({ className, children }: TitleProps) {
- return
{children}
+function Title({ className, children, required, errorMessage }: TitleProps) {
+ return (
+
+
+
+ {children}
+ {required && (
+
+ *
+
+ )}
+
+
+ {errorMessage && (
+
+ {errorMessage}
+
+ )}
+
+ )
}
function Content({ className, children }: ContentProps) {
@@ -44,11 +74,12 @@ function Content({ className, children }: ContentProps) {
* @features
* - 기본 스타일: `rounded-base`, `p-large`, `shadow-drop`, `flex-col gap-medium`
* - `className`을 통해 스타일 확장 가능
+ * - Title에 `errorMessage` 프롭을 전달하면 타이틀 옆에 에러 메시지 표시
*
* @example
* ```tsx
*
- * 컨테이너 타이틀
+ * 컨테이너 타이틀
* 내용이 들어갑니다
*
* ```
diff --git a/src/shared/ui/Datepicker.tsx b/src/shared/ui/Datepicker.tsx
index eb7876c..a9a1200 100644
--- a/src/shared/ui/Datepicker.tsx
+++ b/src/shared/ui/Datepicker.tsx
@@ -1,6 +1,7 @@
import { format } from 'date-fns'
import { CalendarDays } from 'lucide-react'
import * as React from 'react'
+import type { Matcher } from 'react-day-picker'
import { cn } from '@/shared/lib/utils'
import { Calendar } from '@/shared/ui/Calendar'
@@ -11,6 +12,8 @@ type DatePickerProps = {
onChange: (date: Date | null) => void
placeholder?: string
className?: string
+ disabled?: Matcher | Matcher[]
+ isDisabled?: boolean
}
/**
@@ -27,7 +30,10 @@ type DatePickerProps = {
* ```
*/
-function DatePicker({ value, onChange, placeholder = '날짜 선택', className }: DatePickerProps) {
+const DatePicker = React.forwardRef
(function DatePicker(
+ { value, onChange, placeholder = '날짜 선택', className, disabled, isDisabled = false },
+ ref
+) {
const [date, setDate] = React.useState(value)
React.useEffect(() => {
@@ -43,26 +49,34 @@ function DatePicker({ value, onChange, placeholder = '날짜 선택', className
-
+
)
-}
+})
export { DatePicker }
diff --git a/src/shared/ui/Input.tsx b/src/shared/ui/Input.tsx
index d6521cc..21ecc60 100644
--- a/src/shared/ui/Input.tsx
+++ b/src/shared/ui/Input.tsx
@@ -42,18 +42,10 @@ type InputProps = React.ComponentProps<'input'> & {
*
* ```
*/
-function Input({
- className,
- type,
- label,
- error,
- errorMessage,
- helperText,
- maxLength,
- disabled,
- value,
- ...props
-}: InputProps) {
+const Input = React.forwardRef(function Input(
+ { className, type, label, error, errorMessage, helperText, maxLength, disabled, value, ...props },
+ ref
+) {
const currentLength = typeof value === 'string' ? value.length : 0
const showCount = maxLength !== undefined
const showFooter = error || helperText || showCount
@@ -62,6 +54,7 @@ function Input({
{label &&
{label}
}
)
-}
+})
export { Input }
diff --git a/src/shared/ui/Select.tsx b/src/shared/ui/Select.tsx
index c4b06e1..6e05635 100644
--- a/src/shared/ui/Select.tsx
+++ b/src/shared/ui/Select.tsx
@@ -38,22 +38,30 @@ function SelectTrigger({
label,
...props
}: React.ComponentProps
& { label?: string }) {
+ const trigger = (
+
+ {children}
+
+
+
+
+ )
+
+ if (!label) {
+ return trigger
+ }
+
return (
- {label &&
{label}
}
-
- {children}
-
-
-
-
+
{label}
+ {trigger}
)
}
diff --git a/src/vite-env.d.ts b/src/vite-env.d.ts
index e2d7f08..589d602 100644
--- a/src/vite-env.d.ts
+++ b/src/vite-env.d.ts
@@ -3,6 +3,7 @@
interface ImportMetaEnv {
readonly VITE_API_URL: string
readonly VITE_APP_URL: string
+ readonly VITE_KAKAO_MAP_KEY: string
}
interface ImportMeta {