cashdoc-cms-design-system 1.0.0 → 1.0.2

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.
Files changed (39) hide show
  1. package/README.md +106 -0
  2. package/dist/components/Button/Button.d.ts +116 -0
  3. package/dist/components/Checkbox/Checkbox.d.ts +79 -0
  4. package/dist/components/DatePicker/DatePicker.d.ts +82 -0
  5. package/dist/components/DatePicker/index.d.ts +0 -2
  6. package/dist/components/DateRangePicker/DateRangePicker.d.ts +93 -0
  7. package/dist/components/DateRangePicker/index.d.ts +2 -0
  8. package/dist/components/Dropdown/Combobox.d.ts +78 -0
  9. package/dist/components/Dropdown/Dropdown.d.ts +81 -0
  10. package/dist/components/Dropdown/Select.d.ts +78 -0
  11. package/dist/components/LoadingCircle/LoadingCircle.d.ts +70 -0
  12. package/dist/components/Modal/ConfirmModal.d.ts +24 -0
  13. package/dist/components/Modal/DeleteModal.d.ts +19 -0
  14. package/dist/components/Modal/ErrorModal.d.ts +20 -0
  15. package/dist/components/Modal/Modal.d.ts +171 -0
  16. package/dist/components/Modal/SuccessModal.d.ts +19 -0
  17. package/dist/components/Modal/WarningModal.d.ts +21 -0
  18. package/dist/components/Pagination/Pagination.d.ts +106 -0
  19. package/dist/components/Pagination/index.d.ts +2 -0
  20. package/dist/components/Popover/Popover.d.ts +70 -0
  21. package/dist/components/Popover/PopoverMenuItem.d.ts +25 -0
  22. package/dist/components/RadioButton/RadioButton.d.ts +71 -0
  23. package/dist/components/SideNavigation/SideNavigation.d.ts +77 -0
  24. package/dist/components/Switch/Switch.d.ts +60 -0
  25. package/dist/components/TagInput/TagInput.d.ts +96 -0
  26. package/dist/components/Text/Text.d.ts +57 -0
  27. package/dist/components/TextInput/TextInput.d.ts +78 -0
  28. package/dist/components/TimePicker/TimePicker.d.ts +110 -0
  29. package/dist/components/TimePicker/index.d.ts +2 -0
  30. package/dist/components/Toast/Toaster.d.ts +78 -0
  31. package/dist/components/icons/ChevronRightIcon.d.ts +11 -0
  32. package/dist/components/index.d.ts +3 -0
  33. package/dist/index.es.js +3770 -3292
  34. package/dist/index.es.js.map +1 -1
  35. package/dist/index.umd.js +37 -22
  36. package/dist/index.umd.js.map +1 -1
  37. package/dist/style.css +1 -1
  38. package/package.json +1 -1
  39. package/dist/components/DatePicker/DateRangePicker.d.ts +0 -14
package/README.md CHANGED
@@ -1 +1,107 @@
1
+ # Cashdoc CMS Design System
1
2
 
3
+ Cashdoc CMS용 디자인 시스템 컴포넌트 라이브러리 [Storybook](https://cashdoc-cms-design-system.vercel.app/?path=/docs/components-button--docs)
4
+
5
+ ## 기술 스택
6
+
7
+ - **React 18** - UI 라이브러리
8
+ - **TypeScript** - 타입 안전성
9
+ - **TailwindCSS** - 스타일링
10
+ - **Radix UI** - 접근성 프리미티브
11
+ - **Framer Motion** - 애니메이션
12
+ - **Vite** - 빌드 도구
13
+ - **Storybook** - 컴포넌트 문서화
14
+
15
+ ## 설치
16
+
17
+ ```bash
18
+ pnpm install cashdoc-cms-design-system
19
+ ```
20
+
21
+ ## 사용법
22
+
23
+ 프로젝트 최상단에서 cashdoc-cms-design-system의 `style.css` 파일을 import 후 사용하면 됩니다.
24
+
25
+ ```tsx
26
+ import "cashdoc-cms-design-system/dist/style.css";
27
+ ```
28
+
29
+ ```tsx
30
+ import { Button, Modal, DatePicker } from "cashdoc-cms-design-system";
31
+
32
+ function App() {
33
+ return <Button variant="default">버튼</Button>;
34
+ }
35
+ ```
36
+
37
+ ## 컴포넌트 리스트
38
+
39
+ ### Form
40
+
41
+ - `Button` - 기본 버튼
42
+ - `Checkbox` - 체크박스
43
+ - `RadioButton` - 라디오 버튼
44
+ - `Switch` - 토글 스위치
45
+ - `TextInput` - 텍스트 입력 필드
46
+ - `TagInput` - 태그 입력 필드
47
+
48
+ ### Data Input
49
+
50
+ - `DatePicker` - 날짜 선택
51
+ - `DateRangePicker` - 기간 선택
52
+ - `Dropdown` - 드롭다운 메뉴
53
+ - `Select` - 선택 입력
54
+ - `Combobox` - 검색 가능한 선택
55
+
56
+ ### Feedback
57
+
58
+ - `Modal` - 모달 다이얼로그
59
+ - `ConfirmModal` - 확인 모달
60
+ - `DeleteModal` - 삭제 확인 모달
61
+ - `ErrorModal` - 에러 알림
62
+ - `SuccessModal` - 성공 알림
63
+ - `WarningModal` - 경고 알림
64
+ - `Toast` - 토스트 알림
65
+ - `LoadingCircle` - 로딩 인디케이터
66
+
67
+ ### Navigation
68
+
69
+ - `SideNavigation` - 사이드바 네비게이션
70
+ - `Popover` - 팝오버 메뉴
71
+
72
+ ### Display
73
+
74
+ - `Text` - 타이포그래피
75
+ - `Icons` - 아이콘 세트
76
+
77
+ ## 개발
78
+
79
+ ### 로컬 개발 서버
80
+
81
+ ```bash
82
+ pnpm dev
83
+ ```
84
+
85
+ ### Storybook 실행
86
+
87
+ ```bash
88
+ pnpm storybook
89
+ ```
90
+
91
+ ### 빌드
92
+
93
+ ```bash
94
+ pnpm build
95
+ ```
96
+
97
+ ### 타입 체크
98
+
99
+ ```bash
100
+ pnpm type-check
101
+ ```
102
+
103
+ ### 린트
104
+
105
+ ```bash
106
+ pnpm lint
107
+ ```
@@ -1,11 +1,127 @@
1
1
  import { VariantProps } from 'class-variance-authority';
2
2
  import { ButtonHTMLAttributes } from 'react';
3
3
 
4
+ /**
5
+ * 버튼 컴포넌트의 스타일 variant를 정의합니다.
6
+ *
7
+ * @variant default - 기본 스타일 (회색 배경)
8
+ * @variant secondary - 보조 스타일 (밝은 회색 배경)
9
+ * @variant outline - 테두리 스타일 (투명 배경)
10
+ * @variant ghost - 고스트 스타일 (투명 배경, hover시 배경)
11
+ * @variant link - 링크 스타일 (밑줄)
12
+ *
13
+ * @size default - 기본 크기 (h-10)
14
+ * @size sm - 작은 크기 (h-8)
15
+ * @size lg - 큰 크기 (h-11)
16
+ * @size icon - 아이콘 크기 (정사각형 10x10)
17
+ */
4
18
  export declare const buttonVariants: (props?: ({
5
19
  variant?: "default" | "secondary" | "outline" | "ghost" | "link" | null | undefined;
6
20
  size?: "default" | "sm" | "lg" | "icon" | null | undefined;
7
21
  } & import('class-variance-authority/types').ClassProp) | undefined) => string;
8
22
  export interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {
9
23
  }
24
+ /**
25
+ * 사용자의 클릭 동작을 통해 특정 액션을 실행하거나 페이지를 이동시키는 기본적인 컴포넌트입니다.
26
+ *
27
+ * {@link Button}은 다양한 시각적 스타일(Variant)과 크기(Size)를 제공하여 인터페이스의
28
+ * 계층 구조를 명확히 하고 사용자의 행동을 유도합니다.
29
+ *
30
+ * ## When (언제 사용해야 하는가)
31
+ * ### 사용해야 하는 경우
32
+ *
33
+ * - **액션 실행**: 데이터 저장, 삭제, 전송 등 시스템 상태를 변경하는 작업을 수행할 때
34
+ * - **명확한 콜 투 액션(CTA)**: 페이지 내에서 가장 중요한 작업을 강조할 때
35
+ * - **내비게이션**: 다른 페이지로의 이동이나 섹션 전환이 필요할 때
36
+ * - **상태 변경**: 모달 열기, 드롭다운 토글 등 UI 요소를 제어할 때
37
+ *
38
+ * ### 사용하지 말아야 하는 경우:
39
+ *
40
+ * - **단순 링크**: 본문 내에서 다른 페이지로 연결되는 텍스트 링크는 `<a>` 태그나 별도의 Link 컴포넌트를 사용하세요
41
+ * - **여러 선택지 중 하나 선택**: `RadioButton`이나 `Checkbox`를 고려하세요
42
+ * - **탐색 메뉴**: `SideNavigation`이나 상단 메뉴에는 전용 메뉴 아이템을 사용하세요
43
+ *
44
+ * ---
45
+ *
46
+ * ## Layout behavior
47
+ *
48
+ * - **Inline-flex**: 기본적으로 인라인 블록 요소처럼 동작하여 텍스트 흐름 내에 배치됩니다.
49
+ * - **W-full**: `fullWidth` prop을 통해 부모 컨테이너의 전체 너비를 차지하게 할 수 있습니다.
50
+ * - **Center Alignment**: 버튼 내부의 텍스트와 아이콘은 항상 중앙에 정렬됩니다.
51
+ * - **Responsive**: 모바일 환경을 위해 `fullWidth`를 적극 활용하는 것이 좋습니다.
52
+ *
53
+ * ---
54
+ *
55
+ * ## Usage guidelines
56
+ *
57
+ * ### ✅ Do (권장 사항)
58
+ *
59
+ * - **명확한 동사 사용**: '저장', '삭제', '추가' 등 행동을 직접적으로 나타내는 레이블을 사용하세요.
60
+ * - **계층 구조 유지**: 한 화면에 여러 버튼이 있다면 가장 중요한 버튼에만 'primary' variant를 적용하세요.
61
+ * - **일관된 위치**: 확인 버튼은 오른쪽, 취소 버튼은 왼쪽에 배치하는 등 일관된 배치 규칙을 따르세요.
62
+ * - **로딩 상태 활용**: 서버 통신 등 시간이 걸리는 작업 시 `isLoading` 상태를 표시하여 중복 클릭을 방지하세요.
63
+ *
64
+ * ### 🚫 Don't (주의/금지 사항)
65
+ *
66
+ * - **레이블 생략 지양**: 아이콘만 있는 버튼(Icon Button)의 경우 접근성을 위해 반드시 `aria-label`을 제공하세요.
67
+ * - **너무 긴 텍스트**: 버튼 레이블은 가급적 짧고 간결하게 유지하세요 (보통 2-4자).
68
+ * - **모호한 표현**: '확인'보다는 '변경사항 저장'과 같이 구체적인 결과가 예상되는 레이블이 좋습니다.
69
+ *
70
+ * ---
71
+ *
72
+ * ## Accessibility
73
+ *
74
+ * - **Keyboard Support**: `Enter`와 `Space` 키로 실행 가능하며, 포커스 상태가 시각적으로 명확히 표시됩니다.
75
+ * - **ARIA Attributes**: `disabled` 상태 시 `aria-disabled`가 자동으로 처리됩니다.
76
+ * - **Role**: 기본적으로 `<button>` 태그를 사용하며, 필요한 경우 `asChild`를 통해 다른 요소(Link 등)로 렌더링하면서도 버튼의 스타일을 유지할 수 있습니다.
77
+ *
78
+ * ---
79
+ *
80
+ * ## Example
81
+ *
82
+ * {@tool snippet}
83
+ * 기본적인 버튼 사용 예시:
84
+ *
85
+ * ```tsx
86
+ * <div className="flex gap-2">
87
+ * <Button variant="primary">저장하기</Button>
88
+ * <Button variant="outline">취소</Button>
89
+ * <Button variant="ghost">닫기</Button>
90
+ * </div>
91
+ * ```
92
+ * {@end-tool}
93
+ *
94
+ * {@tool snippet}
95
+ * 아이콘과 로딩 상태가 포함된 버튼:
96
+ *
97
+ * ```tsx
98
+ * <Button
99
+ * isLoading={isSubmitting}
100
+ * leftIcon={<SaveIcon />}
101
+ * onClick={handleSubmit}
102
+ * >
103
+ * 데이터 저장
104
+ * </Button>
105
+ * ```
106
+ * {@end-tool}
107
+ *
108
+ * {@tool snippet}
109
+ * 크기 변형 예시:
110
+ *
111
+ * ```tsx
112
+ * <div className="flex items-center gap-2">
113
+ * <Button size="sm">Small</Button>
114
+ * <Button size="md">Medium</Button>
115
+ * <Button size="lg">Large</Button>
116
+ * </div>
117
+ * ```
118
+ * {@end-tool}
119
+ *s
120
+ * See also:
121
+ *
122
+ * - {@link TextInput}, 입력과 함께 액션이 필요한 경우
123
+ * - {@link Modal}, 중요한 결정을 위한 버튼을 포함하는 오버레이
124
+ * - {@link IconButton}, 아이콘만으로 구성된 버튼을 구성할 때
125
+ */
10
126
  declare const Button: import('react').ForwardRefExoticComponent<ButtonProps & import('react').RefAttributes<HTMLButtonElement>>;
11
127
  export { Button };
@@ -5,4 +5,83 @@ export interface CheckboxProps extends React.ComponentPropsWithoutRef<typeof Che
5
5
  label?: string;
6
6
  id?: string;
7
7
  }
8
+ /**
9
+ * 사용자가 여러 옵션 중 하나 이상을 선택하거나, 특정 항목의 활성화 상태를 제어할 때 사용하는 컴포넌트입니다.
10
+ *
11
+ * {@link Checkbox}는 개별적인 On/Off 상태를 표시하며, 주로 목록에서의 다중 선택이나
12
+ * 설정 화면에서 특정 기능의 사용 여부를 결정할 때 사용됩니다.
13
+ *
14
+ * Radix UI의 Checkbox 컴포넌트를 기반으로 구현되어 접근성과 키보드 내비게이션이
15
+ * 자동으로 처리됩니다.
16
+ *
17
+ * ## When (언제 사용해야 하는가)
18
+ *
19
+ * **사용해야 하는 경우:**
20
+ * - **다중 선택**: 목록에서 여러 항목을 동시에 선택해야 할 때
21
+ * - **단일 승인**: 이용약관 동의와 같이 하나의 항목에 대해 확인이 필요할 때
22
+ * - **설정 제어**: 특정 기능의 활성화/비활성화 상태를 토글할 때
23
+ * - **필터링**: 여러 조건(카테고리, 날짜 등)을 동시에 적용하여 결과를 필터링할 때
24
+ *
25
+ * **사용하지 말아야 하는 경우:**
26
+ * - **상호 배타적 선택**: 여러 옵션 중 단 하나만 선택해야 하는 경우 `RadioButton`을 사용하세요.
27
+ * - **즉각적인 상태 반영**: 설정을 바꾸자마자 페이지에 즉시 반영되는 경우 `Switch` 컴포넌트가 더 적절할 수 있습니다.
28
+ *
29
+ * ## Layout behavior
30
+ *
31
+ * - **Inline Alignment**: 레이블과 함께 가로로 나란히 배치되며, 기본적으로 인라인 블록 요소처럼 동작합니다.
32
+ * - **Spacing**: 체크박스와 레이블 사이에는 일정한 간격(8px/0.5rem)이 유지됩니다.
33
+ * - **Touch Area**: 모바일 대응을 위해 레이블 클릭 시에도 체크박스가 선택되도록 `htmlFor` 속성이 연결되어 있습니다.
34
+ *
35
+ * ## Usage guidelines
36
+ *
37
+ * ### ✅ Do (권장 사항)
38
+ *
39
+ * - **명확한 레이블 제공**: 체크박스가 무엇을 제어하는지 명확하게 설명하는 레이블을 함께 사용하세요.
40
+ * - **긍정형 문장 사용**: '알림 받지 않기'보다는 '알림 받기'와 같이 긍정형 문구로 작성하는 것이 혼란을 줄입니다.
41
+ * - **그룹화**: 여러 체크박스가 하나의 주제를 다룬다면 적절한 제목 아래에 그룹화하세요.
42
+ *
43
+ * ### 🚫 Don't (주의/금지 사항)
44
+ *
45
+ * - **레이블 생략 지양**: 공간이 매우 협소한 경우가 아니라면 항상 레이블을 함께 제공하세요.
46
+ * - **복잡한 텍스트**: 레이블에 너무 많은 정보나 설명을 넣지 마세요. 필요하다면 툴팁이나 별도의 설명 텍스트를 사용하세요.
47
+ *
48
+ * ## Accessibility
49
+ *
50
+ * - **Keyboard Interaction**: `Space` 키를 사용하여 체크 상태를 전환할 수 있습니다.
51
+ * - **Focus Management**: 탭 키를 통해 포커스를 이동할 수 있으며, 포커스 시 시각적인 강조 효과가 나타납니다.
52
+ * - **WAI-ARIA**: `role="checkbox"`를 사용하며, 체크 상태에 따라 `aria-checked` 값이 자동으로 업데이트됩니다.
53
+ * - **Label Connection**: `id`와 `htmlFor`가 자동으로 연결되어 스크린 리더가 레이블을 읽어줍니다.
54
+ *
55
+ * ## Example
56
+ *
57
+ * {@tool snippet}
58
+ * 기본적인 체크박스 사용 예시:
59
+ *
60
+ * ```tsx
61
+ * <Checkbox
62
+ * label="이용약관에 동의합니다"
63
+ * checked={agreed}
64
+ * onCheckedChange={setAgreed}
65
+ * />
66
+ * ```
67
+ * {@end-tool}
68
+ *
69
+ * {@tool snippet}
70
+ * 비활성화된 체크박스:
71
+ *
72
+ * ```tsx
73
+ * <Checkbox
74
+ * label="선택 불가능한 옵션"
75
+ * disabled
76
+ * checked={true}
77
+ * />
78
+ * ```
79
+ * {@end-tool}
80
+ *
81
+ * See also:
82
+ *
83
+ * - {@link RadioButton}, 하나만 선택해야 하는 경우
84
+ * - {@link Switch}, 즉각적인 상태 반영이 필요한 경우
85
+ * - {@link Button}, 단순 액션 실행이 필요한 경우
86
+ */
8
87
  export declare const Checkbox: React.ForwardRefExoticComponent<CheckboxProps & React.RefAttributes<HTMLButtonElement>>;
@@ -13,4 +13,86 @@ export interface DatePickerProps {
13
13
  helperText?: string;
14
14
  className?: string;
15
15
  }
16
+ /**
17
+ * 사용자가 달력 인터페이스를 통해 특정 날짜를 선택할 수 있게 하는 컴포넌트입니다.
18
+ *
19
+ * {@link DatePicker}는 직접적인 텍스트 입력 대신 시각적인 달력을 제공하여
20
+ * 날짜 형식의 오류를 방지하고 사용자 편의성을 높입니다.
21
+ *
22
+ * `react-day-picker`와 `dayjs`를 기반으로 구현되었으며, 한국어 로케일을 기본으로 지원합니다.
23
+ *
24
+ * ## When (언제 사용해야 하는가)
25
+ *
26
+ * **사용해야 하는 경우:**
27
+ * - **특정일 선택**: 생년월일, 예약일, 마감일 등 단일 날짜를 입력받아야 할 때
28
+ * - **제한된 범위 내 선택**: 과거 날짜만 선택 가능하거나, 특정 기간 내에서만 선택해야 할 때
29
+ * - **정확한 날짜 입력**: 텍스트 입력 시 발생할 수 있는 포맷 오류를 방지하고 싶을 때
30
+ *
31
+ * **사용하지 말아야 하는 경우:**
32
+ * - **기간 선택**: 시작일과 종료일을 함께 선택해야 하는 경우 `DateRangePicker`를 사용하세요.
33
+ * - **대략적인 시간/날짜**: '방금 전', '1주일 내' 등 상대적인 시간 선택이 필요한 경우 `Dropdown`이나 `RadioButton`이 더 적절할 수 있습니다.
34
+ * - **빠른 연도 이동**: 수십 년 전의 날짜를 선택해야 하는 경우(예: 생년월일) 달력보다는 직접 입력이나 연도 선택 기능이 포함된 별도 UI를 고려하세요.
35
+ *
36
+ * ## Layout behavior
37
+ *
38
+ * - **Popover 기반**: 클릭 시 입력창 아래에 달력 팝오버가 나타나며, 화면 공간을 효율적으로 사용합니다.
39
+ * - **Responsive**: 팝오버는 화면 경계 내에서 최적의 위치를 자동으로 찾아 표시됩니다.
40
+ * - **Full Width**: `className`을 통해 부모 요소의 너비에 맞게 조절할 수 있습니다.
41
+ *
42
+ * ## Usage guidelines
43
+ *
44
+ * ### ✅ Do (권장 사항)
45
+ *
46
+ * - **적절한 Placeholder**: "YYYY-MM-DD"와 같이 기대하는 날짜 형식을 명시하세요.
47
+ * - **최소/최대 날짜 설정**: 비즈니스 로직에 따라 `min`, `max` 속성을 사용하여 유효하지 않은 날짜 선택을 방지하세요.
48
+ * - **레이블 및 헬퍼 텍스트**: 입력 항목의 용도를 명확히 하고, 필요한 경우 보충 설명을 제공하세요.
49
+ *
50
+ * ### 🚫 Don't (주의/금지 사항)
51
+ *
52
+ * - **Read-only 입력**: 사용자가 직접 타이핑하여 입력하는 기능은 현재 지원하지 않으므로, 반드시 달력을 통해 선택하도록 안내하세요.
53
+ * - **복잡한 로직**: 너무 많은 날짜 제한 로직은 사용자에게 혼란을 줄 수 있습니다. 필요한 경우 에러 메시지로 명확히 안내하세요.
54
+ *
55
+ * ## Accessibility
56
+ *
57
+ * - **Keyboard Navigation**: 팝오버는 키보드로 열고 닫을 수 있으며, `Esc` 키로 취소할 수 있습니다.
58
+ * - **Focus Trap**: 달력이 열려 있는 동안 포커스가 달력 내부에 머무르도록 관리됩니다.
59
+ * - **Aria Labels**: 달력의 각 요소에는 스크린 리더를 위한 적절한 레이블이 포함되어 있습니다.
60
+ *
61
+ * ## Example
62
+ *
63
+ * {@tool snippet}
64
+ * 기본적인 날짜 선택 예시:
65
+ *
66
+ * ```tsx
67
+ * const [date, setDate] = useState("");
68
+ *
69
+ * <DatePicker
70
+ * label="방문 예약일"
71
+ * value={date}
72
+ * onChange={setDate}
73
+ * placeholder="예약 날짜를 선택하세요"
74
+ * />
75
+ * ```
76
+ * {@end-tool}
77
+ *
78
+ * {@tool snippet}
79
+ * 날짜 범위 제한 및 에러 상태:
80
+ *
81
+ * ```tsx
82
+ * <DatePicker
83
+ * label="종료일"
84
+ * min="2024-01-01"
85
+ * max="2024-12-31"
86
+ * error={true}
87
+ * errorMessage="2024년 내의 날짜만 선택 가능합니다"
88
+ * />
89
+ * ```
90
+ * {@end-tool}
91
+ *
92
+ * See also:
93
+ *
94
+ * - {@link DateRangePicker}, 기간을 선택해야 하는 경우
95
+ * - {@link TextInput}, 단순한 텍스트 입력이 필요한 경우
96
+ * - {@link Popover}, 일반적인 팝오버 컴포넌트
97
+ */
16
98
  export declare const DatePicker: React.ForwardRefExoticComponent<DatePickerProps & React.RefAttributes<HTMLDivElement>>;
@@ -1,4 +1,2 @@
1
1
  export { DatePicker } from './DatePicker';
2
2
  export type { DatePickerProps } from './DatePicker';
3
- export { DateRangePicker } from './DateRangePicker';
4
- export type { DateRangePickerProps, DateRange } from './DateRangePicker';
@@ -0,0 +1,93 @@
1
+ import { default as React } from 'react';
2
+
3
+ export interface DateRange {
4
+ start: string;
5
+ end: string;
6
+ }
7
+ export interface DateRangePickerProps {
8
+ value?: DateRange;
9
+ onChange?: (range: DateRange) => void;
10
+ startLabel?: string;
11
+ endLabel?: string;
12
+ className?: string;
13
+ }
14
+ /**
15
+ * 사용자가 특정 기간(시작일과 종료일)을 선택할 수 있게 하는 컴포넌트입니다.
16
+ *
17
+ * {@link DateRangePicker}는 두 개의 연동된 달력을 통해 기간을 시각적으로 선택할 수 있으며,
18
+ * '오늘', '이번주', '7일' 등 자주 사용되는 기간에 대한 빠른 선택(Quick Select) 기능을 제공합니다.
19
+ *
20
+ * `react-day-picker`와 `dayjs`를 기반으로 구현되었으며, 대규모 데이터 조회나
21
+ * 일정 설정 등 기간 입력이 필요한 서비스에서 주로 사용됩니다.
22
+ *
23
+ * ## When (언제 사용해야 하는가)
24
+ *
25
+ * **사용해야 하는 경우:**
26
+ * - **조회 기간 설정**: 특정 기간 내의 로그, 주문 내역, 통계 데이터 등을 조회할 때
27
+ * - **일정 범위 지정**: 이벤트 진행 기간, 캠페인 유효 기간 등 시작과 끝이 있는 일정을 설정할 때
28
+ * - **상대적 기간 선택**: '최근 7일', '이번 달' 등 현재 시점 기준의 상대적 기간을 빠르게 선택해야 할 때
29
+ *
30
+ * **사용하지 말아야 하는 경우:**
31
+ * - **단일 날짜 선택**: 하나의 날짜만 필요한 경우 `DatePicker`를 사용하세요.
32
+ * - **고정된 기간**: '1주일', '1개월' 등 기간이 고정되어 있고 시작일만 선택하면 되는 경우 `DatePicker`와 드롭다운 조합이 더 나을 수 있습니다.
33
+ *
34
+ * ## Layout behavior
35
+ *
36
+ * - **Dual Calendar**: 두 개의 달력이 나란히 표시되어 시작일과 종료일을 한눈에 확인하고 조절할 수 있습니다.
37
+ * - **Side Panels**: 왼쪽 사이드바에 '오늘', '이번주' 등 빠른 선택 버튼이 배치되어 접근성을 높입니다.
38
+ * - **Combined Input**: 두 개의 입력창(시작, 종료)이 하나의 그룹으로 묶여 표시됩니다.
39
+ *
40
+ * ## Usage guidelines
41
+ *
42
+ * ### ✅ Do (권장 사항)
43
+ *
44
+ * - **적절한 시작/종료 레이블**: "시작일", "종료일" 또는 "등록일", "수정일" 등 문맥에 맞는 레이블을 사용하세요.
45
+ * - **기간 확인 피드백**: 선택된 총 일수(예: 7일간)를 하단에 표시하여 사용자가 선택한 범위를 쉽게 인지하게 하세요.
46
+ * - **빠른 선택 활용**: 사용자 조사의 80% 이상이 '최근 7일'이라면 해당 옵션을 눈에 띄게 배치하거나 기본값으로 고려하세요.
47
+ *
48
+ * ### 🚫 Don't (주의/금지 사항)
49
+ *
50
+ * - **너무 넓은 기본 범위**: 데이터 양이 많을 경우 기본 범위를 너무 넓게 잡으면 성능 문제가 발생할 수 있습니다.
51
+ * - **모바일에서의 레이아웃**: 2개의 달력이 나란히 표시되므로 모바일 환경에서는 화면을 넘칠 수 있습니다. 반응형 대응에 주의하세요.
52
+ *
53
+ * ## Accessibility
54
+ *
55
+ * - **Keyboard Management**: `Tab` 키로 시작일/종료일 입력창과 달력 내부 요소를 순차적으로 이동할 수 있습니다.
56
+ * - **Visual Indicators**: 선택된 기간 내의 날짜들은 배경색으로 하이라이트되어 시각적으로 구분됩니다.
57
+ * - **Screen Reader**: 시작일과 종료일의 레이블이 각각 명확히 연결되어 음성으로 안내됩니다.
58
+ *
59
+ * ## Example
60
+ *
61
+ * {@tool snippet}
62
+ * 기본적인 기간 선택 예시:
63
+ *
64
+ * ```tsx
65
+ * const [range, setRange] = useState({ start: "2024-01-01", end: "2024-01-07" });
66
+ *
67
+ * <DateRangePicker
68
+ * value={range}
69
+ * onChange={setRange}
70
+ * startLabel="조회 시작"
71
+ * endLabel="조회 종료"
72
+ * />
73
+ * ```
74
+ * {@end-tool}
75
+ *
76
+ * {@tool snippet}
77
+ * 빠른 선택 옵션이 포함된 초기 상태:
78
+ *
79
+ * ```tsx
80
+ * // '전체', '오늘', '내일', '이번주', '이번달', '7일', '30일' 등의
81
+ * // 빠른 선택 옵션이 기본적으로 내장되어 있습니다.
82
+ * <DateRangePicker
83
+ * className="w-[400px]"
84
+ * />
85
+ * ```
86
+ * {@end-tool}
87
+ *
88
+ * See also:
89
+ *
90
+ * - {@link DatePicker}, 단일 날짜 선택이 필요한 경우
91
+ * - {@link Dropdown}, 기간을 텍스트 기반의 선택지로 제공할 때
92
+ */
93
+ export declare const DateRangePicker: React.ForwardRefExoticComponent<DateRangePickerProps & React.RefAttributes<HTMLDivElement>>;
@@ -0,0 +1,2 @@
1
+ export { DateRangePicker } from './DateRangePicker';
2
+ export type { DateRangePickerProps, DateRange } from './DateRangePicker';
@@ -5,4 +5,82 @@ export interface ComboboxProps extends Omit<DropdownProps, "searchable"> {
5
5
  createable?: boolean;
6
6
  onCreateOption?: (value: string) => void;
7
7
  }
8
+ /**
9
+ * 텍스트 입력과 드롭다운 선택 기능이 결합되어, 목록에서 검색하거나 새로운 옵션을 생성할 수 있는 컴포넌트입니다.
10
+ *
11
+ * {@link Combobox}는 사용자가 방대한 목록에서 원하는 항목을 빠르게 찾을 수 있도록 돕고,
12
+ * 만약 찾는 항목이 없을 경우 즉석에서 새로운 값을 추가할 수 있는 유연성을 제공합니다.
13
+ *
14
+ * {@link Dropdown}의 확장 버전으로, 기본적으로 `searchable` 기능이 활성화되어 있습니다.
15
+ *
16
+ * ## When (언제 사용해야 하는가)
17
+ *
18
+ * **사용해야 하는 경우:**
19
+ * - **대량 데이터 검색**: 옵션이 수백 개 이상이어서 단순 스크롤로는 찾기 어려운 경우
20
+ * - **동적 옵션 추가**: 목록에 없는 값을 사용자가 직접 입력하여 데이터베이스에 추가해야 할 때 (예: 태그 입력, 신규 제조사 추가 등)
21
+ * - **빠른 필터링**: 사용자가 정확한 명칭을 입력하여 필터링된 결과만 보고 싶어 할 때
22
+ *
23
+ * **사용하지 말아야 하는 경우:**
24
+ * - **옵션이 고정된 경우**: 새로운 값을 추가할 필요가 없고 옵션 개수가 적다면 일반 `Dropdown`이나 `Select`가 더 단순합니다.
25
+ * - **자유 텍스트 입력**: 미리 정의된 옵션 없이 자유로운 입력을 받는 것이 주 목적이라면 `TextInput`을 사용하세요.
26
+ *
27
+ * ## Layout behavior
28
+ *
29
+ * - **Auto-filtering**: 사용자가 입력할 때마다 목록이 즉시 필터링되어 업데이트됩니다.
30
+ * - **Create Option**: `createable` 설정 시, 검색 결과가 없을 경우 최하단에 '생성' 옵션이 나타납니다.
31
+ *
32
+ * ## Usage guidelines
33
+ *
34
+ * ### ✅ Do (권장 사항)
35
+ *
36
+ * - **로딩 상태 표시**: 대규모 데이터를 원격에서 가져오는 경우 `loading` 속성을 통해 사용자에게 진행 상황을 알리세요.
37
+ * - **명확한 생성 문구**: 새로운 항목을 생성할 때 무엇이 생성되는지 사용자에게 명확히 전달하세요.
38
+ * - **검색 최적화**: 대소문자 구분 없는 검색 등 사용자가 입력하기 편한 검색 환경을 제공하세요.
39
+ *
40
+ * ### 🚫 Don't (주의/금지 사항)
41
+ *
42
+ * - **검색창 없는 콤보박스**: 콤보박스의 핵심은 검색입니다. 검색이 필요 없다면 일반 드롭다운을 사용하세요.
43
+ * - **복잡한 생성 과정**: `onCreateOption`에서 너무 복잡한 로직을 처리하면 UI가 멈춘 것처럼 보일 수 있습니다. 비동기 처리 시 로딩 상태를 적절히 활용하세요.
44
+ *
45
+ * ## Accessibility
46
+ *
47
+ * - **Aria Roles**: `role="combobox"`를 사용하여 입력과 선택이 가능한 요소임을 스크린 리더에 알립니다.
48
+ * - **Live Regions**: 필터링 결과의 개수 변화 등을 시각 장애 사용자에게 알릴 수 있도록 설계되었습니다.
49
+ *
50
+ * ## Example
51
+ *
52
+ * {@tool snippet}
53
+ * 새로운 옵션을 생성할 수 있는 콤보박스:
54
+ *
55
+ * ```tsx
56
+ * <Combobox
57
+ * options={existingTags}
58
+ * createable={true}
59
+ * onCreateOption={(newTag) => {
60
+ * // 서버에 태그 추가 요청 후 목록 업데이트
61
+ * handleCreateTag(newTag);
62
+ * }}
63
+ * placeholder="태그를 검색하거나 새로 추가하세요"
64
+ * />
65
+ * ```
66
+ * {@end-tool}
67
+ *
68
+ * {@tool snippet}
69
+ * 데이터를 로딩 중인 콤보박스:
70
+ *
71
+ * ```tsx
72
+ * <Combobox
73
+ * options={[]}
74
+ * loading={true}
75
+ * placeholder="데이터를 불러오는 중..."
76
+ * />
77
+ * ```
78
+ * {@end-tool}
79
+ *
80
+ * See also:
81
+ *
82
+ * - {@link Dropdown}, 기본 검색/선택 기능이 필요한 경우
83
+ * - {@link TagInput}, 여러 개의 값을 검색하여 추가해야 할 때
84
+ * - {@link TextInput}, 단순한 텍스트 입력만 필요한 경우
85
+ */
8
86
  export declare const Combobox: import('react').ForwardRefExoticComponent<ComboboxProps & import('react').RefAttributes<HTMLButtonElement>>;
@@ -22,4 +22,85 @@ export interface DropdownProps extends VariantProps<typeof dropdownTriggerVarian
22
22
  multiple?: boolean;
23
23
  maxHeight?: number;
24
24
  }
25
+ /**
26
+ * 사용자가 목록에서 하나 또는 여러 개의 옵션을 선택할 수 있게 하는 컴포넌트입니다.
27
+ *
28
+ * {@link Dropdown}은 공간이 제한적인 UI에서 다양한 선택지를 효율적으로 제공합니다.
29
+ * 검색 기능, 다중 선택(Multiple), 선택 해제(Clearable) 등 복잡한 선택 시나리오를 지원합니다.
30
+ *
31
+ * ## When (언제 사용해야 하는가)
32
+ *
33
+ * **사용해야 하는 경우:**
34
+ * - **단일/다중 선택**: 5개 이상의 옵션 중 하나 또는 여러 개를 선택해야 할 때
35
+ * - **공간 절약**: 라디오 버튼이나 체크박스 그룹을 표시하기엔 화면 공간이 부족할 때
36
+ * - **동적 필터링**: 옵션이 너무 많아 검색을 통해 원하는 항목을 찾아야 할 때
37
+ *
38
+ * **사용하지 말아야 하는 경우:**
39
+ * - **옵션이 적은 경우(2-4개)**: 사용자가 모든 옵션을 한눈에 볼 수 있는 `RadioButton`이나 `Checkbox`가 더 좋습니다.
40
+ * - **설정 토글**: 단순히 On/Off를 전환하는 것이라면 `Switch`를 사용하세요.
41
+ * - **단순 내비게이션**: 클릭 시 다른 페이지로 이동만 하는 기능이라면 `Button`이나 `SideNavigation` 아이템이 더 적절합니다.
42
+ *
43
+ * ## Layout behavior
44
+ *
45
+ * - **Popover Menu**: 클릭 시 버튼 아래(또는 위)에 옵션 목록이 나타나며, 다른 요소들 위에 오버레이됩니다.
46
+ * - **Flexible Width**: 부모 컨테이너의 너비에 맞춰지거나, `className`을 통해 고정 너비를 가질 수 있습니다.
47
+ * - **Scrolling**: 옵션이 많아지면 `maxHeight` 설정에 따라 목록 내부에 스크롤이 발생합니다.
48
+ *
49
+ * ## Usage guidelines
50
+ *
51
+ * ### ✅ Do (권장 사항)
52
+ *
53
+ * - **논리적 정렬**: 옵션 목록은 가나다순, 사용 빈도순 등 사용자가 예측 가능한 순서로 정렬하세요.
54
+ * - **검색 기능 활용**: 옵션이 10개 이상인 경우 `searchable` 속성을 활성화하여 편의성을 높이세요.
55
+ * - **상태 표시**: `placeholder`를 통해 무엇을 선택해야 하는지 안내하고, 선택 후에는 선택된 항목을 명확히 표시하세요.
56
+ *
57
+ * ### 🚫 Don't (주의/금지 사항)
58
+ *
59
+ * - **너무 많은 텍스트**: 각 옵션의 레이블은 가급적 한 줄에 들어오도록 짧게 작성하세요.
60
+ * - **중첩 드롭다운 지양**: 드롭다운 안에서 또 다른 드롭다운이 열리는 복잡한 계층 구조는 피하는 것이 좋습니다.
61
+ *
62
+ * ## Accessibility
63
+ *
64
+ * - **Keyboard Interaction**: `Enter`나 `Space`로 열고, 화살표 키로 이동하며, `Esc`로 닫을 수 있습니다.
65
+ * - **Screen Reader**: `aria-expanded`, `aria-haspopup` 등의 속성을 통해 드롭다운의 상태와 역할을 스크린 리더에 전달합니다.
66
+ * - **Focus Management**: 드롭다운이 열리면 검색창이나 첫 번째 옵션으로 포커스가 이동합니다.
67
+ *
68
+ * ## Example
69
+ *
70
+ * {@tool snippet}
71
+ * 기본적인 단일 선택 드롭다운:
72
+ *
73
+ * ```tsx
74
+ * <Dropdown
75
+ * options={[
76
+ * { value: 'ko', label: '한국어' },
77
+ * { value: 'en', label: '영어' },
78
+ * { value: 'ja', label: '일본어' },
79
+ * ]}
80
+ * placeholder="언어를 선택하세요"
81
+ * onValueChange={(val) => console.log(val)}
82
+ * />
83
+ * ```
84
+ * {@end-tool}
85
+ *
86
+ * {@tool snippet}
87
+ * 검색과 다중 선택이 가능한 드롭다운:
88
+ *
89
+ * ```tsx
90
+ * <Dropdown
91
+ * options={largeOptionList}
92
+ * multiple={true}
93
+ * searchable={true}
94
+ * clearable={true}
95
+ * placeholder="태그 선택"
96
+ * />
97
+ * ```
98
+ * {@end-tool}
99
+ *
100
+ * See also:
101
+ *
102
+ * - {@link Select}, 기본적인 HTML select 스타일의 컴포넌트
103
+ * - {@link Combobox}, 입력과 선택이 결합된 컴포넌트
104
+ * - {@link Popover}, 더 자유로운 형태의 팝오버가 필요한 경우
105
+ */
25
106
  export declare const Dropdown: import('react').ForwardRefExoticComponent<DropdownProps & import('react').RefAttributes<HTMLButtonElement>>;