@crossangle-org/cs-ui 0.2.5 → 0.2.7
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/accordion/cs-accordion.js +116 -0
- package/dist/components/accordion/cs-accordion.js.map +1 -0
- package/dist/components/alert-dialog/cs-alert-dialog.js +148 -0
- package/dist/components/alert-dialog/cs-alert-dialog.js.map +1 -0
- package/dist/components/avatar/cs-avatar.js +44 -0
- package/dist/components/avatar/cs-avatar.js.map +1 -0
- package/dist/components/badge/cs-badge.js +40 -0
- package/dist/components/badge/cs-badge.js.map +1 -0
- package/dist/components/box/cs-box.js +37 -0
- package/dist/components/box/cs-box.js.map +1 -0
- package/dist/components/button/cs-button.js +91 -0
- package/dist/components/button/cs-button.js.map +1 -0
- package/dist/components/calendar/cs-calendar.js +199 -0
- package/dist/components/calendar/cs-calendar.js.map +1 -0
- package/dist/components/card/cs-card.js +95 -0
- package/dist/components/card/cs-card.js.map +1 -0
- package/dist/components/chart/cs-chart.js +88 -0
- package/dist/components/chart/cs-chart.js.map +1 -0
- package/dist/components/checkbox/cs-checkbox.js +55 -0
- package/dist/components/checkbox/cs-checkbox.js.map +1 -0
- package/dist/components/code-block/cs-code-block.js +39 -0
- package/dist/components/code-block/cs-code-block.js.map +1 -0
- package/dist/components/code-block/cs-code-highlighter.js +59 -0
- package/dist/components/code-block/cs-code-highlighter.js.map +1 -0
- package/dist/components/collapsible/cs-collapsible.js +36 -0
- package/dist/components/collapsible/cs-collapsible.js.map +1 -0
- package/dist/components/date-picker/cs-date-picker.js +25 -0
- package/dist/components/date-picker/cs-date-picker.js.map +1 -0
- package/dist/components/dialog/cs-dialog.js +131 -0
- package/dist/components/dialog/cs-dialog.js.map +1 -0
- package/dist/components/drawer/cs-drawer.js +131 -0
- package/dist/components/drawer/cs-drawer.js.map +1 -0
- package/dist/components/dropdown-menu/cs-dropdown-menu.js +247 -0
- package/dist/components/dropdown-menu/cs-dropdown-menu.js.map +1 -0
- package/dist/components/dropzone/cs-dropzone.js +147 -0
- package/dist/components/dropzone/cs-dropzone.js.map +1 -0
- package/dist/components/empty/cs-empty.js +107 -0
- package/dist/components/empty/cs-empty.js.map +1 -0
- package/dist/components/field/cs-field.js +218 -0
- package/dist/components/field/cs-field.js.map +1 -0
- package/dist/components/input/cs-input-group.js +207 -0
- package/dist/components/input/cs-input-group.js.map +1 -0
- package/dist/components/input/cs-input.js +40 -0
- package/dist/components/input/cs-input.js.map +1 -0
- package/dist/components/label/cs-label.js +26 -0
- package/dist/components/label/cs-label.js.map +1 -0
- package/dist/components/navigation-menu/cs-navigation-menu.js +214 -0
- package/dist/components/navigation-menu/cs-navigation-menu.js.map +1 -0
- package/dist/components/pagination/cs-pagination.js +124 -0
- package/dist/components/pagination/cs-pagination.js.map +1 -0
- package/dist/components/popover/cs-popover.js +60 -0
- package/dist/components/popover/cs-popover.js.map +1 -0
- package/dist/components/progress/cs-progress.js +62 -0
- package/dist/components/progress/cs-progress.js.map +1 -0
- package/dist/components/scroll-area/cs-scroll-area.js +61 -0
- package/dist/components/scroll-area/cs-scroll-area.js.map +1 -0
- package/dist/components/select/cs-select.js +195 -0
- package/dist/components/select/cs-select.js.map +1 -0
- package/dist/components/select/cs-simple-select.js +32 -0
- package/dist/components/select/cs-simple-select.js.map +1 -0
- package/dist/components/separator/cs-separator.js +28 -0
- package/dist/components/separator/cs-separator.js.map +1 -0
- package/dist/components/sheet/cs-sheet.js +128 -0
- package/dist/components/sheet/cs-sheet.js.map +1 -0
- package/dist/components/sidebar/cs-sidebar.js +657 -0
- package/dist/components/sidebar/cs-sidebar.js.map +1 -0
- package/dist/components/skeleton/cs-skeleton.js +32 -0
- package/dist/components/skeleton/cs-skeleton.js.map +1 -0
- package/dist/components/sonner/cs-sonner.js +76 -0
- package/dist/components/sonner/cs-sonner.js.map +1 -0
- package/dist/components/spinner/cs-spinner.js +34 -0
- package/dist/components/spinner/cs-spinner.js.map +1 -0
- package/dist/components/switch/cs-switch.js +38 -0
- package/dist/components/switch/cs-switch.js.map +1 -0
- package/dist/components/table/cs-data-base-table.js +108 -0
- package/dist/components/table/cs-data-base-table.js.map +1 -0
- package/dist/components/table/cs-data-table.js +32 -0
- package/dist/components/table/cs-data-table.js.map +1 -0
- package/dist/components/table/cs-skeleton-table.js +41 -0
- package/dist/components/table/cs-skeleton-table.js.map +1 -0
- package/dist/components/table/cs-table.js +120 -0
- package/dist/components/table/cs-table.js.map +1 -0
- package/dist/components/tabs/cs-simple-tabs.js +24 -0
- package/dist/components/tabs/cs-simple-tabs.js.map +1 -0
- package/dist/components/tabs/cs-tabs.js +114 -0
- package/dist/components/tabs/cs-tabs.js.map +1 -0
- package/dist/components/toggle/cs-toggle-group.js +65 -0
- package/dist/components/toggle/cs-toggle-group.js.map +1 -0
- package/dist/components/toggle/cs-toggle.js +46 -0
- package/dist/components/toggle/cs-toggle.js.map +1 -0
- package/dist/components/tooltip/cs-simple-tooltip.js +16 -0
- package/dist/components/tooltip/cs-simple-tooltip.js.map +1 -0
- package/dist/components/tooltip/cs-tooltip.js +72 -0
- package/dist/components/tooltip/cs-tooltip.js.map +1 -0
- package/dist/constants/cs-chart-option.constant.js +105 -0
- package/dist/constants/cs-chart-option.constant.js.map +1 -0
- package/dist/cs-ui.css +73 -108
- package/dist/hooks/use-accordion.js +54 -0
- package/dist/hooks/use-accordion.js.map +1 -0
- package/dist/hooks/use-infinite-scroll.js +40 -0
- package/dist/hooks/use-infinite-scroll.js.map +1 -0
- package/dist/hooks/use-laptop.js +20 -0
- package/dist/hooks/use-laptop.js.map +1 -0
- package/dist/hooks/use-mobile.js +20 -0
- package/dist/hooks/use-mobile.js.map +1 -0
- package/dist/index.d.ts +19 -6
- package/dist/index.js +287 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/chart.util.js +48 -0
- package/dist/lib/chart.util.js.map +1 -0
- package/dist/lib/style.util.js +19 -0
- package/dist/lib/style.util.js.map +1 -0
- package/dist/lib/utils.js +27 -0
- package/dist/lib/utils.js.map +1 -0
- package/package.json +4 -5
- package/dist/index.cjs.js +0 -147659
- package/dist/index.cjs.js.map +0 -1
- package/dist/index.es.js +0 -147624
- package/dist/index.es.js.map +0 -1
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { cn } from "../../lib/utils.js";
|
|
3
|
+
function CsTable({ className, ...props }) {
|
|
4
|
+
return /* @__PURE__ */ jsx(
|
|
5
|
+
"div",
|
|
6
|
+
{
|
|
7
|
+
"data-slot": "table-container",
|
|
8
|
+
className: "relative w-full overflow-x-auto bg-(--table-container-bg) rounded-(--table-container-radius) border-(--table-container-border) border-(length:--table-container-border-width)",
|
|
9
|
+
children: /* @__PURE__ */ jsx(
|
|
10
|
+
"table",
|
|
11
|
+
{
|
|
12
|
+
"data-slot": "table",
|
|
13
|
+
className: cn("w-full caption-bottom", className),
|
|
14
|
+
...props
|
|
15
|
+
}
|
|
16
|
+
)
|
|
17
|
+
}
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
function CsTableHeader({ className, ...props }) {
|
|
21
|
+
return /* @__PURE__ */ jsx(
|
|
22
|
+
"thead",
|
|
23
|
+
{
|
|
24
|
+
"data-slot": "table-header",
|
|
25
|
+
className: cn(className),
|
|
26
|
+
...props
|
|
27
|
+
}
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
function CsTableBody({ className, ...props }) {
|
|
31
|
+
return /* @__PURE__ */ jsx(
|
|
32
|
+
"tbody",
|
|
33
|
+
{
|
|
34
|
+
"data-slot": "table-body",
|
|
35
|
+
className,
|
|
36
|
+
...props
|
|
37
|
+
}
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
function CsTableFooter({ className, ...props }) {
|
|
41
|
+
return /* @__PURE__ */ jsx(
|
|
42
|
+
"tfoot",
|
|
43
|
+
{
|
|
44
|
+
"data-slot": "table-footer",
|
|
45
|
+
className: cn(
|
|
46
|
+
"bg-(--table-item-footer-cell-bg) text-(--table-item-footer-cell-font) border-t-(--table-item-footer-cell-border) border-t-(length:--table-item-footer-cell-boder-width) typo-body-sm",
|
|
47
|
+
"[&_svg]:size-(--table-item-common-icon-size) [&_svg]:text-(--table-item-footer-cell-icon)",
|
|
48
|
+
className
|
|
49
|
+
),
|
|
50
|
+
...props
|
|
51
|
+
}
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
function CsTableRow({ className, ...props }) {
|
|
55
|
+
return /* @__PURE__ */ jsx(
|
|
56
|
+
"tr",
|
|
57
|
+
{
|
|
58
|
+
"data-slot": "table-row",
|
|
59
|
+
className: cn(
|
|
60
|
+
"border-b-(--table-item-cell-border) border-b-(length:--table-item-cell-boder-width) transition-colors",
|
|
61
|
+
"last:border-b-0",
|
|
62
|
+
"last:[&>td]:bg-(--table-item-cell-last-bg) last:[&>td]:text-(--table-item-cell-last-font) last:[&>td]:[&_svg]:text-(--table-item-cell-last-icon)",
|
|
63
|
+
className
|
|
64
|
+
),
|
|
65
|
+
...props
|
|
66
|
+
}
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
function CsTableHead({ className, ...props }) {
|
|
70
|
+
return /* @__PURE__ */ jsx(
|
|
71
|
+
"th",
|
|
72
|
+
{
|
|
73
|
+
"data-slot": "table-head",
|
|
74
|
+
className: cn(
|
|
75
|
+
"typo-body-xs-bold bg-(--table-item-header-bg) text-(--table-item-header-font) px-(--table-item-common-padding-x) py-(--table-item-common-padding-y) text-left align-middle whitespace-nowrap border-b-(--table-item-header-border) border-b-(length:--table-item-header-boder-width) [&_svg]:size-(--table-item-common-icon-size) [&_svg]:text-(--table-item-header-icon)",
|
|
76
|
+
"[&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",
|
|
77
|
+
className
|
|
78
|
+
),
|
|
79
|
+
...props
|
|
80
|
+
}
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
function CsTableCell({ className, ...props }) {
|
|
84
|
+
return /* @__PURE__ */ jsx(
|
|
85
|
+
"td",
|
|
86
|
+
{
|
|
87
|
+
"data-slot": "table-cell",
|
|
88
|
+
className: cn(
|
|
89
|
+
"typo-metric-sm bg-(--table-item-cell-bg) text-(--table-item-cell-font) px-(--table-item-common-padding-x) py-(--table-item-common-padding-y) align-middle whitespace-nowrap [&_svg]:size-(--table-item-common-icon-size) [&_svg]:text-(--table-item-cell-icon)",
|
|
90
|
+
"[&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",
|
|
91
|
+
className
|
|
92
|
+
),
|
|
93
|
+
...props
|
|
94
|
+
}
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
function CsTableCaption({
|
|
98
|
+
className,
|
|
99
|
+
...props
|
|
100
|
+
}) {
|
|
101
|
+
return /* @__PURE__ */ jsx(
|
|
102
|
+
"caption",
|
|
103
|
+
{
|
|
104
|
+
"data-slot": "table-caption",
|
|
105
|
+
className: cn("typo-productive-caption text-(--table-item-cell-value-font-brand)", className),
|
|
106
|
+
...props
|
|
107
|
+
}
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
export {
|
|
111
|
+
CsTable,
|
|
112
|
+
CsTableBody,
|
|
113
|
+
CsTableCaption,
|
|
114
|
+
CsTableCell,
|
|
115
|
+
CsTableFooter,
|
|
116
|
+
CsTableHead,
|
|
117
|
+
CsTableHeader,
|
|
118
|
+
CsTableRow
|
|
119
|
+
};
|
|
120
|
+
//# sourceMappingURL=cs-table.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cs-table.js","sources":["../../../src/components/table/cs-table.tsx"],"sourcesContent":["\n\nimport * as React from \"react\"\n\nimport { cn } from \"../../lib/utils\"\n\n/**\n * CsTable 스타일 시스템 (Design Token Reference)\n *\n * ## Figma Token → Props 매핑\n * | Figma 토큰 패턴 | 컴포넌트 |\n * |----------------|---------|\n * | `table/container/*` | `CsTable` (컨테이너) |\n * | `table/item/header-*` | `CsTableHead` |\n * | `table/item/cell-*` | `CsTableCell` |\n * | `table/item/footer-*` | `CsTableFooter` |\n *\n * ## CSS Variables\n * ```css\n * --table-container-bg | radius | border | border-width\n * --table-item-common-padding-x | padding-y | icon-size\n * --table-item-header-bg | font | icon | border | border-width\n * --table-item-cell-bg | font | icon | border | border-width\n * --table-item-cell-last-bg | font | icon\n * --table-item-footer-cell-bg | font | icon | border | border-width\n * ```\n *\n * ## 서브 컴포넌트 구조\n * ```\n * CsTable\n * ├── CsTableHeader\n * │ └── CsTableRow\n * │ └── CsTableHead\n * ├── CsTableBody\n * │ └── CsTableRow\n * │ └── CsTableCell\n * ├── CsTableFooter\n * │ └── CsTableRow\n * │ └── CsTableCell\n * └── CsTableCaption\n * ```\n */\n\n/**\n * CS Design System 테이블 컴포넌트\n *\n * 여러 서브 컴포넌트를 조합하여 사용.\n * 반응형 스크롤 지원.\n *\n * ## 유사 컴포넌트와의 차이\n * - **CsDataTable**: 데이터 바인딩, 로딩, 무한 스크롤 등 고급 기능 포함 (TanStack Table 기반)\n * - CsTable은 정적 마크업 테이블 - 단순 데이터 표시만\n *\n * @example 기본 조합\n * ```tsx\n * <CsTable>\n * <CsTableHeader>\n * <CsTableRow>\n * <CsTableHead>이름</CsTableHead>\n * <CsTableHead>이메일</CsTableHead>\n * </CsTableRow>\n * </CsTableHeader>\n * <CsTableBody>\n * <CsTableRow>\n * <CsTableCell>홍길동</CsTableCell>\n * <CsTableCell>hong@example.com</CsTableCell>\n * </CsTableRow>\n * </CsTableBody>\n * </CsTable>\n * ```\n *\n * @example Footer 포함\n * ```tsx\n * <CsTable>\n * <CsTableHeader>...</CsTableHeader>\n * <CsTableBody>...</CsTableBody>\n * <CsTableFooter>\n * <CsTableRow>\n * <CsTableCell colSpan={2}>합계</CsTableCell>\n * </CsTableRow>\n * </CsTableFooter>\n * </CsTable>\n * ```\n *\n * @see CsDataTable - 데이터 바인딩, 정렬, 무한 스크롤 등 고급 기능 필요 시\n */\n/** 테이블 루트 - 스크롤 컨테이너 포함 */\nfunction CsTable({ className, ...props }: React.ComponentProps<\"table\">) {\n return (\n <div\n data-slot=\"table-container\"\n className=\"relative w-full overflow-x-auto bg-(--table-container-bg) rounded-(--table-container-radius) border-(--table-container-border) border-(length:--table-container-border-width)\"\n >\n <table\n data-slot=\"table\"\n className={cn(\"w-full caption-bottom\", className)}\n {...props}\n />\n </div>\n )\n}\n\n/** 테이블 헤더 영역 */\nfunction CsTableHeader({ className, ...props }: React.ComponentProps<\"thead\">) {\n return (\n <thead\n data-slot=\"table-header\"\n className={cn(className)}\n {...props}\n />\n )\n}\n\n/** 테이블 바디 영역 */\nfunction CsTableBody({ className, ...props }: React.ComponentProps<\"tbody\">) {\n return (\n <tbody\n data-slot=\"table-body\"\n className={className}\n {...props}\n />\n )\n}\n\n/** 테이블 푸터 영역 */\nfunction CsTableFooter({ className, ...props }: React.ComponentProps<\"tfoot\">) {\n return (\n <tfoot\n data-slot=\"table-footer\"\n className={cn(\n \"bg-(--table-item-footer-cell-bg) text-(--table-item-footer-cell-font) border-t-(--table-item-footer-cell-border) border-t-(length:--table-item-footer-cell-boder-width) typo-body-sm\",\n \"[&_svg]:size-(--table-item-common-icon-size) [&_svg]:text-(--table-item-footer-cell-icon)\",\n className\n )}\n {...props}\n />\n )\n}\n\n/** 테이블 행 - 마지막 행에 특별 스타일 적용 */\nfunction CsTableRow({ className, ...props }: React.ComponentProps<\"tr\">) {\n return (\n <tr\n data-slot=\"table-row\"\n className={cn(\n \"border-b-(--table-item-cell-border) border-b-(length:--table-item-cell-boder-width) transition-colors\",\n \"last:border-b-0\",\n \"last:[&>td]:bg-(--table-item-cell-last-bg) last:[&>td]:text-(--table-item-cell-last-font) last:[&>td]:[&_svg]:text-(--table-item-cell-last-icon)\",\n className\n )}\n {...props}\n />\n )\n}\n\n/** 테이블 헤더 셀 */\nfunction CsTableHead({ className, ...props }: React.ComponentProps<\"th\">) {\n return (\n <th\n data-slot=\"table-head\"\n className={cn(\n \"typo-body-xs-bold bg-(--table-item-header-bg) text-(--table-item-header-font) px-(--table-item-common-padding-x) py-(--table-item-common-padding-y) text-left align-middle whitespace-nowrap border-b-(--table-item-header-border) border-b-(length:--table-item-header-boder-width) [&_svg]:size-(--table-item-common-icon-size) [&_svg]:text-(--table-item-header-icon)\",\n \"[&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]\",\n className\n )}\n {...props}\n />\n )\n}\n\n/** 테이블 데이터 셀 */\nfunction CsTableCell({ className, ...props }: React.ComponentProps<\"td\">) {\n return (\n <td\n data-slot=\"table-cell\"\n className={cn(\n \"typo-metric-sm bg-(--table-item-cell-bg) text-(--table-item-cell-font) px-(--table-item-common-padding-x) py-(--table-item-common-padding-y) align-middle whitespace-nowrap [&_svg]:size-(--table-item-common-icon-size) [&_svg]:text-(--table-item-cell-icon)\",\n \"[&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]\",\n className\n )}\n {...props}\n />\n )\n}\n\n/** 테이블 캡션 */\nfunction CsTableCaption({\n className,\n ...props\n}: React.ComponentProps<\"caption\">) {\n return (\n <caption\n data-slot=\"table-caption\"\n className={cn(\"typo-productive-caption text-(--table-item-cell-value-font-brand)\", className)}\n {...props}\n />\n )\n}\n\nexport {\n CsTable,\n CsTableHeader,\n CsTableBody,\n CsTableFooter,\n CsTableHead,\n CsTableRow,\n CsTableCell,\n CsTableCaption,\n}\n"],"names":[],"mappings":";;AAuFA,SAAS,QAAQ,EAAE,WAAW,GAAG,SAAwC;AACvE,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAU;AAAA,MAEV,UAAA;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,aAAU;AAAA,UACV,WAAW,GAAG,yBAAyB,SAAS;AAAA,UAC/C,GAAG;AAAA,QAAA;AAAA,MAAA;AAAA,IACN;AAAA,EAAA;AAGN;AAGA,SAAS,cAAc,EAAE,WAAW,GAAG,SAAwC;AAC7E,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,SAAS;AAAA,MACtB,GAAG;AAAA,IAAA;AAAA,EAAA;AAGV;AAGA,SAAS,YAAY,EAAE,WAAW,GAAG,SAAwC;AAC3E,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,aAAU;AAAA,MACV;AAAA,MACC,GAAG;AAAA,IAAA;AAAA,EAAA;AAGV;AAGA,SAAS,cAAc,EAAE,WAAW,GAAG,SAAwC;AAC7E,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,MAAA;AAAA,MAED,GAAG;AAAA,IAAA;AAAA,EAAA;AAGV;AAGA,SAAS,WAAW,EAAE,WAAW,GAAG,SAAqC;AACvE,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MAAA;AAAA,MAED,GAAG;AAAA,IAAA;AAAA,EAAA;AAGV;AAGA,SAAS,YAAY,EAAE,WAAW,GAAG,SAAqC;AACxE,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,MAAA;AAAA,MAED,GAAG;AAAA,IAAA;AAAA,EAAA;AAGV;AAGA,SAAS,YAAY,EAAE,WAAW,GAAG,SAAqC;AACxE,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,MAAA;AAAA,MAED,GAAG;AAAA,IAAA;AAAA,EAAA;AAGV;AAGA,SAAS,eAAe;AAAA,EACtB;AAAA,EACA,GAAG;AACL,GAAoC;AAClC,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,qEAAqE,SAAS;AAAA,MAC3F,GAAG;AAAA,IAAA;AAAA,EAAA;AAGV;"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import { CsTabs, CsTabsList, CsTabsTrigger } from "./cs-tabs.js";
|
|
4
|
+
function CsSimpleTabs({
|
|
5
|
+
list,
|
|
6
|
+
listProps,
|
|
7
|
+
triggerProps,
|
|
8
|
+
...props
|
|
9
|
+
}) {
|
|
10
|
+
return /* @__PURE__ */ jsx(CsTabs, { ...props, children: /* @__PURE__ */ jsx(CsTabsList, { ...listProps, children: list.map((item) => /* @__PURE__ */ jsx(
|
|
11
|
+
CsTabsTrigger,
|
|
12
|
+
{
|
|
13
|
+
value: item.value,
|
|
14
|
+
disabled: item.disabled,
|
|
15
|
+
...triggerProps,
|
|
16
|
+
children: item.label
|
|
17
|
+
},
|
|
18
|
+
item.value
|
|
19
|
+
)) }) });
|
|
20
|
+
}
|
|
21
|
+
export {
|
|
22
|
+
CsSimpleTabs
|
|
23
|
+
};
|
|
24
|
+
//# sourceMappingURL=cs-simple-tabs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cs-simple-tabs.js","sources":["../../../src/components/tabs/cs-simple-tabs.tsx"],"sourcesContent":["\"use client\"\n\nimport { ComponentProps, ReactNode } from 'react'\nimport { CsTabs, CsTabsList, CsTabsTrigger, type CsTabsListProps } from './cs-tabs'\n\n/**\n * CsSimpleTabs 스타일 시스템 (Design Token Reference)\n *\n * CsTabs의 래퍼 컴포넌트입니다.\n * 상세한 토큰 매핑은 CsTabs 문서를 참조하세요.\n *\n * ## CsTabs와의 차이점\n * - 단순 탭 네비게이션에 최적화 (Content 미지원)\n * - list prop으로 탭 배열 전달\n * - content는 외부에서 value에 따라 조건부 렌더링\n *\n * @see CsTabs - CsTabsContent 등 복잡한 조합 필요 시 직접 사용\n */\n\n/**\n * 탭 아이템 타입\n */\ninterface CsSimpleTabsItemProps {\n /** 탭의 실제 값 (상태 저장용) */\n value: string\n /** 탭의 표시 콘텐츠 (텍스트 또는 아이콘 포함 ReactNode) */\n label: ReactNode\n /** 선택 불가능 여부 */\n disabled?: boolean\n}\n\n/**\n * CsSimpleTabs Props\n */\ninterface CsSimpleTabsProps extends Omit<ComponentProps<typeof CsTabs>, 'children'> {\n /**\n * 탭 리스트 (필수)\n * @example [{ value: 'overview', label: 'Overview' }, { value: 'details', label: 'Details' }]\n */\n list: CsSimpleTabsItemProps[]\n\n /**\n * 탭 리스트 컨테이너 props\n * variant, background, className 등 CsTabsList에 전달\n */\n listProps?: Omit<CsTabsListProps, 'children'>\n\n /**\n * 개별 탭 트리거 props\n * className 등 CsTabsTrigger에 전달 (공통 적용)\n */\n triggerProps?: Omit<ComponentProps<typeof CsTabsTrigger>, 'value' | 'children'>\n}\n\n/**\n * CS Design System 간편 탭\n *\n * 단순 탭 네비게이션을 위한 래퍼 컴포넌트.\n * CsTabsContent가 필요하거나 복잡한 구조가 필요하면 CsTabs 직접 사용.\n *\n * @example 기본\n * ```tsx\n * <CsSimpleTabs\n * value={tab}\n * onValueChange={setTab}\n * list={[\n * { value: 'overview', label: 'Overview' },\n * { value: 'transactions', label: 'Transactions' },\n * ]}\n * />\n * {tab === 'overview' && <OverviewContent />}\n * {tab === 'transactions' && <TransactionsContent />}\n * ```\n *\n * @example variant 변경\n * ```tsx\n * <CsSimpleTabs\n * list={tabs}\n * listProps={{ variant: 'bottom-border', background: false }}\n * />\n * ```\n *\n * @example 비제어 컴포넌트\n * ```tsx\n * <CsSimpleTabs\n * defaultValue=\"overview\"\n * list={tabs}\n * />\n * ```\n */\nfunction CsSimpleTabs({\n list,\n listProps,\n triggerProps,\n ...props\n}: CsSimpleTabsProps) {\n return (\n <CsTabs {...props}>\n <CsTabsList {...listProps}>\n {list.map((item) => (\n <CsTabsTrigger\n key={item.value}\n value={item.value}\n disabled={item.disabled}\n {...triggerProps}\n >\n {item.label}\n </CsTabsTrigger>\n ))}\n </CsTabsList>\n </CsTabs>\n )\n}\n\nexport { CsSimpleTabs, type CsSimpleTabsProps, type CsSimpleTabsItemProps }\n"],"names":[],"mappings":";;;AA0FsB,SACpB,aAAA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACF,GAAsB;AACpB,GAAA;AAIQ,SAAC,oBAAA,QAAA,EAAA,GAAA,OAAA,UAAA,oBAAA,YAAA,EAAA,GAAA,WAAA,UAAA,KAAA,IAAA,CAAA,SAAA;AAAA,IAAA;AAAA,IAAA;AAAA,MAGC,OAAA,KAAU;AAAA,MACT,UAAG,KAAA;AAAA,MAEH,GAAA;AAAA,MAAK,UAAA,KAAA;AAAA,IALD;AAAA,SASb;AAAA,EAEJ,CAAA,EAAA,CAAA,EAAA,CAAA;;"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import * as TabsPrimitive from "@radix-ui/react-tabs";
|
|
4
|
+
import { cva } from "class-variance-authority";
|
|
5
|
+
import { cn } from "../../lib/utils.js";
|
|
6
|
+
const csTabsListVariants = cva(
|
|
7
|
+
"group inline-flex h-fit w-fit items-center justify-center rounded-(--tabs-container-radius) px-(--tabs-container-padding-x) py-(--tabs-container-padding-y) gap-(--tabs-container-gap)",
|
|
8
|
+
{
|
|
9
|
+
variants: {
|
|
10
|
+
variant: {
|
|
11
|
+
solid: "",
|
|
12
|
+
"solid-line": "",
|
|
13
|
+
"solid-ghost": "",
|
|
14
|
+
"bottom-border": "",
|
|
15
|
+
gradient: ""
|
|
16
|
+
},
|
|
17
|
+
background: {
|
|
18
|
+
true: "bg-(--tabs-container-bg)",
|
|
19
|
+
false: "bg-transparent"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
defaultVariants: {
|
|
23
|
+
variant: "solid",
|
|
24
|
+
background: true
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
);
|
|
28
|
+
function CsTabs({
|
|
29
|
+
className,
|
|
30
|
+
...props
|
|
31
|
+
}) {
|
|
32
|
+
return /* @__PURE__ */ jsx(
|
|
33
|
+
TabsPrimitive.Root,
|
|
34
|
+
{
|
|
35
|
+
"data-slot": "tabs",
|
|
36
|
+
className: cn("flex flex-col gap-(--tabs-container-gap) overflow-x-auto [&_[data-slot=tabs-list]+[data-slot=tabs-list]]:mt-(--tabs-container-group-gap)", className),
|
|
37
|
+
...props
|
|
38
|
+
}
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
function CsTabsList({
|
|
42
|
+
className,
|
|
43
|
+
variant = "solid",
|
|
44
|
+
background,
|
|
45
|
+
...props
|
|
46
|
+
}) {
|
|
47
|
+
return /* @__PURE__ */ jsx(
|
|
48
|
+
TabsPrimitive.List,
|
|
49
|
+
{
|
|
50
|
+
"data-slot": "tabs-list",
|
|
51
|
+
"data-variant": variant,
|
|
52
|
+
className: cn(csTabsListVariants({ variant, background }), className),
|
|
53
|
+
...props
|
|
54
|
+
}
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
function CsTabsTrigger({
|
|
58
|
+
className,
|
|
59
|
+
...props
|
|
60
|
+
}) {
|
|
61
|
+
return /* @__PURE__ */ jsx(
|
|
62
|
+
TabsPrimitive.Trigger,
|
|
63
|
+
{
|
|
64
|
+
"data-slot": "tabs-trigger",
|
|
65
|
+
className: cn(
|
|
66
|
+
"cursor-pointer inline-flex items-center justify-center whitespace-nowrap rounded-(--tabs-item-common-radius) px-(--tabs-item-common-padding-x) py-(--tabs-item-common-padding-y) gap-(--tabs-item-common-gap) transition-all focus-visible:outline-none focus-visible:ring-0 disabled:pointer-events-none [&_svg]:size-(--tabs-item-common-icon-size) typo-body-sm-bold",
|
|
67
|
+
// Solid
|
|
68
|
+
"group-data-[variant=solid]:data-[state=active]:bg-(--tabs-item-solid-on-bg) group-data-[variant=solid]:data-[state=active]:text-(--tabs-item-solid-on-font) group-data-[variant=solid]:data-[state=active]:[&_svg]:text-(--tabs-item-solid-on-icon)",
|
|
69
|
+
"group-data-[variant=solid]:bg-(--tabs-item-solid-off-bg) group-data-[variant=solid]:text-(--tabs-item-solid-off-font) group-data-[variant=solid]:[&_svg]:text-(--tabs-item-solid-off-icon)",
|
|
70
|
+
"group-data-[variant=solid]:hover:bg-(--tabs-item-solid-hover-bg) group-data-[variant=solid]:hover:text-(--tabs-item-solid-hover-font) group-data-[variant=solid]:hover:[&_svg]:text-(--tabs-item-solid-hover-icon)",
|
|
71
|
+
// Solid-line
|
|
72
|
+
"group-data-[variant=solid-line]:data-[state=active]:bg-(--tabs-item-solid-line-on-bg) group-data-[variant=solid-line]:data-[state=active]:text-(--tabs-item-solid-line-on-font) group-data-[variant=solid-line]:data-[state=active]:[&_svg]:text-(--tabs-item-solid-line-on-icon)",
|
|
73
|
+
"group-data-[variant=solid-line]:bg-(--tabs-item-solid-line-off-bg) group-data-[variant=solid-line]:text-(--tabs-item-solid-line-off-font) group-data-[variant=solid-line]:[&_svg]:text-(--tabs-item-solid-line-off-icon) group-data-[variant=solid-line]:border-(--tabs-item-solid-line-off-border) group-data-[variant=solid-line]:border-(length:--tabs-item-solid-line-off-border-width)",
|
|
74
|
+
"group-data-[variant=solid-line]:hover:bg-(--tabs-item-solid-line-hover-bg) group-data-[variant=solid-line]:hover:text-(--tabs-item-solid-line-hover-font) group-data-[variant=solid-line]:hover:[&_svg]:text-(--tabs-item-solid-line-hover-icon) group-data-[variant=solid-line]:hover:border-(--tabs-item-solid-line-hover-border) group-data-[variant=solid-line]:hover:border-(length:--tabs-item-solid-line-hover-border-width)",
|
|
75
|
+
// Solid-ghost
|
|
76
|
+
"group-data-[variant=solid-ghost]:data-[state=active]:bg-(--tabs-item-solid-ghost-on-bg) group-data-[variant=solid-ghost]:data-[state=active]:text-(--tabs-item-solid-ghost-on-font) group-data-[variant=solid-ghost]:data-[state=active]:[&_svg]:text-(--tabs-item-solid-ghost-on-icon)",
|
|
77
|
+
"group-data-[variant=solid-ghost]:text-(--tabs-item-solid-ghost-off-font) group-data-[variant=solid-ghost]:[&_svg]:text-(--tabs-item-solid-ghost-off-icon)",
|
|
78
|
+
"group-data-[variant=solid-ghost]:hover:bg-(--tabs-item-solid-ghost-hover-bg) group-data-[variant=solid-ghost]:hover:text-(--tabs-item-solid-ghost-hover-font) group-data-[variant=solid-ghost]:hover:[&_svg]:text-(--tabs-item-solid-ghost-hover-icon)",
|
|
79
|
+
// Bottom-border
|
|
80
|
+
"group-data-[variant=bottom-border]:rounded-none",
|
|
81
|
+
"group-data-[variant=bottom-border]:data-[state=active]:text-(--tabs-item-bottom-border-on-font) group-data-[variant=bottom-border]:data-[state=active]:[&_svg]:text-(--tabs-item-bottom-border-on-icon) group-data-[variant=bottom-border]:data-[state=active]:border-b-(length:--tabs-item-bottom-border-on-border-width) group-data-[variant=bottom-border]:data-[state=active]:border-b-(--tabs-item-bottom-border-on-border)",
|
|
82
|
+
"group-data-[variant=bottom-border]:text-(--tabs-item-bottom-border-off-font) group-data-[variant=bottom-border]:[&_svg]:text-(--tabs-item-bottom-border-off-icon) group-data-[variant=bottom-border]:border-b-(length:--tabs-item-bottom-border-on-border-width) group-data-[variant=bottom-border]:border-b-transparent",
|
|
83
|
+
"group-data-[variant=bottom-border]:hover:text-(--tabs-item-bottom-border-hover-font) group-data-[variant=bottom-border]:hover:[&_svg]:text-(--tabs-item-bottom-border-hover-icon)",
|
|
84
|
+
// Gradient
|
|
85
|
+
"group-data-[variant=gradient]:data-[state=active]:gradient-primary-vertical group-data-[variant=gradient]:data-[state=active]:text-(--tabs-item-gradient-on-font) group-data-[variant=gradient]:data-[state=active]:[&_svg]:text-(--tabs-item-gradient-on-icon)",
|
|
86
|
+
"group-data-[variant=gradient]:bg-(--tabs-item-gradient-off-bg) group-data-[variant=gradient]:text-(--tabs-item-gradient-off-font) group-data-[variant=gradient]:[&_svg]:text-(--tabs-item-gradient-off-icon)",
|
|
87
|
+
"group-data-[variant=gradient]:hover:bg-(--tabs-item-gradient-hover-bg) group-data-[variant=gradient]:hover:text-(--tabs-item-gradient-hover-font) group-data-[variant=gradient]:hover:[&_svg]:text-(--tabs-item-gradient-hover-icon)",
|
|
88
|
+
className
|
|
89
|
+
),
|
|
90
|
+
...props
|
|
91
|
+
}
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
function CsTabsContent({
|
|
95
|
+
className,
|
|
96
|
+
...props
|
|
97
|
+
}) {
|
|
98
|
+
return /* @__PURE__ */ jsx(
|
|
99
|
+
TabsPrimitive.Content,
|
|
100
|
+
{
|
|
101
|
+
"data-slot": "tabs-content",
|
|
102
|
+
className: cn("flex-1 outline-none", className),
|
|
103
|
+
...props
|
|
104
|
+
}
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
export {
|
|
108
|
+
CsTabs,
|
|
109
|
+
CsTabsContent,
|
|
110
|
+
CsTabsList,
|
|
111
|
+
CsTabsTrigger,
|
|
112
|
+
csTabsListVariants
|
|
113
|
+
};
|
|
114
|
+
//# sourceMappingURL=cs-tabs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cs-tabs.js","sources":["../../../src/components/tabs/cs-tabs.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport * as TabsPrimitive from \"@radix-ui/react-tabs\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"../../lib/utils\"\n\ntype TabsVariant = \"solid\" | \"solid-line\" | \"solid-ghost\" | \"bottom-border\" | \"gradient\"\n\n/**\n * CsTabsList 스타일 시스템 (Design Token Reference)\n *\n * ## Figma Token → Props 매핑\n * | Figma 토큰 패턴 | Props |\n * |----------------|-------|\n * | `tabs/item/solid/*` | `variant=\"solid\"` |\n * | `tabs/item/solid-line/*` | `variant=\"solid-line\"` |\n * | `tabs/item/solid-ghost/*` | `variant=\"solid-ghost\"` |\n * | `tabs/item/bottom-border/*` | `variant=\"bottom-border\"` |\n * | `tabs/item/gradient/*` | `variant=\"gradient\"` |\n *\n * ## State 매핑\n * | UI 상태 | Token state |\n * |---------|-------------|\n * | 비활성 | off |\n * | 활성 (data-[state=active]) | on |\n * | hover: | hover |\n *\n * ## CSS Variables\n * ```css\n * --tabs-container-radius | padding-x | padding-y | gap | bg\n * --tabs-item-common-radius | padding-x | padding-y | gap | icon-size\n * --tabs-item-{variant}-{state}-bg | font | icon | border\n * ```\n */\nconst csTabsListVariants = cva(\n \"group inline-flex h-fit w-fit items-center justify-center rounded-(--tabs-container-radius) px-(--tabs-container-padding-x) py-(--tabs-container-padding-y) gap-(--tabs-container-gap)\",\n {\n variants: {\n variant: {\n solid: \"\",\n \"solid-line\": \"\",\n \"solid-ghost\": \"\",\n \"bottom-border\": \"\",\n gradient: \"\",\n },\n background: {\n true: \"bg-(--tabs-container-bg)\",\n false: \"bg-transparent\",\n },\n },\n defaultVariants: {\n variant: \"solid\",\n background: true,\n },\n }\n)\n\n/**\n * CS Design System 탭 컴포넌트\n *\n * 여러 콘텐츠 영역을 하나의 공간에서 전환할 수 있는 탭 네비게이션 컴포넌트.\n * **일반적인 경우 CsSimpleTabs 사용을 권장합니다.**\n * variant 변경, 복잡한 커스텀이 필요할 때만 이 컴포넌트를 직접 사용하세요.\n *\n * ## 사용 시나리오\n * - 여러 variant 필요: solid, solid-line, bottom-border, gradient 등\n * - 복잡한 탭 구조: 중첩 탭, 동적 탭\n * - 커스텀 레이아웃: 탭 버튼 + 콘텐츠 배치 조정\n *\n * ## 유사 컴포넌트와의 차이\n * - **CsSimpleTabs**: 단순 탭 네비게이션 - 일반적인 경우 이것을 사용하세요 (권장)\n * - **CsNavigationMenu**: 전역 네비게이션 (페이지 간 이동)\n * - Tabs는 페이지 내 섹션 전환, NavigationMenu는 페이지 간 이동\n *\n * @example 기본 조합\n * ```tsx\n * <CsTabs defaultValue=\"tab1\">\n * <CsTabsList>\n * <CsTabsTrigger value=\"tab1\">Tab 1</CsTabsTrigger>\n * <CsTabsTrigger value=\"tab2\">Tab 2</CsTabsTrigger>\n * </CsTabsList>\n * <CsTabsContent value=\"tab1\">Content 1</CsTabsContent>\n * <CsTabsContent value=\"tab2\">Content 2</CsTabsContent>\n * </CsTabs>\n * ```\n *\n * @example variant 변경\n * ```tsx\n * <CsTabsList variant=\"solid-line\">...</CsTabsList>\n * <CsTabsList variant=\"bottom-border\">...</CsTabsList>\n * <CsTabsList variant=\"gradient\">...</CsTabsList>\n * ```\n *\n * @see CsSimpleTabs - 단순 탭 네비게이션 시 래퍼 컴포넌트 권장 (일반적인 경우)\n * @see {@link https://www.radix-ui.com/primitives/docs/components/tabs | Radix Tabs}\n */\nfunction CsTabs({\n className,\n ...props\n}: React.ComponentProps<typeof TabsPrimitive.Root>) {\n return (\n <TabsPrimitive.Root\n data-slot=\"tabs\"\n className={cn(\"flex flex-col gap-(--tabs-container-gap) overflow-x-auto [&_[data-slot=tabs-list]+[data-slot=tabs-list]]:mt-(--tabs-container-group-gap)\", className)}\n {...props}\n />\n )\n}\n\n/**\n * CsTabsList Props\n */\ninterface CsTabsListProps\n extends React.ComponentProps<typeof TabsPrimitive.List>,\n VariantProps<typeof csTabsListVariants> {\n /**\n * 탭 리스트 스타일\n * - `solid`: 배경 채움 (기본)\n * - `solid-line`: 배경 + 테두리\n * - `solid-ghost`: 투명 배경\n * - `bottom-border`: 하단 테두리만\n * - `gradient`: 그라데이션 배경\n * @default 'solid'\n */\n variant?: TabsVariant\n /**\n * 컨테이너 배경 표시 여부\n * @default true\n */\n background?: boolean\n}\n\n/**\n * 탭 트리거 버튼들을 감싸는 컨테이너\n *\n * @param variant - 스타일 변형\n * - `\"solid\"` (기본) - 배경 채움\n * - `\"solid-line\"` - 배경 + 테두리\n * - `\"solid-ghost\"` - 투명 배경\n * - `\"bottom-border\"` - 하단 테두리만\n * - `\"gradient\"` - 그라데이션 배경\n * @param background - 컨테이너 배경 표시 여부 (기본: true)\n */\nfunction CsTabsList({\n className,\n variant = \"solid\",\n background,\n ...props\n}: CsTabsListProps) {\n return (\n <TabsPrimitive.List\n data-slot=\"tabs-list\"\n data-variant={variant}\n className={cn(csTabsListVariants({ variant, background }), className)}\n {...props}\n />\n )\n}\n\n/**\n * 개별 탭 트리거 버튼\n *\n * 아이콘 크기 자동 조절: `[&_svg]:size-(--tabs-item-common-icon-size)`\n */\nfunction CsTabsTrigger({\n className,\n ...props\n}: React.ComponentProps<typeof TabsPrimitive.Trigger>) {\n return (\n <TabsPrimitive.Trigger\n data-slot=\"tabs-trigger\"\n className={cn(\n \"cursor-pointer inline-flex items-center justify-center whitespace-nowrap rounded-(--tabs-item-common-radius) px-(--tabs-item-common-padding-x) py-(--tabs-item-common-padding-y) gap-(--tabs-item-common-gap) transition-all focus-visible:outline-none focus-visible:ring-0 disabled:pointer-events-none [&_svg]:size-(--tabs-item-common-icon-size) typo-body-sm-bold\",\n // Solid\n \"group-data-[variant=solid]:data-[state=active]:bg-(--tabs-item-solid-on-bg) group-data-[variant=solid]:data-[state=active]:text-(--tabs-item-solid-on-font) group-data-[variant=solid]:data-[state=active]:[&_svg]:text-(--tabs-item-solid-on-icon)\",\n \"group-data-[variant=solid]:bg-(--tabs-item-solid-off-bg) group-data-[variant=solid]:text-(--tabs-item-solid-off-font) group-data-[variant=solid]:[&_svg]:text-(--tabs-item-solid-off-icon)\",\n \"group-data-[variant=solid]:hover:bg-(--tabs-item-solid-hover-bg) group-data-[variant=solid]:hover:text-(--tabs-item-solid-hover-font) group-data-[variant=solid]:hover:[&_svg]:text-(--tabs-item-solid-hover-icon)\",\n // Solid-line\n \"group-data-[variant=solid-line]:data-[state=active]:bg-(--tabs-item-solid-line-on-bg) group-data-[variant=solid-line]:data-[state=active]:text-(--tabs-item-solid-line-on-font) group-data-[variant=solid-line]:data-[state=active]:[&_svg]:text-(--tabs-item-solid-line-on-icon)\",\n \"group-data-[variant=solid-line]:bg-(--tabs-item-solid-line-off-bg) group-data-[variant=solid-line]:text-(--tabs-item-solid-line-off-font) group-data-[variant=solid-line]:[&_svg]:text-(--tabs-item-solid-line-off-icon) group-data-[variant=solid-line]:border-(--tabs-item-solid-line-off-border) group-data-[variant=solid-line]:border-(length:--tabs-item-solid-line-off-border-width)\",\n \"group-data-[variant=solid-line]:hover:bg-(--tabs-item-solid-line-hover-bg) group-data-[variant=solid-line]:hover:text-(--tabs-item-solid-line-hover-font) group-data-[variant=solid-line]:hover:[&_svg]:text-(--tabs-item-solid-line-hover-icon) group-data-[variant=solid-line]:hover:border-(--tabs-item-solid-line-hover-border) group-data-[variant=solid-line]:hover:border-(length:--tabs-item-solid-line-hover-border-width)\",\n // Solid-ghost\n \"group-data-[variant=solid-ghost]:data-[state=active]:bg-(--tabs-item-solid-ghost-on-bg) group-data-[variant=solid-ghost]:data-[state=active]:text-(--tabs-item-solid-ghost-on-font) group-data-[variant=solid-ghost]:data-[state=active]:[&_svg]:text-(--tabs-item-solid-ghost-on-icon)\",\n \"group-data-[variant=solid-ghost]:text-(--tabs-item-solid-ghost-off-font) group-data-[variant=solid-ghost]:[&_svg]:text-(--tabs-item-solid-ghost-off-icon)\",\n \"group-data-[variant=solid-ghost]:hover:bg-(--tabs-item-solid-ghost-hover-bg) group-data-[variant=solid-ghost]:hover:text-(--tabs-item-solid-ghost-hover-font) group-data-[variant=solid-ghost]:hover:[&_svg]:text-(--tabs-item-solid-ghost-hover-icon)\",\n // Bottom-border\n \"group-data-[variant=bottom-border]:rounded-none\",\n \"group-data-[variant=bottom-border]:data-[state=active]:text-(--tabs-item-bottom-border-on-font) group-data-[variant=bottom-border]:data-[state=active]:[&_svg]:text-(--tabs-item-bottom-border-on-icon) group-data-[variant=bottom-border]:data-[state=active]:border-b-(length:--tabs-item-bottom-border-on-border-width) group-data-[variant=bottom-border]:data-[state=active]:border-b-(--tabs-item-bottom-border-on-border)\",\n \"group-data-[variant=bottom-border]:text-(--tabs-item-bottom-border-off-font) group-data-[variant=bottom-border]:[&_svg]:text-(--tabs-item-bottom-border-off-icon) group-data-[variant=bottom-border]:border-b-(length:--tabs-item-bottom-border-on-border-width) group-data-[variant=bottom-border]:border-b-transparent\",\n \"group-data-[variant=bottom-border]:hover:text-(--tabs-item-bottom-border-hover-font) group-data-[variant=bottom-border]:hover:[&_svg]:text-(--tabs-item-bottom-border-hover-icon)\",\n // Gradient\n \"group-data-[variant=gradient]:data-[state=active]:gradient-primary-vertical group-data-[variant=gradient]:data-[state=active]:text-(--tabs-item-gradient-on-font) group-data-[variant=gradient]:data-[state=active]:[&_svg]:text-(--tabs-item-gradient-on-icon)\",\n \"group-data-[variant=gradient]:bg-(--tabs-item-gradient-off-bg) group-data-[variant=gradient]:text-(--tabs-item-gradient-off-font) group-data-[variant=gradient]:[&_svg]:text-(--tabs-item-gradient-off-icon)\",\n \"group-data-[variant=gradient]:hover:bg-(--tabs-item-gradient-hover-bg) group-data-[variant=gradient]:hover:text-(--tabs-item-gradient-hover-font) group-data-[variant=gradient]:hover:[&_svg]:text-(--tabs-item-gradient-hover-icon)\",\n className\n )}\n {...props}\n />\n )\n}\n\n/** 탭 컨텐츠 영역 - value와 일치하는 탭 선택 시 표시 */\nfunction CsTabsContent({\n className,\n ...props\n}: React.ComponentProps<typeof TabsPrimitive.Content>) {\n return (\n <TabsPrimitive.Content\n data-slot=\"tabs-content\"\n className={cn(\"flex-1 outline-none\", className)}\n {...props}\n />\n )\n}\n\nexport { CsTabs, CsTabsList, CsTabsTrigger, CsTabsContent, csTabsListVariants }\nexport type { TabsVariant, CsTabsListProps }\n"],"names":[],"mappings":";;;;;AAoC2B,MACzB,qBAAA;AAAA,EACA;AAAA,EAAA;AAAA,IACY,UACR;AAAA,MAAS,SACA;AAAA,QACP,OAAA;AAAA,QACA;QACA,eAAA;AAAA,QACA,iBAAU;AAAA,QACZ,UAAA;AAAA,MACA;AAAA,MAAY,YACJ;AAAA,QACN,MAAA;AAAA,QAAO,OAAA;AAAA,MAEX;AAAA,IACA;AAAA,IAAiB,iBACN;AAAA,MACT;MAAY,YAAA;AAAA,IACd;AAAA,EAEJ;AAyCA;AAAgB,SACd,OAAA;AAAA,EACA;AAAA,EACF,GAAoD;AAClD;AACE,SAAe;AAAA,IAAd,cAAA;AAAA,IAAA;AAAA,MAEC,aAAW;AAAA,MACV,WAAG,GAAA,4IAAA,SAAA;AAAA,MAAA,GAAA;AAAA,IACN;AAAA,EAEJ;AAoCA;AAAoB,SAClB,WAAA;AAAA,EACA;AAAA,EACA,UAAA;AAAA,EACA;AAAA,EACF,GAAoB;AAClB;AACE,SAAe;AAAA,IAAd,cAAA;AAAA,IAAA;AAAA,MAEC,aAAA;AAAA,MACA;MACC,WAAG,GAAA,mBAAA,EAAA,SAAA,WAAA,CAAA,GAAA,SAAA;AAAA,MAAA,GAAA;AAAA,IACN;AAAA,EAEJ;AAOA;AAAuB,SACrB,cAAA;AAAA,EACA;AAAA,EACF,GAAuD;AACrD;AACE,SAAe;AAAA,IAAd,cAAA;AAAA,IAAA;AAAA,MAEC,aAAW;AAAA,MAAA,WACT;AAAA,QAAA;AAAA;AAAA,QAGA;AAAA,QACA;AAAA,QAAA;AAAA;AAAA,QAGA;AAAA,QACA;AAAA,QAAA;AAAA;AAAA,QAGA;AAAA,QACA;AAAA,QAAA;AAAA;AAAA,QAGA;AAAA,QACA;AAAA,QACA;AAAA,QAAA;AAAA;AAAA,QAGA;AAAA,QACA;AAAA,QACA;AAAA,QACF;AAAA,MACC;AAAA,MAAG,GAAA;AAAA,IACN;AAAA,EAEJ;AAGA;AAAuB,SACrB,cAAA;AAAA,EACA;AAAA,EACF,GAAuD;AACrD;AACE,SAAe;AAAA,IAAd,cAAA;AAAA,IAAA;AAAA,MAEC,aAAW;AAAA,MACV,WAAG,GAAA,uBAAA,SAAA;AAAA,MAAA,GAAA;AAAA,IACN;AAAA,EAEJ;;"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import * as CsToggleGroupPrimitive from "@radix-ui/react-toggle-group";
|
|
5
|
+
import { cn } from "../../lib/utils.js";
|
|
6
|
+
import { csToggleVariants } from "./cs-toggle.js";
|
|
7
|
+
const CsCsToggleGroupContext = React.createContext({
|
|
8
|
+
variant: "solid"
|
|
9
|
+
});
|
|
10
|
+
function CsToggleGroup({
|
|
11
|
+
className,
|
|
12
|
+
variant = "solid",
|
|
13
|
+
spacing,
|
|
14
|
+
children,
|
|
15
|
+
...props
|
|
16
|
+
}) {
|
|
17
|
+
const isConnected = spacing === 0;
|
|
18
|
+
const hasCustomSpacing = typeof spacing === "number" && spacing > 0;
|
|
19
|
+
return /* @__PURE__ */ jsx(
|
|
20
|
+
CsToggleGroupPrimitive.Root,
|
|
21
|
+
{
|
|
22
|
+
"data-slot": "toggle-group",
|
|
23
|
+
"data-variant": variant,
|
|
24
|
+
"data-spacing": spacing,
|
|
25
|
+
...hasCustomSpacing ? { style: { "--gap": `${spacing}px` } } : {},
|
|
26
|
+
className: cn(
|
|
27
|
+
"group/toggle-group flex w-fit items-center",
|
|
28
|
+
isConnected ? "gap-0" : hasCustomSpacing ? "gap-(--gap)" : "gap-(--toggle-common-gap-group)",
|
|
29
|
+
className
|
|
30
|
+
),
|
|
31
|
+
...props,
|
|
32
|
+
children: /* @__PURE__ */ jsx(CsCsToggleGroupContext.Provider, { value: { variant, spacing }, children })
|
|
33
|
+
}
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
function CsToggleGroupItem({
|
|
37
|
+
className,
|
|
38
|
+
children,
|
|
39
|
+
variant,
|
|
40
|
+
...props
|
|
41
|
+
}) {
|
|
42
|
+
const context = React.useContext(CsCsToggleGroupContext);
|
|
43
|
+
return /* @__PURE__ */ jsx(
|
|
44
|
+
CsToggleGroupPrimitive.Item,
|
|
45
|
+
{
|
|
46
|
+
"data-slot": "toggle-group-item",
|
|
47
|
+
"data-variant": context.variant || variant,
|
|
48
|
+
"data-spacing": context.spacing,
|
|
49
|
+
className: cn(
|
|
50
|
+
csToggleVariants({
|
|
51
|
+
variant: context.variant || variant
|
|
52
|
+
}),
|
|
53
|
+
"data-[spacing=0]:rounded-none data-[spacing=0]:shadow-none data-[spacing=0]:first:rounded-l-(--toggle-common-radius) data-[spacing=0]:last:rounded-r-(--toggle-common-radius) data-[spacing=0]:data-[variant=outline]:border-l-0 data-[spacing=0]:data-[variant=outline]:first:border-l",
|
|
54
|
+
className
|
|
55
|
+
),
|
|
56
|
+
...props,
|
|
57
|
+
children
|
|
58
|
+
}
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
export {
|
|
62
|
+
CsToggleGroup,
|
|
63
|
+
CsToggleGroupItem
|
|
64
|
+
};
|
|
65
|
+
//# sourceMappingURL=cs-toggle-group.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cs-toggle-group.js","sources":["../../../src/components/toggle/cs-toggle-group.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport * as CsToggleGroupPrimitive from \"@radix-ui/react-toggle-group\"\nimport { type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"../../lib/utils\"\nimport { csToggleVariants } from \"./cs-toggle\"\n\n/**\n * CsCsToggleGroup 스타일 시스템 (Design Token Reference)\n *\n * CsToggle과 동일한 토큰 사용.\n * 상세한 토큰 매핑은 CsToggle 문서 참조.\n *\n * ## Figma Token → Props 매핑\n * | Figma 토큰 패턴 | Props |\n * |----------------|-------|\n * | `toggle/solid/*` | `variant=\"solid\"` (기본) |\n * | `toggle/outline/*` | `variant=\"outline\"` |\n *\n * ## Props 옵션\n * | prop | 값 | 설명 |\n * |------|-----|------|\n * | type | `single` | 단일 선택 |\n * | type | `multiple` | 다중 선택 |\n * | spacing | 미지정 | 토큰 gap 분리 형태 (기본, `--toggle-common-gap-group`) |\n * | spacing | `0` | 연결된 형태 |\n * | spacing | `number` | 커스텀 gap 분리 형태 |\n *\n * ## CSS Variables\n * ```css\n * --toggle-common-gap-group | radius\n * --toggle-solid-* | --toggle-outline-*\n * ```\n *\n * @see CsToggle - 토큰 매핑 상세 정보\n * @see {@link https://www.radix-ui.com/primitives/docs/components/toggle-group | Radix CsToggleGroup}\n */\n\n/**\n * CS Design System 토글 그룹 컴포넌트\n *\n * 여러 토글 버튼을 하나의 그룹으로 묶어서 관리하는 컴포넌트.\n * 텍스트 정렬, 뷰 모드 선택 등 상호 배타적인 옵션 선택에 사용됩니다.\n * 단일 선택(single) 또는 다중 선택(multiple) 모드를 지원합니다.\n *\n * ## 사용 시나리오\n * - 텍스트 정렬: 왼쪽/중앙/오른쪽 정렬 선택 (single)\n * - 뷰 모드: 리스트/그리드/카드 뷰 전환 (single)\n * - 텍스트 포맷: Bold, Italic, Underline 동시 선택 (multiple)\n * - 필터 옵션: 여러 필터 동시 적용 (multiple)\n *\n * @example 기본 (토큰 gap 분리 형태)\n * ```tsx\n * <CsToggleGroup type=\"single\" value={value} onValueChange={setValue}>\n * <CsToggleGroupItem value=\"left\"><AlignLeft /></CsToggleGroupItem>\n * <CsToggleGroupItem value=\"center\"><AlignCenter /></CsToggleGroupItem>\n * <CsToggleGroupItem value=\"right\"><AlignRight /></CsToggleGroupItem>\n * </CsToggleGroup>\n * ```\n *\n * @example 연결된 형태 (spacing={0})\n * ```tsx\n * <CsToggleGroup type=\"single\" spacing={0}>\n * <CsToggleGroupItem value=\"a\">A</CsToggleGroupItem>\n * <CsToggleGroupItem value=\"b\">B</CsToggleGroupItem>\n * </CsToggleGroup>\n * ```\n *\n * @example 커스텀 gap\n * ```tsx\n * <CsToggleGroup type=\"single\" spacing={16}>\n * <CsToggleGroupItem value=\"a\">A</CsToggleGroupItem>\n * <CsToggleGroupItem value=\"b\">B</CsToggleGroupItem>\n * </CsToggleGroup>\n * ```\n */\nconst CsCsToggleGroupContext = React.createContext<\n VariantProps<typeof csToggleVariants> & {\n spacing?: number\n }\n>({\n variant: \"solid\",\n})\n\nfunction CsToggleGroup({\n className,\n variant = \"solid\",\n spacing,\n children,\n ...props\n}: React.ComponentProps<typeof CsToggleGroupPrimitive.Root> &\n VariantProps<typeof csToggleVariants> & {\n /**\n * 아이템 간 간격 (px)\n * - 미지정: 토큰 gap 분리 형태 (`--toggle-common-gap-group`)\n * - `0`: 연결된 형태\n * - `number`: 커스텀 gap 분리 형태\n */\n spacing?: number\n }) {\n const isConnected = spacing === 0\n const hasCustomSpacing = typeof spacing === 'number' && spacing > 0\n\n return (\n <CsToggleGroupPrimitive.Root\n data-slot=\"toggle-group\"\n data-variant={variant}\n data-spacing={spacing}\n {...(hasCustomSpacing ? { style: { \"--gap\": `${spacing}px` } as React.CSSProperties } : {})}\n className={cn(\n \"group/toggle-group flex w-fit items-center\",\n isConnected\n ? \"gap-0\"\n : hasCustomSpacing\n ? \"gap-(--gap)\"\n : \"gap-(--toggle-common-gap-group)\",\n className\n )}\n {...props}\n >\n <CsCsToggleGroupContext.Provider value={{ variant, spacing }}>\n {children}\n </CsCsToggleGroupContext.Provider>\n </CsToggleGroupPrimitive.Root>\n )\n}\n\nfunction CsToggleGroupItem({\n className,\n children,\n variant,\n ...props\n}: React.ComponentProps<typeof CsToggleGroupPrimitive.Item> &\n VariantProps<typeof csToggleVariants>) {\n const context = React.useContext(CsCsToggleGroupContext)\n\n return (\n <CsToggleGroupPrimitive.Item\n data-slot=\"toggle-group-item\"\n data-variant={context.variant || variant}\n data-spacing={context.spacing}\n className={cn(\n csToggleVariants({\n variant: context.variant || variant,\n }),\n \"data-[spacing=0]:rounded-none data-[spacing=0]:shadow-none data-[spacing=0]:first:rounded-l-(--toggle-common-radius) data-[spacing=0]:last:rounded-r-(--toggle-common-radius) data-[spacing=0]:data-[variant=outline]:border-l-0 data-[spacing=0]:data-[variant=outline]:first:border-l\",\n className\n )}\n {...props}\n >\n {children}\n </CsToggleGroupPrimitive.Item>\n )\n}\n\nexport { CsToggleGroup, CsToggleGroupItem }\n"],"names":[],"mappings":";;;;;;AAkFE,+BACS,MAAA,cAAA;AAAA,EACV,SAAA;AAED,CAAA;AAAuB,SACrB,cAAA;AAAA,EACA;AAAA,EACA,UAAA;AAAA,EACA;AAAA,EACA;AAAA,EACF,GASK;AACH,GAAA;AACA,QAAM,cAAA,YAA0B;AAEhC,2BACE,OAAA,YAAA,YAAA,UAAA;AAAA,SAAC;AAAA,IAAA,uBAAA;AAAA,IAAA;AAAA,MAEC,aAAA;AAAA,MACA,gBAAc;AAAA,MACb,gBAAI;AAAA,MACL,GAAA,mBAAW,EAAA,OAAA,EAAA,SAAA,GAAA,OAAA,KAAA,EAAA,IAAA,CAAA;AAAA,MAAA,WACT;AAAA,QACA;AAAA,QAKA,cAAA,UAAA,mBAAA,gBAAA;AAAA,QACF;AAAA,MACC;AAAA,MAED;MAEA,UAAA,oBAAA,uBAAA,UAAA,EAAA,OAAA,EAAA,SAAA,QAAA,GAAA,SAAA,CAAA;AAAA,IACF;AAAA,EAEJ;AAEA;AAA2B,SACzB,kBAAA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACF,GACyC;AACvC,GAAA;AAEA,mCACE,sBAAA;AAAA,SAAC;AAAA,IAAA,uBAAA;AAAA,IAAA;AAAA,MAEC;MACA,gBAAc,QAAQ,WAAA;AAAA,MACtB,gBAAW,QAAA;AAAA,MAAA;QACQ,iBACN;AAAA,UACV,SAAA,QAAA,WAAA;AAAA,QACD,CAAA;AAAA,QACA;AAAA,QACF;AAAA,MACC;AAAA,MAEA,GAAA;AAAA,MAAA;AAAA,IACH;AAAA,EAEJ;;"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import * as TogglePrimitive from "@radix-ui/react-toggle";
|
|
4
|
+
import { cva } from "class-variance-authority";
|
|
5
|
+
import { cn } from "../../lib/utils.js";
|
|
6
|
+
const csToggleVariants = cva(
|
|
7
|
+
"inline-flex items-center w-fit justify-center gap-(--toggle-common-gap) rounded-(--toggle-common-radius) px-(--toggle-common-padding-x) py-(--toggle-common-padding-y) typo-body-sm disabled:pointer-events-none disabled:opacity-(--toggle-common-opacity) [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-(--toggle-common-icon-size) [&_svg]:shrink-0 focus-visible:ring-0 outline-none transition-[color,box-shadow] whitespace-nowrap",
|
|
8
|
+
{
|
|
9
|
+
variants: {
|
|
10
|
+
variant: {
|
|
11
|
+
solid: [
|
|
12
|
+
"bg-(--toggle-solid-default-bg) text-(--toggle-solid-default-font) [&_svg]:text-(--toggle-solid-default-icon)",
|
|
13
|
+
"hover:bg-(--toggle-solid-hover-bg) hover:text-(--toggle-solid-hover-font) hover:[&_svg]:text-(--toggle-solid-hover-icon)",
|
|
14
|
+
"data-[state=on]:bg-(--toggle-solid-active-bg) data-[state=on]:text-(--toggle-solid-active-font) data-[state=on]:[&_svg]:text-(--toggle-solid-active-icon)"
|
|
15
|
+
].join(" "),
|
|
16
|
+
outline: [
|
|
17
|
+
"bg-(--toggle-outline-default-bg) text-(--toggle-outline-default-font) [&_svg]:text-(--toggle-outline-default-icon) border-(length:--toggle-outline-border-width) border-(--toggle-outline-default-border)",
|
|
18
|
+
"hover:bg-(--toggle-outline-hover-bg) hover:text-(--toggle-outline-hover-font) hover:[&_svg]:text-(--toggle-outline-hover-icon) border-(--toggle-outline-hover-border)",
|
|
19
|
+
"data-[state=on]:bg-(--toggle-outline-active-bg) data-[state=on]:text-(--toggle-outline-active-font) data-[state=on]:[&_svg]:text-(--toggle-outline-active-icon) data-[state=on]:border-(--toggle-outline-active-border)"
|
|
20
|
+
].join(" ")
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
defaultVariants: {
|
|
24
|
+
variant: "solid"
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
);
|
|
28
|
+
function CsToggle({
|
|
29
|
+
className,
|
|
30
|
+
variant,
|
|
31
|
+
...props
|
|
32
|
+
}) {
|
|
33
|
+
return /* @__PURE__ */ jsx(
|
|
34
|
+
TogglePrimitive.Root,
|
|
35
|
+
{
|
|
36
|
+
"data-slot": "toggle",
|
|
37
|
+
className: cn(csToggleVariants({ variant, className })),
|
|
38
|
+
...props
|
|
39
|
+
}
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
export {
|
|
43
|
+
CsToggle,
|
|
44
|
+
csToggleVariants
|
|
45
|
+
};
|
|
46
|
+
//# sourceMappingURL=cs-toggle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cs-toggle.js","sources":["../../../src/components/toggle/cs-toggle.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport * as TogglePrimitive from \"@radix-ui/react-toggle\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"../../lib/utils\"\n\n/**\n * CsToggle 스타일 시스템 (Design Token Reference)\n *\n * ## Figma Token → Props 매핑\n * | Figma 토큰 패턴 | Props |\n * |----------------|-------|\n * | `toggle/solid/*` | `variant=\"solid\"` (기본) |\n * | `toggle/outline/*` | `variant=\"outline\"` |\n *\n * ## State 매핑\n * | UI 상태 | Token state |\n * |---------|-------------|\n * | 기본 | default |\n * | hover: | hover |\n * | 활성 (data-[state=on]) | active |\n *\n * ## CSS Variables\n * ```css\n * --toggle-common-gap | radius | padding-x | padding-y | icon-size | opacity\n * --toggle-{variant}-{state}-bg | font | icon | border (outline only)\n * ```\n */\nconst csToggleVariants = cva(\n \"inline-flex items-center w-fit justify-center gap-(--toggle-common-gap) rounded-(--toggle-common-radius) px-(--toggle-common-padding-x) py-(--toggle-common-padding-y) typo-body-sm disabled:pointer-events-none disabled:opacity-(--toggle-common-opacity) [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-(--toggle-common-icon-size) [&_svg]:shrink-0 focus-visible:ring-0 outline-none transition-[color,box-shadow] whitespace-nowrap\",\n {\n variants: {\n variant: {\n solid: [\n \"bg-(--toggle-solid-default-bg) text-(--toggle-solid-default-font) [&_svg]:text-(--toggle-solid-default-icon)\",\n \"hover:bg-(--toggle-solid-hover-bg) hover:text-(--toggle-solid-hover-font) hover:[&_svg]:text-(--toggle-solid-hover-icon)\",\n \"data-[state=on]:bg-(--toggle-solid-active-bg) data-[state=on]:text-(--toggle-solid-active-font) data-[state=on]:[&_svg]:text-(--toggle-solid-active-icon)\",\n ].join(' '),\n outline: [\n \"bg-(--toggle-outline-default-bg) text-(--toggle-outline-default-font) [&_svg]:text-(--toggle-outline-default-icon) border-(length:--toggle-outline-border-width) border-(--toggle-outline-default-border)\",\n \"hover:bg-(--toggle-outline-hover-bg) hover:text-(--toggle-outline-hover-font) hover:[&_svg]:text-(--toggle-outline-hover-icon) border-(--toggle-outline-hover-border)\",\n \"data-[state=on]:bg-(--toggle-outline-active-bg) data-[state=on]:text-(--toggle-outline-active-font) data-[state=on]:[&_svg]:text-(--toggle-outline-active-icon) data-[state=on]:border-(--toggle-outline-active-border)\",\n ].join(' '),\n },\n },\n defaultVariants: {\n variant: \"solid\",\n },\n }\n)\n\n/**\n * CsToggle Props\n */\ntype CsToggleProps = React.ComponentProps<typeof TogglePrimitive.Root> &\n VariantProps<typeof csToggleVariants> & {\n /**\n * 토글 버튼 스타일\n * - `solid`: 채워진 배경 (기본) - 일반 토글\n * - `outline`: 테두리 스타일 - 툴바, 에디터 버튼\n * @default 'solid'\n */\n variant?: 'solid' | 'outline'\n /**\n * 토글 상태\n * controlled 모드에서 사용\n */\n pressed?: boolean\n /**\n * 토글 상태 변경 핸들러\n * @param pressed - 변경된 상태\n */\n onPressedChange?: (pressed: boolean) => void\n}\n\n/**\n * CS Design System 토글 버튼 컴포넌트\n *\n * 눌림 상태를 유지하는 버튼으로, 에디터 포맷 버튼, 필터 칩 등에 사용됩니다.\n * 클릭 시 상태가 전환되며 시각적 피드백을 제공합니다.\n * Radix UI 기반이며, 아이콘 크기가 자동 조절됩니다.\n *\n * ## 사용 시나리오\n * - 에디터 툴바: 텍스트 포맷 (Bold, Italic, Underline)\n * - 필터 칩: 검색 필터 선택/해제\n * - 뷰 전환: 리스트/그리드 뷰 토글\n * - 즐겨찾기: 북마크 추가/제거\n *\n * ## 유사 컴포넌트와의 차이\n * - **CsToggleGroup**: 여러 토글을 그룹으로 묶어 단일/다중 선택 지원\n * - **CsButton**: 일회성 액션 (클릭 시 실행, 상태 없음)\n * - **CsSwitch**: 즉시 반영되는 설정 토글 (스위치 UI)\n * - Toggle은 버튼 형태 + 상태 유지, Button은 액션만, Switch는 ON/OFF UI\n *\n * @example 기본 (solid)\n * ```tsx\n * <CsToggle pressed={isOn} onPressedChange={setIsOn}>\n * <Star /> 즐겨찾기\n * </CsToggle>\n * ```\n *\n * @example outline 스타일\n * ```tsx\n * <CsToggle variant=\"outline\" pressed={isOn} onPressedChange={setIsOn}>\n * <Bold /> Bold\n * </CsToggle>\n * ```\n *\n * @example 에디터 툴바\n * ```tsx\n * <div className=\"flex gap-1\">\n * <CsToggle variant=\"outline\" pressed={isBold} onPressedChange={setIsBold}>\n * <Bold />\n * </CsToggle>\n * <CsToggle variant=\"outline\" pressed={isItalic} onPressedChange={setIsItalic}>\n * <Italic />\n * </CsToggle>\n * </div>\n * ```\n *\n * @see CsToggleGroup - 여러 토글을 그룹으로 묶을 때\n * @see {@link https://www.radix-ui.com/primitives/docs/components/toggle | Radix Toggle}\n */\nfunction CsToggle({\n className,\n variant,\n ...props\n}: CsToggleProps) {\n return (\n <TogglePrimitive.Root\n data-slot=\"toggle\"\n className={cn(csToggleVariants({ variant, className }))}\n {...props}\n />\n )\n}\n\nexport { CsToggle, csToggleVariants, type CsToggleProps }\n"],"names":[],"mappings":";;;;;AA8ByB,MACvB,mBAAA;AAAA,EACA;AAAA,EAAA;AAAA,IACY,UACR;AAAA,MAAS,SACA;AAAA,QAAA,OACL;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF,OAAA,GAAS;AAAA,QAAA,SACP;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QAAQ,EAAA,KAAA,GAAA;AAAA,MAEd;AAAA,IACA;AAAA,IAAiB,iBACN;AAAA,MAAA,SAAA;AAAA,IACX;AAAA,EAEJ;AA0EA;AAAkB,SAChB,SAAA;AAAA,EACA;AAAA,EACA;AAAA,EACF,GAAkB;AAChB;AACE,SAAiB;AAAA,IAAhB,gBAAA;AAAA,IAAA;AAAA,MAEC,aAAW;AAAA,MACV,WAAG,GAAA,iBAAA,EAAA,SAAA,UAAA,CAAA,CAAA;AAAA,MAAA,GAAA;AAAA,IACN;AAAA,EAEJ;;"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { CsTooltipProvider, CsTooltip, CsTooltipTrigger, CsTooltipContent } from "./cs-tooltip.js";
|
|
4
|
+
function CsSimpleTooltip({ children, tooltip, contentProps, variant, ...rootProps }) {
|
|
5
|
+
if (!tooltip) {
|
|
6
|
+
return children;
|
|
7
|
+
}
|
|
8
|
+
return /* @__PURE__ */ jsx(CsTooltipProvider, { children: /* @__PURE__ */ jsxs(CsTooltip, { ...rootProps, children: [
|
|
9
|
+
/* @__PURE__ */ jsx(CsTooltipTrigger, { asChild: true, children }),
|
|
10
|
+
/* @__PURE__ */ jsx(CsTooltipContent, { variant, ...contentProps, children: tooltip })
|
|
11
|
+
] }) });
|
|
12
|
+
}
|
|
13
|
+
export {
|
|
14
|
+
CsSimpleTooltip
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=cs-simple-tooltip.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cs-simple-tooltip.js","sources":["../../../src/components/tooltip/cs-simple-tooltip.tsx"],"sourcesContent":["'use client'\n\nimport type { ReactNode, ComponentProps } from 'react'\n\nimport { CsTooltip, CsTooltipTrigger, CsTooltipContent, CsTooltipProvider } from './cs-tooltip'\n\n/**\n * CsSimpleTooltip 스타일 시스템 (Design Token Reference)\n *\n * CsTooltip의 래퍼 컴포넌트입니다.\n * 상세한 토큰 매핑은 CsTooltip 문서를 참조하세요.\n *\n * ## Figma Token → Props 매핑\n * | Figma 토큰 패턴 | Props |\n * |----------------|-------|\n * | `tooltip/solid/*` | `variant=\"solid\"` (기본) |\n * | `tooltip/outline/*` | `variant=\"outline\"` |\n *\n * ## CsTooltip과의 차이점\n * - Provider 자동 포함 (개별 Tooltip에 Provider 불필요)\n * - tooltip prop으로 내용 직접 전달\n * - tooltip이 falsy면 children만 렌더링 (조건부 툴팁)\n *\n * @see CsTooltip - 더 세밀한 제어 필요 시 직접 사용\n */\n\ntype CsTooltipRootProps = ComponentProps<typeof CsTooltip>\ntype CsTooltipContentProps = Omit<ComponentProps<typeof CsTooltipContent>, 'children'>\n\n/**\n * CsSimpleTooltip Props\n */\ninterface ICsSimpleTooltipProps extends Omit<CsTooltipRootProps, 'children'> {\n /** 툴팁 트리거 요소 (호버 대상) */\n children: ReactNode\n\n /**\n * 툴팁 내용\n * 문자열 또는 ReactNode. falsy면 children만 렌더링.\n */\n tooltip: ReactNode\n\n /**\n * CsTooltipContent에 전달할 추가 props\n * side, align, className 등\n */\n contentProps?: CsTooltipContentProps\n\n /**\n * 툴팁 스타일 변형\n * - `solid`: 채워진 배경 (기본)\n * - `outline`: 테두리 스타일\n * @default 'solid'\n */\n variant?: 'solid' | 'outline'\n}\n\n/**\n * CS Design System 간편 툴팁\n *\n * 호버 시 추가 정보를 표시하는 래퍼 컴포넌트.\n * tooltip이 없으면 children만 렌더링하여 조건부 툴팁 구현 가능.\n *\n * @example 기본\n * ```tsx\n * <CsSimpleTooltip tooltip=\"도움말 텍스트\">\n * <CsButton>Hover me</CsButton>\n * </CsSimpleTooltip>\n * ```\n *\n * @example variant 변경\n * ```tsx\n * <CsSimpleTooltip tooltip=\"테두리 있는 툴팁\" variant=\"outline\">\n * <span>Hover</span>\n * </CsSimpleTooltip>\n * ```\n *\n * @example 커스텀 컨텐츠\n * ```tsx\n * <CsSimpleTooltip\n * tooltip={<div className=\"flex gap-2\"><Icon /> 커스텀</div>}\n * >\n * <CsButton>Hover</CsButton>\n * </CsSimpleTooltip>\n * ```\n *\n * @example 조건부 툴팁\n * ```tsx\n * <CsSimpleTooltip tooltip={isDisabled ? \"비활성화됨\" : undefined}>\n * <CsButton disabled={isDisabled}>버튼</CsButton>\n * </CsSimpleTooltip>\n * ```\n */\nfunction CsSimpleTooltip({ children, tooltip, contentProps, variant, ...rootProps }: ICsSimpleTooltipProps) {\n if (!tooltip) {\n return children\n }\n\n return (\n <CsTooltipProvider>\n <CsTooltip {...rootProps}>\n <CsTooltipTrigger asChild>\n {children}\n </CsTooltipTrigger>\n <CsTooltipContent variant={variant} {...contentProps}>\n {tooltip}\n </CsTooltipContent>\n </CsTooltip>\n </CsTooltipProvider>\n )\n}\n\nexport { CsSimpleTooltip, type ICsSimpleTooltipProps }\n"],"names":[],"mappings":";;;AA8FE,SAAK,gBAAS,EAAA,UAAA,SAAA,cAAA,SAAA,GAAA,UAAA,GAAA;AACZ,gBAAO;AACT,WAAA;AAAA,EAEA;AAGM,SAAC,oBAAA,mBAAiB,EAAA,UAElB,qBAAA,WAAA,EAAA,GAAA,WAAA,UAAA;AAAA,IACA,oBAAC,kBAAA,EAAiB,SAAmB,MAAG;IAI5C,oBAAA,kBAAA,EAAA,SAAA,GAAA,cAAA,UAAA,QAAA,CAAA;AAAA,EAEJ,EAAA,CAAA,EAAA,CAAA;;"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import * as TooltipPrimitive from "@radix-ui/react-tooltip";
|
|
4
|
+
import { cva } from "class-variance-authority";
|
|
5
|
+
import { cn } from "../../lib/utils.js";
|
|
6
|
+
const tooltipBaseStyles = "typo-body-sm z-50 w-fit flex flex-col gap-(--tooltip-gap) origin-(--radix-tooltip-content-transform-origin) rounded-(--tooltip-radius) px-(--tooltip-padding-x) py-(--tooltip-padding-y) text-balance text-(--tooltip-font) empty:hidden";
|
|
7
|
+
const tooltipVariants = {
|
|
8
|
+
solid: "bg-(--tooltip-solid-bg) boxshadow-sm",
|
|
9
|
+
outline: "bg-(--tooltip-outline-bg) border-(--tooltip-outline-border) border-(length:--tooltip-outline-border-width)"
|
|
10
|
+
};
|
|
11
|
+
const csTooltipContentVariants = cva(
|
|
12
|
+
`${tooltipBaseStyles} animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2`,
|
|
13
|
+
{
|
|
14
|
+
variants: {
|
|
15
|
+
variant: tooltipVariants
|
|
16
|
+
},
|
|
17
|
+
defaultVariants: {
|
|
18
|
+
variant: "solid"
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
);
|
|
22
|
+
const csChartTooltipStyle = cn(tooltipBaseStyles, tooltipVariants.solid);
|
|
23
|
+
function CsTooltipProvider({
|
|
24
|
+
delayDuration = 0,
|
|
25
|
+
...props
|
|
26
|
+
}) {
|
|
27
|
+
return /* @__PURE__ */ jsx(
|
|
28
|
+
TooltipPrimitive.Provider,
|
|
29
|
+
{
|
|
30
|
+
"data-slot": "tooltip-provider",
|
|
31
|
+
delayDuration,
|
|
32
|
+
...props
|
|
33
|
+
}
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
function CsTooltip({
|
|
37
|
+
...props
|
|
38
|
+
}) {
|
|
39
|
+
return /* @__PURE__ */ jsx(CsTooltipProvider, { children: /* @__PURE__ */ jsx(TooltipPrimitive.Root, { "data-slot": "tooltip", ...props }) });
|
|
40
|
+
}
|
|
41
|
+
function CsTooltipTrigger({
|
|
42
|
+
...props
|
|
43
|
+
}) {
|
|
44
|
+
return /* @__PURE__ */ jsx(TooltipPrimitive.Trigger, { "data-slot": "tooltip-trigger", ...props });
|
|
45
|
+
}
|
|
46
|
+
function CsTooltipContent({
|
|
47
|
+
className,
|
|
48
|
+
sideOffset = 4,
|
|
49
|
+
children,
|
|
50
|
+
variant,
|
|
51
|
+
...props
|
|
52
|
+
}) {
|
|
53
|
+
return /* @__PURE__ */ jsx(TooltipPrimitive.Portal, { children: /* @__PURE__ */ jsx(
|
|
54
|
+
TooltipPrimitive.Content,
|
|
55
|
+
{
|
|
56
|
+
"data-slot": "tooltip-content",
|
|
57
|
+
sideOffset,
|
|
58
|
+
className: cn(csTooltipContentVariants({ variant }), className),
|
|
59
|
+
...props,
|
|
60
|
+
children
|
|
61
|
+
}
|
|
62
|
+
) });
|
|
63
|
+
}
|
|
64
|
+
export {
|
|
65
|
+
CsTooltip,
|
|
66
|
+
CsTooltipContent,
|
|
67
|
+
CsTooltipProvider,
|
|
68
|
+
CsTooltipTrigger,
|
|
69
|
+
csChartTooltipStyle,
|
|
70
|
+
csTooltipContentVariants
|
|
71
|
+
};
|
|
72
|
+
//# sourceMappingURL=cs-tooltip.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cs-tooltip.js","sources":["../../../src/components/tooltip/cs-tooltip.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport * as TooltipPrimitive from \"@radix-ui/react-tooltip\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"../../lib/utils\"\n\n/**\n * CsTooltip 스타일 시스템 (Design Token Reference)\n *\n * ## Figma Token → Props 매핑\n * | Figma 토큰 패턴 | Props |\n * |----------------|-------|\n * | `tooltip/solid/*` | `variant=\"solid\"` (기본) |\n * | `tooltip/outline/*` | `variant=\"outline\"` |\n *\n * ## CSS Variables\n * ```css\n * --tooltip-radius | padding-x | padding-y | gap | font\n * --tooltip-solid-bg\n * --tooltip-outline-bg | border | border-width\n * ```\n */\nconst tooltipBaseStyles = \"typo-body-sm z-50 w-fit flex flex-col gap-(--tooltip-gap) origin-(--radix-tooltip-content-transform-origin) rounded-(--tooltip-radius) px-(--tooltip-padding-x) py-(--tooltip-padding-y) text-balance text-(--tooltip-font) empty:hidden\"\nconst tooltipVariants = {\n solid: \"bg-(--tooltip-solid-bg) boxshadow-sm\",\n outline: \"bg-(--tooltip-outline-bg) border-(--tooltip-outline-border) border-(length:--tooltip-outline-border-width)\"\n}\n\nconst csTooltipContentVariants = cva(\n `${tooltipBaseStyles} animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2`,\n {\n variants: {\n variant: tooltipVariants\n },\n defaultVariants: {\n variant: \"solid\",\n }\n }\n)\n\n/**\n * Styles for chart tooltips (ECharts).\n * Excludes animations and state-based transitions to avoid conflicts with ECharts rendering.\n */\nconst csChartTooltipStyle = cn(tooltipBaseStyles, tooltipVariants.solid)\n\n/** 툴팁 Provider - delayDuration 기본값 설정 */\nfunction CsTooltipProvider({\n delayDuration = 0,\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Provider>) {\n return (\n <TooltipPrimitive.Provider\n data-slot=\"tooltip-provider\"\n delayDuration={delayDuration}\n {...props}\n />\n )\n}\n\n/**\n * CS Design System 툴팁 컴포넌트\n *\n * 요소에 마우스를 올렸을 때 짧은 힌트나 설명을 표시하는 컴포넌트.\n * 아이콘 설명, 버튼 기능 안내 등 간단한 도움말에 사용되며, CsTooltipProvider가 자동 포함됩니다.\n *\n * ## 사용 시나리오\n * - 아이콘 설명: 아이콘 버튼의 기능 설명 (호버 시)\n * - 짧은 힌트: 입력 필드 옆 물음표 아이콘 호버 시 설명\n * - 버튼 기능 안내: disabled 버튼에 대한 설명\n * - 축약된 텍스트: 말줄임표(...) 된 텍스트 전체 보기\n *\n * ## 유사 컴포넌트와의 차이\n * - **CsPopover**: 클릭 시 표시, 폼 입력 가능 (상호작용 가능)\n * - **CsSimpleTooltip**: 더 간단한 래퍼 - 일반적인 경우 이것을 사용하세요 (권장)\n * - Tooltip은 호버 + 읽기만, Popover는 클릭 + 입력 가능\n *\n * @example 기본 조합\n * ```tsx\n * <CsTooltip>\n * <CsTooltipTrigger asChild>\n * <CsButton>호버</CsButton>\n * </CsTooltipTrigger>\n * <CsTooltipContent>툴팁 내용</CsTooltipContent>\n * </CsTooltip>\n * ```\n *\n * @example outline 스타일\n * ```tsx\n * <CsTooltipContent variant=\"outline\">테두리 있는 툴팁</CsTooltipContent>\n * ```\n *\n * @see CsSimpleTooltip - 간단한 사용 시 래퍼 컴포넌트 권장 (일반적인 경우)\n * @see {@link https://www.radix-ui.com/primitives/docs/components/tooltip | Radix Tooltip}\n */\nfunction CsTooltip({\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Root>) {\n return (\n <CsTooltipProvider>\n <TooltipPrimitive.Root data-slot=\"tooltip\" {...props} />\n </CsTooltipProvider>\n )\n}\n\n/** 툴팁 트리거 - asChild로 자식 요소 사용 권장 */\nfunction CsTooltipTrigger({\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Trigger>) {\n return <TooltipPrimitive.Trigger data-slot=\"tooltip-trigger\" {...props} />\n}\n\n/**\n * CsTooltipContent Props\n */\ntype CsTooltipContentProps = React.ComponentProps<typeof TooltipPrimitive.Content> &\n VariantProps<typeof csTooltipContentVariants> & {\n /**\n * 툴팁 스타일\n * - `solid`: 채워진 배경 (기본)\n * - `outline`: 테두리 스타일\n * @default 'solid'\n */\n variant?: 'solid' | 'outline'\n /**\n * 트리거와의 간격 (px)\n * @default 4\n */\n sideOffset?: number\n}\n\n/** 툴팁 콘텐츠 영역 - 애니메이션 자동 적용 */\nfunction CsTooltipContent({\n className,\n sideOffset = 4,\n children,\n variant,\n ...props\n}: CsTooltipContentProps) {\n return (\n <TooltipPrimitive.Portal>\n <TooltipPrimitive.Content\n data-slot=\"tooltip-content\"\n sideOffset={sideOffset}\n className={cn(csTooltipContentVariants({ variant }), className)}\n {...props}\n >\n {children}\n {/* <TooltipPrimitive.Arrow className=\"bg-(--color-bg-surface-default) fill-(--color-bg-surface-default) z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px]\" /> */}\n </TooltipPrimitive.Content>\n </TooltipPrimitive.Portal>\n )\n}\n\nexport {\n CsTooltip,\n CsTooltipTrigger,\n CsTooltipContent,\n CsTooltipProvider,\n csTooltipContentVariants,\n csChartTooltipStyle,\n type CsTooltipContentProps,\n}\n"],"names":[],"mappings":";;;;;AAyBA,MAAM,oBAAkB;AAAA,MACtB,kBAAO;AAAA,EACP,OAAA;AAAA,EACF,SAAA;AAEA;AAAiC,MAC5B;EACH,GAAA,iBAAA;AAAA,EAAA;AAAA,IACY,UACR;AAAA,MACF,SAAA;AAAA,IACA;AAAA,IAAiB,iBACN;AAAA,MAAA,SAAA;AAAA,IACX;AAAA,EAEJ;AAMA;AAGA,MAAA,sBAA2B,GAAA,mBAAA,gBAAA,KAAA;AAAA,SACzB,kBAAgB;AAAA,EAChB,gBAAG;AAAA,EACL,GAA2D;AACzD;AACE,SAAkB;AAAA,IAAjB,iBAAA;AAAA,IAAA;AAAA,MAEC,aAAA;AAAA,MACC;AAAA,MAAG,GAAA;AAAA,IACN;AAAA,EAEJ;AAqCA;AAAmB,SACd,UAAA;AAAA,EACL,GAAuD;AACrD,GAAA;AAKF,SAAA,oBAAA,mBAAA,EAAA,UAAA,oBAAA,iBAAA,MAAA,EAAA,aAAA,WAAA,GAAA,MAAA,CAAA,EAAA,CAAA;AAGA;AAA0B,SACrB,iBAAA;AAAA,EACL,GAA0D;AACxD,GAAA;AACF,SAAA,oBAAA,iBAAA,SAAA,EAAA,aAAA,mBAAA,GAAA,MAAA,CAAA;AAsBA;AAA0B,SACxB,iBAAA;AAAA,EACA;AAAA,EACA,aAAA;AAAA,EACA;AAAA,EACA;AAAA,EACF,GAA0B;AACxB,GAAA;AAEI,SAAkB,oBAAA,iBAAA,QAAA,EAAA,UAAA;AAAA,IAAjB,iBAAA;AAAA,IAAA;AAAA,MAEC,aAAA;AAAA,MACA;AAAA,MACC,WAAG,GAAA,yBAAA,EAAA,QAAA,CAAA,GAAA,SAAA;AAAA,MAEH,GAAA;AAAA,MAAA;AAAA;EAKT,EAAA,CAAA;;"}
|