@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.
Files changed (119) hide show
  1. package/dist/components/accordion/cs-accordion.js +116 -0
  2. package/dist/components/accordion/cs-accordion.js.map +1 -0
  3. package/dist/components/alert-dialog/cs-alert-dialog.js +148 -0
  4. package/dist/components/alert-dialog/cs-alert-dialog.js.map +1 -0
  5. package/dist/components/avatar/cs-avatar.js +44 -0
  6. package/dist/components/avatar/cs-avatar.js.map +1 -0
  7. package/dist/components/badge/cs-badge.js +40 -0
  8. package/dist/components/badge/cs-badge.js.map +1 -0
  9. package/dist/components/box/cs-box.js +37 -0
  10. package/dist/components/box/cs-box.js.map +1 -0
  11. package/dist/components/button/cs-button.js +91 -0
  12. package/dist/components/button/cs-button.js.map +1 -0
  13. package/dist/components/calendar/cs-calendar.js +199 -0
  14. package/dist/components/calendar/cs-calendar.js.map +1 -0
  15. package/dist/components/card/cs-card.js +95 -0
  16. package/dist/components/card/cs-card.js.map +1 -0
  17. package/dist/components/chart/cs-chart.js +88 -0
  18. package/dist/components/chart/cs-chart.js.map +1 -0
  19. package/dist/components/checkbox/cs-checkbox.js +55 -0
  20. package/dist/components/checkbox/cs-checkbox.js.map +1 -0
  21. package/dist/components/code-block/cs-code-block.js +39 -0
  22. package/dist/components/code-block/cs-code-block.js.map +1 -0
  23. package/dist/components/code-block/cs-code-highlighter.js +59 -0
  24. package/dist/components/code-block/cs-code-highlighter.js.map +1 -0
  25. package/dist/components/collapsible/cs-collapsible.js +36 -0
  26. package/dist/components/collapsible/cs-collapsible.js.map +1 -0
  27. package/dist/components/date-picker/cs-date-picker.js +25 -0
  28. package/dist/components/date-picker/cs-date-picker.js.map +1 -0
  29. package/dist/components/dialog/cs-dialog.js +131 -0
  30. package/dist/components/dialog/cs-dialog.js.map +1 -0
  31. package/dist/components/drawer/cs-drawer.js +131 -0
  32. package/dist/components/drawer/cs-drawer.js.map +1 -0
  33. package/dist/components/dropdown-menu/cs-dropdown-menu.js +247 -0
  34. package/dist/components/dropdown-menu/cs-dropdown-menu.js.map +1 -0
  35. package/dist/components/dropzone/cs-dropzone.js +147 -0
  36. package/dist/components/dropzone/cs-dropzone.js.map +1 -0
  37. package/dist/components/empty/cs-empty.js +107 -0
  38. package/dist/components/empty/cs-empty.js.map +1 -0
  39. package/dist/components/field/cs-field.js +218 -0
  40. package/dist/components/field/cs-field.js.map +1 -0
  41. package/dist/components/input/cs-input-group.js +207 -0
  42. package/dist/components/input/cs-input-group.js.map +1 -0
  43. package/dist/components/input/cs-input.js +40 -0
  44. package/dist/components/input/cs-input.js.map +1 -0
  45. package/dist/components/label/cs-label.js +26 -0
  46. package/dist/components/label/cs-label.js.map +1 -0
  47. package/dist/components/navigation-menu/cs-navigation-menu.js +214 -0
  48. package/dist/components/navigation-menu/cs-navigation-menu.js.map +1 -0
  49. package/dist/components/pagination/cs-pagination.js +124 -0
  50. package/dist/components/pagination/cs-pagination.js.map +1 -0
  51. package/dist/components/popover/cs-popover.js +60 -0
  52. package/dist/components/popover/cs-popover.js.map +1 -0
  53. package/dist/components/progress/cs-progress.js +62 -0
  54. package/dist/components/progress/cs-progress.js.map +1 -0
  55. package/dist/components/scroll-area/cs-scroll-area.js +61 -0
  56. package/dist/components/scroll-area/cs-scroll-area.js.map +1 -0
  57. package/dist/components/select/cs-select.js +195 -0
  58. package/dist/components/select/cs-select.js.map +1 -0
  59. package/dist/components/select/cs-simple-select.js +32 -0
  60. package/dist/components/select/cs-simple-select.js.map +1 -0
  61. package/dist/components/separator/cs-separator.js +28 -0
  62. package/dist/components/separator/cs-separator.js.map +1 -0
  63. package/dist/components/sheet/cs-sheet.js +128 -0
  64. package/dist/components/sheet/cs-sheet.js.map +1 -0
  65. package/dist/components/sidebar/cs-sidebar.js +657 -0
  66. package/dist/components/sidebar/cs-sidebar.js.map +1 -0
  67. package/dist/components/skeleton/cs-skeleton.js +32 -0
  68. package/dist/components/skeleton/cs-skeleton.js.map +1 -0
  69. package/dist/components/sonner/cs-sonner.js +76 -0
  70. package/dist/components/sonner/cs-sonner.js.map +1 -0
  71. package/dist/components/spinner/cs-spinner.js +34 -0
  72. package/dist/components/spinner/cs-spinner.js.map +1 -0
  73. package/dist/components/switch/cs-switch.js +38 -0
  74. package/dist/components/switch/cs-switch.js.map +1 -0
  75. package/dist/components/table/cs-data-base-table.js +108 -0
  76. package/dist/components/table/cs-data-base-table.js.map +1 -0
  77. package/dist/components/table/cs-data-table.js +32 -0
  78. package/dist/components/table/cs-data-table.js.map +1 -0
  79. package/dist/components/table/cs-skeleton-table.js +41 -0
  80. package/dist/components/table/cs-skeleton-table.js.map +1 -0
  81. package/dist/components/table/cs-table.js +120 -0
  82. package/dist/components/table/cs-table.js.map +1 -0
  83. package/dist/components/tabs/cs-simple-tabs.js +24 -0
  84. package/dist/components/tabs/cs-simple-tabs.js.map +1 -0
  85. package/dist/components/tabs/cs-tabs.js +114 -0
  86. package/dist/components/tabs/cs-tabs.js.map +1 -0
  87. package/dist/components/toggle/cs-toggle-group.js +65 -0
  88. package/dist/components/toggle/cs-toggle-group.js.map +1 -0
  89. package/dist/components/toggle/cs-toggle.js +46 -0
  90. package/dist/components/toggle/cs-toggle.js.map +1 -0
  91. package/dist/components/tooltip/cs-simple-tooltip.js +16 -0
  92. package/dist/components/tooltip/cs-simple-tooltip.js.map +1 -0
  93. package/dist/components/tooltip/cs-tooltip.js +72 -0
  94. package/dist/components/tooltip/cs-tooltip.js.map +1 -0
  95. package/dist/constants/cs-chart-option.constant.js +105 -0
  96. package/dist/constants/cs-chart-option.constant.js.map +1 -0
  97. package/dist/cs-ui.css +73 -108
  98. package/dist/hooks/use-accordion.js +54 -0
  99. package/dist/hooks/use-accordion.js.map +1 -0
  100. package/dist/hooks/use-infinite-scroll.js +40 -0
  101. package/dist/hooks/use-infinite-scroll.js.map +1 -0
  102. package/dist/hooks/use-laptop.js +20 -0
  103. package/dist/hooks/use-laptop.js.map +1 -0
  104. package/dist/hooks/use-mobile.js +20 -0
  105. package/dist/hooks/use-mobile.js.map +1 -0
  106. package/dist/index.d.ts +19 -6
  107. package/dist/index.js +287 -0
  108. package/dist/index.js.map +1 -0
  109. package/dist/lib/chart.util.js +48 -0
  110. package/dist/lib/chart.util.js.map +1 -0
  111. package/dist/lib/style.util.js +19 -0
  112. package/dist/lib/style.util.js.map +1 -0
  113. package/dist/lib/utils.js +27 -0
  114. package/dist/lib/utils.js.map +1 -0
  115. package/package.json +4 -5
  116. package/dist/index.cjs.js +0 -147659
  117. package/dist/index.cjs.js.map +0 -1
  118. package/dist/index.es.js +0 -147624
  119. package/dist/index.es.js.map +0 -1
@@ -0,0 +1,116 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import * as AccordionPrimitive from "@radix-ui/react-accordion";
4
+ import { ChevronRightIcon } from "lucide-react";
5
+ import { cn } from "../../lib/utils.js";
6
+ import { cva } from "class-variance-authority";
7
+ function CsAccordion({
8
+ ...props
9
+ }) {
10
+ return /* @__PURE__ */ jsx(AccordionPrimitive.Root, { "data-slot": "accordion", ...props });
11
+ }
12
+ const csAccordionItemVariants = cva(
13
+ "group/accordion",
14
+ {
15
+ variants: {
16
+ variant: {
17
+ default: [
18
+ "bg-(--accordion-common-bg) border-b-(length:--accordion-default-border-width) border-b-(--accordion-default-border)",
19
+ "data-[state=open]:pb-(--accordion-default-padding-y)"
20
+ ],
21
+ custom: [
22
+ "rounded-(--accordion-custom-radius) px-(--accordion-custom-padding-x) border-(length:--accordion-custom-border-width)",
23
+ "data-[state=open]:pb-(--accordion-custom-padding-y)",
24
+ "bg-(--accordion-custom-closed-bg) border-(--accordion-custom-closed-border)",
25
+ "data-[state=open]:bg-(--accordion-custom-open-bg) data-[state=open]:border-(--accordion-custom-open-border)",
26
+ "hover:bg-(--accordion-custom-hover-bg) hover:border-(--accordion-custom-hover-border)",
27
+ "data-[state=open]:hover:bg-(--accordion-custom-open-bg) data-[state=open]:hover:border-(--accordion-custom-open-border)"
28
+ ]
29
+ }
30
+ },
31
+ defaultVariants: {
32
+ variant: "default"
33
+ }
34
+ }
35
+ );
36
+ function CsAccordionItem({
37
+ className,
38
+ variant = "default",
39
+ ...props
40
+ }) {
41
+ return /* @__PURE__ */ jsx(
42
+ AccordionPrimitive.Item,
43
+ {
44
+ "data-slot": "accordion-item",
45
+ "data-variant": variant,
46
+ className: cn(csAccordionItemVariants({ variant }), className),
47
+ ...props
48
+ }
49
+ );
50
+ }
51
+ function CsAccordionTrigger({
52
+ className,
53
+ children,
54
+ ...props
55
+ }) {
56
+ return /* @__PURE__ */ jsx(AccordionPrimitive.Header, { className: "flex", children: /* @__PURE__ */ jsxs(
57
+ AccordionPrimitive.Trigger,
58
+ {
59
+ "data-slot": "accordion-trigger",
60
+ className: cn(
61
+ "cursor-pointer typo-body-sm-bold flex flex-1 items-center justify-start text-left typo-body-md transition-all outline-none hover:underline disabled:pointer-events-none disabled:opacity-(--opacity-state-disabled) [&[data-state=open]>svg]:rotate-90",
62
+ "[&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg]:transition-transform [&_svg]:duration-200",
63
+ // default
64
+ "group-data-[variant=default]/accordion:py-(--accordion-default-padding-y) group-data-[variant=default]/accordion:gap-(--accordion-default-gap)",
65
+ "group-data-[variant=default]/accordion:data-[state=closed]:text-(--accordion-default-closed-title) group-data-[variant=default]/accordion:data-[state=closed]:[&_svg]:text-(--accordion-default-closed-icon)",
66
+ "group-data-[variant=default]/accordion:data-[state=open]:text-(--accordion-default-open-title) group-data-[variant=default]/accordion:data-[state=open]:[&_svg]:text-(--accordion-default-open-icon)",
67
+ "group-data-[variant=default]/accordion:hover:text-(--accordion-default-hover-title) group-data-[variant=default]/accordion:hover:[&_svg]:text-(--accordion-default-hover-icon)",
68
+ "group-data-[variant=default]/accordion:data-[state=open]:hover:text-(--accordion-default-open-title) group-data-[variant=default]/accordion:data-[state=open]:hover:[&_svg]:text-(--accordion-default-open-icon)",
69
+ "group-data-[variant=default]/accordion:[&_svg:not([class*='size-'])]:size-(--accordion-default-icon-size)",
70
+ // custom
71
+ "group-data-[variant=custom]/accordion:py-(--accordion-custom-padding-y) group-data-[variant=custom]/accordion:gap-(--accordion-custom-gap)",
72
+ "group-data-[variant=custom]/accordion:data-[state=closed]:text-(--accordion-custom-closed-title) group-data-[variant=custom]/accordion:data-[state=closed]:[&_svg]:text-(--accordion-custom-closed-icon)",
73
+ "group-data-[variant=custom]/accordion:data-[state=open]:text-(--accordion-custom-open-title) group-data-[variant=custom]/accordion:data-[state=open]:[&_svg]:text-(--accordion-custom-open-icon)",
74
+ "group-data-[variant=custom]/accordion:hover:text-(--accordion-custom-hover-title) group-data-[variant=custom]/accordion:hover:[&_svg]:text-(--accordion-custom-hover-icon)",
75
+ "group-data-[variant=custom]/accordion:data-[state=open]:hover:text-(--accordion-custom-open-title) group-data-[variant=custom]/accordion:data-[state=open]:hover:[&_svg]:text-(--accordion-custom-open-icon)",
76
+ "group-data-[variant=custom]/accordion:[&_svg:not([class*='size-'])]:size-(--accordion-custom-icon-size)",
77
+ className
78
+ ),
79
+ ...props,
80
+ children: [
81
+ /* @__PURE__ */ jsx(ChevronRightIcon, {}),
82
+ children
83
+ ]
84
+ }
85
+ ) });
86
+ }
87
+ function CsAccordionContent({
88
+ className,
89
+ children,
90
+ ...props
91
+ }) {
92
+ return /* @__PURE__ */ jsx(
93
+ AccordionPrimitive.Content,
94
+ {
95
+ "data-slot": "accordion-content",
96
+ className: "data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down overflow-hidden",
97
+ ...props,
98
+ children: /* @__PURE__ */ jsx("div", { className: cn(
99
+ "typo-body-sm",
100
+ "group-data-[variant=default]/accordion:pt-(--accordion-default-open-gap)",
101
+ "group-data-[variant=default]/accordion:text-(--accordion-default-open-description)",
102
+ "group-data-[variant=custom]/accordion:pt-(--accordion-custom-open-gap)",
103
+ "group-data-[variant=custom]/accordion:typo-body-sm group-data-[variant=custom]/accordion:text-(--accordion-custom-open-description)",
104
+ className
105
+ ), children })
106
+ }
107
+ );
108
+ }
109
+ export {
110
+ CsAccordion,
111
+ CsAccordionContent,
112
+ CsAccordionItem,
113
+ CsAccordionTrigger,
114
+ csAccordionItemVariants
115
+ };
116
+ //# sourceMappingURL=cs-accordion.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cs-accordion.js","sources":["../../../src/components/accordion/cs-accordion.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport * as AccordionPrimitive from \"@radix-ui/react-accordion\"\nimport { ChevronDownIcon, ChevronRightIcon } from \"lucide-react\"\n\nimport { cn } from \"../../lib/utils\"\nimport { cva, VariantProps } from \"class-variance-authority\"\n\n/**\n * CsAccordion Props\n */\ntype CsAccordionProps = React.ComponentProps<typeof AccordionPrimitive.Root> & {\n /**\n * 아코디언 타입\n * - `single`: 하나만 열림\n * - `multiple`: 여러 개 동시 열림\n */\n type?: 'single' | 'multiple'\n /**\n * 모두 닫기 가능 여부 (type=\"single\"일 때)\n * @default false\n */\n collapsible?: boolean\n}\n\n/**\n * CS Design System 아코디언 컴포넌트\n *\n * 여러 섹션을 접고 펼치며 탐색하는 컴포넌트. Radix UI 기반.\n * FAQ, 단계별 가이드, 설정 그룹 등에서 많은 정보를 효율적으로 표시합니다.\n * 단일 선택(type=\"single\") 또는 다중 선택(type=\"multiple\") 모드를 지원합니다.\n *\n * ## 사용 시나리오\n * - FAQ: `type=\"single\"` + `collapsible` - 한 번에 하나만 열림\n * - 단계별 가이드: `type=\"single\"` - 순차적 정보 표시\n * - 설정 그룹: `type=\"multiple\"` - 여러 그룹 동시 열기\n * - 제품 상세: `variant=\"custom\"` - 카드 스타일, 사양/리뷰/배송 정보\n * - 문서 목차: `variant=\"default\"` - 섹션별 내용 접기/펼치기\n * - 필터 옵션: 여러 필터 그룹을 아코디언으로 정리\n *\n * ## 유사 컴포넌트와의 차이\n * - **CsCollapsible**: 스타일 없는 프로그래밍적 토글 (사이드바 등 내부 용도)\n * - 사용자에게 보이는 접기/펼치기 UI는 단일 항목이라도 **항상 Accordion 사용**\n * - Collapsible은 스타일이 없으므로, UI용으로 쓰면 직접 스타일링해야 함\n *\n * @example 기본 조합\n * ```tsx\n * <CsAccordion type=\"single\" collapsible>\n * <CsAccordionItem value=\"item-1\">\n * <CsAccordionTrigger>제목 1</CsAccordionTrigger>\n * <CsAccordionContent>내용 1</CsAccordionContent>\n * </CsAccordionItem>\n * </CsAccordion>\n * ```\n *\n * @example custom variant (카드 스타일)\n * ```tsx\n * <CsAccordionItem variant=\"custom\" value=\"item-1\">...</CsAccordionItem>\n * ```\n *\n * @see {@link https://www.radix-ui.com/primitives/docs/components/accordion | Radix Accordion}\n */\nfunction CsAccordion({\n ...props\n}: CsAccordionProps) {\n return <AccordionPrimitive.Root data-slot=\"accordion\" {...props} />\n}\n\n/**\n * CsAccordionItem 스타일 시스템 (Design Token Reference)\n *\n * ## Figma Token → Props 매핑\n * | Figma 토큰 패턴 | Props |\n * |----------------|-------|\n * | `accordion/default/*` | `variant=\"default\"` (기본) |\n * | `accordion/custom/*` | `variant=\"custom\"` |\n *\n * ## State 매핑\n * | UI 상태 | Token state |\n * |---------|-------------|\n * | 닫힘 | closed |\n * | 열림 (data-[state=open]) | open |\n * | hover: | hover |\n *\n * ## CSS Variables\n * ```css\n * --accordion-common-bg\n * --accordion-{variant}-radius | padding-x | padding-y | gap | border | border-width\n * --accordion-{variant}-{state}-bg | border | title | icon | description\n * ```\n */\nconst csAccordionItemVariants = cva(\n \"group/accordion\",\n {\n variants: {\n variant: {\n default: [\n \"bg-(--accordion-common-bg) border-b-(length:--accordion-default-border-width) border-b-(--accordion-default-border)\",\n \"data-[state=open]:pb-(--accordion-default-padding-y)\"\n ],\n custom: [\n \"rounded-(--accordion-custom-radius) px-(--accordion-custom-padding-x) border-(length:--accordion-custom-border-width)\",\n \"data-[state=open]:pb-(--accordion-custom-padding-y)\",\n \"bg-(--accordion-custom-closed-bg) border-(--accordion-custom-closed-border)\",\n \"data-[state=open]:bg-(--accordion-custom-open-bg) data-[state=open]:border-(--accordion-custom-open-border)\",\n \"hover:bg-(--accordion-custom-hover-bg) hover:border-(--accordion-custom-hover-border)\",\n \"data-[state=open]:hover:bg-(--accordion-custom-open-bg) data-[state=open]:hover:border-(--accordion-custom-open-border)\",\n ],\n },\n },\n defaultVariants: {\n variant: \"default\",\n }\n }\n)\n\n/**\n * CsAccordionItem Props\n */\ntype CsAccordionItemProps = React.ComponentProps<typeof AccordionPrimitive.Item> & VariantProps<typeof csAccordionItemVariants> & {\n /**\n * 아코디언 아이템 스타일\n * - `default`: 기본 스타일 - 하단 보더\n * - `custom`: 카드 스타일 - 배경색, 테두리\n * @default 'default'\n */\n variant?: 'default' | 'custom'\n /**\n * 아이템 식별 값 (필수)\n */\n value: string\n}\n\n/** 아코디언 아이템 컨테이너 */\nfunction CsAccordionItem({\n className,\n variant = \"default\",\n ...props\n}: CsAccordionItemProps) {\n return (\n <AccordionPrimitive.Item\n data-slot=\"accordion-item\"\n data-variant={variant}\n className={cn(csAccordionItemVariants({ variant }), className)}\n {...props}\n />\n )\n}\n\n/** 아코디언 트리거 - ChevronDownIcon 자동 포함 */\nfunction CsAccordionTrigger({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof AccordionPrimitive.Trigger>) {\n return (\n <AccordionPrimitive.Header className=\"flex\">\n <AccordionPrimitive.Trigger\n data-slot=\"accordion-trigger\"\n className={cn(\n \"cursor-pointer typo-body-sm-bold flex flex-1 items-center justify-start text-left typo-body-md transition-all outline-none hover:underline disabled:pointer-events-none disabled:opacity-(--opacity-state-disabled) [&[data-state=open]>svg]:rotate-90\",\n \"[&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg]:transition-transform [&_svg]:duration-200\",\n // default\n \"group-data-[variant=default]/accordion:py-(--accordion-default-padding-y) group-data-[variant=default]/accordion:gap-(--accordion-default-gap)\",\n \"group-data-[variant=default]/accordion:data-[state=closed]:text-(--accordion-default-closed-title) group-data-[variant=default]/accordion:data-[state=closed]:[&_svg]:text-(--accordion-default-closed-icon)\",\n \"group-data-[variant=default]/accordion:data-[state=open]:text-(--accordion-default-open-title) group-data-[variant=default]/accordion:data-[state=open]:[&_svg]:text-(--accordion-default-open-icon)\",\n \"group-data-[variant=default]/accordion:hover:text-(--accordion-default-hover-title) group-data-[variant=default]/accordion:hover:[&_svg]:text-(--accordion-default-hover-icon)\",\n \"group-data-[variant=default]/accordion:data-[state=open]:hover:text-(--accordion-default-open-title) group-data-[variant=default]/accordion:data-[state=open]:hover:[&_svg]:text-(--accordion-default-open-icon)\",\n \"group-data-[variant=default]/accordion:[&_svg:not([class*='size-'])]:size-(--accordion-default-icon-size)\",\n // custom\n \"group-data-[variant=custom]/accordion:py-(--accordion-custom-padding-y) group-data-[variant=custom]/accordion:gap-(--accordion-custom-gap)\",\n \"group-data-[variant=custom]/accordion:data-[state=closed]:text-(--accordion-custom-closed-title) group-data-[variant=custom]/accordion:data-[state=closed]:[&_svg]:text-(--accordion-custom-closed-icon)\",\n \"group-data-[variant=custom]/accordion:data-[state=open]:text-(--accordion-custom-open-title) group-data-[variant=custom]/accordion:data-[state=open]:[&_svg]:text-(--accordion-custom-open-icon)\",\n \"group-data-[variant=custom]/accordion:hover:text-(--accordion-custom-hover-title) group-data-[variant=custom]/accordion:hover:[&_svg]:text-(--accordion-custom-hover-icon)\",\n \"group-data-[variant=custom]/accordion:data-[state=open]:hover:text-(--accordion-custom-open-title) group-data-[variant=custom]/accordion:data-[state=open]:hover:[&_svg]:text-(--accordion-custom-open-icon)\",\n \"group-data-[variant=custom]/accordion:[&_svg:not([class*='size-'])]:size-(--accordion-custom-icon-size)\",\n className\n )}\n {...props}\n >\n <ChevronRightIcon />\n {children}\n </AccordionPrimitive.Trigger>\n </AccordionPrimitive.Header>\n )\n}\n\n/** 아코디언 컨텐츠 영역 - 애니메이션 자동 적용 */\nfunction CsAccordionContent({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof AccordionPrimitive.Content>) {\n return (\n <AccordionPrimitive.Content\n data-slot=\"accordion-content\"\n className=\"data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down overflow-hidden\"\n {...props}\n >\n <div className={cn(\n \"typo-body-sm\",\n \"group-data-[variant=default]/accordion:pt-(--accordion-default-open-gap)\",\n \"group-data-[variant=default]/accordion:text-(--accordion-default-open-description)\",\n \"group-data-[variant=custom]/accordion:pt-(--accordion-custom-open-gap)\",\n \"group-data-[variant=custom]/accordion:typo-body-sm group-data-[variant=custom]/accordion:text-(--accordion-custom-open-description)\",\n className\n )}>\n {children}\n </div>\n </AccordionPrimitive.Content>\n )\n}\n\nexport {\n CsAccordion,\n CsAccordionItem,\n CsAccordionTrigger,\n CsAccordionContent,\n csAccordionItemVariants,\n type CsAccordionProps,\n type CsAccordionItemProps,\n}\n"],"names":[],"mappings":";;;;;;AA+DqB,SAChB,YAAA;AAAA,EACL,GAAqB;AACnB,GAAA;AACF,SAAA,oBAAA,mBAAA,MAAA,EAAA,aAAA,aAAA,GAAA,MAAA,CAAA;AAyBA;AAAgC,MAC9B,0BAAA;AAAA,EACA;AAAA,EAAA;AAAA,IACY,UACR;AAAA,MAAS,SACP;AAAA,QAAS,SACP;AAAA,UACA;AAAA,UACF;AAAA,QACA;AAAA,QAAQ,QACN;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UAAA;AAAA,QACF;AAAA,MAEJ;AAAA,IACA;AAAA,IAAiB,iBACN;AAAA,MAAA,SAAA;AAAA,IACX;AAAA,EAEJ;AAoBA;AAAyB,SACvB,gBAAA;AAAA,EACA;AAAA,EACA,UAAG;AAAA,EACL,GAAyB;AACvB;AACE,SAAoB;AAAA,IAAnB,mBAAA;AAAA,IAAA;AAAA,MAEC,aAAA;AAAA,MACA,gBAAc;AAAA,MACb,WAAG,GAAA,wBAAA,EAAA,QAAA,CAAA,GAAA,SAAA;AAAA,MAAA,GAAA;AAAA,IACN;AAAA,EAEJ;AAGA;AAA4B,SAC1B,mBAAA;AAAA,EACA;AAAA,EACA;AAAA,EACF,GAA4D;AAC1D,GAAA;AAEI,SAAoB,oBAAA,mBAAA,QAAA,EAAA,WAAA,QAAA,UAAA;AAAA,IAAnB,mBAAA;AAAA,IAAA;AAAA,MAEC,aAAW;AAAA,MAAA,WACT;AAAA,QACA;AAAA,QAAA;AAAA;AAAA,QAGA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QAAA;AAAA;AAAA,QAGA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACF;AAAA,MACC;AAAA,MAED;MAAA,UAAA;AAAA,QACC,oBAAA,kBAAA,CAAA,CAAA;AAAA,QAAA;AAAA,MAAA;AAAA;EAIT,EAAA,CAAA;AAGA;AAA4B,SAC1B,mBAAA;AAAA,EACA;AAAA,EACA;AAAA,EACF,GAA4D;AAC1D;AACE,SAAoB;AAAA,IAAnB,mBAAA;AAAA,IAAA;AAAA,MAEC,aAAU;AAAA,MACT,WAAG;AAAA,MAEJ,GAAA;AAAA,MAAgB,UACd,oBAAA,OAAA,EAAA,WAAA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA;MAGF,GAAA,SAAA,CAAA;AAAA,IACF;AAAA,EAEJ;;"}
@@ -0,0 +1,148 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import * as AlertDialogPrimitive from "@radix-ui/react-alert-dialog";
4
+ import { cn } from "../../lib/utils.js";
5
+ import { csButtonVariants } from "../button/cs-button.js";
6
+ function CsAlertDialog({
7
+ ...props
8
+ }) {
9
+ return /* @__PURE__ */ jsx(AlertDialogPrimitive.Root, { "data-slot": "alert-dialog", ...props });
10
+ }
11
+ function CsAlertDialogTrigger({
12
+ ...props
13
+ }) {
14
+ return /* @__PURE__ */ jsx(AlertDialogPrimitive.Trigger, { "data-slot": "alert-dialog-trigger", ...props });
15
+ }
16
+ function CsAlertDialogPortal({
17
+ ...props
18
+ }) {
19
+ return /* @__PURE__ */ jsx(AlertDialogPrimitive.Portal, { "data-slot": "alert-dialog-portal", ...props });
20
+ }
21
+ function CsAlertDialogOverlay({
22
+ className,
23
+ ...props
24
+ }) {
25
+ return /* @__PURE__ */ jsx(
26
+ AlertDialogPrimitive.Overlay,
27
+ {
28
+ "data-slot": "alert-dialog-overlay",
29
+ className: cn(
30
+ "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-(--dialog-common-bg-overlay)",
31
+ className
32
+ ),
33
+ ...props
34
+ }
35
+ );
36
+ }
37
+ function CsAlertDialogContent({
38
+ className,
39
+ ...props
40
+ }) {
41
+ return /* @__PURE__ */ jsxs(CsAlertDialogPortal, { children: [
42
+ /* @__PURE__ */ jsx(CsAlertDialogOverlay, {}),
43
+ /* @__PURE__ */ jsx(
44
+ AlertDialogPrimitive.Content,
45
+ {
46
+ "data-slot": "alert-dialog-content",
47
+ className: cn(
48
+ "bg-(--dialog-common-bg) data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-(2*var(--dialog-common-padding-x)))] translate-x-[-50%] translate-y-[-50%] gap-(--dialog-common-gap) rounded-(--dialog-common-radius) border-(--dialog-common-border) border-(length:--dialog-common-border-width) px-(--dialog-common-padding-x) py-(--dialog-common-padding-y) duration-200",
49
+ className
50
+ ),
51
+ ...props
52
+ }
53
+ )
54
+ ] });
55
+ }
56
+ function CsAlertDialogHeader({
57
+ className,
58
+ ...props
59
+ }) {
60
+ return /* @__PURE__ */ jsx(
61
+ "div",
62
+ {
63
+ "data-slot": "alert-dialog-header",
64
+ className: cn("flex flex-col gap-(--dialog-container-header-gap) max-mobile:text-center text-left", className),
65
+ ...props
66
+ }
67
+ );
68
+ }
69
+ function CsAlertDialogFooter({
70
+ className,
71
+ ...props
72
+ }) {
73
+ return /* @__PURE__ */ jsx(
74
+ "div",
75
+ {
76
+ "data-slot": "alert-dialog-footer",
77
+ className: cn(
78
+ "flex flex-col-reverse gap-(--dialog-container-footer-gap) max-mobile:flex-row max-mobile:justify-end",
79
+ className
80
+ ),
81
+ ...props
82
+ }
83
+ );
84
+ }
85
+ function CsAlertDialogTitle({
86
+ className,
87
+ ...props
88
+ }) {
89
+ return /* @__PURE__ */ jsx(
90
+ AlertDialogPrimitive.Title,
91
+ {
92
+ "data-slot": "alert-dialog-title",
93
+ className: cn("typo-heading-sm text-(--dialog-container-header-title)", className),
94
+ ...props
95
+ }
96
+ );
97
+ }
98
+ function CsAlertDialogDescription({
99
+ className,
100
+ ...props
101
+ }) {
102
+ return /* @__PURE__ */ jsx(
103
+ AlertDialogPrimitive.Description,
104
+ {
105
+ "data-slot": "alert-dialog-description",
106
+ className: cn("typo-body-sm text-(--dialog-container-header-description)", className),
107
+ ...props
108
+ }
109
+ );
110
+ }
111
+ function CsAlertDialogAction({
112
+ className,
113
+ ...props
114
+ }) {
115
+ return /* @__PURE__ */ jsx(
116
+ AlertDialogPrimitive.Action,
117
+ {
118
+ className: cn(csButtonVariants(), className),
119
+ ...props
120
+ }
121
+ );
122
+ }
123
+ function CsAlertDialogCancel({
124
+ className,
125
+ ...props
126
+ }) {
127
+ return /* @__PURE__ */ jsx(
128
+ AlertDialogPrimitive.Cancel,
129
+ {
130
+ className: cn(csButtonVariants({ variant: "outline" }), className),
131
+ ...props
132
+ }
133
+ );
134
+ }
135
+ export {
136
+ CsAlertDialog,
137
+ CsAlertDialogAction,
138
+ CsAlertDialogCancel,
139
+ CsAlertDialogContent,
140
+ CsAlertDialogDescription,
141
+ CsAlertDialogFooter,
142
+ CsAlertDialogHeader,
143
+ CsAlertDialogOverlay,
144
+ CsAlertDialogPortal,
145
+ CsAlertDialogTitle,
146
+ CsAlertDialogTrigger
147
+ };
148
+ //# sourceMappingURL=cs-alert-dialog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cs-alert-dialog.js","sources":["../../../src/components/alert-dialog/cs-alert-dialog.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport * as AlertDialogPrimitive from \"@radix-ui/react-alert-dialog\"\n\nimport { cn } from \"../../lib/utils\"\nimport { csButtonVariants } from \"../button\"\n\n/**\n * CsAlertDialog 스타일 시스템 (Design Token Reference)\n *\n * ## Figma Token → 컴포넌트 매핑\n * | Figma 토큰 패턴 | 컴포넌트 |\n * |----------------|---------|\n * | `dialog/common/*` | `CsAlertDialogContent`, `CsAlertDialogOverlay` |\n * | `dialog/container/header-*` | `CsAlertDialogHeader`, `CsAlertDialogTitle`, `CsAlertDialogDescription` |\n * | `dialog/container/footer-*` | `CsAlertDialogFooter` |\n * | `button/solid-primary/*` | `CsAlertDialogAction` (확인 버튼) |\n * | `button/outline/*` | `CsAlertDialogCancel` (취소 버튼) |\n *\n * ## State 매핑\n * | UI 상태 | data 속성 | 적용 |\n * |---------|----------|------|\n * | 열림 | `data-state=\"open\"` | fade-in, zoom-in 애니메이션 |\n * | 닫힘 | `data-state=\"closed\"` | fade-out, zoom-out 애니메이션 |\n *\n * ## CSS Variables\n * ```css\n * --dialog-common-bg | bg-overlay | gap | radius | border | border-width | padding-x | padding-y\n * --dialog-container-header-gap | header-title | header-description | footer-gap\n * ```\n *\n * ## 서브 컴포넌트 구조\n * ```\n * CsAlertDialog (Root)\n * ├── CsAlertDialogTrigger\n * └── CsAlertDialogContent\n * ├── CsAlertDialogHeader\n * │ ├── CsAlertDialogTitle\n * │ └── CsAlertDialogDescription\n * └── CsAlertDialogFooter\n * ├── CsAlertDialogCancel\n * └── CsAlertDialogAction\n * ```\n *\n * ## CsDialog와의 차이점\n * - ESC/오버레이 클릭으로 닫히지 않음 (명시적 버튼 클릭 필요)\n * - Action/Cancel 버튼에 CsButton 스타일 자동 적용\n *\n * @see {@link https://www.radix-ui.com/primitives/docs/components/alert-dialog | Radix AlertDialog}\n * @see CsDialog - 일반 모달 다이얼로그\n */\n\n/**\n * CS Design System 확인 다이얼로그\n *\n * 중요하거나 되돌릴 수 없는 작업 전에 사용자 확인을 받는 모달.\n * 삭제, 저장 취소, 계정 탈퇴 등 신중한 결정이 필요한 경우에 사용되며,\n * ESC나 오버레이 클릭으로 닫히지 않아 명시적인 선택을 유도합니다.\n *\n * ## 사용 시나리오\n * - 삭제 확인: 데이터, 계정, 파일 영구 삭제\n * - 작업 취소 확인: 저장하지 않고 나가기\n * - 중요한 설정 변경: 되돌리기 어려운 설정\n * - 결제/구매 확인: 금전적 영향이 있는 액션\n *\n * ## 유사 컴포넌트와의 차이\n * - **CsDialog**: 일반 모달 (복잡한 폼, 정보 표시) - ESC/오버레이로 닫힘\n * - AlertDialog는 확인/취소 전용, Dialog는 범용 모달\n *\n * @example 삭제 확인\n * ```tsx\n * <CsAlertDialog>\n * <CsAlertDialogTrigger asChild>\n * <CsButton variant=\"outline\">삭제</CsButton>\n * </CsAlertDialogTrigger>\n * <CsAlertDialogContent>\n * <CsAlertDialogHeader>\n * <CsAlertDialogTitle>정말 삭제하시겠습니까?</CsAlertDialogTitle>\n * <CsAlertDialogDescription>이 작업은 되돌릴 수 없습니다.</CsAlertDialogDescription>\n * </CsAlertDialogHeader>\n * <CsAlertDialogFooter>\n * <CsAlertDialogCancel>취소</CsAlertDialogCancel>\n * <CsAlertDialogAction>삭제</CsAlertDialogAction>\n * </CsAlertDialogFooter>\n * </CsAlertDialogContent>\n * </CsAlertDialog>\n * ```\n */\nfunction CsAlertDialog({\n ...props\n}: React.ComponentProps<typeof AlertDialogPrimitive.Root>) {\n return <AlertDialogPrimitive.Root data-slot=\"alert-dialog\" {...props} />\n}\n\n/** 알럿 다이얼로그 트리거 버튼 */\nfunction CsAlertDialogTrigger({\n ...props\n}: React.ComponentProps<typeof AlertDialogPrimitive.Trigger>) {\n return (\n <AlertDialogPrimitive.Trigger data-slot=\"alert-dialog-trigger\" {...props} />\n )\n}\n\n/** 알럿 다이얼로그 포탈 - body에 렌더링 */\nfunction CsAlertDialogPortal({\n ...props\n}: React.ComponentProps<typeof AlertDialogPrimitive.Portal>) {\n return (\n <AlertDialogPrimitive.Portal data-slot=\"alert-dialog-portal\" {...props} />\n )\n}\n\n/** 알럿 다이얼로그 오버레이 (반투명 배경) */\nfunction CsAlertDialogOverlay({\n className,\n ...props\n}: React.ComponentProps<typeof AlertDialogPrimitive.Overlay>) {\n return (\n <AlertDialogPrimitive.Overlay\n data-slot=\"alert-dialog-overlay\"\n className={cn(\n \"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-(--dialog-common-bg-overlay)\",\n className\n )}\n {...props}\n />\n )\n}\n\n/**\n * 알럿 다이얼로그 콘텐츠 영역\n *\n * 화면 중앙에 표시되는 모달 본체.\n * 자동으로 Portal과 Overlay 포함.\n */\nfunction CsAlertDialogContent({\n className,\n ...props\n}: React.ComponentProps<typeof AlertDialogPrimitive.Content>) {\n return (\n <CsAlertDialogPortal>\n <CsAlertDialogOverlay />\n <AlertDialogPrimitive.Content\n data-slot=\"alert-dialog-content\"\n className={cn(\n \"bg-(--dialog-common-bg) data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-(2*var(--dialog-common-padding-x)))] translate-x-[-50%] translate-y-[-50%] gap-(--dialog-common-gap) rounded-(--dialog-common-radius) border-(--dialog-common-border) border-(length:--dialog-common-border-width) px-(--dialog-common-padding-x) py-(--dialog-common-padding-y) duration-200\",\n className\n )}\n {...props}\n />\n </CsAlertDialogPortal>\n )\n}\n\n/**\n * 알럿 다이얼로그 헤더 영역\n *\n * Title과 Description을 담는 컨테이너.\n */\nfunction CsAlertDialogHeader({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"alert-dialog-header\"\n className={cn(\"flex flex-col gap-(--dialog-container-header-gap) max-mobile:text-center text-left\", className)}\n {...props}\n />\n )\n}\n\n/**\n * 알럿 다이얼로그 푸터 영역\n *\n * Action/Cancel 버튼을 담는 컨테이너.\n */\nfunction CsAlertDialogFooter({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"alert-dialog-footer\"\n className={cn(\n \"flex flex-col-reverse gap-(--dialog-container-footer-gap) max-mobile:flex-row max-mobile:justify-end\",\n className\n )}\n {...props}\n />\n )\n}\n\n/**\n * 알럿 다이얼로그 제목\n *\n * `typo-heading-sm` 타이포그래피 적용.\n */\nfunction CsAlertDialogTitle({\n className,\n ...props\n}: React.ComponentProps<typeof AlertDialogPrimitive.Title>) {\n return (\n <AlertDialogPrimitive.Title\n data-slot=\"alert-dialog-title\"\n className={cn(\"typo-heading-sm text-(--dialog-container-header-title)\", className)}\n {...props}\n />\n )\n}\n\n/**\n * 알럿 다이얼로그 설명 텍스트\n *\n * `typo-body-sm` 타이포그래피 적용.\n */\nfunction CsAlertDialogDescription({\n className,\n ...props\n}: React.ComponentProps<typeof AlertDialogPrimitive.Description>) {\n return (\n <AlertDialogPrimitive.Description\n data-slot=\"alert-dialog-description\"\n className={cn(\"typo-body-sm text-(--dialog-container-header-description)\", className)}\n {...props}\n />\n )\n}\n\n/**\n * 확인(액션) 버튼\n *\n * CsButton solid-primary 스타일 자동 적용.\n * 클릭 시 다이얼로그 닫힘.\n */\nfunction CsAlertDialogAction({\n className,\n ...props\n}: React.ComponentProps<typeof AlertDialogPrimitive.Action>) {\n return (\n <AlertDialogPrimitive.Action\n className={cn(csButtonVariants(), className)}\n {...props}\n />\n )\n}\n\n/**\n * 취소 버튼\n *\n * CsButton outline 스타일 자동 적용.\n * 클릭 시 다이얼로그 닫힘.\n */\nfunction CsAlertDialogCancel({\n className,\n ...props\n}: React.ComponentProps<typeof AlertDialogPrimitive.Cancel>) {\n return (\n <AlertDialogPrimitive.Cancel\n className={cn(csButtonVariants({ variant: \"outline\" }), className)}\n {...props}\n />\n )\n}\n\nexport {\n CsAlertDialog,\n CsAlertDialogPortal,\n CsAlertDialogOverlay,\n CsAlertDialogTrigger,\n CsAlertDialogContent,\n CsAlertDialogHeader,\n CsAlertDialogFooter,\n CsAlertDialogTitle,\n CsAlertDialogDescription,\n CsAlertDialogAction,\n CsAlertDialogCancel,\n}\n"],"names":[],"mappings":";;;;;AAyFuB,SAClB,cAAA;AAAA,EACL,GAA2D;AACzD,GAAA;AACF,SAAA,oBAAA,qBAAA,MAAA,EAAA,aAAA,gBAAA,GAAA,MAAA,CAAA;AAGA;AAA8B,SACzB,qBAAA;AAAA,EACL,GAA8D;AAC5D,GAAA;AAGF,SAAA,oBAAA,qBAAA,SAAA,EAAA,aAAA,wBAAA,GAAA,MAAA,CAAA;AAGA;AAA6B,SACxB,oBAAA;AAAA,EACL,GAA6D;AAC3D,GAAA;AAGF,SAAA,oBAAA,qBAAA,QAAA,EAAA,aAAA,uBAAA,GAAA,MAAA,CAAA;AAGA;AAA8B,SAC5B,qBAAA;AAAA,EACA;AAAA,EACF,GAA8D;AAC5D;AACE,SAAsB;AAAA,IAArB,qBAAA;AAAA,IAAA;AAAA,MAEC,aAAW;AAAA,MAAA,WACT;AAAA,QACA;AAAA,QACF;AAAA,MACC;AAAA,MAAG,GAAA;AAAA,IACN;AAAA,EAEJ;AAQA;AAA8B,SAC5B,qBAAA;AAAA,EACA;AAAA,EACF,GAA8D;AAC5D;AAEI,SAAC,qBAAA,qBAAqB,EAAA,UAAA;AAAA,IACtB,oBAAA,sBAAA,CAAA,CAAA;AAAA,IAAC;AAAA,MAAA,qBAAA;AAAA,MAAA;AAAA,QAEC,aAAW;AAAA,QAAA,WACT;AAAA,UACA;AAAA,UACF;AAAA,QACC;AAAA,QAAG,GAAA;AAAA,MAAA;AAAA;EAIZ,EAAA,CAAA;AAOA;AAA6B,SAC3B,oBAAA;AAAA,EACA;AAAA,EACF,GAAgC;AAC9B;AACE,SAAC;AAAA,IAAA;AAAA,IAAA;AAAA,MAEC,aAAW;AAAA,MACV,WAAG,GAAA,sFAAA,SAAA;AAAA,MAAA,GAAA;AAAA,IACN;AAAA,EAEJ;AAOA;AAA6B,SAC3B,oBAAA;AAAA,EACA;AAAA,EACF,GAAgC;AAC9B;AACE,SAAC;AAAA,IAAA;AAAA,IAAA;AAAA,MAEC,aAAW;AAAA,MAAA,WACT;AAAA,QACA;AAAA,QACF;AAAA,MACC;AAAA,MAAG,GAAA;AAAA,IACN;AAAA,EAEJ;AAOA;AAA4B,SAC1B,mBAAA;AAAA,EACA;AAAA,EACF,GAA4D;AAC1D;AACE,SAAsB;AAAA,IAArB,qBAAA;AAAA,IAAA;AAAA,MAEC,aAAW;AAAA,MACV,WAAG,GAAA,0DAAA,SAAA;AAAA,MAAA,GAAA;AAAA,IACN;AAAA,EAEJ;AAOA;AAAkC,SAChC,yBAAA;AAAA,EACA;AAAA,EACF,GAAkE;AAChE;AACE,SAAsB;AAAA,IAArB,qBAAA;AAAA,IAAA;AAAA,MAEC,aAAW;AAAA,MACV,WAAG,GAAA,6DAAA,SAAA;AAAA,MAAA,GAAA;AAAA,IACN;AAAA,EAEJ;AAQA;AAA6B,SAC3B,oBAAA;AAAA,EACA;AAAA,EACF,GAA6D;AAC3D;AACE,SAAsB;AAAA,IAArB,qBAAA;AAAA,IAAA;AAAA,MAEE,WAAG,GAAA,iBAAA,GAAA,SAAA;AAAA,MAAA,GAAA;AAAA,IACN;AAAA,EAEJ;AAQA;AAA6B,SAC3B,oBAAA;AAAA,EACA;AAAA,EACF,GAA6D;AAC3D;AACE,SAAsB;AAAA,IAArB,qBAAA;AAAA,IAAA;AAAA,MAEE,WAAG,GAAA,iBAAA,EAAA,SAAA,UAAA,CAAA,GAAA,SAAA;AAAA,MAAA,GAAA;AAAA,IACN;AAAA,EAEJ;;"}
@@ -0,0 +1,44 @@
1
+ "use client";
2
+ import { jsx } from "react/jsx-runtime";
3
+ import * as AvatarPrimitive from "@radix-ui/react-avatar";
4
+ import * as React from "react";
5
+ import { cn } from "../../lib/utils.js";
6
+ const CsAvatar = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
7
+ AvatarPrimitive.Root,
8
+ {
9
+ ref,
10
+ className: cn(
11
+ "relative flex h-10 w-10 shrink-0 overflow-hidden",
12
+ className
13
+ ),
14
+ ...props
15
+ }
16
+ ));
17
+ CsAvatar.displayName = AvatarPrimitive.Root.displayName;
18
+ const CsAvatarImage = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
19
+ AvatarPrimitive.Image,
20
+ {
21
+ ref,
22
+ className: cn("aspect-square h-full w-full", className),
23
+ ...props
24
+ }
25
+ ));
26
+ CsAvatarImage.displayName = AvatarPrimitive.Image.displayName;
27
+ const CsAvatarFallback = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
28
+ AvatarPrimitive.Fallback,
29
+ {
30
+ ref,
31
+ className: cn(
32
+ "flex h-full w-full items-center justify-center",
33
+ className
34
+ ),
35
+ ...props
36
+ }
37
+ ));
38
+ CsAvatarFallback.displayName = AvatarPrimitive.Fallback.displayName;
39
+ export {
40
+ CsAvatar,
41
+ CsAvatarFallback,
42
+ CsAvatarImage
43
+ };
44
+ //# sourceMappingURL=cs-avatar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cs-avatar.js","sources":["../../../src/components/avatar/cs-avatar.tsx"],"sourcesContent":["'use client'\n\nimport * as AvatarPrimitive from '@radix-ui/react-avatar'\nimport * as React from 'react'\n\nimport { cn } from '../../lib/utils'\n\n/**\n * CsAvatar 스타일 시스템 (Design Token Reference)\n *\n * ## Figma Token → Props 매핑\n * | Figma 토큰 패턴 | 컴포넌트 |\n * |----------------|---------|\n * | - | 현재 하드코딩된 스타일 (h-10 w-10) |\n *\n * ## 서브 컴포넌트 구조\n * ```\n * CsAvatar (Root, 컨테이너)\n * ├── CsAvatarImage (이미지)\n * └── CsAvatarFallback (이미지 로드 실패 시 표시)\n * ```\n *\n * ## 이미지 로드 순서\n * 1. CsAvatarImage 로드 시도\n * 2. 로드 실패 또는 src 없음 → CsAvatarFallback 표시\n *\n * @see {@link https://www.radix-ui.com/primitives/docs/components/avatar | Radix Avatar}\n */\n\n/**\n * CsAvatar Props\n */\ntype CsAvatarProps = React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Root> & {\n /**\n * 추가 CSS 클래스\n * 크기, 모서리 등 커스터마이즈\n * @example \"h-16 w-16 rounded-full\"\n */\n className?: string\n}\n\n/**\n * CsAvatarImage Props\n */\ntype CsAvatarImageProps = React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Image> & {\n /**\n * 이미지 URL\n */\n src?: string\n /**\n * 이미지 대체 텍스트 (접근성 필수)\n */\n alt?: string\n}\n\n/**\n * CsAvatarFallback Props\n */\ntype CsAvatarFallbackProps = React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Fallback> & {\n /**\n * 폴백 로딩 지연 시간 (ms)\n * 이미지 로드 시도 후 표시까지 대기\n */\n delayMs?: number\n}\n\n/**\n * CS Design System 아바타 컴포넌트\n *\n * 사용자 프로필 이미지를 표시하는 컴포넌트. Radix UI 기반.\n * 이미지 로드 실패 시 자동으로 폴백(이니셜)을 표시하여 안정적인 UI를 제공합니다.\n * CsAvatarImage와 CsAvatarFallback을 조합하여 사용합니다.\n *\n * ## 사용 시나리오\n * - 사용자 프로필: 헤더, 사이드바, 설정 페이지의 프로필 이미지\n * - 댓글/리뷰 작성자: 게시글, 댓글 목록의 작성자 아바타\n * - 팀 멤버 목록: 프로젝트 멤버, 조직도, 참여자 목록\n * - 채팅/메시징: 대화 상대, 그룹 멤버 표시\n * - 크기 커스텀: className으로 다양한 크기 조정 (작은 아이콘 ~ 큰 프로필)\n * - 원형 아바타: `rounded-full`로 원형 프로필 이미지\n *\n * @example 기본 조합\n * ```tsx\n * <CsAvatar>\n * <CsAvatarImage src=\"/avatar.png\" alt=\"사용자\" />\n * <CsAvatarFallback>AB</CsAvatarFallback>\n * </CsAvatar>\n * ```\n *\n * @example 크기 커스텀\n * ```tsx\n * <CsAvatar className=\"h-16 w-16\">\n * <CsAvatarImage src=\"/avatar.png\" alt=\"사용자\" />\n * <CsAvatarFallback>AB</CsAvatarFallback>\n * </CsAvatar>\n * ```\n *\n * @example 원형 아바타\n * ```tsx\n * <CsAvatar className=\"rounded-full\">\n * <CsAvatarImage src=\"/avatar.png\" alt=\"사용자\" />\n * <CsAvatarFallback className=\"rounded-full bg-gray-200\">AB</CsAvatarFallback>\n * </CsAvatar>\n * ```\n */\nconst CsAvatar = React.forwardRef<\nReact.ElementRef<typeof AvatarPrimitive.Root>,\nReact.ComponentPropsWithoutRef<typeof AvatarPrimitive.Root>\n>(({ className, ...props }, ref) => (\n <AvatarPrimitive.Root\n ref={ref}\n className={cn(\n 'relative flex h-10 w-10 shrink-0 overflow-hidden',\n className\n )}\n {...props}\n />\n))\nCsAvatar.displayName = AvatarPrimitive.Root.displayName\n\n/**\n * 아바타 이미지\n *\n * img 요소 기반. 로드 실패 시 자동으로 CsAvatarFallback 표시.\n * alt 속성 필수 (접근성).\n */\nconst CsAvatarImage = React.forwardRef<\nReact.ElementRef<typeof AvatarPrimitive.Image>,\nReact.ComponentPropsWithoutRef<typeof AvatarPrimitive.Image>\n>(({ className, ...props }, ref) => (\n <AvatarPrimitive.Image\n ref={ref}\n className={cn('aspect-square h-full w-full', className)}\n {...props}\n />\n))\nCsAvatarImage.displayName = AvatarPrimitive.Image.displayName\n\n/**\n * 아바타 폴백\n *\n * 이미지 로드 실패 또는 src 없을 때 표시.\n * 보통 사용자 이니셜(AB) 또는 기본 아이콘 배치.\n *\n * @example\n * ```tsx\n * <CsAvatarFallback className=\"bg-gray-200 text-gray-600\">\n * AB\n * </CsAvatarFallback>\n * ```\n */\nconst CsAvatarFallback = React.forwardRef<\nReact.ElementRef<typeof AvatarPrimitive.Fallback>,\nReact.ComponentPropsWithoutRef<typeof AvatarPrimitive.Fallback>\n>(({ className, ...props }, ref) => (\n <AvatarPrimitive.Fallback\n ref={ref}\n className={cn(\n 'flex h-full w-full items-center justify-center',\n className\n )}\n {...props}\n />\n))\nCsAvatarFallback.displayName = AvatarPrimitive.Fallback.displayName\n\nexport {\n CsAvatar,\n CsAvatarImage,\n CsAvatarFallback,\n type CsAvatarProps,\n type CsAvatarImageProps,\n type CsAvatarFallbackProps,\n}\n"],"names":[],"mappings":";;;;;AA6GE,MAAC,WAAA,MAAgB,WAAA,CAAA,EAAA,WAAA,GAAA,MAAA,GAAA,QAAA;AAAA,EAAhB,gBAAA;AAAA,EAAA;AAAA,IAEC;AAAA,IAAW,WACT;AAAA,MACA;AAAA,MACF;AAAA,IACC;AAAA,IAAG,GAAA;AAAA,EAEP;AACD,CAAA;AAQA,uBAAsB,gBAGpB,KAAG;AACH,MAAC,gBAAgB,MAAA,WAAA,CAAA,EAAA,WAAA,GAAA,MAAA,GAAA,QAAA;AAAA,EAAhB,gBAAA;AAAA,EAAA;AAAA,IAEC;AAAA,IACC,WAAG,GAAA,+BAAA,SAAA;AAAA,IAAA,GAAA;AAAA,EAEP;AACD,CAAA;AAeA,4BAAyB,gBAGtB,MAAE;AACH,MAAC,mBAAgB,MAAA,WAAA,CAAA,EAAA,WAAA,GAAA,MAAA,GAAA,QAAA;AAAA,EAAhB,gBAAA;AAAA,EAAA;AAAA,IAEC;AAAA,IAAW,WACT;AAAA,MACA;AAAA,MACF;AAAA,IACC;AAAA,IAAG,GAAA;AAAA,EAEP;AACD,CAAA;;"}
@@ -0,0 +1,40 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { Slot } from "@radix-ui/react-slot";
3
+ import { cva } from "class-variance-authority";
4
+ import { cn } from "../../lib/utils.js";
5
+ const csBadgeVariants = cva(
6
+ "inline-flex items-center justify-center rounded-(--badge-common-radius) border-(length:--badge-outline-border-width) px-(--badge-common-padding-x) py-(--badge-common-padding-y) gap-(--badge-common-gap) typo-productive-label-sm w-fit whitespace-nowrap shrink-0 [&>svg]:size-(--badge-common-icon-size) [&>svg]:pointer-events-none focus-visible:ring-0 transition-[color,box-shadow] overflow-hidden",
7
+ {
8
+ variants: {
9
+ variant: {
10
+ solid: "bg-(--badge-solid-bg) text-(--badge-solid-font) [&_svg]:text-(--badge-solid-icon) border-transparent",
11
+ outline: "bg-(--badge-outline-bg) text-(--badge-outline-font) [&_svg]:text-(--badge-outline-icon) border-(--badge-outline-border)",
12
+ gradient: "gradient-primary-vertical text-(--badge-gradient-font) [&_svg]:text-(--badge-gradient-icon) border-transparent"
13
+ }
14
+ },
15
+ defaultVariants: {
16
+ variant: "solid"
17
+ }
18
+ }
19
+ );
20
+ function CsBadge({
21
+ className,
22
+ variant,
23
+ asChild = false,
24
+ ...props
25
+ }) {
26
+ const Comp = asChild ? Slot : "span";
27
+ return /* @__PURE__ */ jsx(
28
+ Comp,
29
+ {
30
+ "data-slot": "badge",
31
+ className: cn(csBadgeVariants({ variant }), className),
32
+ ...props
33
+ }
34
+ );
35
+ }
36
+ export {
37
+ CsBadge,
38
+ csBadgeVariants
39
+ };
40
+ //# sourceMappingURL=cs-badge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cs-badge.js","sources":["../../../src/components/badge/cs-badge.tsx"],"sourcesContent":["import * as React from \"react\"\nimport { Slot } from \"@radix-ui/react-slot\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"../../lib/utils\"\n\n/**\n * CsBadge 스타일 시스템 (Design Token Reference)\n *\n * ## Figma Token → Props 매핑\n * | Figma 토큰 패턴 | Props |\n * |----------------|-------|\n * | `badge/solid/*` | `variant=\"solid\"` |\n * | `badge/outline/*` | `variant=\"outline\"` |\n * | `badge/gradient/*` | `variant=\"gradient\"` |\n *\n * ## 특이사항\n * - Badge는 상태(hover, disabled 등)가 없는 정적 컴포넌트\n * - 크기는 고정 (size prop 없음)\n *\n * ## CSS Variables\n * ```css\n * --badge-common-radius\n * --badge-common-padding-x | padding-y | gap | icon-size\n * --badge-{variant}-bg | font | icon\n * --badge-outline-border | border-width\n * ```\n */\nconst csBadgeVariants = cva(\n \"inline-flex items-center justify-center rounded-(--badge-common-radius) border-(length:--badge-outline-border-width) px-(--badge-common-padding-x) py-(--badge-common-padding-y) gap-(--badge-common-gap) typo-productive-label-sm w-fit whitespace-nowrap shrink-0 [&>svg]:size-(--badge-common-icon-size) [&>svg]:pointer-events-none focus-visible:ring-0 transition-[color,box-shadow] overflow-hidden\",\n {\n variants: {\n variant: {\n solid: \"bg-(--badge-solid-bg) text-(--badge-solid-font) [&_svg]:text-(--badge-solid-icon) border-transparent\",\n outline: \"bg-(--badge-outline-bg) text-(--badge-outline-font) [&_svg]:text-(--badge-outline-icon) border-(--badge-outline-border)\",\n gradient: \"gradient-primary-vertical text-(--badge-gradient-font) [&_svg]:text-(--badge-gradient-icon) border-transparent\",\n },\n },\n defaultVariants: {\n variant: \"solid\",\n },\n }\n)\n\n/**\n * CsBadge Props\n *\n * ## 아이콘 사용\n * children으로 SVG/아이콘 컴포넌트를 넣으면 자동으로 크기와 색상이 적용됨\n * - 크기: `--badge-common-icon-size` 적용\n * - 색상: variant에 따라 `--badge-{variant}-icon` 적용\n *\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/span | MDN span}\n */\ntype CsBadgeProps = React.ComponentProps<\"span\"> &\n VariantProps<typeof csBadgeVariants> & {\n /**\n * 뱃지 스타일\n * - `solid`: 채워진 배경, 기본 스타일\n * - `outline`: 테두리만 있는 스타일\n * - `gradient`: 그라디언트 배경, 강조용\n * @default 'solid'\n */\n variant?: 'solid' | 'outline' | 'gradient'\n\n /**\n * 자식 요소를 뱃지로 렌더링 (Radix Slot)\n * @default false\n */\n asChild?: boolean\n }\n\n/**\n * CS Design System 뱃지 컴포넌트\n *\n * 상태, 카운트, 카테고리를 나타내는 작은 라벨 컴포넌트.\n * 정적 정보 표시에 사용하며, 클릭이나 상호작용은 제공하지 않습니다.\n * 아이콘과 텍스트를 함께 표시할 수 있습니다.\n *\n * ## 사용 시나리오\n * - 상태 표시: `variant=\"solid\"` - 활성/비활성, 승인/대기 등 상태 라벨\n * - 알림 카운트: `variant=\"solid\"` - 읽지 않은 메시지 수, 새 알림 수\n * - 카테고리 태그: `variant=\"outline\"` - 게시글 태그, 상품 카테고리\n * - 강조 라벨: `variant=\"gradient\"` - 신규, 인기, 추천 등\n * - 인라인 정보: 텍스트 내 작은 정보 표시 (버전, 타입 등)\n * - 아이콘 + 텍스트: 상태 아이콘과 함께 표시\n *\n * ## 유사 컴포넌트와의 차이\n * - **CsButton**: 클릭 가능한 액션 버튼\n * - Badge는 정적 라벨, Button은 상호작용 요소\n *\n * @example 기본\n * ```tsx\n * <CsBadge>New</CsBadge>\n * <CsBadge variant=\"outline\">Featured</CsBadge>\n * <CsBadge variant=\"gradient\">Popular</CsBadge>\n * ```\n *\n * @example 아이콘 + 텍스트\n * ```tsx\n * <CsBadge><CheckCircle /> Success</CsBadge>\n * <CsBadge variant=\"outline\"><AlertCircle /> Warning</CsBadge>\n * ```\n */\nfunction CsBadge({\n className,\n variant,\n asChild = false,\n ...props\n}: CsBadgeProps) {\n const Comp = asChild ? Slot : \"span\"\n\n return (\n <Comp\n data-slot=\"badge\"\n className={cn(csBadgeVariants({ variant }), className)}\n {...props}\n />\n )\n}\n\nexport { CsBadge, csBadgeVariants, type CsBadgeProps }\n"],"names":[],"mappings":";;;;AA4BA,MAAM,kBAAkB;AAAA,EACtB;AAAA,EACA;AAAA,IACE,UAAU;AAAA,MACR,SAAS;AAAA,QACP,OAAO;AAAA,QACP,SAAS;AAAA,QACT,UAAU;AAAA,MAAA;AAAA,IACZ;AAAA,IAEF,iBAAiB;AAAA,MACf,SAAS;AAAA,IAAA;AAAA,EACX;AAEJ;AA8DA,SAAS,QAAQ;AAAA,EACf;AAAA,EACA;AAAA,EACA,UAAU;AAAA,EACV,GAAG;AACL,GAAiB;AACf,QAAM,OAAO,UAAU,OAAO;AAE9B,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,gBAAgB,EAAE,QAAA,CAAS,GAAG,SAAS;AAAA,MACpD,GAAG;AAAA,IAAA;AAAA,EAAA;AAGV;"}
@@ -0,0 +1,37 @@
1
+ "use client";
2
+ import { jsx } from "react/jsx-runtime";
3
+ import { cva } from "class-variance-authority";
4
+ import { cn } from "../../lib/utils.js";
5
+ const csBoxVariants = cva(
6
+ "flex flex-col",
7
+ {
8
+ variants: {
9
+ variant: {
10
+ solid: "rounded-(--box-solid-radius) bg-(--box-solid-bg) gap-(--box-solid-gap) max-mobile:gap-(--box-solid-gap-mobile) py-(--box-solid-padding-y) max-mobile:py-(--box-solid-padding-y-mobile) px-(--box-solid-padding-x) max-mobile:px-(--box-solid-padding-x-mobile)",
11
+ outline: "rounded-(--box-outline-radius) bg-(--box-outline-bg) border-(--box-outline-border) border-(length:--box-outline-border-width) gap-(--box-outline-gap) max-mobile:gap-(--box-outline-gap-mobile) py-(--box-outline-padding-y) max-mobile:py-(--box-outline-padding-y-mobile) px-(--box-outline-padding-x) max-mobile:px-(--box-outline-padding-x-mobile)"
12
+ }
13
+ },
14
+ defaultVariants: {
15
+ variant: "solid"
16
+ }
17
+ }
18
+ );
19
+ function CsBox({
20
+ className,
21
+ variant,
22
+ ...props
23
+ }) {
24
+ return /* @__PURE__ */ jsx(
25
+ "div",
26
+ {
27
+ "data-slot": "box",
28
+ className: cn(csBoxVariants({ variant }), className),
29
+ ...props
30
+ }
31
+ );
32
+ }
33
+ export {
34
+ CsBox,
35
+ csBoxVariants
36
+ };
37
+ //# sourceMappingURL=cs-box.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cs-box.js","sources":["../../../src/components/box/cs-box.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"../../lib/utils\"\n\n/**\n * CsBox 스타일 시스템 (Design Token Reference)\n *\n * ## Figma Token → Props 매핑\n * | Figma 토큰 패턴 | Props |\n * |----------------|-------|\n * | `box/solid/*` | `variant=\"solid\"` (기본) |\n * | `box/outline/*` | `variant=\"outline\"` |\n *\n * ## CSS Variables\n * ```css\n * --box-solid-radius | bg | gap | padding-x | padding-y\n * --box-solid-*-mobile (반응형)\n * --box-outline-radius | bg | border | border-width | gap | padding-x | padding-y\n * --box-outline-*-mobile (반응형)\n * ```\n */\nconst csBoxVariants = cva(\n \"flex flex-col\",\n {\n variants: {\n variant: {\n solid: \"rounded-(--box-solid-radius) bg-(--box-solid-bg) gap-(--box-solid-gap) max-mobile:gap-(--box-solid-gap-mobile) py-(--box-solid-padding-y) max-mobile:py-(--box-solid-padding-y-mobile) px-(--box-solid-padding-x) max-mobile:px-(--box-solid-padding-x-mobile)\",\n outline: \"rounded-(--box-outline-radius) bg-(--box-outline-bg) border-(--box-outline-border) border-(length:--box-outline-border-width) gap-(--box-outline-gap) max-mobile:gap-(--box-outline-gap-mobile) py-(--box-outline-padding-y) max-mobile:py-(--box-outline-padding-y-mobile) px-(--box-outline-padding-x) max-mobile:px-(--box-outline-padding-x-mobile)\",\n },\n },\n defaultVariants: {\n variant: \"solid\",\n },\n }\n)\n/**\n * CsBox Props\n */\ntype CsBoxProps = React.ComponentProps<\"div\"> & VariantProps<typeof csBoxVariants> & {\n /**\n * 박스 스타일\n * - `solid`: 채워진 배경 (기본) - 섹션 그룹핑, 카드 내부 영역\n * - `outline`: 테두리 스타일 - 구분이 필요한 영역, 폼 그룹\n * @default 'solid'\n */\n variant?: 'solid' | 'outline'\n}\n\n/**\n * CS Design System 박스 컴포넌트\n *\n * 상호작용 없는 순수한 레이아웃 컨테이너로, 콘텐츠를 시각적으로 그룹화할 때 사용합니다.\n * hover나 click 같은 상호작용이 필요 없는 정적인 영역 구분에 적합하며,\n * 반응형 padding/gap이 자동 적용됩니다 (mobile breakpoint).\n *\n * ## 사용 시나리오\n * - 섹션 구분: 페이지 내 영역을 시각적으로 나눔 (상호작용 없음)\n * - 정보 그룹: 관련 데이터를 묶어서 표시 (클릭 불필요)\n * - 레이아웃 래퍼: 내부 요소들의 배치와 간격 조정\n * - 폼 그룹: 여러 입력 필드를 하나의 섹션으로 묶음\n *\n * ## 유사 컴포넌트와의 차이\n * - **CsCard**: 상호작용 있는 컨테이너 (hover, click 가능) - 클릭 가능한 카드\n * - Box는 정적 레이아웃만, Card는 hover/click 상호작용\n *\n * @example 기본 (solid)\n * ```tsx\n * <CsBox>콘텐츠</CsBox>\n * ```\n *\n * @example outline 스타일\n * ```tsx\n * <CsBox variant=\"outline\">테두리 있는 박스</CsBox>\n * ```\n *\n * @example 중첩 사용\n * ```tsx\n * <CsBox>\n * <CsBox variant=\"outline\">내부 섹션</CsBox>\n * <CsBox variant=\"outline\">내부 섹션</CsBox>\n * </CsBox>\n * ```\n */\nfunction CsBox({\n className,\n variant,\n ...props\n}: CsBoxProps) {\n return (\n <div\n data-slot=\"box\"\n className={cn(csBoxVariants({ variant }), className)}\n {...props}\n />\n )\n}\n\nexport { CsBox, csBoxVariants, type CsBoxProps }\n"],"names":[],"mappings":";;;;AAwBsB,MACpB,gBAAA;AAAA,EACA;AAAA,EAAA;AAAA,IACY,UACR;AAAA,MAAS,SACA;AAAA,QACP,OAAA;AAAA,QAAS,SAAA;AAAA,MAEb;AAAA,IACA;AAAA,IAAiB,iBACN;AAAA,MAAA,SAAA;AAAA,IACX;AAAA,EAEJ;AAiDA;AAAe,SACb,MAAA;AAAA,EACA;AAAA,EACA;AAAA,EACF,GAAe;AACb;AACE,SAAC;AAAA,IAAA;AAAA,IAAA;AAAA,MAEC,aAAW;AAAA,MACV,WAAG,GAAA,cAAA,EAAA,QAAA,CAAA,GAAA,SAAA;AAAA,MAAA,GAAA;AAAA,IACN;AAAA,EAEJ;;"}
@@ -0,0 +1,91 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { Slot } from "@radix-ui/react-slot";
3
+ import { cva } from "class-variance-authority";
4
+ import { cn } from "../../lib/utils.js";
5
+ const csButtonVariants = cva(
6
+ "typo-body-sm-bold inline-flex items-center justify-center whitespace-nowrap transition-all cursor-pointer disabled:pointer-events-none disabled:opacity-(--button-common-opacity) shrink-0 [&_svg]:shrink-0 ring-0 focus:ring-0 focus-visible:ring-0 outline-none",
7
+ {
8
+ variants: {
9
+ variant: {
10
+ "solid-primary": [
11
+ "bg-(--button-solid-primary-default-bg) text-(--button-solid-primary-default-font) [&_svg]:text-(--button-solid-primary-default-icon)",
12
+ "hover:bg-(--button-solid-primary-hover-bg) hover:text-(--button-solid-primary-hover-font) hover:[&_svg]:text-(--button-solid-primary-hover-icon)",
13
+ "disabled:bg-(--button-solid-primary-disabled-bg) disabled:text-(--button-solid-primary-disabled-font) disabled:[&_svg]:text-(--button-solid-primary-disabled-icon)"
14
+ ].join(" "),
15
+ "solid-secondary": [
16
+ "bg-(--button-solid-secondary-default-bg) text-(--button-solid-secondary-default-font) [&_svg]:text-(--button-solid-secondary-default-icon)",
17
+ "hover:bg-(--button-solid-secondary-hover-bg) hover:text-(--button-solid-secondary-hover-font) hover:[&_svg]:text-(--button-solid-secondary-hover-icon)",
18
+ "disabled:bg-(--button-solid-secondary-disabled-bg) disabled:text-(--button-solid-secondary-disabled-font) disabled:[&_svg]:text-(--button-solid-secondary-disabled-icon)"
19
+ ].join(" "),
20
+ outline: [
21
+ "bg-(--button-outline-default-bg) border-(length:--button-outline-border-width) border-(--button-outline-default-border) text-(--button-outline-default-font) [&_svg]:text-(--button-outline-default-icon)",
22
+ "hover:bg-(--button-outline-hover-bg) hover:border-(--button-outline-hover-border) hover:text-(--button-outline-hover-font) hover:[&_svg]:text-(--button-outline-hover-icon)",
23
+ "disabled:bg-(--button-outline-disabled-bg) disabled:border-(--button-outline-disabled-border) disabled:text-(--button-outline-disabled-font) disabled:[&_svg]:text-(--button-outline-disabled-icon)"
24
+ ].join(" "),
25
+ ghost: [
26
+ "text-(--button-ghost-default-font) [&_svg]:text-(--button-ghost-default-icon)",
27
+ "hover:bg-(--button-ghost-hover-bg) hover:text-(--button-ghost-hover-font) hover:[&_svg]:text-(--button-ghost-hover-icon)",
28
+ "disabled:text-(--button-ghost-disabled-font) disabled:[&_svg]:text-(--button-ghost-disabled-icon)"
29
+ ].join(" "),
30
+ link: [
31
+ "p-0! text-(--button-link-default-font) [&_svg]:text-(--button-link-default-icon)",
32
+ "hover:underline hover:text-(--button-link-hover-font) hover:[&_svg]:text-(--button-link-hover-icon)",
33
+ "disabled:text-(--button-link-disabled-font) disabled:[&_svg]:text-(--button-link-disabled-icon) typo-metric-sm"
34
+ // 'hover:bg-(--button-link-hover-bg) '
35
+ ].join(" "),
36
+ gradient: [
37
+ "gradient-primary-vertical text-(--button-gradient-default-font) [&_svg]:text-(--button-gradient-default-icon)",
38
+ "hover:gradient-primary-hover-vertical hover:text-(--button-gradient-hover-font) hover:[&_svg]:text-(--button-gradient-hover-icon)",
39
+ "disabled:gradient-primary-vertical disabled:text-(--button-gradient-disabled-font) disabled:[&_svg]:text-(--button-gradient-disabled-icon)"
40
+ ].join(" ")
41
+ },
42
+ size: {
43
+ default: [
44
+ "px-(--button-common-padding-x) py-(--button-common-padding-y) rounded-(--button-common-radius)",
45
+ "gap-(--button-common-gap) [&_svg]:size-(--button-common-icon-size)"
46
+ ].join(" "),
47
+ small: [
48
+ "h-(--button-size-small-height) typo-body-xs",
49
+ "px-(--button-size-small-padding-x) gap-(--button-size-small-gap) rounded-(--button-size-small-radius)",
50
+ "[&_svg]:size-(--button-size-small-icon-size)"
51
+ ].join(" "),
52
+ medium: [
53
+ "h-(--button-size-medium-height)",
54
+ "px-(--button-size-medium-padding-x) gap-(--button-size-medium-gap) rounded-(--button-size-medium-radius)",
55
+ "[&_svg]:size-(--button-size-medium-icon-size)"
56
+ ].join(" "),
57
+ large: [
58
+ "h-(--button-size-large-height)",
59
+ "px-(--button-size-large-padding-x) gap-(--button-size-large-gap) rounded-(--button-size-large-radius)",
60
+ "[&_svg]:size-(--button-size-large-icon-size)"
61
+ ].join(" ")
62
+ }
63
+ },
64
+ defaultVariants: {
65
+ variant: "solid-primary",
66
+ size: "default"
67
+ }
68
+ }
69
+ );
70
+ function CsButton({
71
+ className,
72
+ variant,
73
+ size,
74
+ asChild = false,
75
+ ...props
76
+ }) {
77
+ const Comp = asChild ? Slot : "button";
78
+ return /* @__PURE__ */ jsx(
79
+ Comp,
80
+ {
81
+ "data-slot": "button",
82
+ className: cn(csButtonVariants({ variant, size, className })),
83
+ ...props
84
+ }
85
+ );
86
+ }
87
+ export {
88
+ CsButton,
89
+ csButtonVariants
90
+ };
91
+ //# sourceMappingURL=cs-button.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cs-button.js","sources":["../../../src/components/button/cs-button.tsx"],"sourcesContent":["import * as React from \"react\"\nimport { Slot } from \"@radix-ui/react-slot\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"../../lib/utils\"\n\n/**\n * CsButton 스타일 시스템 (Design Token Reference)\n *\n * ## Figma Token → Props 매핑\n * | Figma 토큰 패턴 | Props |\n * |----------------|-------|\n * | `button/solid-primary/*` | `variant=\"solid-primary\"` |\n * | `button/solid-secondary/*` | `variant=\"solid-secondary\"` |\n * | `button/outline/*` | `variant=\"outline\"` |\n * | `button/ghost/*` | `variant=\"ghost\"` |\n * | `button/link/*` | `variant=\"link\"` |\n * | `button/gradient/*` | `variant=\"gradient\"` |\n * | `button/size/small/*` | `size=\"small\"` |\n * | `button/size/medium/*` | `size=\"medium\"` |\n * | `button/size/large/*` | `size=\"large\"` |\n *\n * ## State 매핑\n * | UI 상태 | Token state |\n * |---------|-------------|\n * | 기본 | `default` |\n * | hover: | `hover` |\n * | disabled: | `disabled` |\n *\n * ## CSS Variables\n * ```css\n * --button-common-radius\n * --button-common-opacity\n * --button-size-{size}-height | icon-size | padding-x | gap | radius\n * --button-{variant}-{state}-bg | font | icon\n * --button-outline-border-width\n * --button-outline-{state}-border\n * ```\n */\nconst csButtonVariants = cva(\n \"typo-body-sm-bold inline-flex items-center justify-center whitespace-nowrap \" + \n \"transition-all cursor-pointer disabled:pointer-events-none disabled:opacity-(--button-common-opacity) \" +\n \"shrink-0 [&_svg]:shrink-0 ring-0 focus:ring-0 focus-visible:ring-0 outline-none\",\n {\n variants: {\n variant: {\n 'solid-primary': [\n 'bg-(--button-solid-primary-default-bg) text-(--button-solid-primary-default-font) [&_svg]:text-(--button-solid-primary-default-icon)',\n 'hover:bg-(--button-solid-primary-hover-bg) hover:text-(--button-solid-primary-hover-font) hover:[&_svg]:text-(--button-solid-primary-hover-icon)',\n 'disabled:bg-(--button-solid-primary-disabled-bg) disabled:text-(--button-solid-primary-disabled-font) disabled:[&_svg]:text-(--button-solid-primary-disabled-icon)',\n ].join(' '),\n 'solid-secondary': [\n 'bg-(--button-solid-secondary-default-bg) text-(--button-solid-secondary-default-font) [&_svg]:text-(--button-solid-secondary-default-icon)',\n 'hover:bg-(--button-solid-secondary-hover-bg) hover:text-(--button-solid-secondary-hover-font) hover:[&_svg]:text-(--button-solid-secondary-hover-icon)',\n 'disabled:bg-(--button-solid-secondary-disabled-bg) disabled:text-(--button-solid-secondary-disabled-font) disabled:[&_svg]:text-(--button-solid-secondary-disabled-icon)',\n ].join(' '),\n outline: [\n 'bg-(--button-outline-default-bg) border-(length:--button-outline-border-width) border-(--button-outline-default-border) text-(--button-outline-default-font) [&_svg]:text-(--button-outline-default-icon)',\n 'hover:bg-(--button-outline-hover-bg) hover:border-(--button-outline-hover-border) hover:text-(--button-outline-hover-font) hover:[&_svg]:text-(--button-outline-hover-icon)',\n 'disabled:bg-(--button-outline-disabled-bg) disabled:border-(--button-outline-disabled-border) disabled:text-(--button-outline-disabled-font) disabled:[&_svg]:text-(--button-outline-disabled-icon)',\n ].join(' '),\n ghost: [\n 'text-(--button-ghost-default-font) [&_svg]:text-(--button-ghost-default-icon)',\n 'hover:bg-(--button-ghost-hover-bg) hover:text-(--button-ghost-hover-font) hover:[&_svg]:text-(--button-ghost-hover-icon)',\n 'disabled:text-(--button-ghost-disabled-font) disabled:[&_svg]:text-(--button-ghost-disabled-icon)',\n ].join(' '),\n link: [\n 'p-0! text-(--button-link-default-font) [&_svg]:text-(--button-link-default-icon)',\n 'hover:underline hover:text-(--button-link-hover-font) hover:[&_svg]:text-(--button-link-hover-icon)',\n 'disabled:text-(--button-link-disabled-font) disabled:[&_svg]:text-(--button-link-disabled-icon) typo-metric-sm',\n // 'hover:bg-(--button-link-hover-bg) '\n ].join(' '),\n gradient: [\n 'gradient-primary-vertical text-(--button-gradient-default-font) [&_svg]:text-(--button-gradient-default-icon)',\n 'hover:gradient-primary-hover-vertical hover:text-(--button-gradient-hover-font) hover:[&_svg]:text-(--button-gradient-hover-icon)',\n 'disabled:gradient-primary-vertical disabled:text-(--button-gradient-disabled-font) disabled:[&_svg]:text-(--button-gradient-disabled-icon)',\n ].join(' '),\n },\n size: {\n default: [\n \"px-(--button-common-padding-x) py-(--button-common-padding-y) rounded-(--button-common-radius)\",\n \"gap-(--button-common-gap) [&_svg]:size-(--button-common-icon-size)\"\n ].join(' '),\n small: [\n \"h-(--button-size-small-height) typo-body-xs\",\n \"px-(--button-size-small-padding-x) gap-(--button-size-small-gap) rounded-(--button-size-small-radius)\",\n \"[&_svg]:size-(--button-size-small-icon-size)\",\n ].join(' '),\n medium: [\n \"h-(--button-size-medium-height)\",\n \"px-(--button-size-medium-padding-x) gap-(--button-size-medium-gap) rounded-(--button-size-medium-radius)\",\n \"[&_svg]:size-(--button-size-medium-icon-size)\",\n ].join(' '),\n large: [\n \"h-(--button-size-large-height)\",\n \"px-(--button-size-large-padding-x) gap-(--button-size-large-gap) rounded-(--button-size-large-radius)\",\n \"[&_svg]:size-(--button-size-large-icon-size)\",\n ].join(' ')\n },\n },\n defaultVariants: {\n variant: \"solid-primary\",\n size: \"default\",\n },\n }\n)\n\n/**\n * CsButton Props\n *\n * ## 아이콘 사용\n * children으로 SVG/아이콘 컴포넌트를 넣으면 자동으로 크기와 색상이 적용됨\n * - 크기: size에 따라 `--button-size-{size}-icon-size` 적용\n * - 색상: variant/state에 따라 `--button-{variant}-{state}-icon` 적용\n *\n * ## 기타 Props\n * onClick, disabled, type, children, aria-* 등 HTML button 속성 모두 사용 가능\n *\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button | MDN button}\n */\ntype CsButtonProps = React.ComponentProps<\"button\"> &\n VariantProps<typeof csButtonVariants> & {\n /**\n * 버튼 스타일\n * - `solid-primary`: 주요 CTA (페이지당 1-2개 권장)\n * - `solid-secondary`: 보조 액션\n * - `outline`: 취소, 뒤로가기 등\n * - `ghost`: 툴바, 내비게이션, 아이콘 전용 버튼\n * - `link`: 인라인 텍스트 링크\n * - `gradient`: 프로모션, 특별 강조\n * @default 'solid-primary'\n */\n variant?: 'solid-primary' | 'solid-secondary' | 'outline' | 'ghost' | 'link' | 'gradient'\n\n /**\n * 버튼 크기\n * - `small` (28px): 테이블 내부, 좁은 공간\n * - `medium` (36px): 일반 폼, 카드 내부\n * - `large` (44px): 히어로, 주요 CTA, 모바일\n * @default 'medium'\n */\n size?: 'small' | 'medium' | 'large' | 'default'\n\n /**\n * 자식 요소를 버튼으로 렌더링 (Radix Slot)\n * Next.js Link 등과 조합 시 사용\n * @default false\n */\n asChild?: boolean\n }\n\n/**\n * CS Design System 버튼 컴포넌트\n *\n * 사용자 액션을 트리거하는 인터랙티브 요소. 폼 제출, 다이얼로그 열기,\n * 페이지 이동, 데이터 저장/삭제 등 모든 사용자 상호작용에 사용됩니다.\n *\n * ## 사용 시나리오\n * - 주요 액션 (페이지당 1-2개): `variant=\"solid-primary\"` + `size=\"large\"`\n * - 폼 제출 버튼: `variant=\"solid-primary\"` + `type=\"submit\"`\n * - 취소/뒤로가기: `variant=\"outline\"`\n * - 보조 액션: `variant=\"solid-secondary\"`\n * - 툴바 아이콘 버튼: `variant=\"ghost\"` + `size=\"small\"` (아이콘만)\n * - 프로모션/특별 강조: `variant=\"gradient\"`\n * - 인라인 텍스트 링크: `variant=\"link\"`\n *\n * ## 유사 컴포넌트와의 차이\n * - **CsToggle**: 온/오프 상태를 유지하는 버튼 (필터 토글, 설정 스위치)\n * - **CsDropdownMenu**: 여러 옵션 중 하나를 선택하는 드롭다운\n *\n * @example 기본\n * ```tsx\n * <CsButton>저장</CsButton>\n * <CsButton variant=\"outline\">취소</CsButton>\n * ```\n *\n * @example 아이콘 + 텍스트\n * ```tsx\n * <CsButton><Plus /> 추가</CsButton>\n * <CsButton variant=\"ghost\"><Settings /> 설정</CsButton>\n * ```\n *\n * @example 아이콘 전용\n * ```tsx\n * <CsButton variant=\"ghost\" size=\"small\"><Menu /></CsButton>\n * <CsButton variant=\"outline\"><Trash2 /></CsButton>\n * ```\n *\n * @example Next.js Link와 조합\n * ```tsx\n * <CsButton asChild variant=\"link\">\n * <Link href=\"/settings\">설정으로 이동</Link>\n * </CsButton>\n * ```\n */\nfunction CsButton({\n className,\n variant,\n size,\n asChild = false,\n ...props\n}: CsButtonProps) {\n const Comp = asChild ? Slot : \"button\"\n\n return (\n <Comp\n data-slot=\"button\"\n className={cn(csButtonVariants({ variant, size, className }))}\n {...props}\n />\n )\n}\n\nexport { CsButton, csButtonVariants, type CsButtonProps }\n"],"names":[],"mappings":";;;;AAuCA,MAAM,mBAAmB;AAAA,EACvB;AAAA,EAGA;AAAA,IACE,UAAU;AAAA,MACR,SAAS;AAAA,QACP,iBAAiB;AAAA,UACf;AAAA,UACA;AAAA,UACA;AAAA,QAAA,EACA,KAAK,GAAG;AAAA,QACV,mBAAmB;AAAA,UACjB;AAAA,UACA;AAAA,UACA;AAAA,QAAA,EACA,KAAK,GAAG;AAAA,QACV,SAAS;AAAA,UACP;AAAA,UACA;AAAA,UACA;AAAA,QAAA,EACA,KAAK,GAAG;AAAA,QACV,OAAO;AAAA,UACL;AAAA,UACA;AAAA,UACA;AAAA,QAAA,EACA,KAAK,GAAG;AAAA,QACV,MAAM;AAAA,UACJ;AAAA,UACA;AAAA,UACA;AAAA;AAAA,QAAA,EAEA,KAAK,GAAG;AAAA,QACV,UAAU;AAAA,UACR;AAAA,UACA;AAAA,UACA;AAAA,QAAA,EACA,KAAK,GAAG;AAAA,MAAA;AAAA,MAEZ,MAAM;AAAA,QACJ,SAAS;AAAA,UACP;AAAA,UACA;AAAA,QAAA,EACA,KAAK,GAAG;AAAA,QACV,OAAO;AAAA,UACL;AAAA,UACA;AAAA,UACA;AAAA,QAAA,EACA,KAAK,GAAG;AAAA,QACV,QAAQ;AAAA,UACN;AAAA,UACA;AAAA,UACA;AAAA,QAAA,EACA,KAAK,GAAG;AAAA,QACV,OAAO;AAAA,UACL;AAAA,UACA;AAAA,UACA;AAAA,QAAA,EACA,KAAK,GAAG;AAAA,MAAA;AAAA,IACZ;AAAA,IAEF,iBAAiB;AAAA,MACf,SAAS;AAAA,MACT,MAAM;AAAA,IAAA;AAAA,EACR;AAEJ;AA0FA,SAAS,SAAS;AAAA,EAChB;AAAA,EACA;AAAA,EACA;AAAA,EACA,UAAU;AAAA,EACV,GAAG;AACL,GAAkB;AAChB,QAAM,OAAO,UAAU,OAAO;AAE9B,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,iBAAiB,EAAE,SAAS,MAAM,UAAA,CAAW,CAAC;AAAA,MAC3D,GAAG;AAAA,IAAA;AAAA,EAAA;AAGV;"}