cashdoc-cms-design-system 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/Button/Button.d.ts +116 -0
- package/dist/components/Checkbox/Checkbox.d.ts +79 -0
- package/dist/components/DatePicker/DatePicker.d.ts +82 -0
- package/dist/components/DatePicker/index.d.ts +0 -2
- package/dist/components/DateRangePicker/DateRangePicker.d.ts +93 -0
- package/dist/components/DateRangePicker/index.d.ts +2 -0
- package/dist/components/Dropdown/Combobox.d.ts +78 -0
- package/dist/components/Dropdown/Dropdown.d.ts +81 -0
- package/dist/components/Dropdown/Select.d.ts +78 -0
- package/dist/components/LoadingCircle/LoadingCircle.d.ts +70 -0
- package/dist/components/Modal/ConfirmModal.d.ts +24 -0
- package/dist/components/Modal/DeleteModal.d.ts +19 -0
- package/dist/components/Modal/ErrorModal.d.ts +20 -0
- package/dist/components/Modal/Modal.d.ts +171 -0
- package/dist/components/Modal/SuccessModal.d.ts +19 -0
- package/dist/components/Modal/WarningModal.d.ts +21 -0
- package/dist/components/Popover/Popover.d.ts +70 -0
- package/dist/components/Popover/PopoverMenuItem.d.ts +25 -0
- package/dist/components/RadioButton/RadioButton.d.ts +71 -0
- package/dist/components/SideNavigation/SideNavigation.d.ts +77 -0
- package/dist/components/Switch/Switch.d.ts +60 -0
- package/dist/components/TagInput/TagInput.d.ts +96 -0
- package/dist/components/Text/Text.d.ts +57 -0
- package/dist/components/TextInput/TextInput.d.ts +78 -0
- package/dist/components/Toast/Toaster.d.ts +78 -0
- package/dist/components/icons/ChevronRightIcon.d.ts +11 -0
- package/dist/components/index.d.ts +1 -0
- package/dist/index.es.js +1613 -1569
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +12 -12
- package/dist/index.umd.js.map +1 -1
- package/dist/style.css +1 -1
- package/package.json +1 -1
- package/dist/components/DatePicker/DateRangePicker.d.ts +0 -14
|
@@ -2,5 +2,75 @@ interface LoadingCircleProps {
|
|
|
2
2
|
size?: "sm" | "md" | "lg";
|
|
3
3
|
className?: string;
|
|
4
4
|
}
|
|
5
|
+
/**
|
|
6
|
+
* 시스템이 데이터를 처리 중이거나 다음 화면을 준비 중임을 시각적으로 나타내는 인디케이터입니다.
|
|
7
|
+
*
|
|
8
|
+
* {@link LoadingCircle}은 회전하는 원형 애니메이션을 통해 작업이 진행 중임을 알려
|
|
9
|
+
* 사용자가 시스템이 멈춘 것으로 오해하지 않도록 돕습니다.
|
|
10
|
+
*
|
|
11
|
+
* ## When (언제 사용해야 하는가)
|
|
12
|
+
*
|
|
13
|
+
* **사용해야 하는 경우:**
|
|
14
|
+
* - **데이터 로딩**: 페이지 진입 시 API로부터 데이터를 불러올 때
|
|
15
|
+
* - **작업 처리 중**: 버튼 클릭 후 서버 응답을 기다릴 때
|
|
16
|
+
* - **업로드/다운로드**: 파일 전송 상태를 표시할 때
|
|
17
|
+
* - **점진적 로딩**: 무한 스크롤 등 하단에 추가 데이터를 불러올 때
|
|
18
|
+
*
|
|
19
|
+
* **사용하지 말아야 하는 경우:**
|
|
20
|
+
* - **짧은 대기 시간**: 0.3초 미만의 아주 짧은 대기 시간에는 오히려 화면을 깜빡거리게 할 수 있으므로 생략하는 것이 좋습니다.
|
|
21
|
+
* - **진행률 표시**: 전체 작업 중 어느 정도 진행되었는지 정확한 수치가 중요한 경우 Progress Bar를 고려하세요.
|
|
22
|
+
*
|
|
23
|
+
* ## Layout behavior
|
|
24
|
+
*
|
|
25
|
+
* - **Centered**: 기본적으로 컨테이너의 중앙에 배치되도록 설정되어 있습니다.
|
|
26
|
+
* - **Fixed vs Inline**: 페이지 전체 로딩 시에는 고정된 위치(Overlay)에, 버튼 내부 등에는 인라인으로 배치할 수 있습니다.
|
|
27
|
+
*
|
|
28
|
+
* ## Usage guidelines
|
|
29
|
+
*
|
|
30
|
+
* ### ✅ Do (권장 사항)
|
|
31
|
+
*
|
|
32
|
+
* - **적절한 크기 선택**: 로딩이 일어나는 맥락(페이지 전체, 카드 내부, 버튼 내부 등)에 맞는 `size`를 선택하세요.
|
|
33
|
+
* - **텍스트와 병행**: 필요한 경우 '불러오는 중...'과 같은 텍스트를 함께 표시하여 의미를 더 명확히 하세요.
|
|
34
|
+
*
|
|
35
|
+
* ### 🚫 Don't (주의/금지 사항)
|
|
36
|
+
*
|
|
37
|
+
* - **남용 지양**: 한 화면에 너무 많은 로딩 서클이 동시에 나타나면 사용자에게 피로감을 줄 수 있습니다.
|
|
38
|
+
* - **무한 로딩**: 작업이 실패한 경우 로딩을 멈추고 적절한 에러 메시지를 표시해야 합니다.
|
|
39
|
+
*
|
|
40
|
+
* ## Accessibility
|
|
41
|
+
*
|
|
42
|
+
* - **Role**: `role="status"` 또는 `role="progressbar"`를 사용하여 현재 상태를 스크린 리더에 알립니다.
|
|
43
|
+
* - **Aria Label**: 시각적으로 확인이 어려운 사용자를 위해 `aria-label="로딩 중"`과 같은 정보를 제공하는 것이 좋습니다.
|
|
44
|
+
*
|
|
45
|
+
* ## Example
|
|
46
|
+
*
|
|
47
|
+
* {@tool snippet}
|
|
48
|
+
* 기본적인 로딩 서클 사용 예시:
|
|
49
|
+
*
|
|
50
|
+
* ```tsx
|
|
51
|
+
* {isLoading ? (
|
|
52
|
+
* <LoadingCircle size="md" />
|
|
53
|
+
* ) : (
|
|
54
|
+
* <DataContent />
|
|
55
|
+
* )}
|
|
56
|
+
* ```
|
|
57
|
+
* {@end-tool}
|
|
58
|
+
*
|
|
59
|
+
* {@tool snippet}
|
|
60
|
+
* 버튼 내부의 로딩 상태:
|
|
61
|
+
*
|
|
62
|
+
* ```tsx
|
|
63
|
+
* <Button disabled={isSubmitting}>
|
|
64
|
+
* {isSubmitting && <LoadingCircle size="sm" className="mr-2" />}
|
|
65
|
+
* 제출하기
|
|
66
|
+
* </Button>
|
|
67
|
+
* ```
|
|
68
|
+
* {@end-tool}
|
|
69
|
+
*
|
|
70
|
+
* See also:
|
|
71
|
+
*
|
|
72
|
+
* - {@link Button}, 버튼 자체의 로딩 상태를 지원함
|
|
73
|
+
* - {@link Modal}, 로딩 상태를 포함할 수 있는 오버레이
|
|
74
|
+
*/
|
|
5
75
|
export declare function LoadingCircle({ size, className }: LoadingCircleProps): import("react/jsx-runtime").JSX.Element;
|
|
6
76
|
export {};
|
|
@@ -9,4 +9,28 @@ export interface ConfirmModalProps {
|
|
|
9
9
|
onConfirm?: () => void;
|
|
10
10
|
className?: string;
|
|
11
11
|
}
|
|
12
|
+
/**
|
|
13
|
+
* 사용자에게 특정 작업에 대한 최종 확인을 받기 위한 단순화된 모달 컴포넌트입니다.
|
|
14
|
+
*
|
|
15
|
+
* {@link ConfirmModal}은 {@link Modal}을 기반으로 구성되었으며, 상징적인 체크 아이콘과
|
|
16
|
+
* 하나의 '확인' 버튼만을 제공하여 사용자의 빠른 의사결정을 돕습니다.
|
|
17
|
+
* 주로 성공적인 처리 알림이나 단순한 동의가 필요할 때 사용됩니다.
|
|
18
|
+
*
|
|
19
|
+
* ## When (언제 사용해야 하는가)
|
|
20
|
+
*
|
|
21
|
+
* **사용해야 하는 경우:**
|
|
22
|
+
* - **결과 확인**: 설정 변경, 데이터 저장 등 작업이 정상적으로 완료되었음을 알릴 때
|
|
23
|
+
* - **단순 안내**: 사용자에게 중요한 안내 사항을 전달하고 확인을 받아야 할 때
|
|
24
|
+
*
|
|
25
|
+
* **사용하지 말아야 하는 경우:**
|
|
26
|
+
* - **중요한 결정/취소 필요**: '예/아니오'와 같이 선택지가 필요한 경우 일반 `Modal`이나 `DeleteModal`을 사용하세요.
|
|
27
|
+
* - **데이터 입력**: 폼 입력이 필요한 경우 일반 `Modal`을 사용하세요.
|
|
28
|
+
*
|
|
29
|
+
* ## Usage guidelines
|
|
30
|
+
*
|
|
31
|
+
* ### ✅ Do (권장 사항)
|
|
32
|
+
*
|
|
33
|
+
* - **간결한 메시지**: 메시지는 가급적 2-3줄 이내로 짧고 명확하게 작성하세요.
|
|
34
|
+
* - **적절한 타이틀**: "저장 완료", "안내" 등 문맥에 맞는 타이틀을 사용하세요.
|
|
35
|
+
*/
|
|
12
36
|
export declare const ConfirmModal: React.ForwardRefExoticComponent<ConfirmModalProps & React.RefAttributes<HTMLDivElement>>;
|
|
@@ -11,4 +11,23 @@ export interface DeleteModalProps {
|
|
|
11
11
|
onCancel?: () => void;
|
|
12
12
|
className?: string;
|
|
13
13
|
}
|
|
14
|
+
/**
|
|
15
|
+
* 데이터를 삭제하거나 영구적인 작업을 수행하기 전, 사용자의 최종 승인을 받기 위한 경고 모달입니다.
|
|
16
|
+
*
|
|
17
|
+
* {@link DeleteModal}은 파괴적인(Destructive) 액션을 강조하기 위해 빨간색 경고 아이콘과
|
|
18
|
+
* 눈에 띄는 삭제 버튼을 제공합니다. 사용자가 실수로 데이터를 삭제하는 것을 방지하는 안전장치 역할을 합니다.
|
|
19
|
+
*
|
|
20
|
+
* ## When (언제 사용해야 하는가)
|
|
21
|
+
*
|
|
22
|
+
* **사용해야 하는 경우:**
|
|
23
|
+
* - **영구적 데이터 삭제**: 게시글, 사용자 계정, 설정값 등을 삭제할 때
|
|
24
|
+
* - **되돌릴 수 없는 작업**: 초기화, 데이터 덮어쓰기 등 주의가 필요한 작업을 수행할 때
|
|
25
|
+
*
|
|
26
|
+
* ## Usage guidelines
|
|
27
|
+
*
|
|
28
|
+
* ### ✅ Do (권장 사항)
|
|
29
|
+
*
|
|
30
|
+
* - **구체적인 정보 포함**: 단순히 "삭제하시겠습니까?" 보다는 "사용자 '홍길동'의 정보를 삭제하시겠습니까?"와 같이 구체적인 대상을 명시하는 것이 좋습니다.
|
|
31
|
+
* - **위험성 강조**: 해당 작업이 되돌릴 수 없음을 메시지에 포함하세요.
|
|
32
|
+
*/
|
|
14
33
|
export declare const DeleteModal: React.ForwardRefExoticComponent<DeleteModalProps & React.RefAttributes<HTMLDivElement>>;
|
|
@@ -9,4 +9,24 @@ export interface ErrorModalProps {
|
|
|
9
9
|
onConfirm?: () => void;
|
|
10
10
|
className?: string;
|
|
11
11
|
}
|
|
12
|
+
/**
|
|
13
|
+
* 시스템 오류나 사용자의 잘못된 조작으로 인해 작업이 실패했음을 알리는 모달입니다.
|
|
14
|
+
*
|
|
15
|
+
* {@link ErrorModal}은 빨간색 X 아이콘을 통해 부정적인 결과임을 즉각적으로 전달하며,
|
|
16
|
+
* 사용자가 문제를 인지하고 다음 행동을 취할 수 있도록 돕습니다.
|
|
17
|
+
*
|
|
18
|
+
* ## When (언제 사용해야 하는가)
|
|
19
|
+
*
|
|
20
|
+
* **사용해야 하는 경우:**
|
|
21
|
+
* - **API 통신 실패**: 서버 오류나 네트워크 문제로 요청을 처리할 수 없을 때
|
|
22
|
+
* - **유효성 검사 실패**: 입력한 정보에 중대한 결함이 있어 처리가 중단되었을 때
|
|
23
|
+
* - **권한 부족**: 특정 기능을 사용할 권한이 없음을 알릴 때
|
|
24
|
+
*
|
|
25
|
+
* ## Usage guidelines
|
|
26
|
+
*
|
|
27
|
+
* ### ✅ Do (권장 사항)
|
|
28
|
+
*
|
|
29
|
+
* - **구체적인 원인 안내**: 단순히 "오류가 발생했습니다" 보다는 "이미 존재하는 이메일입니다"와 같이 해결 가능한 정보를 제공하세요.
|
|
30
|
+
* - **해결 방법 제시**: 가능하다면 "나중에 다시 시도해 주세요" 또는 "고객센터로 문의해 주세요"와 같은 가이드를 포함하세요.
|
|
31
|
+
*/
|
|
12
32
|
export declare const ErrorModal: React.ForwardRefExoticComponent<ErrorModalProps & React.RefAttributes<HTMLDivElement>>;
|
|
@@ -11,4 +11,175 @@ export interface ModalProps {
|
|
|
11
11
|
showCloseButton?: boolean;
|
|
12
12
|
size?: "sm" | "md" | "lg";
|
|
13
13
|
}
|
|
14
|
+
/**
|
|
15
|
+
* 사용자에게 중요한 정보를 표시하거나 입력을 요구하는 오버레이 대화상자입니다.
|
|
16
|
+
*
|
|
17
|
+
* {@link Modal}은 사용자의 주의를 집중시켜야 하는 상황에서 사용됩니다.
|
|
18
|
+
* 모달이 열리면 배경이 어두워지며, 사용자는 모달과 상호작용하거나 닫기 전까지
|
|
19
|
+
* 페이지의 다른 부분과 상호작용할 수 없습니다.
|
|
20
|
+
*
|
|
21
|
+
* Radix UI의 Dialog 컴포넌트를 기반으로 구현되어 접근성과 키보드 내비게이션이
|
|
22
|
+
* 자동으로 처리됩니다.
|
|
23
|
+
*
|
|
24
|
+
* ## When (언제 사용해야 하는가)
|
|
25
|
+
*
|
|
26
|
+
* **사용해야 하는 경우:**
|
|
27
|
+
* - **중요한 의사 결정**: 삭제, 저장, 제출 등 되돌릴 수 없는 작업 확인
|
|
28
|
+
* - **필수 정보 입력**: 다음 단계로 진행하기 전 반드시 입력해야 하는 정보 수집
|
|
29
|
+
* - **중요 알림**: 사용자가 반드시 확인해야 하는 에러, 경고, 성공 메시지
|
|
30
|
+
* - **간단한 폼**: 페이지 전환 없이 빠르게 정보를 입력받아야 할 때
|
|
31
|
+
*
|
|
32
|
+
* **사용하지 말아야 하는 경우:**
|
|
33
|
+
* - **긴급하지 않은 알림**: Toast 컴포넌트를 사용하세요
|
|
34
|
+
* - **복잡한 다단계 폼**: 별도 페이지로 이동하세요
|
|
35
|
+
* - **많은 정보 표시**: 페이지 내 섹션으로 구현하세요
|
|
36
|
+
* - **비필수 부가 정보**: Popover나 Tooltip을 사용하세요
|
|
37
|
+
*
|
|
38
|
+
* ## Layout behavior
|
|
39
|
+
*
|
|
40
|
+
* 모달은 항상 화면 중앙에 고정되며, 배경 오버레이는 전체 화면을 덮습니다.
|
|
41
|
+
* 크기는 `size` prop에 따라 결정됩니다:
|
|
42
|
+
* - `sm`: 최대 너비 24rem (384px) - 간단한 확인 대화상자
|
|
43
|
+
* - `md`: 최대 너비 28rem (448px) - 기본값, 일반적인 폼이나 메시지
|
|
44
|
+
* - `lg`: 최대 너비 32rem (512px) - 많은 내용이나 복잡한 폼
|
|
45
|
+
*
|
|
46
|
+
* 모달의 높이는 콘텐츠에 따라 자동으로 조절되며, 화면을 넘어가면 스크롤이 발생합니다.
|
|
47
|
+
*
|
|
48
|
+
* ## Usage guidelines
|
|
49
|
+
*
|
|
50
|
+
* ### ✅ Do (권장 사항)
|
|
51
|
+
*
|
|
52
|
+
* - **명확한 제목 사용**: 모달의 목적을 한눈에 알 수 있는 제목을 제공하세요
|
|
53
|
+
* ```tsx
|
|
54
|
+
* <Modal title="항목 삭제">...</Modal> // Good
|
|
55
|
+
* <Modal title="확인">...</Modal> // Bad - 너무 모호함
|
|
56
|
+
* ```
|
|
57
|
+
*
|
|
58
|
+
* - **행동 지향적 버튼**: 버튼 레이블은 수행할 동작을 명확히 표현하세요
|
|
59
|
+
* ```tsx
|
|
60
|
+
* <Button>삭제하기</Button> // Good
|
|
61
|
+
* <Button>확인</Button> // Bad - 무엇을 확인하는지 불명확
|
|
62
|
+
* ```
|
|
63
|
+
*
|
|
64
|
+
* - **적절한 크기 선택**: 콘텐츠 양에 맞는 size를 선택하세요
|
|
65
|
+
* - **명확한 닫기 방법**: X 버튼, 취소 버튼, 배경 클릭 중 최소 하나는 제공하세요
|
|
66
|
+
* - **중요도에 따른 변형**: ConfirmModal, SuccessModal, ErrorModal 등 사용
|
|
67
|
+
*
|
|
68
|
+
* ### 🚫 Don't (주의/금지 사항)
|
|
69
|
+
*
|
|
70
|
+
* - **모달 위에 모달을 띄우지 마세요** - UX가 복잡해지고 혼란스러워집니다
|
|
71
|
+
* - **긴 스크롤이 필요한 콘텐츠는 피하세요** - 별도 페이지로 이동하는 것이 좋습니다
|
|
72
|
+
* - **자동으로 모달을 열지 마세요** - 사용자의 명시적 동작(클릭 등) 후에만 열어야 합니다
|
|
73
|
+
* - **모달 없이도 작업 가능한 경우** - 불필요하게 모달을 사용하지 마세요
|
|
74
|
+
* - **모바일에서 큰 모달(lg) 사용 지양** - 화면을 거의 다 차지하므로 페이지 이동 권장
|
|
75
|
+
*
|
|
76
|
+
* ## Accessibility
|
|
77
|
+
*
|
|
78
|
+
* 이 컴포넌트는 WAI-ARIA Dialog 패턴을 따릅니다:
|
|
79
|
+
*
|
|
80
|
+
* - **키보드 내비게이션**:
|
|
81
|
+
* - `Esc`: 모달 닫기
|
|
82
|
+
* - `Tab`: 모달 내부 포커스 순환 (모달 외부로 나가지 않음)
|
|
83
|
+
* - 모달이 열리면 첫 번째 포커스 가능한 요소로 자동 포커스
|
|
84
|
+
*
|
|
85
|
+
* - **스크린 리더**:
|
|
86
|
+
* - `role="dialog"`: 대화상자임을 인식
|
|
87
|
+
* - `aria-labelledby`: title이 모달의 레이블로 연결됨
|
|
88
|
+
* - `aria-describedby`: children 콘텐츠가 설명으로 연결됨
|
|
89
|
+
*
|
|
90
|
+
* - **포커스 트랩**: 모달이 열려있는 동안 포커스가 모달 내부에서만 순환합니다
|
|
91
|
+
* - **배경 스크롤 방지**: 모달이 열리면 body 스크롤이 자동으로 비활성화됩니다
|
|
92
|
+
*
|
|
93
|
+
* ## Example
|
|
94
|
+
*
|
|
95
|
+
* {@tool snippet}
|
|
96
|
+
* 기본적인 확인 모달 예시:
|
|
97
|
+
*
|
|
98
|
+
* ```tsx
|
|
99
|
+
* function DeleteConfirmDialog() {
|
|
100
|
+
* const [open, setOpen] = useState(false);
|
|
101
|
+
*
|
|
102
|
+
* return (
|
|
103
|
+
* <>
|
|
104
|
+
* <Button onClick={() => setOpen(true)}>삭제</Button>
|
|
105
|
+
* <Modal
|
|
106
|
+
* open={open}
|
|
107
|
+
* onOpenChange={setOpen}
|
|
108
|
+
* title="항목 삭제"
|
|
109
|
+
* footer={
|
|
110
|
+
* <div className="flex gap-2">
|
|
111
|
+
* <Button onClick={() => setOpen(false)} variant="outline">
|
|
112
|
+
* 취소
|
|
113
|
+
* </Button>
|
|
114
|
+
* <Button onClick={handleDelete} variant="destructive">
|
|
115
|
+
* 삭제하기
|
|
116
|
+
* </Button>
|
|
117
|
+
* </div>
|
|
118
|
+
* }
|
|
119
|
+
* >
|
|
120
|
+
* 이 항목을 삭제하시겠습니까? 이 작업은 되돌릴 수 없습니다.
|
|
121
|
+
* </Modal>
|
|
122
|
+
* </>
|
|
123
|
+
* );
|
|
124
|
+
* }
|
|
125
|
+
* ```
|
|
126
|
+
* {@end-tool}
|
|
127
|
+
*
|
|
128
|
+
* {@tool snippet}
|
|
129
|
+
* 성공 아이콘이 포함된 모달 예시:
|
|
130
|
+
*
|
|
131
|
+
* ```tsx
|
|
132
|
+
* <Modal
|
|
133
|
+
* open={open}
|
|
134
|
+
* onOpenChange={setOpen}
|
|
135
|
+
* icon={<CheckCircle className="w-12 h-12 text-green-500" />}
|
|
136
|
+
* title="저장 완료"
|
|
137
|
+
* footer={
|
|
138
|
+
* <Button onClick={() => setOpen(false)} className="w-full">
|
|
139
|
+
* 확인
|
|
140
|
+
* </Button>
|
|
141
|
+
* }
|
|
142
|
+
* >
|
|
143
|
+
* 데이터가 성공적으로 저장되었습니다.
|
|
144
|
+
* </Modal>
|
|
145
|
+
* ```
|
|
146
|
+
* {@end-tool}
|
|
147
|
+
*
|
|
148
|
+
* {@tool snippet}
|
|
149
|
+
* 큰 크기의 폼 모달 예시:
|
|
150
|
+
*
|
|
151
|
+
* ```tsx
|
|
152
|
+
* <Modal
|
|
153
|
+
* open={open}
|
|
154
|
+
* onOpenChange={setOpen}
|
|
155
|
+
* title="새 사용자 추가"
|
|
156
|
+
* size="lg"
|
|
157
|
+
* footer={
|
|
158
|
+
* <div className="flex justify-end gap-2">
|
|
159
|
+
* <Button variant="outline" onClick={() => setOpen(false)}>
|
|
160
|
+
* 취소
|
|
161
|
+
* </Button>
|
|
162
|
+
* <Button onClick={handleSubmit}>저장</Button>
|
|
163
|
+
* </div>
|
|
164
|
+
* }
|
|
165
|
+
* >
|
|
166
|
+
* <form className="space-y-4">
|
|
167
|
+
* <TextInput label="이름" required />
|
|
168
|
+
* <TextInput label="이메일" type="email" required />
|
|
169
|
+
* <TextInput label="전화번호" />
|
|
170
|
+
* </form>
|
|
171
|
+
* </Modal>
|
|
172
|
+
* ```
|
|
173
|
+
* {@end-tool}
|
|
174
|
+
*
|
|
175
|
+
* See also:
|
|
176
|
+
*
|
|
177
|
+
* - {@link ConfirmModal}, 간단한 확인 모달을 위한 사전 구성된 변형
|
|
178
|
+
* - {@link SuccessModal}, 성공 메시지를 표시하는 모달
|
|
179
|
+
* - {@link ErrorModal}, 에러 메시지를 표시하는 모달
|
|
180
|
+
* - {@link WarningModal}, 경고 메시지를 표시하는 모달
|
|
181
|
+
* - {@link DeleteModal}, 삭제 확인을 위한 모달
|
|
182
|
+
* - {@link Toast}, 긴급하지 않은 알림을 위한 컴포넌트
|
|
183
|
+
* - {@link Popover}, 비필수 부가 정보를 표시하는 컴포넌트
|
|
184
|
+
*/
|
|
14
185
|
export declare const Modal: React.ForwardRefExoticComponent<ModalProps & React.RefAttributes<HTMLDivElement>>;
|
|
@@ -9,4 +9,23 @@ export interface SuccessModalProps {
|
|
|
9
9
|
onConfirm?: () => void;
|
|
10
10
|
className?: string;
|
|
11
11
|
}
|
|
12
|
+
/**
|
|
13
|
+
* 요청한 작업이 성공적으로 완료되었음을 축하하거나 알리는 모달입니다.
|
|
14
|
+
*
|
|
15
|
+
* {@link SuccessModal}은 초록색 체크 아이콘을 통해 긍정적인 결과를 전달합니다.
|
|
16
|
+
* 단순한 Toast 알림보다 더 강조된 확인이 필요할 때 사용됩니다.
|
|
17
|
+
*
|
|
18
|
+
* ## When (언제 사용해야 하는가)
|
|
19
|
+
*
|
|
20
|
+
* **사용해야 하는 경우:**
|
|
21
|
+
* - **중요 작업 완료**: 회원가입 완료, 대규모 데이터 처리 완료 등
|
|
22
|
+
* - **영구적 저장 완료**: 중요한 설정이나 게시글이 성공적으로 서버에 저장되었을 때
|
|
23
|
+
*
|
|
24
|
+
* ## Usage guidelines
|
|
25
|
+
*
|
|
26
|
+
* ### ✅ Do (권장 사항)
|
|
27
|
+
*
|
|
28
|
+
* - **긍정적인 피드백**: "처리가 완료되었습니다" 보다는 "성공적으로 저장되었습니다"와 같이 명확한 피드백을 제공하세요.
|
|
29
|
+
* - **후속 조치 안내**: 필요한 경우 다음 단계로 무엇을 해야 하는지(예: 리스트로 이동 등) 메시지에 포함하세요.
|
|
30
|
+
*/
|
|
12
31
|
export declare const SuccessModal: React.ForwardRefExoticComponent<SuccessModalProps & React.RefAttributes<HTMLDivElement>>;
|
|
@@ -11,4 +11,25 @@ export interface WarningModalProps {
|
|
|
11
11
|
onCancel?: () => void;
|
|
12
12
|
className?: string;
|
|
13
13
|
}
|
|
14
|
+
/**
|
|
15
|
+
* 잠재적인 문제를 경고하거나 주의가 필요한 작업을 수행하기 전 사용자의 동의를 구하는 모달입니다.
|
|
16
|
+
*
|
|
17
|
+
* {@link WarningModal}은 주황색 경고 아이콘을 통해 주의를 환기시킵니다.
|
|
18
|
+
* 완전한 파괴적 액션(삭제)은 아니지만, 데이터 변경이나 시스템 설정 변경 등
|
|
19
|
+
* 신중함이 필요한 상황에서 사용됩니다.
|
|
20
|
+
*
|
|
21
|
+
* ## When (언제 사용해야 하는가)
|
|
22
|
+
*
|
|
23
|
+
* **사용해야 하는 경우:**
|
|
24
|
+
* - **데이터 변경**: 기존 정보를 대량으로 수정하거나 업데이트할 때
|
|
25
|
+
* - **민감한 설정 변경**: 시스템 동작에 영향을 줄 수 있는 설정을 변경할 때
|
|
26
|
+
* - **동작 확인**: 예기치 않은 부작용이 발생할 수 있는 기능을 실행할 때
|
|
27
|
+
*
|
|
28
|
+
* ## Usage guidelines
|
|
29
|
+
*
|
|
30
|
+
* ### ✅ Do (권장 사항)
|
|
31
|
+
*
|
|
32
|
+
* - **위험성 명시**: 이 작업을 실행했을 때 어떤 결과가 초래될 수 있는지 명확히 설명하세요.
|
|
33
|
+
* - **취소 옵션 제공**: 사용자가 마음을 바꿀 수 있도록 명확한 취소 버튼을 함께 배치하세요.
|
|
34
|
+
*/
|
|
14
35
|
export declare const WarningModal: React.ForwardRefExoticComponent<WarningModalProps & React.RefAttributes<HTMLDivElement>>;
|
|
@@ -1,4 +1,74 @@
|
|
|
1
1
|
import * as PopoverPrimitive from "@radix-ui/react-popover";
|
|
2
|
+
/**
|
|
3
|
+
* 특정 요소 근처에 부가적인 정보나 컨트롤을 표시하는 플로팅 컴포넌트입니다.
|
|
4
|
+
*
|
|
5
|
+
* {@link Popover}는 사용자가 버튼이나 아이콘을 클릭했을 때 나타나며,
|
|
6
|
+
* 기존 화면의 맥락을 유지하면서 추가적인 작업(메뉴 선택, 상세 정보 확인 등)을 수행할 수 있게 합니다.
|
|
7
|
+
*
|
|
8
|
+
* Radix UI의 Popover 컴포넌트를 기반으로 구현되어 포커스 트랩, 키보드 내비게이션 등이
|
|
9
|
+
* 자동으로 처리됩니다.
|
|
10
|
+
*
|
|
11
|
+
* ## When (언제 사용해야 하는가)
|
|
12
|
+
*
|
|
13
|
+
* **사용해야 하는 경우:**
|
|
14
|
+
* - **맥락 기반 메뉴**: '더 보기' 버튼 클릭 시 나타나는 관리 기능(수정, 삭제 등)
|
|
15
|
+
* - **상세 정보 표시**: 아이콘 클릭 시 해당 항목에 대한 간단한 설명이나 데이터를 보여줄 때
|
|
16
|
+
* - **간단한 설정**: 필터 옵션이나 정렬 기준을 선택할 때
|
|
17
|
+
*
|
|
18
|
+
* **사용하지 말아야 하는 경우:**
|
|
19
|
+
* - **중요한 의사 결정**: 사용자의 주의를 완전히 집중시켜야 하는 작업은 `Modal`을 사용하세요.
|
|
20
|
+
* - **단순 힌트**: 마우스 호버 시에만 짧게 보여주는 정보는 Tooltip을 사용하세요.
|
|
21
|
+
* - **입력 폼**: 복잡한 입력이 필요한 경우 모달이나 별도 페이지가 더 적합할 수 있습니다.
|
|
22
|
+
*
|
|
23
|
+
* ## Layout behavior
|
|
24
|
+
*
|
|
25
|
+
* - **Anchor Positioning**: 트리거(버튼 등)를 기준으로 상하좌우 적절한 위치에 자동으로 배치됩니다.
|
|
26
|
+
* - **Overlay**: 다른 UI 요소들 위에 겹쳐서 나타나며, 배경(Overlay)을 생성하지 않아 뒤쪽 화면을 볼 수 있습니다.
|
|
27
|
+
* - **Size**: 콘텐츠의 양에 따라 크기가 결정되지만, `min-w-[200px]`의 최소 너비를 가집니다.
|
|
28
|
+
*
|
|
29
|
+
* ## Usage guidelines
|
|
30
|
+
*
|
|
31
|
+
* ### ✅ Do (권장 사항)
|
|
32
|
+
*
|
|
33
|
+
* - **명확한 트리거**: 사용자가 무엇을 클릭하면 팝오버가 열릴지 명확히 인지할 수 있는 버튼이나 아이콘을 사용하세요.
|
|
34
|
+
* - **적절한 배치**: `align` 속성을 조절하여 팝오버가 화면 밖으로 나가지 않도록 관리하세요. (기본값: 'end')
|
|
35
|
+
*
|
|
36
|
+
* ### 🚫 Don't (주의/금지 사항)
|
|
37
|
+
*
|
|
38
|
+
* - **너무 많은 정보**: 팝오버는 빠르고 간단한 상호작용을 위한 것입니다. 너무 많은 내용을 담지 마세요.
|
|
39
|
+
* - **비정상적인 닫기**: 팝오버 외부를 클릭하거나 `Esc`를 누르면 자연스럽게 닫히도록 기본 동작을 유지하세요.
|
|
40
|
+
*
|
|
41
|
+
* ## Accessibility
|
|
42
|
+
*
|
|
43
|
+
* - **Keyboard Interaction**: `Space`나 `Enter`로 열고, `Esc`로 닫으며, 팝오버 내부에서 `Tab` 키로 내비게이션이 가능합니다.
|
|
44
|
+
* - **Aria Attributes**: `aria-expanded`, `aria-controls` 등의 속성이 자동으로 부여됩니다.
|
|
45
|
+
*
|
|
46
|
+
* ## Example
|
|
47
|
+
*
|
|
48
|
+
* {@tool snippet}
|
|
49
|
+
* 버튼 클릭 시 상세 정보를 보여주는 팝오버:
|
|
50
|
+
*
|
|
51
|
+
* ```tsx
|
|
52
|
+
* <Popover>
|
|
53
|
+
* <PopoverTrigger asChild>
|
|
54
|
+
* <Button variant="ghost">상세 정보</Button>
|
|
55
|
+
* </PopoverTrigger>
|
|
56
|
+
* <PopoverContent>
|
|
57
|
+
* <div className="p-4">
|
|
58
|
+
* <h4 className="font-bold">계정 상태</h4>
|
|
59
|
+
* <p className="text-sm">현재 활성화된 계정입니다.</p>
|
|
60
|
+
* </div>
|
|
61
|
+
* </PopoverContent>
|
|
62
|
+
* </Popover>
|
|
63
|
+
* ```
|
|
64
|
+
* {@end-tool}
|
|
65
|
+
*
|
|
66
|
+
* See also:
|
|
67
|
+
*
|
|
68
|
+
* - {@link Modal}, 더 중요하거나 복잡한 상호작용이 필요한 경우
|
|
69
|
+
* - {@link Dropdown}, 정해진 리스트에서 값을 선택하는 것이 주 목적인 경우
|
|
70
|
+
* - {@link PopoverMenuItem}, 팝오버 내부의 메뉴 항목을 구성할 때
|
|
71
|
+
*/
|
|
2
72
|
declare const Popover: import('react').FC<PopoverPrimitive.PopoverProps>;
|
|
3
73
|
declare const PopoverTrigger: import('react').ForwardRefExoticComponent<PopoverPrimitive.PopoverTriggerProps & import('react').RefAttributes<HTMLButtonElement>>;
|
|
4
74
|
declare const PopoverContent: import('react').ForwardRefExoticComponent<Omit<PopoverPrimitive.PopoverContentProps & import('react').RefAttributes<HTMLDivElement>, "ref"> & import('react').RefAttributes<HTMLDivElement>>;
|
|
@@ -7,5 +7,30 @@ declare const popoverMenuItemVariants: (props?: ({
|
|
|
7
7
|
export interface PopoverMenuItemProps extends ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof popoverMenuItemVariants> {
|
|
8
8
|
icon?: React.ReactNode;
|
|
9
9
|
}
|
|
10
|
+
/**
|
|
11
|
+
* Popover 내부에 배치되는 개별 액션 항목 컴포넌트입니다.
|
|
12
|
+
*
|
|
13
|
+
* {@link PopoverMenuItem}은 아이콘과 텍스트가 결합된 형태의 메뉴 버튼으로,
|
|
14
|
+
* 일관된 패딩, 폰트, 호버 효과를 제공합니다.
|
|
15
|
+
*
|
|
16
|
+
* ## Example
|
|
17
|
+
*
|
|
18
|
+
* ```tsx
|
|
19
|
+
* <PopoverContent>
|
|
20
|
+
* <div className="flex flex-col gap-1">
|
|
21
|
+
* <PopoverMenuItem icon={<EditIcon />} onClick={handleEdit}>
|
|
22
|
+
* 수정하기
|
|
23
|
+
* </PopoverMenuItem>
|
|
24
|
+
* <PopoverMenuItem
|
|
25
|
+
* variant="destructive"
|
|
26
|
+
* icon={<TrashIcon />}
|
|
27
|
+
* onClick={handleDelete}
|
|
28
|
+
* >
|
|
29
|
+
* 삭제하기
|
|
30
|
+
* </PopoverMenuItem>
|
|
31
|
+
* </div>
|
|
32
|
+
* </PopoverContent>
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
10
35
|
declare const PopoverMenuItem: import('react').ForwardRefExoticComponent<PopoverMenuItemProps & import('react').RefAttributes<HTMLButtonElement>>;
|
|
11
36
|
export { PopoverMenuItem, popoverMenuItemVariants };
|
|
@@ -2,6 +2,77 @@ import { default as React } from 'react';
|
|
|
2
2
|
import { VariantProps } from 'class-variance-authority';
|
|
3
3
|
|
|
4
4
|
import * as RadioGroupPrimitives from "@radix-ui/react-radio-group";
|
|
5
|
+
/**
|
|
6
|
+
* 상호 배타적인 옵션 목록 중 단 하나만을 선택해야 할 때 사용하는 컴포넌트입니다.
|
|
7
|
+
*
|
|
8
|
+
* {@link RadioGroup}은 여러 개의 {@link RadioGroupItem}을 포함하는 컨테이너이며,
|
|
9
|
+
* 한 번에 하나의 아이템만 선택될 수 있도록 상태를 관리합니다.
|
|
10
|
+
*
|
|
11
|
+
* Radix UI의 Radio Group 컴포넌트를 기반으로 구현되어 방향키를 이용한 내비게이션 등
|
|
12
|
+
* 표준 라디오 그룹 동작을 지원합니다.
|
|
13
|
+
*
|
|
14
|
+
* ## When (언제 사용해야 하는가)
|
|
15
|
+
*
|
|
16
|
+
* **사용해야 하는 경우:**
|
|
17
|
+
* - **단일 선택**: 성별 선택, 배송 방법 선택 등 여러 옵션 중 하나만 골라야 할 때
|
|
18
|
+
* - **옵션 노출**: 모든 선택지가 사용자에게 한눈에 보여야 할 때 (옵션이 5개 이하인 경우 권장)
|
|
19
|
+
*
|
|
20
|
+
* **사용하지 말아야 하는 경우:**
|
|
21
|
+
* - **다중 선택**: 여러 개를 동시에 선택할 수 있어야 하는 경우 `Checkbox`를 사용하세요.
|
|
22
|
+
* - **옵션이 많은 경우**: 선택지가 5-6개를 넘어간다면 화면 공간을 위해 `Dropdown`을 사용하는 것이 좋습니다.
|
|
23
|
+
* - **독립적 On/Off**: 단순히 하나의 항목을 켜고 끄는 것이라면 `Checkbox`나 `Switch`가 더 적절합니다.
|
|
24
|
+
*
|
|
25
|
+
* ## Layout behavior
|
|
26
|
+
*
|
|
27
|
+
* - **asChild**: `asChild` 속성을 사용하면 기본 렌더링 요소 대신 자식 요소를 렌더링하고 속성을 병합합니다.
|
|
28
|
+
* 커스텀 컴포넌트나 다른 라이브러리와 연동할 때 유용합니다.
|
|
29
|
+
*
|
|
30
|
+
* ## Accessibility
|
|
31
|
+
*
|
|
32
|
+
* - **Keyboard Navigation**: `Tab` 키로 그룹에 진입한 후, 화살표 키(`Up`, `Down`, `Left`, `Right`)를 사용하여 옵션 간 이동 및 선택이 가능합니다.
|
|
33
|
+
* - **Roles**: `role="radiogroup"` 및 `role="radio"` 속성이 자동으로 부여됩니다.
|
|
34
|
+
*
|
|
35
|
+
* ## Example
|
|
36
|
+
*
|
|
37
|
+
* {@tool snippet}
|
|
38
|
+
* 기본적인 라디오 그룹 사용 예시:
|
|
39
|
+
*
|
|
40
|
+
* ```tsx
|
|
41
|
+
* <RadioGroup defaultValue="apple" onValueChange={(val) => console.log(val)}>
|
|
42
|
+
* <div className="flex items-center gap-2">
|
|
43
|
+
* <RadioGroupItem value="apple" id="apple" />
|
|
44
|
+
* <label htmlFor="apple">사과</label>
|
|
45
|
+
* </div>
|
|
46
|
+
* <div className="flex items-center gap-2">
|
|
47
|
+
* <RadioGroupItem value="banana" id="banana" />
|
|
48
|
+
* <label htmlFor="banana">바나나</label>
|
|
49
|
+
* </div>
|
|
50
|
+
* </RadioGroup>
|
|
51
|
+
* ```
|
|
52
|
+
* {@end-tool}
|
|
53
|
+
*
|
|
54
|
+
* {@tool snippet}
|
|
55
|
+
* `asChild`를 사용한 커스텀 렌더링 예시:
|
|
56
|
+
*
|
|
57
|
+
* ```tsx
|
|
58
|
+
* <RadioGroup asChild>
|
|
59
|
+
* <section className="my-custom-group">
|
|
60
|
+
* <RadioGroupItem asChild value="custom">
|
|
61
|
+
* <button type="button" className="custom-radio-trigger">
|
|
62
|
+
* 커스텀 라디오
|
|
63
|
+
* </button>
|
|
64
|
+
* </RadioGroupItem>
|
|
65
|
+
* </section>
|
|
66
|
+
* </RadioGroup>
|
|
67
|
+
* ```
|
|
68
|
+
* {@end-tool}
|
|
69
|
+
*
|
|
70
|
+
* See also:
|
|
71
|
+
*
|
|
72
|
+
* - {@link Checkbox}, 다중 선택이 필요한 경우
|
|
73
|
+
* - {@link Dropdown}, 옵션이 많아 리스트로 숨겨야 하는 경우
|
|
74
|
+
* - {@link Switch}, 단순 활성화/비활성화를 토글할 때
|
|
75
|
+
*/
|
|
5
76
|
declare const RadioGroup: React.ForwardRefExoticComponent<Omit<RadioGroupPrimitives.RadioGroupProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
6
77
|
declare const radioGroupItemVariants: (props?: ({
|
|
7
78
|
variant?: "default" | "black" | "green" | "blue" | "red" | null | undefined;
|
|
@@ -18,4 +18,81 @@ export interface SideNavigationProps {
|
|
|
18
18
|
headerSlot?: React.ReactNode;
|
|
19
19
|
className?: string;
|
|
20
20
|
}
|
|
21
|
+
/**
|
|
22
|
+
* 어플리케이션의 주요 섹션 간 이동을 담당하는 왼쪽 사이드바 메뉴 컴포넌트입니다.
|
|
23
|
+
*
|
|
24
|
+
* {@link SideNavigation}은 계층형 메뉴 구조(1단계 및 서브메뉴)를 지원하며,
|
|
25
|
+
* 현재 사용자의 위치를 시각적으로 강조하여 내비게이션 맥락을 제공합니다.
|
|
26
|
+
* 다크 테마(Dark Theme) 스타일로 고정되어 대시보드 및 CMS 관리 도구에 적합합니다.
|
|
27
|
+
*
|
|
28
|
+
* Radix UI의 Accordion 컴포넌트를 기반으로 구현되어 서브메뉴의 펼침/접힘 동작이
|
|
29
|
+
* 부드럽게 처리됩니다.
|
|
30
|
+
*
|
|
31
|
+
* ## When (언제 사용해야 하는가)
|
|
32
|
+
*
|
|
33
|
+
* **사용해야 하는 경우:**
|
|
34
|
+
* - **메인 내비게이션**: 서비스의 핵심 기능을 상시 노출하고 접근해야 할 때
|
|
35
|
+
* - **계층 구조 관리**: 대메뉴와 그에 속한 소메뉴를 구조적으로 보여줘야 할 때
|
|
36
|
+
* - **관리자 페이지**: 다양한 관리 도구와 설정 항목을 분류하여 제공할 때
|
|
37
|
+
*
|
|
38
|
+
* **사용하지 말아야 하는 경우:**
|
|
39
|
+
* - **단순 링크 목록**: 3-4개의 단순한 링크라면 상단 내비게이션(GNB)이 더 적절할 수 있습니다.
|
|
40
|
+
* - **모바일 전용 탭**: 모바일 앱 스타일의 내비게이션이 필요하다면 하단 탭 바를 고려하세요.
|
|
41
|
+
*
|
|
42
|
+
* ## Layout behavior
|
|
43
|
+
*
|
|
44
|
+
* - **Fixed Width**: 기본적으로 `w-70` (280px)의 고정 너비를 가지며, 세로 전체(h-full)를 차지합니다.
|
|
45
|
+
* - **Scrollable**: 메뉴 항목이 많아 화면 높이를 넘어가면 메뉴 영역 내부에 스크롤이 발생합니다.
|
|
46
|
+
* - **Accordion**: 서브메뉴가 있는 항목 클릭 시 아래로 펼쳐지는 애니메이션이 적용됩니다.
|
|
47
|
+
*
|
|
48
|
+
* ## Usage guidelines
|
|
49
|
+
*
|
|
50
|
+
* ### ✅ Do (권장 사항)
|
|
51
|
+
*
|
|
52
|
+
* - **아이콘 활용**: 각 대메뉴에 적절한 아이콘을 배치하여 사용자가 메뉴의 성격을 빠르게 파악하게 하세요.
|
|
53
|
+
* - **상태 연동**: 현재 활성화된 페이지의 URL과 `selectedUrl`을 정확히 일치시켜 하이라이트가 올바르게 표시되도록 하세요.
|
|
54
|
+
* - **일관된 그룹화**: 연관된 기능들은 하나의 대메뉴 아래 서브메뉴로 묶어 복잡도를 낮추세요.
|
|
55
|
+
*
|
|
56
|
+
* ### 🚫 Don't (주의/금지 사항)
|
|
57
|
+
*
|
|
58
|
+
* - **과도한 계층**: 서브메뉴의 서브메뉴(3단계 이상)는 가급적 피하세요. UI가 복잡해지고 사용성이 떨어집니다.
|
|
59
|
+
* - **긴 메뉴 명칭**: 사이드바 너비가 제한적이므로 메뉴 이름은 짧고 명확하게(가급적 10자 이내) 작성하세요.
|
|
60
|
+
*
|
|
61
|
+
* ## Accessibility
|
|
62
|
+
*
|
|
63
|
+
* - **Accordion Support**: 서브메뉴 상태를 스크린 리더에서 '펼쳐짐/접힘'으로 인식합니다.
|
|
64
|
+
* - **Keyboard Interaction**: `Tab` 키로 메뉴를 이동하고, `Enter`나 `Space`로 메뉴를 열거나 이동할 수 있습니다.
|
|
65
|
+
*
|
|
66
|
+
* ## Example
|
|
67
|
+
*
|
|
68
|
+
* {@tool snippet}
|
|
69
|
+
* 서브메뉴를 포함한 사이드 네비게이션:
|
|
70
|
+
*
|
|
71
|
+
* ```tsx
|
|
72
|
+
* const menus = [
|
|
73
|
+
* { url: '/dashboard', title: '홈', icon: <HomeIcon /> },
|
|
74
|
+
* {
|
|
75
|
+
* url: '/contents',
|
|
76
|
+
* title: '콘텐츠 관리',
|
|
77
|
+
* icon: <FileTextIcon />,
|
|
78
|
+
* subMenu: [
|
|
79
|
+
* { url: '/contents/posts', title: '게시글 목록' },
|
|
80
|
+
* { url: '/contents/comments', title: '댓글 관리' },
|
|
81
|
+
* ]
|
|
82
|
+
* },
|
|
83
|
+
* ];
|
|
84
|
+
*
|
|
85
|
+
* <SideNavigation
|
|
86
|
+
* menus={menus}
|
|
87
|
+
* selectedUrl="/contents/posts"
|
|
88
|
+
* onMenuClick={(url) => navigate(url)}
|
|
89
|
+
* />
|
|
90
|
+
* ```
|
|
91
|
+
* {@end-tool}
|
|
92
|
+
*
|
|
93
|
+
* See also:
|
|
94
|
+
*
|
|
95
|
+
* - {@link Button}, 단순 액션 실행을 위한 요소
|
|
96
|
+
* - {@link Popover}, 클릭 시 일시적으로 나타나는 추가 메뉴가 필요한 경우
|
|
97
|
+
*/
|
|
21
98
|
export declare const SideNavigation: React.ForwardRefExoticComponent<SideNavigationProps & React.RefAttributes<HTMLDivElement>>;
|