cashdoc-cms-design-system 1.0.2 → 1.0.4

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/README.md CHANGED
@@ -1,6 +1,16 @@
1
1
  # Cashdoc CMS Design System
2
2
 
3
- Cashdoc CMS용 디자인 시스템 컴포넌트 라이브러리 [Storybook](https://cashdoc-cms-design-system.vercel.app/?path=/docs/components-button--docs)
3
+ Cashdoc CMS용 디자인 시스템 컴포넌트 라이브러리
4
+
5
+ ## 문서
6
+ Storybook과 JSDoc, 둘 중 더 편한 쪽을 보면 됩니다.
7
+ ### Storybook
8
+ [Storybook](https://cashdoc-cms-design-system.vercel.app/?path=/docs/components-button--docs)
9
+
10
+ ### JSDoc(TSDoc)
11
+ <img width="1038" height="363" alt="스크린샷 2025-12-24 오후 3 48 42" src="https://github.com/user-attachments/assets/1178fa60-30cb-436b-944c-495417179ac3" />
12
+
13
+ <br />
4
14
 
5
15
  ## 기술 스택
6
16
 
@@ -12,12 +22,16 @@ Cashdoc CMS용 디자인 시스템 컴포넌트 라이브러리 [Storybook](http
12
22
  - **Vite** - 빌드 도구
13
23
  - **Storybook** - 컴포넌트 문서화
14
24
 
25
+ <br />
26
+
15
27
  ## 설치
16
28
 
17
29
  ```bash
18
30
  pnpm install cashdoc-cms-design-system
19
31
  ```
20
32
 
33
+ <br />
34
+
21
35
  ## 사용법
22
36
 
23
37
  프로젝트 최상단에서 cashdoc-cms-design-system의 `style.css` 파일을 import 후 사용하면 됩니다.
@@ -34,6 +48,8 @@ function App() {
34
48
  }
35
49
  ```
36
50
 
51
+ <br />
52
+
37
53
  ## 컴포넌트 리스트
38
54
 
39
55
  ### Form
@@ -74,7 +90,9 @@ function App() {
74
90
  - `Text` - 타이포그래피
75
91
  - `Icons` - 아이콘 세트
76
92
 
77
- ## 개발
93
+ #
94
+ <br />
95
+ # 개발
78
96
 
79
97
  ### 로컬 개발 서버
80
98
 
@@ -0,0 +1,151 @@
1
+ import { default as React } from 'react';
2
+ import { VariantProps } from 'class-variance-authority';
3
+
4
+ /**
5
+ * 데이터를 행과 열로 구조화하여 표시하는 테이블 컴포넌트입니다.
6
+ *
7
+ * {@link Table}은 Compound Component 패턴을 사용하여 구성되며,
8
+ * TableHeader, TableBody, TableFooter, TableRow, TableHead, TableCell, TableCaption
9
+ * 등의 하위 컴포넌트를 조합하여 유연한 테이블 레이아웃을 만들 수 있습니다.
10
+ *
11
+ * ## When (언제 사용해야 하는가)
12
+ *
13
+ * **사용해야 하는 경우:**
14
+ * - **데이터 목록**: 사용자 목록, 주문 내역, 제품 리스트 등 구조화된 데이터를 표시할 때
15
+ * - **비교**: 여러 항목의 속성을 나란히 비교해야 할 때
16
+ * - **정렬 및 필터**: 데이터를 정렬하거나 필터링해서 보여줄 때
17
+ * - **대량 데이터**: 많은 양의 정보를 조직적으로 표시해야 할 때
18
+ *
19
+ * **사용하지 말아야 하는 경우:**
20
+ * - **레이아웃 목적**: 단순히 레이아웃을 만들기 위해서는 CSS Grid나 Flexbox를 사용하세요.
21
+ * - **소량 데이터**: 2-3개의 간단한 정보는 리스트나 카드 형태가 더 적합할 수 있습니다.
22
+ * - **복잡한 인터랙션**: 각 행마다 많은 버튼이나 입력이 필요하다면 카드 레이아웃을 고려하세요.
23
+ *
24
+ * ## Layout behavior
25
+ *
26
+ * - **Responsive**: 기본적으로 스크롤 가능한 컨테이너로 래핑되어 모바일에서도 사용 가능합니다.
27
+ * - **Full Width**: 부모 컨테이너의 전체 너비를 차지합니다.
28
+ * - **Auto Height**: 내용에 따라 높이가 자동으로 조정됩니다.
29
+ *
30
+ * ## Usage guidelines
31
+ *
32
+ * ### ✅ Do (권장 사항)
33
+ *
34
+ * - **명확한 헤더**: TableHead를 사용하여 각 열의 의미를 명확히 표시하세요.
35
+ * - **일관된 정렬**: 숫자는 오른쪽, 텍스트는 왼쪽 정렬하는 것이 일반적입니다.
36
+ * - **적절한 variant**: 데이터가 많을 때는 `striped`나 `hoverable`을 사용하여 가독성을 높이세요.
37
+ * - **Caption 활용**: 테이블의 목적을 설명하는 caption을 추가하면 접근성이 향상됩니다.
38
+ *
39
+ * ### 🚫 Don't (주의/금지 사항)
40
+ *
41
+ * - **과도한 열**: 너무 많은 열은 가독성을 해칩니다. 중요한 정보만 표시하세요.
42
+ * - **중첩 테이블**: 테이블 안에 테이블을 넣지 마세요. 복잡도가 급격히 증가합니다.
43
+ * - **빈 셀 남용**: 빈 셀이 많으면 데이터 구조를 다시 검토하세요.
44
+ *
45
+ * ## Accessibility
46
+ *
47
+ * - **Semantic HTML**: 적절한 `<table>`, `<thead>`, `<tbody>`, `<th>`, `<td>` 태그를 사용합니다.
48
+ * - **Scope Attribute**: TableHead는 `scope="col"`을 자동으로 가집니다.
49
+ * - **ARIA Attributes**: 정렬, 선택 등의 상태는 `aria-sort`, `aria-selected`로 표현됩니다.
50
+ * - **Caption**: 테이블의 목적을 설명하는 `<caption>`을 사용할 수 있습니다.
51
+ *
52
+ * ## Example
53
+ *
54
+ * {@tool snippet}
55
+ * 기본 테이블 사용:
56
+ *
57
+ * ```tsx
58
+ * <Table>
59
+ * <TableCaption>사용자 목록</TableCaption>
60
+ * <TableHeader>
61
+ * <TableRow>
62
+ * <TableHead>이름</TableHead>
63
+ * <TableHead>이메일</TableHead>
64
+ * <TableHead align="right">역할</TableHead>
65
+ * </TableRow>
66
+ * </TableHeader>
67
+ * <TableBody>
68
+ * <TableRow>
69
+ * <TableCell>홍길동</TableCell>
70
+ * <TableCell>hong@example.com</TableCell>
71
+ * <TableCell align="right">관리자</TableCell>
72
+ * </TableRow>
73
+ * </TableBody>
74
+ * </Table>
75
+ * ```
76
+ *
77
+ * Striped 테이블:
78
+ *
79
+ * ```tsx
80
+ * <Table striped hoverable>
81
+ * <TableHeader>
82
+ * <TableRow>
83
+ * <TableHead>제품명</TableHead>
84
+ * <TableHead align="right">가격</TableHead>
85
+ * </TableRow>
86
+ * </TableHeader>
87
+ * <TableBody>
88
+ * {products.map((product) => (
89
+ * <TableRow key={product.id}>
90
+ * <TableCell>{product.name}</TableCell>
91
+ * <TableCell align="right">{product.price}</TableCell>
92
+ * </TableRow>
93
+ * ))}
94
+ * </TableBody>
95
+ * </Table>
96
+ * ```
97
+ * {@end-tool}
98
+ */
99
+ declare const tableVariants: (props?: ({
100
+ bordered?: boolean | null | undefined;
101
+ } & import('class-variance-authority/types').ClassProp) | undefined) => string;
102
+ export interface TableProps extends React.TableHTMLAttributes<HTMLTableElement>, VariantProps<typeof tableVariants> {
103
+ /** zebra stripe 패턴 적용 여부 */
104
+ striped?: boolean;
105
+ /** row hover 효과 적용 여부 */
106
+ hoverable?: boolean;
107
+ /** 테두리 표시 여부 */
108
+ bordered?: boolean;
109
+ /** 좁은 padding 적용 여부 */
110
+ compact?: boolean;
111
+ }
112
+ export declare const Table: React.ForwardRefExoticComponent<TableProps & React.RefAttributes<HTMLTableElement>>;
113
+ export interface TableHeaderProps extends React.HTMLAttributes<HTMLTableSectionElement> {
114
+ }
115
+ export declare const TableHeader: React.ForwardRefExoticComponent<TableHeaderProps & React.RefAttributes<HTMLTableSectionElement>>;
116
+ export interface TableBodyProps extends React.HTMLAttributes<HTMLTableSectionElement> {
117
+ }
118
+ export declare const TableBody: React.ForwardRefExoticComponent<TableBodyProps & React.RefAttributes<HTMLTableSectionElement>>;
119
+ export interface TableFooterProps extends React.HTMLAttributes<HTMLTableSectionElement> {
120
+ }
121
+ export declare const TableFooter: React.ForwardRefExoticComponent<TableFooterProps & React.RefAttributes<HTMLTableSectionElement>>;
122
+ declare const tableRowVariants: (props?: ({
123
+ hoverable?: boolean | null | undefined;
124
+ selected?: boolean | null | undefined;
125
+ } & import('class-variance-authority/types').ClassProp) | undefined) => string;
126
+ export interface TableRowProps extends React.HTMLAttributes<HTMLTableRowElement>, VariantProps<typeof tableRowVariants> {
127
+ /** 선택된 행 표시 여부 */
128
+ selected?: boolean;
129
+ }
130
+ export declare const TableRow: React.ForwardRefExoticComponent<TableRowProps & React.RefAttributes<HTMLTableRowElement>>;
131
+ export interface TableHeadProps extends React.ThHTMLAttributes<HTMLTableCellElement> {
132
+ /** 정렬 가능 여부 */
133
+ sortable?: boolean;
134
+ /** 정렬 방향 */
135
+ sortDirection?: "asc" | "desc" | null;
136
+ /** 정렬 클릭 핸들러 */
137
+ onSort?: () => void;
138
+ }
139
+ export declare const TableHead: React.ForwardRefExoticComponent<TableHeadProps & React.RefAttributes<HTMLTableCellElement>>;
140
+ declare const tableCellVariants: (props?: ({
141
+ align?: "center" | "right" | "left" | null | undefined;
142
+ } & import('class-variance-authority/types').ClassProp) | undefined) => string;
143
+ export interface TableCellProps extends React.TdHTMLAttributes<HTMLTableCellElement>, VariantProps<typeof tableCellVariants> {
144
+ /** 텍스트 정렬 방식 */
145
+ align?: "left" | "center" | "right";
146
+ }
147
+ export declare const TableCell: React.ForwardRefExoticComponent<TableCellProps & React.RefAttributes<HTMLTableCellElement>>;
148
+ export interface TableCaptionProps extends React.HTMLAttributes<HTMLTableCaptionElement> {
149
+ }
150
+ export declare const TableCaption: React.ForwardRefExoticComponent<TableCaptionProps & React.RefAttributes<HTMLTableCaptionElement>>;
151
+ export {};
@@ -0,0 +1,2 @@
1
+ export { Table, TableHeader, TableBody, TableFooter, TableRow, TableHead, TableCell, TableCaption, } from './Table';
2
+ export type { TableProps, TableHeaderProps, TableBodyProps, TableFooterProps, TableRowProps, TableHeadProps, TableCellProps, TableCaptionProps, } from './Table';
@@ -0,0 +1,110 @@
1
+ import { default as React } from 'react';
2
+ import * as TooltipPrimitive from "@radix-ui/react-tooltip";
3
+ /**
4
+ * 마우스 호버나 포커스 시 간단한 힌트나 설명을 제공하는 툴팁 컴포넌트입니다.
5
+ *
6
+ * {@link ToolTip}은 UI 요소에 대한 추가 정보를 간결하게 제공하여
7
+ * 사용자가 인터페이스를 더 쉽게 이해할 수 있도록 돕습니다.
8
+ *
9
+ * Radix UI의 Tooltip 컴포넌트를 기반으로 구현되어 접근성 기능이
10
+ * 자동으로 처리됩니다.
11
+ *
12
+ * ## When (언제 사용해야 하는가)
13
+ *
14
+ * **사용해야 하는 경우:**
15
+ * - **아이콘 설명**: 텍스트 레이블이 없는 아이콘 버튼의 기능을 설명할 때
16
+ * - **축약된 텍스트**: 말줄임표(...)로 잘린 텍스트의 전체 내용을 보여줄 때
17
+ * - **간단한 힌트**: 입력 필드나 기능에 대한 짧은 도움말을 제공할 때
18
+ * - **추가 정보**: UI 요소의 상태나 제약사항을 간단히 알려줄 때
19
+ *
20
+ * **사용하지 말아야 하는 경우:**
21
+ * - **필수 정보**: 사용자가 반드시 알아야 하는 정보는 본문에 직접 표시하세요.
22
+ * - **복잡한 내용**: 여러 줄의 긴 텍스트나 인터랙티브 요소는 Popover나 Modal을 사용하세요.
23
+ * - **모바일 전용 UI**: 터치 기기에서는 호버가 없으므로 중요한 정보를 툴팁에만 의존하지 마세요.
24
+ *
25
+ * ## Layout behavior
26
+ *
27
+ * - **Positioning**: 트리거 요소를 기준으로 상하좌우 원하는 위치에 배치됩니다. (기본: top)
28
+ * - **Auto-adjustment**: 화면 경계를 벗어나지 않도록 자동으로 위치를 조정합니다.
29
+ * - **Floating**: 다른 UI 요소들 위에 떠 있으며, 레이아웃에 영향을 주지 않습니다.
30
+ * - **Arrow**: 트리거와의 연결을 시각적으로 나타내는 화살표를 선택적으로 표시할 수 있습니다.
31
+ *
32
+ * ## Usage guidelines
33
+ *
34
+ * ### ✅ Do (권장 사항)
35
+ *
36
+ * - **간결한 텍스트**: 한두 줄 이내의 짧은 텍스트로 핵심만 전달하세요.
37
+ * - **적절한 지연**: `delayDuration`을 조절하여 우발적인 호버로 인한 깜빡임을 방지하세요. (기본: 200ms)
38
+ * - **명확한 트리거**: 툴팁이 붙는 요소가 호버 가능함을 사용자가 인지할 수 있도록 하세요.
39
+ *
40
+ * ### 🚫 Don't (주의/금지 사항)
41
+ *
42
+ * - **중요 정보 숨기기**: 필수적인 정보를 툴팁에만 넣지 마세요.
43
+ * - **상호작용 요소**: 툴팁 내부에 클릭 가능한 버튼이나 링크를 넣지 마세요. (Popover 사용 권장)
44
+ * - **과도한 사용**: 모든 요소에 툴팁을 붙이면 오히려 사용성이 떨어집니다.
45
+ *
46
+ * ## Accessibility
47
+ *
48
+ * - **Keyboard Support**: 포커스 가능한 요소에 툴팁이 붙으면 포커스 시 자동으로 표시됩니다.
49
+ * - **ESC Key**: `Esc` 키를 누르면 툴팁이 닫힙니다.
50
+ * - **Screen Readers**: `aria-describedby` 속성이 자동으로 부여되어 스크린 리더가 내용을 읽습니다.
51
+ * - **Touch Devices**: 터치 기기에서는 탭으로 툴팁을 활성화할 수 있습니다.
52
+ *
53
+ * ## Example
54
+ *
55
+ * {@tool snippet}
56
+ * 아이콘 버튼에 툴팁 추가:
57
+ *
58
+ * ```tsx
59
+ * <ToolTip content="설정">
60
+ * <Button variant="ghost" size="icon">
61
+ * <SettingsIcon />
62
+ * </Button>
63
+ * </ToolTip>
64
+ * ```
65
+ *
66
+ * 위치와 지연 시간 커스터마이징:
67
+ *
68
+ * ```tsx
69
+ * <ToolTip
70
+ * content="이 기능은 프리미엄 사용자만 이용할 수 있습니다"
71
+ * side="bottom"
72
+ * delayDuration={300}
73
+ * >
74
+ * <Button disabled>프리미엄 기능</Button>
75
+ * </ToolTip>
76
+ * ```
77
+ * {@end-tool}
78
+ *
79
+ * See also:
80
+ *
81
+ * - {@link Popover}, 클릭으로 열고 상호작용이 필요한 경우
82
+ * - {@link Modal}, 중요한 정보나 복잡한 작업이 필요한 경우
83
+ */
84
+ export interface ToolTipProps extends Omit<React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content>, "content"> {
85
+ /** 툴팁을 트리거하는 요소 */
86
+ children: React.ReactNode;
87
+ /** 툴팁에 표시할 내용 */
88
+ content: React.ReactNode;
89
+ /** 툴팁이 나타날 위치 (기본: "top") */
90
+ side?: "top" | "right" | "bottom" | "left";
91
+ /** 트리거로부터의 거리 (픽셀) (기본: 4) */
92
+ sideOffset?: number;
93
+ /** 트리거와의 정렬 방식 (기본: "center") */
94
+ align?: "start" | "center" | "end";
95
+ /** 마우스 호버 후 툴팁이 나타나기까지의 지연 시간 (밀리초) (기본: 200) */
96
+ delayDuration?: number;
97
+ /** 다른 툴팁에서 빠르게 진입 시 지연 건너뛰기 시간 (밀리초) (기본: 300) */
98
+ skipDelayDuration?: number;
99
+ /** 툴팁 위로 마우스를 이동할 수 있는지 여부 (기본: true) */
100
+ disableHoverableContent?: boolean;
101
+ /** 화살표 표시 여부 (기본: true) */
102
+ showArrow?: boolean;
103
+ /** Controlled 모드: 툴팁 열림 상태 */
104
+ open?: boolean;
105
+ /** Uncontrolled 모드: 초기 열림 상태 */
106
+ defaultOpen?: boolean;
107
+ /** 툴팁 열림 상태 변경 시 콜백 */
108
+ onOpenChange?: (open: boolean) => void;
109
+ }
110
+ export declare const ToolTip: React.ForwardRefExoticComponent<ToolTipProps & React.RefAttributes<HTMLDivElement>>;
@@ -0,0 +1,2 @@
1
+ export { ToolTip } from './ToolTip';
2
+ export type { ToolTipProps } from './ToolTip';
@@ -15,3 +15,5 @@ export * from './Pagination';
15
15
  export * from './Checkbox';
16
16
  export * from './Modal';
17
17
  export * from './Toast';
18
+ export * from './ToolTip';
19
+ export * from './Table';