@j-solution/components 1.6.1 → 1.8.0

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 (272) hide show
  1. package/README.md +8 -6
  2. package/assets/jwms-portal-frontend-BtHTA-UF.css +1 -0
  3. package/assets/styles/global-utilities.css +34 -0
  4. package/assets/styles/j-components.css +1 -1
  5. package/assets/styles/themes.css +128 -21
  6. package/components/atoms/JAvatar.vue.cjs +1 -1
  7. package/components/atoms/JAvatar.vue.cjs.map +1 -1
  8. package/components/atoms/JAvatar.vue.js +10 -7
  9. package/components/atoms/JAvatar.vue.js.map +1 -1
  10. package/components/atoms/JBadge.vue.cjs +1 -1
  11. package/components/atoms/JBadge.vue.cjs.map +1 -1
  12. package/components/atoms/JBadge.vue.js +7 -6
  13. package/components/atoms/JBadge.vue.js.map +1 -1
  14. package/components/atoms/JButton.vue.cjs +6 -1
  15. package/components/atoms/JButton.vue.cjs.map +1 -1
  16. package/components/atoms/JButton.vue.js +10 -85
  17. package/components/atoms/JButton.vue.js.map +1 -1
  18. package/components/atoms/JButton.vue2.cjs +1 -1
  19. package/components/atoms/JButton.vue2.cjs.map +1 -1
  20. package/components/atoms/JButton.vue2.js +85 -2
  21. package/components/atoms/JButton.vue2.js.map +1 -1
  22. package/components/atoms/JDatepicker.vue.cjs +1 -1
  23. package/components/atoms/JDatepicker.vue.cjs.map +1 -1
  24. package/components/atoms/JDatepicker.vue.js +10 -10
  25. package/components/atoms/JDatepicker.vue.js.map +1 -1
  26. package/components/atoms/JEditor.vue.cjs +1 -1
  27. package/components/atoms/JEditor.vue.js +1 -1
  28. package/components/atoms/JEditor.vue2.cjs +1 -1
  29. package/components/atoms/JEditor.vue2.cjs.map +1 -1
  30. package/components/atoms/JEditor.vue2.js +31 -17
  31. package/components/atoms/JEditor.vue2.js.map +1 -1
  32. package/components/atoms/JGrid.vue.cjs +1 -1
  33. package/components/atoms/JGrid.vue.js +2 -2
  34. package/components/atoms/JGrid.vue2.cjs +1 -1
  35. package/components/atoms/JGrid.vue2.cjs.map +1 -1
  36. package/components/atoms/JGrid.vue2.js +59 -43
  37. package/components/atoms/JGrid.vue2.js.map +1 -1
  38. package/components/atoms/JIcon.vue.cjs +1 -1
  39. package/components/atoms/JIcon.vue.cjs.map +1 -1
  40. package/components/atoms/JIcon.vue.js +14 -13
  41. package/components/atoms/JIcon.vue.js.map +1 -1
  42. package/components/atoms/JKbd.vue.cjs +1 -1
  43. package/components/atoms/JKbd.vue.cjs.map +1 -1
  44. package/components/atoms/JKbd.vue.js +13 -10
  45. package/components/atoms/JKbd.vue.js.map +1 -1
  46. package/components/atoms/JLabel.vue.cjs +1 -1
  47. package/components/atoms/JLabel.vue.cjs.map +1 -1
  48. package/components/atoms/JLabel.vue.js +26 -22
  49. package/components/atoms/JLabel.vue.js.map +1 -1
  50. package/components/atoms/JLink.vue.cjs +1 -1
  51. package/components/atoms/JLink.vue.cjs.map +1 -1
  52. package/components/atoms/JLink.vue.js +5 -5
  53. package/components/atoms/JLink.vue.js.map +1 -1
  54. package/components/atoms/JPreview.vue.cjs +1 -1
  55. package/components/atoms/JPreview.vue.js +2 -2
  56. package/components/atoms/JPreview.vue2.cjs +1 -1
  57. package/components/atoms/JPreview.vue2.cjs.map +1 -1
  58. package/components/atoms/JPreview.vue2.js +33 -20
  59. package/components/atoms/JPreview.vue2.js.map +1 -1
  60. package/components/atoms/JProgress.vue.cjs +1 -1
  61. package/components/atoms/JProgress.vue.cjs.map +1 -1
  62. package/components/atoms/JProgress.vue.js +15 -9
  63. package/components/atoms/JProgress.vue.js.map +1 -1
  64. package/components/atoms/JRadio.vue.cjs +1 -1
  65. package/components/atoms/JRadio.vue.cjs.map +1 -1
  66. package/components/atoms/JRadio.vue.js +1 -1
  67. package/components/atoms/JRadio.vue.js.map +1 -1
  68. package/components/atoms/JSearchCombo.vue.cjs +1 -1
  69. package/components/atoms/JSearchCombo.vue.cjs.map +1 -1
  70. package/components/atoms/JSearchCombo.vue.js +38 -37
  71. package/components/atoms/JSearchCombo.vue.js.map +1 -1
  72. package/components/atoms/JSectionTitle.vue.cjs +7 -0
  73. package/components/atoms/JSectionTitle.vue.cjs.map +1 -0
  74. package/components/atoms/JSectionTitle.vue.js +13 -0
  75. package/components/atoms/JSectionTitle.vue.js.map +1 -0
  76. package/components/atoms/JSectionTitle.vue2.cjs +2 -0
  77. package/components/atoms/JSectionTitle.vue2.cjs.map +1 -0
  78. package/components/atoms/JSectionTitle.vue2.js +67 -0
  79. package/components/atoms/JSectionTitle.vue2.js.map +1 -0
  80. package/components/atoms/JSpinner.vue.cjs +1 -1
  81. package/components/atoms/JSpinner.vue.cjs.map +1 -1
  82. package/components/atoms/JSpinner.vue.js +8 -7
  83. package/components/atoms/JSpinner.vue.js.map +1 -1
  84. package/components/atoms/JSplitter.vue.cjs +6 -1
  85. package/components/atoms/JSplitter.vue.cjs.map +1 -1
  86. package/components/atoms/JSplitter.vue.js +10 -54
  87. package/components/atoms/JSplitter.vue.js.map +1 -1
  88. package/components/atoms/JSplitter.vue2.cjs +1 -1
  89. package/components/atoms/JSplitter.vue2.cjs.map +1 -1
  90. package/components/atoms/JSplitter.vue2.js +59 -2
  91. package/components/atoms/JSplitter.vue2.js.map +1 -1
  92. package/components/atoms/JTooltip.vue.cjs +1 -1
  93. package/components/atoms/JTooltip.vue.cjs.map +1 -1
  94. package/components/atoms/JTooltip.vue.js +18 -15
  95. package/components/atoms/JTooltip.vue.js.map +1 -1
  96. package/components/examples/ExampleCrudPage.vue.cjs +1 -1
  97. package/components/examples/ExampleCrudPage.vue.cjs.map +1 -1
  98. package/components/examples/ExampleCrudPage.vue.js +265 -191
  99. package/components/examples/ExampleCrudPage.vue.js.map +1 -1
  100. package/components/examples/ExampleTabMappingPage.vue.cjs +1 -1
  101. package/components/examples/ExampleTabMappingPage.vue.cjs.map +1 -1
  102. package/components/examples/ExampleTabMappingPage.vue.js +349 -333
  103. package/components/examples/ExampleTabMappingPage.vue.js.map +1 -1
  104. package/components/molecules/JAlert.vue.cjs +1 -1
  105. package/components/molecules/JAlert.vue.cjs.map +1 -1
  106. package/components/molecules/JAlert.vue.js +18 -16
  107. package/components/molecules/JAlert.vue.js.map +1 -1
  108. package/components/molecules/JBreadcrumb.vue.cjs +1 -1
  109. package/components/molecules/JBreadcrumb.vue.cjs.map +1 -1
  110. package/components/molecules/JBreadcrumb.vue.js +3 -3
  111. package/components/molecules/JBreadcrumb.vue.js.map +1 -1
  112. package/components/molecules/JCard.vue.cjs +1 -1
  113. package/components/molecules/JCard.vue.cjs.map +1 -1
  114. package/components/molecules/JCard.vue.js +55 -39
  115. package/components/molecules/JCard.vue.js.map +1 -1
  116. package/components/molecules/JEmptyState.vue.cjs +7 -0
  117. package/components/molecules/JEmptyState.vue.cjs.map +1 -0
  118. package/components/molecules/JEmptyState.vue.js +13 -0
  119. package/components/molecules/JEmptyState.vue.js.map +1 -0
  120. package/components/molecules/JEmptyState.vue2.cjs +2 -0
  121. package/components/molecules/JEmptyState.vue2.cjs.map +1 -0
  122. package/components/molecules/JEmptyState.vue2.js +127 -0
  123. package/components/molecules/JEmptyState.vue2.js.map +1 -0
  124. package/components/molecules/JFormField.vue.cjs +6 -1
  125. package/components/molecules/JFormField.vue.cjs.map +1 -1
  126. package/components/molecules/JFormField.vue.js +10 -262
  127. package/components/molecules/JFormField.vue.js.map +1 -1
  128. package/components/molecules/JFormField.vue2.cjs +2 -0
  129. package/components/molecules/JFormField.vue2.cjs.map +1 -0
  130. package/components/molecules/JFormField.vue2.js +271 -0
  131. package/components/molecules/JFormField.vue2.js.map +1 -0
  132. package/components/molecules/JTabs.vue.cjs +1 -1
  133. package/components/molecules/JTabs.vue.js +1 -1
  134. package/components/molecules/JTabs.vue2.cjs +1 -1
  135. package/components/molecules/JTabs.vue2.cjs.map +1 -1
  136. package/components/molecules/JTabs.vue2.js +50 -56
  137. package/components/molecules/JTabs.vue2.js.map +1 -1
  138. package/components/molecules/JTitlebar.vue.cjs +1 -1
  139. package/components/molecules/JTitlebar.vue.cjs.map +1 -1
  140. package/components/molecules/JTitlebar.vue.js +49 -47
  141. package/components/molecules/JTitlebar.vue.js.map +1 -1
  142. package/components/organisms/JDynamicForm.vue2.cjs +1 -1
  143. package/components/organisms/JDynamicForm.vue2.cjs.map +1 -1
  144. package/components/organisms/JDynamicForm.vue2.js +35 -32
  145. package/components/organisms/JDynamicForm.vue2.js.map +1 -1
  146. package/components/organisms/JDynamicTabs.vue.cjs +1 -1
  147. package/components/organisms/JDynamicTabs.vue.cjs.map +1 -1
  148. package/components/organisms/JDynamicTabs.vue.js +47 -52
  149. package/components/organisms/JDynamicTabs.vue.js.map +1 -1
  150. package/components/organisms/JFilterBar.vue.cjs +6 -1
  151. package/components/organisms/JFilterBar.vue.cjs.map +1 -1
  152. package/components/organisms/JFilterBar.vue.js +10 -137
  153. package/components/organisms/JFilterBar.vue.js.map +1 -1
  154. package/components/organisms/JFilterBar.vue2.cjs +1 -1
  155. package/components/organisms/JFilterBar.vue2.cjs.map +1 -1
  156. package/components/organisms/JFilterBar.vue2.js +141 -2
  157. package/components/organisms/JFilterBar.vue2.js.map +1 -1
  158. package/components/organisms/JFormModal.vue.cjs +1 -1
  159. package/components/organisms/JFormModal.vue.cjs.map +1 -1
  160. package/components/organisms/JFormModal.vue.js +54 -49
  161. package/components/organisms/JFormModal.vue.js.map +1 -1
  162. package/components/organisms/JHeader.vue.cjs +1 -1
  163. package/components/organisms/JHeader.vue.cjs.map +1 -1
  164. package/components/organisms/JHeader.vue.js +211 -208
  165. package/components/organisms/JHeader.vue.js.map +1 -1
  166. package/components/organisms/JModal.vue.cjs +1 -1
  167. package/components/organisms/JModal.vue.cjs.map +1 -1
  168. package/components/organisms/JModal.vue.js +31 -26
  169. package/components/organisms/JModal.vue.js.map +1 -1
  170. package/components/organisms/JPageContainer.vue.cjs +1 -1
  171. package/components/organisms/JPageContainer.vue.cjs.map +1 -1
  172. package/components/organisms/JPageContainer.vue.js +22 -22
  173. package/components/organisms/JPageContainer.vue.js.map +1 -1
  174. package/components/organisms/JSearchPanel.vue2.cjs +1 -1
  175. package/components/organisms/JSearchPanel.vue2.cjs.map +1 -1
  176. package/components/organisms/JSearchPanel.vue2.js +34 -32
  177. package/components/organisms/JSearchPanel.vue2.js.map +1 -1
  178. package/components/organisms/JShuttle.vue.cjs +7 -0
  179. package/components/organisms/JShuttle.vue.cjs.map +1 -0
  180. package/components/organisms/JShuttle.vue.js +13 -0
  181. package/components/organisms/JShuttle.vue.js.map +1 -0
  182. package/components/organisms/JShuttle.vue2.cjs +2 -0
  183. package/components/organisms/JShuttle.vue2.cjs.map +1 -0
  184. package/components/organisms/JShuttle.vue2.js +216 -0
  185. package/components/organisms/JShuttle.vue2.js.map +1 -0
  186. package/components/organisms/JSidebarAdvanced.vue.cjs +1 -1
  187. package/components/organisms/JSidebarAdvanced.vue.js +7 -7
  188. package/components/organisms/JSidebarAdvanced.vue2.cjs +1 -1
  189. package/components/organisms/JSidebarAdvanced.vue2.cjs.map +1 -1
  190. package/components/organisms/JSidebarAdvanced.vue2.js +40 -40
  191. package/components/organisms/JSidebarAdvanced.vue2.js.map +1 -1
  192. package/components/organisms/JSidebarSimple/JDynamicMenuItem.vue.cjs +1 -1
  193. package/components/organisms/JSidebarSimple/JDynamicMenuItem.vue.cjs.map +1 -1
  194. package/components/organisms/JSidebarSimple/JDynamicMenuItem.vue.js +83 -63
  195. package/components/organisms/JSidebarSimple/JDynamicMenuItem.vue.js.map +1 -1
  196. package/components/organisms/JSidebarSimple.vue.cjs +1 -1
  197. package/components/organisms/JSidebarSimple.vue.js +2 -2
  198. package/components/organisms/JSidebarSimple.vue2.cjs +1 -1
  199. package/components/organisms/JSidebarSimple.vue2.cjs.map +1 -1
  200. package/components/organisms/JSidebarSimple.vue2.js +2 -2
  201. package/components/organisms/JSidebarSimple.vue2.js.map +1 -1
  202. package/components/shadcn/AccordionTrigger.vue.cjs +1 -1
  203. package/components/shadcn/AccordionTrigger.vue.cjs.map +1 -1
  204. package/components/shadcn/AccordionTrigger.vue.js +3 -3
  205. package/components/shadcn/AccordionTrigger.vue.js.map +1 -1
  206. package/components/shadcn/Card.vue.cjs +1 -1
  207. package/components/shadcn/Card.vue.cjs.map +1 -1
  208. package/components/shadcn/Card.vue.js +1 -1
  209. package/components/shadcn/Card.vue.js.map +1 -1
  210. package/components/shadcn/CardContent.vue.cjs +1 -1
  211. package/components/shadcn/CardContent.vue.cjs.map +1 -1
  212. package/components/shadcn/CardContent.vue.js +4 -4
  213. package/components/shadcn/CardContent.vue.js.map +1 -1
  214. package/components/shadcn/CardDescription.vue.cjs +1 -1
  215. package/components/shadcn/CardDescription.vue.cjs.map +1 -1
  216. package/components/shadcn/CardDescription.vue.js +1 -1
  217. package/components/shadcn/CardDescription.vue.js.map +1 -1
  218. package/components/shadcn/CardFooter.vue.cjs +1 -1
  219. package/components/shadcn/CardFooter.vue.cjs.map +1 -1
  220. package/components/shadcn/CardFooter.vue.js +7 -7
  221. package/components/shadcn/CardFooter.vue.js.map +1 -1
  222. package/components/shadcn/CardHeader.vue.cjs +1 -1
  223. package/components/shadcn/CardHeader.vue.cjs.map +1 -1
  224. package/components/shadcn/CardHeader.vue.js +8 -8
  225. package/components/shadcn/CardHeader.vue.js.map +1 -1
  226. package/components/shadcn/CardTitle.vue.cjs +1 -1
  227. package/components/shadcn/CardTitle.vue.cjs.map +1 -1
  228. package/components/shadcn/CardTitle.vue.js +5 -5
  229. package/components/shadcn/CardTitle.vue.js.map +1 -1
  230. package/components/shadcn/Input.vue.cjs +1 -1
  231. package/components/shadcn/Input.vue.cjs.map +1 -1
  232. package/components/shadcn/Input.vue.js +3 -3
  233. package/components/shadcn/Input.vue.js.map +1 -1
  234. package/components/shadcn/SelectTrigger.vue.cjs +1 -1
  235. package/components/shadcn/SelectTrigger.vue.cjs.map +1 -1
  236. package/components/shadcn/SelectTrigger.vue.js +2 -2
  237. package/components/shadcn/SelectTrigger.vue.js.map +1 -1
  238. package/components/shadcn/Switch.vue.cjs +1 -1
  239. package/components/shadcn/Switch.vue.cjs.map +1 -1
  240. package/components/shadcn/Switch.vue.js +2 -2
  241. package/components/shadcn/Switch.vue.js.map +1 -1
  242. package/components/shadcn/TabsContent.vue.cjs +1 -1
  243. package/components/shadcn/TabsContent.vue.cjs.map +1 -1
  244. package/components/shadcn/TabsContent.vue.js +1 -1
  245. package/components/shadcn/TabsContent.vue.js.map +1 -1
  246. package/components/shadcn/TabsList.vue.cjs +1 -1
  247. package/components/shadcn/TabsList.vue.cjs.map +1 -1
  248. package/components/shadcn/TabsList.vue.js +10 -10
  249. package/components/shadcn/TabsList.vue.js.map +1 -1
  250. package/components/shadcn/TabsTrigger.vue.cjs +1 -1
  251. package/components/shadcn/TabsTrigger.vue.cjs.map +1 -1
  252. package/components/shadcn/TabsTrigger.vue.js +4 -4
  253. package/components/shadcn/TabsTrigger.vue.js.map +1 -1
  254. package/components/shadcn/Textarea.vue.cjs +1 -1
  255. package/components/shadcn/Textarea.vue.cjs.map +1 -1
  256. package/components/shadcn/Textarea.vue.js +2 -2
  257. package/components/shadcn/Textarea.vue.js.map +1 -1
  258. package/components/shadcn/index.cjs +1 -1
  259. package/components/shadcn/index.cjs.map +1 -1
  260. package/components/shadcn/index.js +9 -8
  261. package/components/shadcn/index.js.map +1 -1
  262. package/components/templates/JLayout.vue.cjs.map +1 -1
  263. package/components/templates/JLayout.vue.js.map +1 -1
  264. package/index.cjs +1 -1
  265. package/index.js +73 -67
  266. package/package.json +1 -1
  267. package/types/index.d.ts +1025 -766
  268. package/assets/jwms-portal-frontend-DntSIcYt.css +0 -1
  269. package/components/molecules/JFormField.vue3.cjs +0 -2
  270. package/components/molecules/JFormField.vue3.cjs.map +0 -1
  271. package/components/molecules/JFormField.vue3.js +0 -6
  272. package/components/molecules/JFormField.vue3.js.map +0 -1
@@ -1,5 +1,88 @@
1
- import f from "./JButton.vue.js";
1
+ import { defineComponent as y, computed as t, createBlock as r, openBlock as o, unref as c, normalizeClass as g, withCtx as b, createCommentVNode as z, renderSlot as k } from "vue";
2
+ import { Loader2 as h } from "lucide-vue-next";
3
+ import "../shadcn/index.js";
4
+ import C from "../shadcn/Button.vue.js";
5
+ const x = /* @__PURE__ */ y({
6
+ __name: "JButton",
7
+ props: {
8
+ type: { default: "button" },
9
+ disabled: { type: Boolean, default: !1 },
10
+ loading: { type: Boolean, default: !1 },
11
+ variant: {},
12
+ size: {},
13
+ class: {},
14
+ styletype: { default: "default" }
15
+ },
16
+ emits: ["click"],
17
+ setup(l, { emit: d }) {
18
+ const a = l, u = d, i = {
19
+ default: {
20
+ variant: "default"
21
+ },
22
+ primary: {
23
+ variant: "default"
24
+ },
25
+ secondary: {
26
+ variant: "secondary"
27
+ },
28
+ success: {
29
+ variant: "default",
30
+ class: "bg-green-600 hover:bg-green-700"
31
+ },
32
+ warning: {
33
+ variant: "default",
34
+ class: "bg-amber-500 hover:bg-amber-600"
35
+ },
36
+ danger: {
37
+ variant: "destructive"
38
+ },
39
+ outline: {
40
+ variant: "outline"
41
+ },
42
+ ghost: {
43
+ variant: "ghost"
44
+ },
45
+ link: {
46
+ variant: "link"
47
+ },
48
+ sm: {
49
+ variant: "default",
50
+ size: "sm"
51
+ },
52
+ lg: {
53
+ variant: "default",
54
+ size: "lg"
55
+ },
56
+ icon: {
57
+ variant: "default",
58
+ size: "icon"
59
+ }
60
+ }, n = t(() => {
61
+ const e = a.styletype || "default";
62
+ return i[e] ?? i.default;
63
+ }), f = t(() => a.variant || n.value?.variant), v = t(() => a.size || n.value?.size || "sm"), m = t(() => [n.value?.class, a.class].filter(Boolean).join(" ")), s = t(() => a.disabled || a.loading), p = (e) => {
64
+ s.value || u("click", e);
65
+ };
66
+ return (e, B) => (o(), r(c(C), {
67
+ type: l.type,
68
+ variant: f.value,
69
+ size: v.value,
70
+ class: g(m.value),
71
+ disabled: s.value,
72
+ onClick: p
73
+ }, {
74
+ default: b(() => [
75
+ l.loading ? (o(), r(c(h), {
76
+ key: 0,
77
+ class: "mr-2 h-4 w-4 animate-spin"
78
+ })) : z("", !0),
79
+ k(e.$slots, "default", {}, void 0, !0)
80
+ ]),
81
+ _: 3
82
+ }, 8, ["type", "variant", "size", "class", "disabled"]));
83
+ }
84
+ });
2
85
  export {
3
- f as default
86
+ x as default
4
87
  };
5
88
  //# sourceMappingURL=JButton.vue2.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"JButton.vue2.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
1
+ {"version":3,"file":"JButton.vue2.js","sources":["../../../../src/components/atoms/JButton.vue"],"sourcesContent":["<script setup lang=\"ts\">\r\nimport { computed } from 'vue'\r\nimport { Loader2 } from 'lucide-vue-next'\r\nimport { Button, type ButtonVariants } from '@/components/shadcn'\r\n\r\ntype StyleType =\r\n | 'default' // 기본 스타일 (primary)\r\n | 'primary' // 강조 버튼 (파랑)\r\n | 'secondary' // 보조 버튼 (회색)\r\n | 'success' // 성공 버튼 (초록)\r\n | 'warning' // 경고 버튼 (주황)\r\n | 'danger' // 위험 버튼 (빨강)\r\n | 'outline' // 아웃라인 버튼\r\n | 'ghost' // 고스트 버튼\r\n | 'link' // 링크 스타일\r\n | 'sm' // 작은 크기\r\n | 'lg' // 큰 크기\r\n | 'icon' // 아이콘 전용\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n /** 버튼 타입 */\r\n type?: 'button' | 'submit' | 'reset'\r\n /** 비활성화 상태 */\r\n disabled?: boolean\r\n /** 로딩 상태 */\r\n loading?: boolean\r\n /** shadcn variant */\r\n variant?: ButtonVariants['variant']\r\n /** shadcn size */\r\n size?: ButtonVariants['size']\r\n /** 추가 CSS 클래스 */\r\n class?: string\r\n /** 스타일 프리셋 (variant + size 조합) */\r\n styletype?: StyleType\r\n }>(),\r\n {\r\n type: 'button',\r\n disabled: false,\r\n loading: false,\r\n styletype: 'default',\r\n },\r\n)\r\n\r\nconst emit = defineEmits<{\r\n click: [event: MouseEvent]\r\n}>()\r\n\r\n/**\r\n * styletype -> variant/size 매핑\r\n */\r\nconst STYLE_PRESETS: Record<StyleType, { variant: ButtonVariants['variant']; size?: ButtonVariants['size']; class?: string }> = {\r\n default: { \r\n variant: 'default',\r\n },\r\n primary: { \r\n variant: 'default',\r\n },\r\n secondary: { \r\n variant: 'secondary',\r\n },\r\n success: { \r\n variant: 'default',\r\n class: 'bg-green-600 hover:bg-green-700',\r\n },\r\n warning: { \r\n variant: 'default',\r\n class: 'bg-amber-500 hover:bg-amber-600',\r\n },\r\n danger: { \r\n variant: 'destructive',\r\n },\r\n outline: { \r\n variant: 'outline',\r\n },\r\n ghost: { \r\n variant: 'ghost',\r\n },\r\n link: { \r\n variant: 'link',\r\n },\r\n sm: { \r\n variant: 'default',\r\n size: 'sm',\r\n },\r\n lg: { \r\n variant: 'default',\r\n size: 'lg',\r\n },\r\n icon: { \r\n variant: 'default',\r\n size: 'icon',\r\n },\r\n}\r\n\r\nconst preset = computed(() => {\r\n const styleKey = props.styletype || 'default'\r\n return STYLE_PRESETS[styleKey] ?? STYLE_PRESETS.default\r\n})\r\n\r\nconst finalVariant = computed(() => props.variant || preset.value?.variant)\nconst finalSize = computed(() => props.size || preset.value?.size || 'sm')\nconst finalClass = computed(() => [preset.value?.class, props.class].filter(Boolean).join(' '))\n\r\nconst isDisabled = computed(() => props.disabled || props.loading)\r\n\r\nconst handleClick = (event: MouseEvent) => {\r\n if (!isDisabled.value) {\r\n emit('click', event)\r\n }\r\n}\r\n</script>\r\n\r\n<template>\r\n <Button\n :type=\"type\"\n :variant=\"finalVariant\"\n :size=\"finalSize\"\n :class=\"finalClass\"\n :disabled=\"isDisabled\"\n @click=\"handleClick\"\n >\n <Loader2 v-if=\"loading\" class=\"mr-2 h-4 w-4 animate-spin\" />\n <slot />\n </Button>\n</template>\n\n<style scoped>\n/* ========================================\n 패턴 10: Button 향상 효과\n ======================================== */\n:deep(button) {\n transition: all 0.2s ease;\n}\n\n:deep(button:not(:disabled):hover) {\n transform: translateY(-1px);\n box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);\n}\n\n:deep(button:not(:disabled):active) {\n transform: translateY(0);\n}\n</style>\n"],"names":["props","__props","emit","__emit","STYLE_PRESETS","preset","computed","styleKey","finalVariant","finalSize","finalClass","isDisabled","handleClick","event","_createBlock","_unref","Button","Loader2","_renderSlot","_ctx"],"mappings":";;;;;;;;;;;;;;;;;AAmBA,UAAMA,IAAQC,GAyBRC,IAAOC,GAOPC,IAA0H;AAAA,MAC9H,SAAS;AAAA,QACP,SAAS;AAAA,MAAA;AAAA,MAEX,SAAS;AAAA,QACP,SAAS;AAAA,MAAA;AAAA,MAEX,WAAW;AAAA,QACT,SAAS;AAAA,MAAA;AAAA,MAEX,SAAS;AAAA,QACP,SAAS;AAAA,QACT,OAAO;AAAA,MAAA;AAAA,MAET,SAAS;AAAA,QACP,SAAS;AAAA,QACT,OAAO;AAAA,MAAA;AAAA,MAET,QAAQ;AAAA,QACN,SAAS;AAAA,MAAA;AAAA,MAEX,SAAS;AAAA,QACP,SAAS;AAAA,MAAA;AAAA,MAEX,OAAO;AAAA,QACL,SAAS;AAAA,MAAA;AAAA,MAEX,MAAM;AAAA,QACJ,SAAS;AAAA,MAAA;AAAA,MAEX,IAAI;AAAA,QACF,SAAS;AAAA,QACT,MAAM;AAAA,MAAA;AAAA,MAER,IAAI;AAAA,QACF,SAAS;AAAA,QACT,MAAM;AAAA,MAAA;AAAA,MAER,MAAM;AAAA,QACJ,SAAS;AAAA,QACT,MAAM;AAAA,MAAA;AAAA,IACR,GAGIC,IAASC,EAAS,MAAM;AAC5B,YAAMC,IAAWP,EAAM,aAAa;AACpC,aAAOI,EAAcG,CAAQ,KAAKH,EAAc;AAAA,IAClD,CAAC,GAEKI,IAAeF,EAAS,MAAMN,EAAM,WAAWK,EAAO,OAAO,OAAO,GACpEI,IAAYH,EAAS,MAAMN,EAAM,QAAQK,EAAO,OAAO,QAAQ,IAAI,GACnEK,IAAaJ,EAAS,MAAM,CAACD,EAAO,OAAO,OAAOL,EAAM,KAAK,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,CAAC,GAExFW,IAAaL,EAAS,MAAMN,EAAM,YAAYA,EAAM,OAAO,GAE3DY,IAAc,CAACC,MAAsB;AACzC,MAAKF,EAAW,SACdT,EAAK,SAASW,CAAK;AAAA,IAEvB;2BAIEC,EAUSC,EAAAC,CAAA,GAAA;AAAA,MATN,MAAMf,EAAA;AAAA,MACN,SAASO,EAAA;AAAA,MACT,MAAMC,EAAA;AAAA,MACN,SAAOC,EAAA,KAAU;AAAA,MACjB,UAAUC,EAAA;AAAA,MACV,SAAOC;AAAA,IAAA;iBAER,MAA4D;AAAA,QAA7CX,EAAA,gBAAfa,EAA4DC,EAAAE,CAAA,GAAA;AAAA;UAApC,OAAM;AAAA,QAAA;QAC9BC,EAAQC,EAAA,QAAA,WAAA,CAAA,GAAA,QAAA,EAAA;AAAA,MAAA;;;;;"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("vue"),_=require("lucide-vue-next"),v=require("@internationalized/date");require("../shadcn/index.cjs");const y=require("../../lib/utils.cjs"),g=require("../shadcn/Popover.vue.cjs"),V=require("../shadcn/PopoverTrigger.vue.cjs"),h=require("../shadcn/Button.vue.cjs"),C=require("../shadcn/PopoverContent.vue.cjs"),b=require("../shadcn/Calendar.vue.cjs"),S=e.defineComponent({__name:"JDatepicker",props:{modelValue:{},id:{},placeholder:{default:"날짜를 선택하세요"},disabled:{type:Boolean},required:{type:Boolean},name:{},class:{},styletype:{default:"default"}},emits:["update:modelValue","change","focus","blur"],setup(n,{emit:i}){const l=n,o=i,s={default:{buttonClass:"h-10"},sm:{buttonClass:"h-9 text-sm"},lg:{buttonClass:"h-11 text-base"}},a=e.ref(),d=t=>{if(t)try{return v.parseDate(t)}catch{return}},c=t=>t?`${t.year}-${String(t.month).padStart(2,"0")}-${String(t.day).padStart(2,"0")}`:null;e.watch(()=>l.modelValue,t=>{const u=d(t);JSON.stringify(a.value)!==JSON.stringify(u)&&(a.value=u)},{immediate:!0});const f=t=>{a.value=t;const u=c(t);u!==l.modelValue&&(o("update:modelValue",u),o("change",u))},m=e.computed(()=>{if(!a.value)return l.placeholder;const t=new Date(a.value.year,a.value.month-1,a.value.day);return new Intl.DateTimeFormat("ko-KR",{year:"numeric",month:"long",day:"numeric"}).format(t)}),p=e.computed(()=>{const t=l.styletype||"default",u=s[t]??s.default,r=l.class||"";return y.cn("w-full justify-start text-left font-normal",u?.buttonClass??"h-10",!a.value&&"text-muted-foreground",r)});return(t,u)=>(e.openBlock(),e.createBlock(e.unref(g.default),null,{default:e.withCtx(()=>[e.createVNode(e.unref(V.default),{"as-child":""},{default:e.withCtx(()=>[e.createVNode(e.unref(h.default),{id:n.id,name:n.name,disabled:n.disabled,class:e.normalizeClass(p.value),variant:"outline",onFocus:u[0]||(u[0]=r=>o("focus",r)),onBlur:u[1]||(u[1]=r=>o("blur",r))},{default:e.withCtx(()=>[e.createVNode(e.unref(_.Calendar),{class:"mr-2 h-4 w-4"}),e.createTextVNode(" "+e.toDisplayString(m.value),1)]),_:1},8,["id","name","disabled","class"])]),_:1}),e.createVNode(e.unref(C.default),{class:"w-auto p-0"},{default:e.withCtx(()=>[e.createVNode(e.unref(b.default),{modelValue:a.value,"onUpdate:modelValue":[u[2]||(u[2]=r=>a.value=r),f],locale:"ko-KR","initial-focus":""},null,8,["modelValue"])]),_:1})]),_:1}))}});exports.default=S;
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("vue"),_=require("lucide-vue-next"),v=require("@internationalized/date");require("../shadcn/index.cjs");const y=require("../../lib/utils.cjs"),g=require("../shadcn/Popover.vue.cjs"),x=require("../shadcn/PopoverTrigger.vue.cjs"),V=require("../shadcn/Button.vue.cjs"),h=require("../shadcn/PopoverContent.vue.cjs"),C=require("../shadcn/Calendar.vue.cjs"),b=e.defineComponent({__name:"JDatepicker",props:{modelValue:{},id:{},placeholder:{default:"날짜를 선택하세요"},disabled:{type:Boolean},required:{type:Boolean},name:{},class:{},styletype:{default:"default"}},emits:["update:modelValue","change","focus","blur"],setup(n,{emit:i}){const l=n,o=i,s={default:{buttonClass:"h-8 text-xs px-2.5"},sm:{buttonClass:"h-7 text-[11px] px-2"},lg:{buttonClass:"h-9 text-sm px-3"}},a=e.ref(),d=t=>{if(t)try{return v.parseDate(t)}catch{return}},c=t=>t?`${t.year}-${String(t.month).padStart(2,"0")}-${String(t.day).padStart(2,"0")}`:null;e.watch(()=>l.modelValue,t=>{const u=d(t);JSON.stringify(a.value)!==JSON.stringify(u)&&(a.value=u)},{immediate:!0});const f=t=>{a.value=t;const u=c(t);u!==l.modelValue&&(o("update:modelValue",u),o("change",u))},p=e.computed(()=>{if(!a.value)return l.placeholder;const t=new Date(a.value.year,a.value.month-1,a.value.day);return new Intl.DateTimeFormat("ko-KR",{year:"numeric",month:"long",day:"numeric"}).format(t)}),m=e.computed(()=>{const t=l.styletype||"default",u=s[t]??s.default,r=l.class||"";return y.cn("w-full justify-start text-left font-normal",u?.buttonClass??"h-10",!a.value&&"text-muted-foreground",r)});return(t,u)=>(e.openBlock(),e.createBlock(e.unref(g.default),null,{default:e.withCtx(()=>[e.createVNode(e.unref(x.default),{"as-child":""},{default:e.withCtx(()=>[e.createVNode(e.unref(V.default),{id:n.id,name:n.name,disabled:n.disabled,class:e.normalizeClass(m.value),variant:"outline",onFocus:u[0]||(u[0]=r=>o("focus",r)),onBlur:u[1]||(u[1]=r=>o("blur",r))},{default:e.withCtx(()=>[e.createVNode(e.unref(_.Calendar),{class:"mr-2 h-4 w-4"}),e.createTextVNode(" "+e.toDisplayString(p.value),1)]),_:1},8,["id","name","disabled","class"])]),_:1}),e.createVNode(e.unref(h.default),{class:"w-auto p-0"},{default:e.withCtx(()=>[e.createVNode(e.unref(C.default),{modelValue:a.value,"onUpdate:modelValue":[u[2]||(u[2]=r=>a.value=r),f],locale:"ko-KR","initial-focus":""},null,8,["modelValue"])]),_:1})]),_:1}))}});exports.default=b;
2
2
  //# sourceMappingURL=JDatepicker.vue.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"JDatepicker.vue.cjs","sources":["../../../../src/components/atoms/JDatepicker.vue"],"sourcesContent":["<script setup lang=\"ts\">\r\nimport { computed, ref, watch } from 'vue'\r\nimport { Calendar as CalendarIcon } from 'lucide-vue-next'\r\nimport { type DateValue, parseDate } from '@internationalized/date'\r\nimport {\r\n Calendar,\r\n Popover,\r\n PopoverContent,\r\n PopoverTrigger,\r\n Button,\r\n} from '@/components/shadcn'\r\nimport { cn } from '@/lib/utils'\r\n\r\n// Props 정의\r\nconst props = withDefaults(\r\n defineProps<{\r\n /** v-model로 양방향 데이터 바인딩 (ISO 8601 문자열: YYYY-MM-DD) */\r\n modelValue?: string | null\r\n /** Input 요소의 id */\r\n id?: string\r\n /** 입력 전 표시되는 안내문 */\r\n placeholder?: string\r\n /** 비활성화 상태 */\r\n disabled?: boolean\r\n /** 필수 입력 여부 */\r\n required?: boolean\r\n /** form 데이터 전송 시 키 이름 */\r\n name?: string\r\n /** 추가 CSS 클래스 */\r\n class?: string\r\n /** 스타일 테마 지정 */\r\n styletype?: 'default' | 'sm' | 'lg'\r\n }>(),\r\n {\r\n placeholder: '날짜를 선택하세요',\r\n styletype: 'default',\r\n }\r\n)\r\n\r\n// 이벤트 정의\r\nconst emit = defineEmits<{\r\n 'update:modelValue': [value: string | null]\r\n 'change': [value: string | null]\r\n 'focus': [event: FocusEvent]\r\n 'blur': [event: FocusEvent]\r\n}>()\r\n\r\n// 스타일 프리셋\r\nconst STYLE_PRESETS: Record<string, { buttonClass: string }> = {\r\n default: {\r\n buttonClass: 'h-10',\r\n },\r\n sm: {\r\n buttonClass: 'h-9 text-sm',\r\n },\r\n lg: {\r\n buttonClass: 'h-11 text-base',\r\n },\r\n}\r\n\r\n// 내부 상태로 DateValue 관리\r\nconst internalDate = ref<DateValue | undefined>()\r\n\r\n// modelValue를 DateValue로 변환\r\nconst convertToDateValue = (value: string | null | undefined): DateValue | undefined => {\r\n if (!value) return undefined\r\n \r\n try {\r\n // ISO 8601 문자열을 직접 parseDate로 변환\r\n return parseDate(value)\r\n } catch {\r\n return undefined\r\n }\r\n}\r\n\r\n// DateValue를 ISO 문자열로 변환\r\nconst convertToString = (date: DateValue | undefined): string | null => {\r\n if (!date) return null\r\n return `${date.year}-${String(date.month).padStart(2, '0')}-${String(date.day).padStart(2, '0')}`\r\n}\r\n\r\n// modelValue 변경 감지\r\nwatch(\r\n () => props.modelValue,\r\n (newValue) => {\r\n const converted = convertToDateValue(newValue)\r\n if (JSON.stringify(internalDate.value) !== JSON.stringify(converted)) {\r\n internalDate.value = converted\r\n }\r\n },\r\n { immediate: true }\r\n)\r\n\r\n// 내부 날짜 변경 시 emit\r\nconst handleDateChange = (date: DateValue | undefined) => {\r\n internalDate.value = date\r\n const stringValue = convertToString(date)\r\n \r\n if (stringValue !== props.modelValue) {\r\n emit('update:modelValue', stringValue)\r\n emit('change', stringValue)\r\n }\r\n}\r\n\r\n// 포맷팅된 날짜 표시\r\nconst formattedDate = computed(() => {\r\n if (!internalDate.value) return props.placeholder\r\n \r\n const date = new Date(\r\n internalDate.value.year,\r\n internalDate.value.month - 1,\r\n internalDate.value.day\r\n )\r\n \r\n return new Intl.DateTimeFormat('ko-KR', {\r\n year: 'numeric',\r\n month: 'long',\r\n day: 'numeric',\r\n }).format(date)\r\n})\r\n\r\n// 버튼 클래스 계산\r\nconst buttonClass = computed(() => {\r\n const styleKey = props.styletype || 'default'\r\n const preset = STYLE_PRESETS[styleKey] ?? STYLE_PRESETS.default\r\n const userClass = props.class || ''\r\n \r\n return cn(\r\n 'w-full justify-start text-left font-normal',\r\n preset?.buttonClass ?? 'h-10',\r\n !internalDate.value && 'text-muted-foreground',\r\n userClass\r\n )\r\n})\r\n</script>\r\n\r\n<template>\r\n <Popover>\r\n <PopoverTrigger as-child>\r\n <Button\r\n :id=\"id\"\r\n :name=\"name\"\r\n :disabled=\"disabled\"\r\n :class=\"buttonClass\"\r\n variant=\"outline\"\r\n @focus=\"emit('focus', $event)\"\r\n @blur=\"emit('blur', $event)\"\r\n >\r\n <CalendarIcon class=\"mr-2 h-4 w-4\" />\r\n {{ formattedDate }}\r\n </Button>\r\n </PopoverTrigger>\r\n <PopoverContent class=\"w-auto p-0\">\r\n <Calendar\r\n v-model=\"internalDate\"\r\n :locale=\"'ko-KR'\"\r\n initial-focus\r\n @update:model-value=\"handleDateChange\"\r\n />\r\n </PopoverContent>\r\n </Popover>\r\n</template>\r\n\r\n"],"names":["props","__props","emit","__emit","STYLE_PRESETS","internalDate","ref","convertToDateValue","value","parseDate","convertToString","date","watch","newValue","converted","handleDateChange","stringValue","formattedDate","computed","buttonClass","styleKey","preset","userClass","cn","_createBlock","_unref","Popover","_createVNode","PopoverTrigger","Button","_cache","$event","CalendarIcon","_createTextVNode","PopoverContent","Calendar"],"mappings":"yuBAcA,MAAMA,EAAQC,EA0BRC,EAAOC,EAQPC,EAAyD,CAC7D,QAAS,CACP,YAAa,MAAA,EAEf,GAAI,CACF,YAAa,aAAA,EAEf,GAAI,CACF,YAAa,gBAAA,CACf,EAIIC,EAAeC,EAAAA,IAAA,EAGfC,EAAsBC,GAA4D,CACtF,GAAKA,EAEL,GAAI,CAEF,OAAOC,EAAAA,UAAUD,CAAK,CACxB,MAAQ,CACN,MACF,CACF,EAGME,EAAmBC,GAClBA,EACE,GAAGA,EAAK,IAAI,IAAI,OAAOA,EAAK,KAAK,EAAE,SAAS,EAAG,GAAG,CAAC,IAAI,OAAOA,EAAK,GAAG,EAAE,SAAS,EAAG,GAAG,CAAC,GAD7E,KAKpBC,EAAAA,MACE,IAAMZ,EAAM,WACXa,GAAa,CACZ,MAAMC,EAAYP,EAAmBM,CAAQ,EACzC,KAAK,UAAUR,EAAa,KAAK,IAAM,KAAK,UAAUS,CAAS,IACjET,EAAa,MAAQS,EAEzB,EACA,CAAE,UAAW,EAAA,CAAK,EAIpB,MAAMC,EAAoBJ,GAAgC,CACxDN,EAAa,MAAQM,EACrB,MAAMK,EAAcN,EAAgBC,CAAI,EAEpCK,IAAgBhB,EAAM,aACxBE,EAAK,oBAAqBc,CAAW,EACrCd,EAAK,SAAUc,CAAW,EAE9B,EAGMC,EAAgBC,EAAAA,SAAS,IAAM,CACnC,GAAI,CAACb,EAAa,MAAO,OAAOL,EAAM,YAEtC,MAAMW,EAAO,IAAI,KACfN,EAAa,MAAM,KACnBA,EAAa,MAAM,MAAQ,EAC3BA,EAAa,MAAM,GAAA,EAGrB,OAAO,IAAI,KAAK,eAAe,QAAS,CACtC,KAAM,UACN,MAAO,OACP,IAAK,SAAA,CACN,EAAE,OAAOM,CAAI,CAChB,CAAC,EAGKQ,EAAcD,EAAAA,SAAS,IAAM,CACjC,MAAME,EAAWpB,EAAM,WAAa,UAC9BqB,EAASjB,EAAcgB,CAAQ,GAAKhB,EAAc,QAClDkB,EAAYtB,EAAM,OAAS,GAEjC,OAAOuB,EAAAA,GACL,6CACAF,GAAQ,aAAe,OACvB,CAAChB,EAAa,OAAS,wBACvBiB,CAAA,CAEJ,CAAC,8BAICE,EAAAA,YAuBUC,EAAAA,MAAAC,EAAAA,OAAA,EAAA,KAAA,mBAtBR,IAaiB,CAbjBC,EAAAA,YAaiBF,EAAAA,MAAAG,EAAAA,OAAA,EAAA,CAbD,WAAA,IAAQ,mBACtB,IAWS,CAXTD,cAWSF,EAAAA,MAAAI,EAAAA,OAAA,EAAA,CAVN,GAAI5B,EAAA,GACJ,KAAMA,EAAA,KACN,SAAUA,EAAA,SACV,uBAAOkB,EAAA,KAAW,EACnB,QAAQ,UACP,QAAKW,EAAA,CAAA,IAAAA,EAAA,CAAA,EAAAC,GAAE7B,EAAI,QAAU6B,CAAM,GAC3B,OAAID,EAAA,CAAA,IAAAA,EAAA,CAAA,EAAAC,GAAE7B,EAAI,OAAS6B,CAAM,EAAA,qBAE1B,IAAqC,CAArCJ,EAAAA,YAAqCF,EAAAA,MAAAO,EAAAA,QAAA,EAAA,CAAvB,MAAM,eAAc,EAAGC,EAAAA,gBAAA,sBAClChB,EAAA,KAAa,EAAA,CAAA,CAAA,oDAGpBU,EAAAA,YAOiBF,EAAAA,MAAAS,EAAAA,OAAA,EAAA,CAPD,MAAM,cAAY,mBAChC,IAKE,CALFP,cAKEF,EAAAA,MAAAU,EAAAA,OAAA,EAAA,YAJS9B,EAAA,4CAAAA,EAAY,MAAA0B,GAGAhB,CAAA,EAFpB,OAAQ,QACT,gBAAA,EAAA"}
1
+ {"version":3,"file":"JDatepicker.vue.cjs","sources":["../../../../src/components/atoms/JDatepicker.vue"],"sourcesContent":["<script setup lang=\"ts\">\r\nimport { computed, ref, watch } from 'vue'\r\nimport { Calendar as CalendarIcon } from 'lucide-vue-next'\r\nimport { type DateValue, parseDate } from '@internationalized/date'\r\nimport {\r\n Calendar,\r\n Popover,\r\n PopoverContent,\r\n PopoverTrigger,\r\n Button,\r\n} from '@/components/shadcn'\r\nimport { cn } from '@/lib/utils'\r\n\r\n// Props 정의\r\nconst props = withDefaults(\r\n defineProps<{\r\n /** v-model로 양방향 데이터 바인딩 (ISO 8601 문자열: YYYY-MM-DD) */\r\n modelValue?: string | null\r\n /** Input 요소의 id */\r\n id?: string\r\n /** 입력 전 표시되는 안내문 */\r\n placeholder?: string\r\n /** 비활성화 상태 */\r\n disabled?: boolean\r\n /** 필수 입력 여부 */\r\n required?: boolean\r\n /** form 데이터 전송 시 키 이름 */\r\n name?: string\r\n /** 추가 CSS 클래스 */\r\n class?: string\r\n /** 스타일 테마 지정 */\r\n styletype?: 'default' | 'sm' | 'lg'\r\n }>(),\r\n {\r\n placeholder: '날짜를 선택하세요',\r\n styletype: 'default',\r\n }\r\n)\r\n\r\n// 이벤트 정의\r\nconst emit = defineEmits<{\r\n 'update:modelValue': [value: string | null]\r\n 'change': [value: string | null]\r\n 'focus': [event: FocusEvent]\r\n 'blur': [event: FocusEvent]\r\n}>()\r\n\r\n// 스타일 프리셋\nconst STYLE_PRESETS: Record<string, { buttonClass: string }> = {\n default: {\n buttonClass: 'h-8 text-xs px-2.5',\n },\n sm: {\n buttonClass: 'h-7 text-[11px] px-2',\n },\n lg: {\n buttonClass: 'h-9 text-sm px-3',\n },\n}\n\r\n// 내부 상태로 DateValue 관리\r\nconst internalDate = ref<DateValue | undefined>()\r\n\r\n// modelValue를 DateValue로 변환\r\nconst convertToDateValue = (value: string | null | undefined): DateValue | undefined => {\r\n if (!value) return undefined\r\n \r\n try {\r\n // ISO 8601 문자열을 직접 parseDate로 변환\r\n return parseDate(value)\r\n } catch {\r\n return undefined\r\n }\r\n}\r\n\r\n// DateValue를 ISO 문자열로 변환\r\nconst convertToString = (date: DateValue | undefined): string | null => {\r\n if (!date) return null\r\n return `${date.year}-${String(date.month).padStart(2, '0')}-${String(date.day).padStart(2, '0')}`\r\n}\r\n\r\n// modelValue 변경 감지\r\nwatch(\r\n () => props.modelValue,\r\n (newValue) => {\r\n const converted = convertToDateValue(newValue)\r\n if (JSON.stringify(internalDate.value) !== JSON.stringify(converted)) {\r\n internalDate.value = converted\r\n }\r\n },\r\n { immediate: true }\r\n)\r\n\r\n// 내부 날짜 변경 시 emit\r\nconst handleDateChange = (date: DateValue | undefined) => {\r\n internalDate.value = date\r\n const stringValue = convertToString(date)\r\n \r\n if (stringValue !== props.modelValue) {\r\n emit('update:modelValue', stringValue)\r\n emit('change', stringValue)\r\n }\r\n}\r\n\r\n// 포맷팅된 날짜 표시\r\nconst formattedDate = computed(() => {\r\n if (!internalDate.value) return props.placeholder\r\n \r\n const date = new Date(\r\n internalDate.value.year,\r\n internalDate.value.month - 1,\r\n internalDate.value.day\r\n )\r\n \r\n return new Intl.DateTimeFormat('ko-KR', {\r\n year: 'numeric',\r\n month: 'long',\r\n day: 'numeric',\r\n }).format(date)\r\n})\r\n\r\n// 버튼 클래스 계산\r\nconst buttonClass = computed(() => {\r\n const styleKey = props.styletype || 'default'\r\n const preset = STYLE_PRESETS[styleKey] ?? STYLE_PRESETS.default\r\n const userClass = props.class || ''\r\n \r\n return cn(\r\n 'w-full justify-start text-left font-normal',\r\n preset?.buttonClass ?? 'h-10',\r\n !internalDate.value && 'text-muted-foreground',\r\n userClass\r\n )\r\n})\r\n</script>\r\n\r\n<template>\r\n <Popover>\r\n <PopoverTrigger as-child>\r\n <Button\r\n :id=\"id\"\r\n :name=\"name\"\r\n :disabled=\"disabled\"\r\n :class=\"buttonClass\"\r\n variant=\"outline\"\r\n @focus=\"emit('focus', $event)\"\r\n @blur=\"emit('blur', $event)\"\r\n >\r\n <CalendarIcon class=\"mr-2 h-4 w-4\" />\r\n {{ formattedDate }}\r\n </Button>\r\n </PopoverTrigger>\r\n <PopoverContent class=\"w-auto p-0\">\r\n <Calendar\r\n v-model=\"internalDate\"\r\n :locale=\"'ko-KR'\"\r\n initial-focus\r\n @update:model-value=\"handleDateChange\"\r\n />\r\n </PopoverContent>\r\n </Popover>\r\n</template>\r\n\r\n"],"names":["props","__props","emit","__emit","STYLE_PRESETS","internalDate","ref","convertToDateValue","value","parseDate","convertToString","date","watch","newValue","converted","handleDateChange","stringValue","formattedDate","computed","buttonClass","styleKey","preset","userClass","cn","_createBlock","_unref","Popover","_createVNode","PopoverTrigger","Button","_cache","$event","CalendarIcon","_createTextVNode","PopoverContent","Calendar"],"mappings":"yuBAcA,MAAMA,EAAQC,EA0BRC,EAAOC,EAQPC,EAAyD,CAC7D,QAAS,CACP,YAAa,oBAAA,EAEf,GAAI,CACF,YAAa,sBAAA,EAEf,GAAI,CACF,YAAa,kBAAA,CACf,EAIIC,EAAeC,EAAAA,IAAA,EAGfC,EAAsBC,GAA4D,CACtF,GAAKA,EAEL,GAAI,CAEF,OAAOC,EAAAA,UAAUD,CAAK,CACxB,MAAQ,CACN,MACF,CACF,EAGME,EAAmBC,GAClBA,EACE,GAAGA,EAAK,IAAI,IAAI,OAAOA,EAAK,KAAK,EAAE,SAAS,EAAG,GAAG,CAAC,IAAI,OAAOA,EAAK,GAAG,EAAE,SAAS,EAAG,GAAG,CAAC,GAD7E,KAKpBC,EAAAA,MACE,IAAMZ,EAAM,WACXa,GAAa,CACZ,MAAMC,EAAYP,EAAmBM,CAAQ,EACzC,KAAK,UAAUR,EAAa,KAAK,IAAM,KAAK,UAAUS,CAAS,IACjET,EAAa,MAAQS,EAEzB,EACA,CAAE,UAAW,EAAA,CAAK,EAIpB,MAAMC,EAAoBJ,GAAgC,CACxDN,EAAa,MAAQM,EACrB,MAAMK,EAAcN,EAAgBC,CAAI,EAEpCK,IAAgBhB,EAAM,aACxBE,EAAK,oBAAqBc,CAAW,EACrCd,EAAK,SAAUc,CAAW,EAE9B,EAGMC,EAAgBC,EAAAA,SAAS,IAAM,CACnC,GAAI,CAACb,EAAa,MAAO,OAAOL,EAAM,YAEtC,MAAMW,EAAO,IAAI,KACfN,EAAa,MAAM,KACnBA,EAAa,MAAM,MAAQ,EAC3BA,EAAa,MAAM,GAAA,EAGrB,OAAO,IAAI,KAAK,eAAe,QAAS,CACtC,KAAM,UACN,MAAO,OACP,IAAK,SAAA,CACN,EAAE,OAAOM,CAAI,CAChB,CAAC,EAGKQ,EAAcD,EAAAA,SAAS,IAAM,CACjC,MAAME,EAAWpB,EAAM,WAAa,UAC9BqB,EAASjB,EAAcgB,CAAQ,GAAKhB,EAAc,QAClDkB,EAAYtB,EAAM,OAAS,GAEjC,OAAOuB,EAAAA,GACL,6CACAF,GAAQ,aAAe,OACvB,CAAChB,EAAa,OAAS,wBACvBiB,CAAA,CAEJ,CAAC,8BAICE,EAAAA,YAuBUC,EAAAA,MAAAC,EAAAA,OAAA,EAAA,KAAA,mBAtBR,IAaiB,CAbjBC,EAAAA,YAaiBF,EAAAA,MAAAG,EAAAA,OAAA,EAAA,CAbD,WAAA,IAAQ,mBACtB,IAWS,CAXTD,cAWSF,EAAAA,MAAAI,EAAAA,OAAA,EAAA,CAVN,GAAI5B,EAAA,GACJ,KAAMA,EAAA,KACN,SAAUA,EAAA,SACV,uBAAOkB,EAAA,KAAW,EACnB,QAAQ,UACP,QAAKW,EAAA,CAAA,IAAAA,EAAA,CAAA,EAAAC,GAAE7B,EAAI,QAAU6B,CAAM,GAC3B,OAAID,EAAA,CAAA,IAAAA,EAAA,CAAA,EAAAC,GAAE7B,EAAI,OAAS6B,CAAM,EAAA,qBAE1B,IAAqC,CAArCJ,EAAAA,YAAqCF,EAAAA,MAAAO,EAAAA,QAAA,EAAA,CAAvB,MAAM,eAAc,EAAGC,EAAAA,gBAAA,sBAClChB,EAAA,KAAa,EAAA,CAAA,CAAA,oDAGpBU,EAAAA,YAOiBF,EAAAA,MAAAS,EAAAA,OAAA,EAAA,CAPD,MAAM,cAAY,mBAChC,IAKE,CALFP,cAKEF,EAAAA,MAAAU,EAAAA,OAAA,EAAA,YAJS9B,EAAA,4CAAAA,EAAY,MAAA0B,GAGAhB,CAAA,EAFpB,OAAQ,QACT,gBAAA,EAAA"}
@@ -1,4 +1,4 @@
1
- import { defineComponent as h, ref as b, watch as V, computed as d, createBlock as C, openBlock as S, unref as o, withCtx as i, createVNode as r, normalizeClass as D, createTextVNode as _, toDisplayString as x } from "vue";
1
+ import { defineComponent as g, ref as h, watch as V, computed as d, createBlock as b, openBlock as C, unref as o, withCtx as i, createVNode as r, normalizeClass as S, createTextVNode as D, toDisplayString as _ } from "vue";
2
2
  import { Calendar as $ } from "lucide-vue-next";
3
3
  import { parseDate as w } from "@internationalized/date";
4
4
  import "../shadcn/index.js";
@@ -8,7 +8,7 @@ import B from "../shadcn/PopoverTrigger.vue.js";
8
8
  import N from "../shadcn/Button.vue.js";
9
9
  import E from "../shadcn/PopoverContent.vue.js";
10
10
  import J from "../shadcn/Calendar.vue.js";
11
- const U = /* @__PURE__ */ h({
11
+ const U = /* @__PURE__ */ g({
12
12
  __name: "JDatepicker",
13
13
  props: {
14
14
  modelValue: {},
@@ -24,15 +24,15 @@ const U = /* @__PURE__ */ h({
24
24
  setup(s, { emit: f }) {
25
25
  const n = s, u = f, m = {
26
26
  default: {
27
- buttonClass: "h-10"
27
+ buttonClass: "h-8 text-xs px-2.5"
28
28
  },
29
29
  sm: {
30
- buttonClass: "h-9 text-sm"
30
+ buttonClass: "h-7 text-[11px] px-2"
31
31
  },
32
32
  lg: {
33
- buttonClass: "h-11 text-base"
33
+ buttonClass: "h-9 text-sm px-3"
34
34
  }
35
- }, a = b(), c = (e) => {
35
+ }, a = h(), c = (e) => {
36
36
  if (e)
37
37
  try {
38
38
  return w(e);
@@ -64,7 +64,7 @@ const U = /* @__PURE__ */ h({
64
64
  month: "long",
65
65
  day: "numeric"
66
66
  }).format(e);
67
- }), g = d(() => {
67
+ }), x = d(() => {
68
68
  const e = n.styletype || "default", t = m[e] ?? m.default, l = n.class || "";
69
69
  return T(
70
70
  "w-full justify-start text-left font-normal",
@@ -73,7 +73,7 @@ const U = /* @__PURE__ */ h({
73
73
  l
74
74
  );
75
75
  });
76
- return (e, t) => (S(), C(o(k), null, {
76
+ return (e, t) => (C(), b(o(k), null, {
77
77
  default: i(() => [
78
78
  r(o(B), { "as-child": "" }, {
79
79
  default: i(() => [
@@ -81,14 +81,14 @@ const U = /* @__PURE__ */ h({
81
81
  id: s.id,
82
82
  name: s.name,
83
83
  disabled: s.disabled,
84
- class: D(g.value),
84
+ class: S(x.value),
85
85
  variant: "outline",
86
86
  onFocus: t[0] || (t[0] = (l) => u("focus", l)),
87
87
  onBlur: t[1] || (t[1] = (l) => u("blur", l))
88
88
  }, {
89
89
  default: i(() => [
90
90
  r(o($), { class: "mr-2 h-4 w-4" }),
91
- _(" " + x(v.value), 1)
91
+ D(" " + _(v.value), 1)
92
92
  ]),
93
93
  _: 1
94
94
  }, 8, ["id", "name", "disabled", "class"])
@@ -1 +1 @@
1
- {"version":3,"file":"JDatepicker.vue.js","sources":["../../../../src/components/atoms/JDatepicker.vue"],"sourcesContent":["<script setup lang=\"ts\">\r\nimport { computed, ref, watch } from 'vue'\r\nimport { Calendar as CalendarIcon } from 'lucide-vue-next'\r\nimport { type DateValue, parseDate } from '@internationalized/date'\r\nimport {\r\n Calendar,\r\n Popover,\r\n PopoverContent,\r\n PopoverTrigger,\r\n Button,\r\n} from '@/components/shadcn'\r\nimport { cn } from '@/lib/utils'\r\n\r\n// Props 정의\r\nconst props = withDefaults(\r\n defineProps<{\r\n /** v-model로 양방향 데이터 바인딩 (ISO 8601 문자열: YYYY-MM-DD) */\r\n modelValue?: string | null\r\n /** Input 요소의 id */\r\n id?: string\r\n /** 입력 전 표시되는 안내문 */\r\n placeholder?: string\r\n /** 비활성화 상태 */\r\n disabled?: boolean\r\n /** 필수 입력 여부 */\r\n required?: boolean\r\n /** form 데이터 전송 시 키 이름 */\r\n name?: string\r\n /** 추가 CSS 클래스 */\r\n class?: string\r\n /** 스타일 테마 지정 */\r\n styletype?: 'default' | 'sm' | 'lg'\r\n }>(),\r\n {\r\n placeholder: '날짜를 선택하세요',\r\n styletype: 'default',\r\n }\r\n)\r\n\r\n// 이벤트 정의\r\nconst emit = defineEmits<{\r\n 'update:modelValue': [value: string | null]\r\n 'change': [value: string | null]\r\n 'focus': [event: FocusEvent]\r\n 'blur': [event: FocusEvent]\r\n}>()\r\n\r\n// 스타일 프리셋\r\nconst STYLE_PRESETS: Record<string, { buttonClass: string }> = {\r\n default: {\r\n buttonClass: 'h-10',\r\n },\r\n sm: {\r\n buttonClass: 'h-9 text-sm',\r\n },\r\n lg: {\r\n buttonClass: 'h-11 text-base',\r\n },\r\n}\r\n\r\n// 내부 상태로 DateValue 관리\r\nconst internalDate = ref<DateValue | undefined>()\r\n\r\n// modelValue를 DateValue로 변환\r\nconst convertToDateValue = (value: string | null | undefined): DateValue | undefined => {\r\n if (!value) return undefined\r\n \r\n try {\r\n // ISO 8601 문자열을 직접 parseDate로 변환\r\n return parseDate(value)\r\n } catch {\r\n return undefined\r\n }\r\n}\r\n\r\n// DateValue를 ISO 문자열로 변환\r\nconst convertToString = (date: DateValue | undefined): string | null => {\r\n if (!date) return null\r\n return `${date.year}-${String(date.month).padStart(2, '0')}-${String(date.day).padStart(2, '0')}`\r\n}\r\n\r\n// modelValue 변경 감지\r\nwatch(\r\n () => props.modelValue,\r\n (newValue) => {\r\n const converted = convertToDateValue(newValue)\r\n if (JSON.stringify(internalDate.value) !== JSON.stringify(converted)) {\r\n internalDate.value = converted\r\n }\r\n },\r\n { immediate: true }\r\n)\r\n\r\n// 내부 날짜 변경 시 emit\r\nconst handleDateChange = (date: DateValue | undefined) => {\r\n internalDate.value = date\r\n const stringValue = convertToString(date)\r\n \r\n if (stringValue !== props.modelValue) {\r\n emit('update:modelValue', stringValue)\r\n emit('change', stringValue)\r\n }\r\n}\r\n\r\n// 포맷팅된 날짜 표시\r\nconst formattedDate = computed(() => {\r\n if (!internalDate.value) return props.placeholder\r\n \r\n const date = new Date(\r\n internalDate.value.year,\r\n internalDate.value.month - 1,\r\n internalDate.value.day\r\n )\r\n \r\n return new Intl.DateTimeFormat('ko-KR', {\r\n year: 'numeric',\r\n month: 'long',\r\n day: 'numeric',\r\n }).format(date)\r\n})\r\n\r\n// 버튼 클래스 계산\r\nconst buttonClass = computed(() => {\r\n const styleKey = props.styletype || 'default'\r\n const preset = STYLE_PRESETS[styleKey] ?? STYLE_PRESETS.default\r\n const userClass = props.class || ''\r\n \r\n return cn(\r\n 'w-full justify-start text-left font-normal',\r\n preset?.buttonClass ?? 'h-10',\r\n !internalDate.value && 'text-muted-foreground',\r\n userClass\r\n )\r\n})\r\n</script>\r\n\r\n<template>\r\n <Popover>\r\n <PopoverTrigger as-child>\r\n <Button\r\n :id=\"id\"\r\n :name=\"name\"\r\n :disabled=\"disabled\"\r\n :class=\"buttonClass\"\r\n variant=\"outline\"\r\n @focus=\"emit('focus', $event)\"\r\n @blur=\"emit('blur', $event)\"\r\n >\r\n <CalendarIcon class=\"mr-2 h-4 w-4\" />\r\n {{ formattedDate }}\r\n </Button>\r\n </PopoverTrigger>\r\n <PopoverContent class=\"w-auto p-0\">\r\n <Calendar\r\n v-model=\"internalDate\"\r\n :locale=\"'ko-KR'\"\r\n initial-focus\r\n @update:model-value=\"handleDateChange\"\r\n />\r\n </PopoverContent>\r\n </Popover>\r\n</template>\r\n\r\n"],"names":["props","__props","emit","__emit","STYLE_PRESETS","internalDate","ref","convertToDateValue","value","parseDate","convertToString","date","watch","newValue","converted","handleDateChange","stringValue","formattedDate","computed","buttonClass","styleKey","preset","userClass","cn","_createBlock","_unref","Popover","_createVNode","PopoverTrigger","Button","_cache","$event","CalendarIcon","_createTextVNode","PopoverContent","Calendar"],"mappings":"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"}
1
+ {"version":3,"file":"JDatepicker.vue.js","sources":["../../../../src/components/atoms/JDatepicker.vue"],"sourcesContent":["<script setup lang=\"ts\">\r\nimport { computed, ref, watch } from 'vue'\r\nimport { Calendar as CalendarIcon } from 'lucide-vue-next'\r\nimport { type DateValue, parseDate } from '@internationalized/date'\r\nimport {\r\n Calendar,\r\n Popover,\r\n PopoverContent,\r\n PopoverTrigger,\r\n Button,\r\n} from '@/components/shadcn'\r\nimport { cn } from '@/lib/utils'\r\n\r\n// Props 정의\r\nconst props = withDefaults(\r\n defineProps<{\r\n /** v-model로 양방향 데이터 바인딩 (ISO 8601 문자열: YYYY-MM-DD) */\r\n modelValue?: string | null\r\n /** Input 요소의 id */\r\n id?: string\r\n /** 입력 전 표시되는 안내문 */\r\n placeholder?: string\r\n /** 비활성화 상태 */\r\n disabled?: boolean\r\n /** 필수 입력 여부 */\r\n required?: boolean\r\n /** form 데이터 전송 시 키 이름 */\r\n name?: string\r\n /** 추가 CSS 클래스 */\r\n class?: string\r\n /** 스타일 테마 지정 */\r\n styletype?: 'default' | 'sm' | 'lg'\r\n }>(),\r\n {\r\n placeholder: '날짜를 선택하세요',\r\n styletype: 'default',\r\n }\r\n)\r\n\r\n// 이벤트 정의\r\nconst emit = defineEmits<{\r\n 'update:modelValue': [value: string | null]\r\n 'change': [value: string | null]\r\n 'focus': [event: FocusEvent]\r\n 'blur': [event: FocusEvent]\r\n}>()\r\n\r\n// 스타일 프리셋\nconst STYLE_PRESETS: Record<string, { buttonClass: string }> = {\n default: {\n buttonClass: 'h-8 text-xs px-2.5',\n },\n sm: {\n buttonClass: 'h-7 text-[11px] px-2',\n },\n lg: {\n buttonClass: 'h-9 text-sm px-3',\n },\n}\n\r\n// 내부 상태로 DateValue 관리\r\nconst internalDate = ref<DateValue | undefined>()\r\n\r\n// modelValue를 DateValue로 변환\r\nconst convertToDateValue = (value: string | null | undefined): DateValue | undefined => {\r\n if (!value) return undefined\r\n \r\n try {\r\n // ISO 8601 문자열을 직접 parseDate로 변환\r\n return parseDate(value)\r\n } catch {\r\n return undefined\r\n }\r\n}\r\n\r\n// DateValue를 ISO 문자열로 변환\r\nconst convertToString = (date: DateValue | undefined): string | null => {\r\n if (!date) return null\r\n return `${date.year}-${String(date.month).padStart(2, '0')}-${String(date.day).padStart(2, '0')}`\r\n}\r\n\r\n// modelValue 변경 감지\r\nwatch(\r\n () => props.modelValue,\r\n (newValue) => {\r\n const converted = convertToDateValue(newValue)\r\n if (JSON.stringify(internalDate.value) !== JSON.stringify(converted)) {\r\n internalDate.value = converted\r\n }\r\n },\r\n { immediate: true }\r\n)\r\n\r\n// 내부 날짜 변경 시 emit\r\nconst handleDateChange = (date: DateValue | undefined) => {\r\n internalDate.value = date\r\n const stringValue = convertToString(date)\r\n \r\n if (stringValue !== props.modelValue) {\r\n emit('update:modelValue', stringValue)\r\n emit('change', stringValue)\r\n }\r\n}\r\n\r\n// 포맷팅된 날짜 표시\r\nconst formattedDate = computed(() => {\r\n if (!internalDate.value) return props.placeholder\r\n \r\n const date = new Date(\r\n internalDate.value.year,\r\n internalDate.value.month - 1,\r\n internalDate.value.day\r\n )\r\n \r\n return new Intl.DateTimeFormat('ko-KR', {\r\n year: 'numeric',\r\n month: 'long',\r\n day: 'numeric',\r\n }).format(date)\r\n})\r\n\r\n// 버튼 클래스 계산\r\nconst buttonClass = computed(() => {\r\n const styleKey = props.styletype || 'default'\r\n const preset = STYLE_PRESETS[styleKey] ?? STYLE_PRESETS.default\r\n const userClass = props.class || ''\r\n \r\n return cn(\r\n 'w-full justify-start text-left font-normal',\r\n preset?.buttonClass ?? 'h-10',\r\n !internalDate.value && 'text-muted-foreground',\r\n userClass\r\n )\r\n})\r\n</script>\r\n\r\n<template>\r\n <Popover>\r\n <PopoverTrigger as-child>\r\n <Button\r\n :id=\"id\"\r\n :name=\"name\"\r\n :disabled=\"disabled\"\r\n :class=\"buttonClass\"\r\n variant=\"outline\"\r\n @focus=\"emit('focus', $event)\"\r\n @blur=\"emit('blur', $event)\"\r\n >\r\n <CalendarIcon class=\"mr-2 h-4 w-4\" />\r\n {{ formattedDate }}\r\n </Button>\r\n </PopoverTrigger>\r\n <PopoverContent class=\"w-auto p-0\">\r\n <Calendar\r\n v-model=\"internalDate\"\r\n :locale=\"'ko-KR'\"\r\n initial-focus\r\n @update:model-value=\"handleDateChange\"\r\n />\r\n </PopoverContent>\r\n </Popover>\r\n</template>\r\n\r\n"],"names":["props","__props","emit","__emit","STYLE_PRESETS","internalDate","ref","convertToDateValue","value","parseDate","convertToString","date","watch","newValue","converted","handleDateChange","stringValue","formattedDate","computed","buttonClass","styleKey","preset","userClass","cn","_createBlock","_unref","Popover","_createVNode","PopoverTrigger","Button","_cache","$event","CalendarIcon","_createTextVNode","PopoverContent","Calendar"],"mappings":"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"}
@@ -3,5 +3,5 @@
3
3
  for (const [t_key, t_val] of t_opts)
4
4
  t_merged[t_key] = t_val;
5
5
  return t_merged;
6
- };,u=t(e.default,[["__scopeId","data-v-4ced4b77"]]);exports.default=u;
6
+ };,u=t(e.default,[["__scopeId","data-v-24e74219"]]);exports.default=u;
7
7
  //# sourceMappingURL=JEditor.vue.cjs.map
@@ -6,7 +6,7 @@ const t = (t_comp, t_opts) => {
6
6
  t_merged[t_key] = t_val;
7
7
  return t_merged;
8
8
  };
9
- const _ = /* @__PURE__ */ t(o, [["__scopeId", "data-v-4ced4b77"]]);
9
+ const _ = /* @__PURE__ */ t(o, [["__scopeId", "data-v-24e74219"]]);
10
10
  export {
11
11
  _ as default
12
12
  };
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const l=require("vue"),r=require("md-editor-v3");;/* empty css */const u=l.defineComponent({__name:"JEditor",props:{modelValue:{default:""},placeholder:{default:"마크다운을 입력하세요..."},disabled:{type:Boolean,default:!1},readonly:{type:Boolean,default:!1},height:{default:"300px"},theme:{default:"light"},class:{}},emits:["update:modelValue","change","save"],setup(e,{emit:d}){const o=e,t=d,n=a=>{t("update:modelValue",a),t("change",a)},i=a=>{t("save",a)};return(a,s)=>(l.openBlock(),l.createElementBlock("div",{class:l.normalizeClass(["j-editor-wrapper",o.class])},[l.createVNode(l.unref(r.MdEditor),{"model-value":e.modelValue,placeholder:e.placeholder,disabled:e.disabled,"read-only":e.readonly,"editor-class-name":"j-editor","preview-class-name":"j-editor-preview",style:l.normalizeStyle({height:typeof e.height=="number"?`${e.height}px`:e.height}),theme:e.theme,language:"en-US","onUpdate:modelValue":n,onOnSave:i},null,8,["model-value","placeholder","disabled","read-only","style","theme"])],2))}});exports.default=u;
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("vue"),m=require("md-editor-v3");;/* empty css */const h=e.defineComponent({__name:"JEditor",props:{modelValue:{default:""},placeholder:{default:"마크다운을 입력하세요..."},disabled:{type:Boolean,default:!1},readonly:{type:Boolean,default:!1},height:{default:"300px"},theme:{},class:{}},emits:["update:modelValue","change","save"],setup(t,{emit:u}){const n=t,d=u,o=e.ref(!1),r=()=>{o.value=document.documentElement.classList.contains("dark")},s=e.computed(()=>n.theme?n.theme:o.value?"dark":"light");let l=null;e.onMounted(()=>{r(),l=new MutationObserver(()=>{r()}),l.observe(document.documentElement,{attributes:!0,attributeFilter:["class"]})}),e.onUnmounted(()=>{l&&l.disconnect()});const i=a=>{d("update:modelValue",a),d("change",a)},c=a=>{d("save",a)};return(a,f)=>(e.openBlock(),e.createElementBlock("div",{class:e.normalizeClass(["j-editor-wrapper",n.class])},[e.createVNode(e.unref(m.MdEditor),{"model-value":t.modelValue,placeholder:t.placeholder,disabled:t.disabled,"read-only":t.readonly,"editor-class-name":"j-editor","preview-class-name":"j-editor-preview",style:e.normalizeStyle({height:typeof t.height=="number"?`${t.height}px`:t.height}),theme:s.value,language:"en-US","onUpdate:modelValue":i,onOnSave:c},null,8,["model-value","placeholder","disabled","read-only","style","theme"])],2))}});exports.default=h;
2
2
  //# sourceMappingURL=JEditor.vue2.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"JEditor.vue2.cjs","sources":["../../../../src/components/atoms/JEditor.vue"],"sourcesContent":["<script setup lang=\"ts\">\r\nimport { MdEditor } from 'md-editor-v3'\r\nimport 'md-editor-v3/lib/style.css'\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n /** 마크다운 내용 (v-model) */\r\n modelValue?: string\r\n /** 플레이스홀더 텍스트 */\r\n placeholder?: string\r\n /** 비활성화 상태 */\r\n disabled?: boolean\r\n /** 읽기 전용 상태 */\r\n readonly?: boolean\r\n /** 에디터 높이 */\r\n height?: string | number\r\n /** 테마 (light/dark) */\r\n theme?: 'light' | 'dark'\r\n /** 추가 CSS 클래스 */\r\n class?: string\r\n }>(),\r\n {\r\n modelValue: '',\r\n placeholder: '마크다운을 입력하세요...',\r\n disabled: false,\r\n readonly: false,\r\n height: '300px',\r\n theme: 'light',\r\n },\r\n)\r\n\r\nconst emit = defineEmits<{\r\n 'update:modelValue': [value: string]\r\n 'change': [value: string]\r\n 'save': [value: string]\r\n}>()\r\n\r\nconst handleChange = (value: string) => {\r\n emit('update:modelValue', value)\r\n emit('change', value)\r\n}\r\n\r\nconst handleSave = (value: string) => {\r\n emit('save', value)\r\n}\r\n</script>\r\n\r\n<template>\r\n <div :class=\"['j-editor-wrapper', props.class]\">\r\n <MdEditor\r\n :model-value=\"modelValue\"\r\n :placeholder=\"placeholder\"\r\n :disabled=\"disabled\"\r\n :read-only=\"readonly\"\r\n :editor-class-name=\"'j-editor'\"\r\n :preview-class-name=\"'j-editor-preview'\"\r\n :style=\"{ height: typeof height === 'number' ? `${height}px` : height }\"\r\n :theme=\"theme\"\r\n language=\"en-US\"\r\n @update:model-value=\"handleChange\"\r\n @on-save=\"handleSave\"\r\n />\r\n </div>\r\n</template>\r\n\r\n<style scoped>\r\n.j-editor-wrapper {\r\n @apply w-full;\r\n}\r\n</style>\r\n"],"names":["props","__props","emit","__emit","handleChange","value","handleSave","_createElementBlock","_normalizeClass","_createVNode","_unref","MdEditor","_normalizeStyle"],"mappings":"8kBAIA,MAAMA,EAAQC,EA2BRC,EAAOC,EAMPC,EAAgBC,GAAkB,CACtCH,EAAK,oBAAqBG,CAAK,EAC/BH,EAAK,SAAUG,CAAK,CACtB,EAEMC,EAAcD,GAAkB,CACpCH,EAAK,OAAQG,CAAK,CACpB,8BAIEE,EAAAA,mBAcM,MAAA,CAdA,MAAKC,EAAAA,eAAA,CAAA,mBAAuBR,EAAM,KAAK,CAAA,CAAA,GAC3CS,cAYEC,EAAAA,MAAAC,EAAAA,QAAA,EAAA,CAXC,cAAaV,EAAA,WACb,YAAaA,EAAA,YACb,SAAUA,EAAA,SACV,YAAWA,EAAA,SACX,oBAAmB,WACnB,qBAAoB,mBACpB,MAAKW,EAAAA,eAAA,CAAA,OAAA,OAAmBX,EAAA,QAAM,SAAA,GAAmBA,EAAA,MAAM,KAAOA,EAAA,OAAM,EACpE,MAAOA,EAAA,MACR,SAAS,QACR,sBAAoBG,EACpB,SAASE,CAAA"}
1
+ {"version":3,"file":"JEditor.vue2.cjs","sources":["../../../../src/components/atoms/JEditor.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ref, computed, onMounted, onUnmounted } from 'vue'\nimport { MdEditor } from 'md-editor-v3'\nimport 'md-editor-v3/lib/style.css'\n\nconst props = withDefaults(\n defineProps<{\n /** 마크다운 내용 (v-model) */\n modelValue?: string\n /** 플레이스홀더 텍스트 */\n placeholder?: string\n /** 비활성화 상태 */\n disabled?: boolean\n /** 읽기 전용 상태 */\n readonly?: boolean\n /** 에디터 높이 */\n height?: string | number\n /** 테마 (light/dark) - 설정하지 않으면 자동으로 다크모드 감지 */\n theme?: 'light' | 'dark'\n /** 추가 CSS 클래스 */\n class?: string\n }>(),\n {\n modelValue: '',\n placeholder: '마크다운을 입력하세요...',\n disabled: false,\n readonly: false,\n height: '300px',\n },\n)\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string]\n 'change': [value: string]\n 'save': [value: string]\n}>()\n\n// 다크모드 상태\nconst isDarkMode = ref(false)\n\n// 다크모드 감지 함수\nconst detectDarkMode = () => {\n isDarkMode.value = document.documentElement.classList.contains('dark')\n}\n\n// 현재 테마 계산 (props.theme이 있으면 그것 사용, 없으면 자동 감지)\nconst currentTheme = computed(() => {\n if (props.theme) {\n return props.theme\n }\n return isDarkMode.value ? 'dark' : 'light'\n})\n\n// MutationObserver로 다크모드 변경 감지\nlet darkModeObserver: MutationObserver | null = null\n\nonMounted(() => {\n // 초기 다크모드 상태 감지\n detectDarkMode()\n \n // MutationObserver로 class 변경 감지\n darkModeObserver = new MutationObserver(() => {\n detectDarkMode()\n })\n \n darkModeObserver.observe(document.documentElement, {\n attributes: true,\n attributeFilter: ['class'],\n })\n})\n\nonUnmounted(() => {\n if (darkModeObserver) {\n darkModeObserver.disconnect()\n }\n})\n\nconst handleChange = (value: string) => {\n emit('update:modelValue', value)\n emit('change', value)\n}\n\nconst handleSave = (value: string) => {\n emit('save', value)\n}\n</script>\n\r\n<template>\n <div :class=\"['j-editor-wrapper', props.class]\">\n <MdEditor\n :model-value=\"modelValue\"\n :placeholder=\"placeholder\"\n :disabled=\"disabled\"\n :read-only=\"readonly\"\n :editor-class-name=\"'j-editor'\"\n :preview-class-name=\"'j-editor-preview'\"\n :style=\"{ height: typeof height === 'number' ? `${height}px` : height }\"\n :theme=\"currentTheme\"\n language=\"en-US\"\n @update:model-value=\"handleChange\"\n @on-save=\"handleSave\"\n />\n </div>\n</template>\n\r\n<style scoped>\r\n.j-editor-wrapper {\r\n @apply w-full;\r\n}\r\n</style>\r\n"],"names":["props","__props","emit","__emit","isDarkMode","ref","detectDarkMode","currentTheme","computed","darkModeObserver","onMounted","onUnmounted","handleChange","value","handleSave","_createElementBlock","_normalizeClass","_createVNode","_unref","MdEditor","_normalizeStyle"],"mappings":"+jBAKA,MAAMA,EAAQC,EA0BRC,EAAOC,EAOPC,EAAaC,EAAAA,IAAI,EAAK,EAGtBC,EAAiB,IAAM,CAC3BF,EAAW,MAAQ,SAAS,gBAAgB,UAAU,SAAS,MAAM,CACvE,EAGMG,EAAeC,EAAAA,SAAS,IACxBR,EAAM,MACDA,EAAM,MAERI,EAAW,MAAQ,OAAS,OACpC,EAGD,IAAIK,EAA4C,KAEhDC,EAAAA,UAAU,IAAM,CAEdJ,EAAA,EAGAG,EAAmB,IAAI,iBAAiB,IAAM,CAC5CH,EAAA,CACF,CAAC,EAEDG,EAAiB,QAAQ,SAAS,gBAAiB,CACjD,WAAY,GACZ,gBAAiB,CAAC,OAAO,CAAA,CAC1B,CACH,CAAC,EAEDE,EAAAA,YAAY,IAAM,CACZF,GACFA,EAAiB,WAAA,CAErB,CAAC,EAED,MAAMG,EAAgBC,GAAkB,CACtCX,EAAK,oBAAqBW,CAAK,EAC/BX,EAAK,SAAUW,CAAK,CACtB,EAEMC,EAAcD,GAAkB,CACpCX,EAAK,OAAQW,CAAK,CACpB,8BAIEE,EAAAA,mBAcM,MAAA,CAdA,MAAKC,EAAAA,eAAA,CAAA,mBAAuBhB,EAAM,KAAK,CAAA,CAAA,GAC3CiB,cAYEC,EAAAA,MAAAC,EAAAA,QAAA,EAAA,CAXC,cAAalB,EAAA,WACb,YAAaA,EAAA,YACb,SAAUA,EAAA,SACV,YAAWA,EAAA,SACX,oBAAmB,WACnB,qBAAoB,mBACpB,MAAKmB,EAAAA,eAAA,CAAA,OAAA,OAAmBnB,EAAA,QAAM,SAAA,GAAmBA,EAAA,MAAM,KAAOA,EAAA,OAAM,EACpE,MAAOM,EAAA,MACR,SAAS,QACR,sBAAoBK,EACpB,SAASE,CAAA"}
@@ -1,7 +1,7 @@
1
- import { defineComponent as i, createElementBlock as m, openBlock as r, normalizeClass as h, createVNode as s, unref as c, normalizeStyle as u } from "vue";
2
- import { MdEditor as f } from "md-editor-v3";
1
+ import { defineComponent as u, ref as m, computed as h, onMounted as f, onUnmounted as p, createElementBlock as v, openBlock as g, normalizeClass as b, createVNode as y, unref as k, normalizeStyle as M } from "vue";
2
+ import { MdEditor as V } from "md-editor-v3";
3
3
  /* empty css */
4
- const V = /* @__PURE__ */ i({
4
+ const S = /* @__PURE__ */ u({
5
5
  __name: "JEditor",
6
6
  props: {
7
7
  modelValue: { default: "" },
@@ -9,36 +9,50 @@ const V = /* @__PURE__ */ i({
9
9
  disabled: { type: Boolean, default: !1 },
10
10
  readonly: { type: Boolean, default: !1 },
11
11
  height: { default: "300px" },
12
- theme: { default: "light" },
12
+ theme: {},
13
13
  class: {}
14
14
  },
15
15
  emits: ["update:modelValue", "change", "save"],
16
- setup(e, { emit: t }) {
17
- const d = e, l = t, o = (a) => {
18
- l("update:modelValue", a), l("change", a);
19
- }, n = (a) => {
20
- l("save", a);
16
+ setup(e, { emit: r }) {
17
+ const l = e, n = r, o = m(!1), d = () => {
18
+ o.value = document.documentElement.classList.contains("dark");
19
+ }, s = h(() => l.theme ? l.theme : o.value ? "dark" : "light");
20
+ let a = null;
21
+ f(() => {
22
+ d(), a = new MutationObserver(() => {
23
+ d();
24
+ }), a.observe(document.documentElement, {
25
+ attributes: !0,
26
+ attributeFilter: ["class"]
27
+ });
28
+ }), p(() => {
29
+ a && a.disconnect();
30
+ });
31
+ const c = (t) => {
32
+ n("update:modelValue", t), n("change", t);
33
+ }, i = (t) => {
34
+ n("save", t);
21
35
  };
22
- return (a, g) => (r(), m("div", {
23
- class: h(["j-editor-wrapper", d.class])
36
+ return (t, E) => (g(), v("div", {
37
+ class: b(["j-editor-wrapper", l.class])
24
38
  }, [
25
- s(c(f), {
39
+ y(k(V), {
26
40
  "model-value": e.modelValue,
27
41
  placeholder: e.placeholder,
28
42
  disabled: e.disabled,
29
43
  "read-only": e.readonly,
30
44
  "editor-class-name": "j-editor",
31
45
  "preview-class-name": "j-editor-preview",
32
- style: u({ height: typeof e.height == "number" ? `${e.height}px` : e.height }),
33
- theme: e.theme,
46
+ style: M({ height: typeof e.height == "number" ? `${e.height}px` : e.height }),
47
+ theme: s.value,
34
48
  language: "en-US",
35
- "onUpdate:modelValue": o,
36
- onOnSave: n
49
+ "onUpdate:modelValue": c,
50
+ onOnSave: i
37
51
  }, null, 8, ["model-value", "placeholder", "disabled", "read-only", "style", "theme"])
38
52
  ], 2));
39
53
  }
40
54
  });
41
55
  export {
42
- V as default
56
+ S as default
43
57
  };
44
58
  //# sourceMappingURL=JEditor.vue2.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"JEditor.vue2.js","sources":["../../../../src/components/atoms/JEditor.vue"],"sourcesContent":["<script setup lang=\"ts\">\r\nimport { MdEditor } from 'md-editor-v3'\r\nimport 'md-editor-v3/lib/style.css'\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n /** 마크다운 내용 (v-model) */\r\n modelValue?: string\r\n /** 플레이스홀더 텍스트 */\r\n placeholder?: string\r\n /** 비활성화 상태 */\r\n disabled?: boolean\r\n /** 읽기 전용 상태 */\r\n readonly?: boolean\r\n /** 에디터 높이 */\r\n height?: string | number\r\n /** 테마 (light/dark) */\r\n theme?: 'light' | 'dark'\r\n /** 추가 CSS 클래스 */\r\n class?: string\r\n }>(),\r\n {\r\n modelValue: '',\r\n placeholder: '마크다운을 입력하세요...',\r\n disabled: false,\r\n readonly: false,\r\n height: '300px',\r\n theme: 'light',\r\n },\r\n)\r\n\r\nconst emit = defineEmits<{\r\n 'update:modelValue': [value: string]\r\n 'change': [value: string]\r\n 'save': [value: string]\r\n}>()\r\n\r\nconst handleChange = (value: string) => {\r\n emit('update:modelValue', value)\r\n emit('change', value)\r\n}\r\n\r\nconst handleSave = (value: string) => {\r\n emit('save', value)\r\n}\r\n</script>\r\n\r\n<template>\r\n <div :class=\"['j-editor-wrapper', props.class]\">\r\n <MdEditor\r\n :model-value=\"modelValue\"\r\n :placeholder=\"placeholder\"\r\n :disabled=\"disabled\"\r\n :read-only=\"readonly\"\r\n :editor-class-name=\"'j-editor'\"\r\n :preview-class-name=\"'j-editor-preview'\"\r\n :style=\"{ height: typeof height === 'number' ? `${height}px` : height }\"\r\n :theme=\"theme\"\r\n language=\"en-US\"\r\n @update:model-value=\"handleChange\"\r\n @on-save=\"handleSave\"\r\n />\r\n </div>\r\n</template>\r\n\r\n<style scoped>\r\n.j-editor-wrapper {\r\n @apply w-full;\r\n}\r\n</style>\r\n"],"names":["props","__props","emit","__emit","handleChange","value","handleSave","_createElementBlock","_normalizeClass","_createVNode","_unref","MdEditor","_normalizeStyle"],"mappings":";;;;;;;;;;;;;;;;AAIA,UAAMA,IAAQC,GA2BRC,IAAOC,GAMPC,IAAe,CAACC,MAAkB;AACtC,MAAAH,EAAK,qBAAqBG,CAAK,GAC/BH,EAAK,UAAUG,CAAK;AAAA,IACtB,GAEMC,IAAa,CAACD,MAAkB;AACpC,MAAAH,EAAK,QAAQG,CAAK;AAAA,IACpB;2BAIEE,EAcM,OAAA;AAAA,MAdA,OAAKC,EAAA,CAAA,oBAAuBR,EAAM,KAAK,CAAA;AAAA,IAAA;MAC3CS,EAYEC,EAAAC,CAAA,GAAA;AAAA,QAXC,eAAaV,EAAA;AAAA,QACb,aAAaA,EAAA;AAAA,QACb,UAAUA,EAAA;AAAA,QACV,aAAWA,EAAA;AAAA,QACX,qBAAmB;AAAA,QACnB,sBAAoB;AAAA,QACpB,OAAKW,EAAA,EAAA,QAAA,OAAmBX,EAAA,UAAM,WAAA,GAAmBA,EAAA,MAAM,OAAOA,EAAA,QAAM;AAAA,QACpE,OAAOA,EAAA;AAAA,QACR,UAAS;AAAA,QACR,uBAAoBG;AAAA,QACpB,UAASE;AAAA,MAAA;;;;"}
1
+ {"version":3,"file":"JEditor.vue2.js","sources":["../../../../src/components/atoms/JEditor.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ref, computed, onMounted, onUnmounted } from 'vue'\nimport { MdEditor } from 'md-editor-v3'\nimport 'md-editor-v3/lib/style.css'\n\nconst props = withDefaults(\n defineProps<{\n /** 마크다운 내용 (v-model) */\n modelValue?: string\n /** 플레이스홀더 텍스트 */\n placeholder?: string\n /** 비활성화 상태 */\n disabled?: boolean\n /** 읽기 전용 상태 */\n readonly?: boolean\n /** 에디터 높이 */\n height?: string | number\n /** 테마 (light/dark) - 설정하지 않으면 자동으로 다크모드 감지 */\n theme?: 'light' | 'dark'\n /** 추가 CSS 클래스 */\n class?: string\n }>(),\n {\n modelValue: '',\n placeholder: '마크다운을 입력하세요...',\n disabled: false,\n readonly: false,\n height: '300px',\n },\n)\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string]\n 'change': [value: string]\n 'save': [value: string]\n}>()\n\n// 다크모드 상태\nconst isDarkMode = ref(false)\n\n// 다크모드 감지 함수\nconst detectDarkMode = () => {\n isDarkMode.value = document.documentElement.classList.contains('dark')\n}\n\n// 현재 테마 계산 (props.theme이 있으면 그것 사용, 없으면 자동 감지)\nconst currentTheme = computed(() => {\n if (props.theme) {\n return props.theme\n }\n return isDarkMode.value ? 'dark' : 'light'\n})\n\n// MutationObserver로 다크모드 변경 감지\nlet darkModeObserver: MutationObserver | null = null\n\nonMounted(() => {\n // 초기 다크모드 상태 감지\n detectDarkMode()\n \n // MutationObserver로 class 변경 감지\n darkModeObserver = new MutationObserver(() => {\n detectDarkMode()\n })\n \n darkModeObserver.observe(document.documentElement, {\n attributes: true,\n attributeFilter: ['class'],\n })\n})\n\nonUnmounted(() => {\n if (darkModeObserver) {\n darkModeObserver.disconnect()\n }\n})\n\nconst handleChange = (value: string) => {\n emit('update:modelValue', value)\n emit('change', value)\n}\n\nconst handleSave = (value: string) => {\n emit('save', value)\n}\n</script>\n\r\n<template>\n <div :class=\"['j-editor-wrapper', props.class]\">\n <MdEditor\n :model-value=\"modelValue\"\n :placeholder=\"placeholder\"\n :disabled=\"disabled\"\n :read-only=\"readonly\"\n :editor-class-name=\"'j-editor'\"\n :preview-class-name=\"'j-editor-preview'\"\n :style=\"{ height: typeof height === 'number' ? `${height}px` : height }\"\n :theme=\"currentTheme\"\n language=\"en-US\"\n @update:model-value=\"handleChange\"\n @on-save=\"handleSave\"\n />\n </div>\n</template>\n\r\n<style scoped>\r\n.j-editor-wrapper {\r\n @apply w-full;\r\n}\r\n</style>\r\n"],"names":["props","__props","emit","__emit","isDarkMode","ref","detectDarkMode","currentTheme","computed","darkModeObserver","onMounted","onUnmounted","handleChange","value","handleSave","_createElementBlock","_normalizeClass","_createVNode","_unref","MdEditor","_normalizeStyle"],"mappings":";;;;;;;;;;;;;;;;AAKA,UAAMA,IAAQC,GA0BRC,IAAOC,GAOPC,IAAaC,EAAI,EAAK,GAGtBC,IAAiB,MAAM;AAC3B,MAAAF,EAAW,QAAQ,SAAS,gBAAgB,UAAU,SAAS,MAAM;AAAA,IACvE,GAGMG,IAAeC,EAAS,MACxBR,EAAM,QACDA,EAAM,QAERI,EAAW,QAAQ,SAAS,OACpC;AAGD,QAAIK,IAA4C;AAEhD,IAAAC,EAAU,MAAM;AAEd,MAAAJ,EAAA,GAGAG,IAAmB,IAAI,iBAAiB,MAAM;AAC5C,QAAAH,EAAA;AAAA,MACF,CAAC,GAEDG,EAAiB,QAAQ,SAAS,iBAAiB;AAAA,QACjD,YAAY;AAAA,QACZ,iBAAiB,CAAC,OAAO;AAAA,MAAA,CAC1B;AAAA,IACH,CAAC,GAEDE,EAAY,MAAM;AAChB,MAAIF,KACFA,EAAiB,WAAA;AAAA,IAErB,CAAC;AAED,UAAMG,IAAe,CAACC,MAAkB;AACtC,MAAAX,EAAK,qBAAqBW,CAAK,GAC/BX,EAAK,UAAUW,CAAK;AAAA,IACtB,GAEMC,IAAa,CAACD,MAAkB;AACpC,MAAAX,EAAK,QAAQW,CAAK;AAAA,IACpB;2BAIEE,EAcM,OAAA;AAAA,MAdA,OAAKC,EAAA,CAAA,oBAAuBhB,EAAM,KAAK,CAAA;AAAA,IAAA;MAC3CiB,EAYEC,EAAAC,CAAA,GAAA;AAAA,QAXC,eAAalB,EAAA;AAAA,QACb,aAAaA,EAAA;AAAA,QACb,UAAUA,EAAA;AAAA,QACV,aAAWA,EAAA;AAAA,QACX,qBAAmB;AAAA,QACnB,sBAAoB;AAAA,QACpB,OAAKmB,EAAA,EAAA,QAAA,OAAmBnB,EAAA,UAAM,WAAA,GAAmBA,EAAA,MAAM,OAAOA,EAAA,QAAM;AAAA,QACpE,OAAOM,EAAA;AAAA,QACR,UAAS;AAAA,QACR,uBAAoBK;AAAA,QACpB,UAASE;AAAA,MAAA;;;;"}
@@ -3,5 +3,5 @@
3
3
  for (const [t_key, t_val] of t_opts)
4
4
  t_merged[t_key] = t_val;
5
5
  return t_merged;
6
- };,u=t(e.default,[["__scopeId","data-v-8d4485e3"]]);exports.default=u;
6
+ };,u=t(e.default,[["__scopeId","data-v-17ece534"]]);exports.default=u;
7
7
  //# sourceMappingURL=JGrid.vue.cjs.map
@@ -6,8 +6,8 @@ const r = (r_comp, r_opts) => {
6
6
  r_merged[r_key] = r_val;
7
7
  return r_merged;
8
8
  };
9
- const _ = /* @__PURE__ */ r(o, [["__scopeId", "data-v-8d4485e3"]]);
9
+ const p = /* @__PURE__ */ r(o, [["__scopeId", "data-v-17ece534"]]);
10
10
  export {
11
- _ as default
11
+ p as default
12
12
  };
13
13
  //# sourceMappingURL=JGrid.vue.js.map
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const a=require("vue"),T=require("ag-grid-vue3"),v=require("ag-grid-community"),N=require("ag-grid-enterprise");;/* empty css */;/* empty css */;/* empty css */const S={class:"ag-grid-container"},A=a.defineComponent({__name:"JGrid",props:{rowData:{},columnDefs:{},theme:{default:"ag-theme-balham"},pagination:{type:Boolean,default:!0},checkbox:{type:Boolean,default:!1},rowNumbers:{type:Boolean,default:!0},actionButtons:{default:void 0},autoDetectDarkMode:{type:Boolean,default:!0},summaryColumn:{type:Boolean,default:!1},hiddenColumn:{type:Boolean,default:!1},enableGrouping:{type:Boolean,default:!0},enablePivot:{type:Boolean,default:!1},enableExcelExport:{type:Boolean,default:!1},enableTreeData:{type:Boolean,default:!1},getDataPath:{type:Function,default:void 0},autoGroupColumnDef:{default:void 0},selectedRows:{default:()=>[]},columnHover:{type:Boolean,default:!0},enableColumnsToolPanel:{type:Boolean,default:!0},statusBar:{type:Boolean,default:!0}},emits:["rowClicked","rowDoubleClicked","cellClicked","selectionChanged","cellValueChanged","gridReady","update:selectedRows"],setup(c,{expose:b,emit:y}){v.ModuleRegistry.registerModules([v.AllCommunityModule,N.AllEnterpriseModule]);const e=c,r=y,n=a.ref(null),d=a.ref(null),p=a.ref(!1),f=()=>{p.value=document.documentElement.classList.contains("dark")},x=a.computed(()=>{if(!e.autoDetectDarkMode)return e.theme;const t=e.theme;return p.value?t.includes("-dark")?t:`${t}-dark`:t.replace(/-dark$/,"")}),k=t=>{const u=e.actionButtons||[],h=t.data,C=u.filter(o=>o.show?o.show(h):!0);if(C.length===0)return"";const i=document.createElement("div");return i.className="flex items-center gap-1",C.forEach(o=>{const l=document.createElement("button");l.className="px-2 py-1 text-xs border rounded transition-colors",o.styletype==="danger"?l.className+=" bg-red-50 border-red-400 text-red-700 hover:bg-red-100 dark:bg-red-950 dark:border-red-700 dark:text-red-400 dark:hover:bg-red-900":l.className+=" bg-gray-50 border-gray-400 text-gray-700 hover:bg-gray-100 dark:bg-gray-800 dark:border-gray-600 dark:text-gray-300 dark:hover:bg-gray-700",o.tooltip&&(l.title=o.tooltip),o.label?l.textContent=o.label:o.icon&&(o.icon==="pencil"?l.textContent="수정":o.icon==="trash2"||o.icon==="trash"?l.textContent="삭제":o.icon==="eye"?l.textContent="보기":o.icon==="copy"?l.textContent="복사":o.icon==="download"?l.textContent="다운로드":o.icon==="circleX"?l.textContent="비활성화":o.icon==="circleCheckBig"?l.textContent="활성화":l.textContent=o.icon),l.addEventListener("click",R=>{R.stopPropagation(),o.onClick(h)}),i.appendChild(l)}),i},m=a.computed(()=>!e.actionButtons||e.actionButtons.length===0?null:{colId:"actionButtons",headerName:"작업",field:"_actions",width:120,minWidth:80,maxWidth:200,lockPosition:"left",sortable:!1,filter:!1,resizable:!0,suppressNavigable:!0,suppressHeaderMenuButton:!0,cellRenderer:k,cellStyle:{display:"flex",justifyContent:"center",alignItems:"center"}}),g=a.computed(()=>{const t=[];return e.checkbox&&t.push({colId:"rowSelection",headerName:"",width:50,minWidth:50,maxWidth:50,lockPosition:"left",checkboxSelection:!0,headerCheckboxSelection:!0,sortable:!1,filter:!1,resizable:!1,suppressNavigable:!0,suppressHeaderMenuButton:!0,cellStyle:{display:"flex",justifyContent:"center",alignItems:"center"}}),m.value&&t.push(m.value),t.push(...e.columnDefs),t}),D=a.computed(()=>({pagination:e.pagination,rowSelection:e.checkbox?"multiple":void 0,suppressRowClickSelection:e.checkbox,rowNumbers:e.rowNumbers,columnHoverHighlight:e.columnHover,sideBar:e.enableColumnsToolPanel||e.enableGrouping||e.enablePivot?{toolPanels:[{id:"columns",labelDefault:"Columns",labelKey:"columns",iconKey:"columns",toolPanel:"agColumnsToolPanel",toolPanelParams:{suppressRowGroups:!e.enableGrouping,suppressValues:!e.enablePivot,suppressPivots:!e.enablePivot,suppressPivotMode:!e.enablePivot}}],defaultToolPanel:""}:void 0,statusBar:e.statusBar?{statusPanels:[{statusPanel:"agTotalAndFilteredRowCountComponent",align:"left"},{statusPanel:"agSelectedRowCountComponent",align:"left"},{statusPanel:"agAggregationComponent",align:"right"}]}:void 0,groupDefaultExpanded:e.enableGrouping||e.enableTreeData?1:void 0,suppressAggFuncInHeader:!1,treeData:e.enableTreeData||void 0,getDataPath:e.enableTreeData?e.getDataPath||(u=>u.path||[]):void 0,autoGroupColumnDef:e.enableTreeData&&e.autoGroupColumnDef?e.autoGroupColumnDef:void 0}));b({gridApi:n,gridColumnApi:d,exportToExcel:()=>{n.value&&e.enableExcelExport&&n.value.exportDataAsExcel({fileName:"grid-export.xlsx"})}});const w=t=>{n.value=t.api,d.value=t.api,r("gridReady",t)},B=t=>{r("rowClicked",t)},P=t=>{r("rowDoubleClicked",t)},E=t=>{r("cellClicked",t)},G=t=>{r("selectionChanged",t),r("update:selectedRows",t.api.getSelectedRows())},M=t=>{r("cellValueChanged",t)};let s=null;return a.onMounted(()=>{e.autoDetectDarkMode&&(f(),s=new MutationObserver(()=>{f()}),s.observe(document.documentElement,{attributes:!0,attributeFilter:["class"]}))}),a.onUnmounted(()=>{s&&s.disconnect()}),a.watch(()=>e.columnDefs,()=>{n.value&&n.value.setGridOption("columnDefs",g.value)},{deep:!0}),a.watch(()=>e.rowData,()=>{n.value&&n.value.setGridOption("rowData",e.rowData)},{deep:!0}),(t,u)=>(a.openBlock(),a.createElementBlock("div",S,[a.createVNode(a.unref(T.AgGridVue),{"column-defs":g.value,"row-data":c.rowData,"grid-options":D.value,class:a.normalizeClass(x.value),style:{height:"100%",width:"100%"},onGridReady:w,onRowClicked:B,onRowDoubleClicked:P,onCellClicked:E,onSelectionChanged:G,onCellValueChanged:M},null,8,["column-defs","row-data","grid-options","class"])]))}});exports.default=A;
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const a=require("vue"),R=require("ag-grid-vue3"),T=require("../../lib/utils.cjs"),C=require("ag-grid-community"),N=require("ag-grid-enterprise");;/* empty css */;/* empty css */;/* empty css */const A=a.defineComponent({__name:"JGrid",props:{class:{},rowData:{},columnDefs:{},theme:{default:"ag-theme-balham"},pagination:{type:Boolean,default:!0},checkbox:{type:Boolean,default:!1},rowNumbers:{type:Boolean,default:!0},actionButtons:{default:void 0},autoDetectDarkMode:{type:Boolean,default:!0},summaryColumn:{type:Boolean,default:!1},hiddenColumn:{type:Boolean,default:!1},enableGrouping:{type:Boolean,default:!0},enablePivot:{type:Boolean,default:!1},enableExcelExport:{type:Boolean,default:!1},enableTreeData:{type:Boolean,default:!1},getDataPath:{type:Function,default:void 0},autoGroupColumnDef:{default:void 0},selectedRows:{default:()=>[]},columnHover:{type:Boolean,default:!0},enableColumnsToolPanel:{type:Boolean,default:!0},statusBar:{type:Boolean,default:!0},compactFooter:{type:Boolean,default:!1},rowGroupPanelShow:{default:"never"},groupDefaultExpanded:{default:-1},pivotPanelShow:{default:"never"},pivotMode:{type:Boolean,default:!1}},emits:["rowClicked","rowDoubleClicked","cellClicked","selectionChanged","cellValueChanged","gridReady","update:selectedRows"],setup(d,{expose:b,emit:w}){C.ModuleRegistry.registerModules([C.AllCommunityModule,N.AllEnterpriseModule]);const e=d,r=w,n=a.ref(null),c=a.ref(null),p=a.ref(!1),f=()=>{p.value=document.documentElement.classList.contains("dark")},y=a.computed(()=>{if(!e.autoDetectDarkMode)return e.theme;const t=e.theme;return p.value?t.includes("-dark")?t:`${t}-dark`:t.replace(/-dark$/,"")}),x=t=>{const u=e.actionButtons||[],h=t.data,v=u.filter(o=>o.show?o.show(h):!0);if(v.length===0)return"";const i=document.createElement("div");return i.className="flex items-center gap-1",v.forEach(o=>{const l=document.createElement("button");l.className="px-2 py-1 text-xs border rounded transition-colors",o.styletype==="danger"?l.className+=" bg-red-50 border-red-400 text-red-700 hover:bg-red-100 dark:bg-red-950 dark:border-red-700 dark:text-red-400 dark:hover:bg-red-900":l.className+=" bg-gray-50 border-gray-400 text-gray-700 hover:bg-gray-100 dark:bg-gray-800 dark:border-gray-600 dark:text-gray-300 dark:hover:bg-gray-700",o.tooltip&&(l.title=o.tooltip),o.label?l.textContent=o.label:o.icon&&(o.icon==="pencil"?l.textContent="수정":o.icon==="trash2"||o.icon==="trash"?l.textContent="삭제":o.icon==="eye"?l.textContent="보기":o.icon==="copy"?l.textContent="복사":o.icon==="download"?l.textContent="다운로드":o.icon==="circleX"?l.textContent="비활성화":o.icon==="circleCheckBig"?l.textContent="활성화":l.textContent=o.icon),l.addEventListener("click",E=>{E.stopPropagation(),o.onClick(h)}),i.appendChild(l)}),i},m=a.computed(()=>!e.actionButtons||e.actionButtons.length===0?null:{colId:"actionButtons",headerName:"작업",field:"_actions",width:120,minWidth:80,maxWidth:200,lockPosition:"left",sortable:!1,filter:!1,resizable:!0,suppressNavigable:!0,suppressHeaderMenuButton:!0,cellRenderer:x,cellStyle:{display:"flex",justifyContent:"center",alignItems:"center"}}),g=a.computed(()=>{const t=[];return e.checkbox&&t.push({colId:"rowSelection",headerName:"",width:50,minWidth:50,maxWidth:50,lockPosition:"left",checkboxSelection:!0,headerCheckboxSelection:!0,sortable:!1,filter:!1,resizable:!1,suppressNavigable:!0,suppressHeaderMenuButton:!0,cellStyle:{display:"flex",justifyContent:"center",alignItems:"center"}}),m.value&&t.push(m.value),t.push(...e.columnDefs),t}),k=a.computed(()=>({pagination:e.pagination,rowSelection:e.checkbox?"multiple":void 0,suppressRowClickSelection:e.checkbox,rowNumbers:e.rowNumbers,columnHoverHighlight:e.columnHover,sideBar:e.enableColumnsToolPanel||e.enableGrouping||e.enablePivot?{toolPanels:[{id:"columns",labelDefault:"Columns",labelKey:"columns",iconKey:"columns",toolPanel:"agColumnsToolPanel",toolPanelParams:{suppressRowGroups:!e.enableGrouping,suppressValues:!e.enablePivot,suppressPivots:!e.enablePivot,suppressPivotMode:!e.enablePivot}}],defaultToolPanel:""}:void 0,statusBar:e.statusBar&&!e.compactFooter?{statusPanels:[{statusPanel:"agTotalAndFilteredRowCountComponent",align:"left"},{statusPanel:"agSelectedRowCountComponent",align:"left"},{statusPanel:"agAggregationComponent",align:"right"}]}:void 0,rowGroupPanelShow:e.rowGroupPanelShow!=="never"?e.rowGroupPanelShow:void 0,pivotPanelShow:e.pivotPanelShow!=="never"?e.pivotPanelShow:void 0,pivotMode:e.pivotMode,groupDefaultExpanded:e.groupDefaultExpanded,suppressAggFuncInHeader:!1,treeData:e.enableTreeData||void 0,getDataPath:e.enableTreeData?e.getDataPath||(u=>u.path||[]):void 0,autoGroupColumnDef:e.enableTreeData&&e.autoGroupColumnDef?e.autoGroupColumnDef:void 0}));b({gridApi:n,gridColumnApi:c,exportToExcel:()=>{n.value&&e.enableExcelExport&&n.value.exportDataAsExcel({fileName:"grid-export.xlsx"})}});const D=t=>{n.value=t.api,c.value=t.api,r("gridReady",t)},P=t=>{r("rowClicked",t)},B=t=>{r("rowDoubleClicked",t)},G=t=>{r("cellClicked",t)},M=t=>{r("selectionChanged",t),r("update:selectedRows",t.api.getSelectedRows())},S=t=>{r("cellValueChanged",t)};let s=null;return a.onMounted(()=>{e.autoDetectDarkMode&&(f(),s=new MutationObserver(()=>{f()}),s.observe(document.documentElement,{attributes:!0,attributeFilter:["class"]}))}),a.onUnmounted(()=>{s&&s.disconnect()}),a.watch(()=>e.columnDefs,()=>{n.value&&n.value.setGridOption("columnDefs",g.value)},{deep:!0}),a.watch(()=>e.rowData,()=>{n.value&&n.value.setGridOption("rowData",e.rowData)},{deep:!0}),(t,u)=>(a.openBlock(),a.createElementBlock("div",{class:a.normalizeClass(a.unref(T.cn)("ag-grid-container",e.class))},[a.createVNode(a.unref(R.AgGridVue),{"column-defs":g.value,"row-data":d.rowData,"grid-options":k.value,class:a.normalizeClass(y.value),style:{height:"100%",width:"100%"},onGridReady:D,onRowClicked:P,onRowDoubleClicked:B,onCellClicked:G,onSelectionChanged:M,onCellValueChanged:S},null,8,["column-defs","row-data","grid-options","class"])],2))}});exports.default=A;
2
2
  //# sourceMappingURL=JGrid.vue2.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"JGrid.vue2.cjs","sources":["../../../../src/components/atoms/JGrid.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, ref, watch, onMounted, onUnmounted } from 'vue'\nimport { AgGridVue } from 'ag-grid-vue3'\nimport type {\n ColDef,\n GridOptions,\n RowClickedEvent,\n CellClickedEvent,\n SelectionChangedEvent,\n CellValueChangedEvent,\n RowDoubleClickedEvent,\n GridReadyEvent,\n ICellRendererParams,\n} from 'ag-grid-community'\nimport { ModuleRegistry, AllCommunityModule } from 'ag-grid-community'\n// Enterprise 모듈 import (Grouping, Pivot, Excel Export 등)\nimport { AllEnterpriseModule } from 'ag-grid-enterprise'\n// ag-grid.css는 제거 - v34에서 Theming API와 충돌 방지\n// 테마 CSS 파일만 사용 (클래스 기반 테마)\n// v34에서는 dark 테마가 같은 CSS 파일 안에 포함되어 있음\n// 예: ag-theme-quartz.css에 .ag-theme-quartz-dark 클래스 포함\nimport 'ag-grid-community/styles/ag-theme-quartz.css'\nimport 'ag-grid-community/styles/ag-theme-alpine.css'\nimport 'ag-grid-community/styles/ag-theme-balham.css'\n\n// AG Grid 모듈 등록 (Community + Enterprise)\nModuleRegistry.registerModules([AllCommunityModule, AllEnterpriseModule])\n\n/**\n * Action Button 정의 타입\n */\nexport type ActionButton = {\n /** 버튼 아이콘 이름 (lucide) - label이 없을 때 기본 텍스트 생성에 사용 */\n icon?: string\n /** 버튼 라벨 */\n label?: string\n /** 툴팁 텍스트 */\n tooltip?: string\n /** 버튼 클릭 핸들러 (rowData 전달) */\n onClick: (rowData: any) => void\n /** 버튼 스타일 타입 */\n styletype?: 'default' | 'primary' | 'secondary' | 'success' | 'warning' | 'danger'\n /** 조건부 표시 함수 (rowData를 받아 boolean 반환) */\n show?: (rowData: any) => boolean\n}\n\nconst props = withDefaults(\n defineProps<{\n /** 그리드에 표시할 데이터 배열 */\n rowData: any[]\n /** 컬럼 정의 배열 */\n columnDefs: ColDef[]\n /** ag-Grid 테마 */\n theme?: string\n /** 페이지네이션 활성화 여부 */\n pagination?: boolean\n /** 체크박스 선택 활성화 여부 */\n checkbox?: boolean\n /** 행 번호 표시 여부 (Enterprise) */\n rowNumbers?: boolean\n /** 행별 액션 버튼 목록 */\n actionButtons?: ActionButton[]\n /** 다크모드 자동 감지 여부 */\n autoDetectDarkMode?: boolean\n /** 요약 컬럼 표시 여부 */\n summaryColumn?: boolean\n /** 숨김 컬럼 관리 활성화 여부 */\n hiddenColumn?: boolean\n /** 그룹핑 기능 활성화 여부 (Enterprise) */\n enableGrouping?: boolean\n /** 피벗 기능 활성화 여부 (Enterprise) */\n enablePivot?: boolean\n /** Excel 내보내기 기능 활성화 여부 (Enterprise) */\n enableExcelExport?: boolean\n /** Tree Data 기능 활성화 여부 (Enterprise) */\n enableTreeData?: boolean\n /** Tree Data 계층 경로를 반환하는 함수 */\n getDataPath?: (data: any) => (string | number)[]\n /** Tree Data 그룹 컬럼 정의 */\n autoGroupColumnDef?: ColDef\n /** 선택된 행 데이터 배열 (v-model:selected-rows) */\n selectedRows?: any[]\n /** 컬럼 호버 하이라이트 활성화 여부 */\n columnHover?: boolean\n /** Columns Tool Panel 활성화 여부 (Enterprise) */\n enableColumnsToolPanel?: boolean\n /** Status Bar 활성화 여부 (Enterprise) */\n statusBar?: boolean\n }>(),\n {\n theme: 'ag-theme-balham',\n pagination: true,\n checkbox: false,\n rowNumbers: true,\n actionButtons: undefined,\n autoDetectDarkMode: true,\n summaryColumn: false,\n hiddenColumn: false,\n enableGrouping: true,\n enablePivot: false,\n enableExcelExport: false,\n enableTreeData: false,\n getDataPath: undefined,\n autoGroupColumnDef: undefined,\n selectedRows: () => [],\n columnHover: true,\n enableColumnsToolPanel: true,\n statusBar: true,\n },\n)\n\nconst emit = defineEmits<{\n /** 행 클릭 이벤트 */\n rowClicked: [event: RowClickedEvent]\n /** 행 더블클릭 이벤트 */\n rowDoubleClicked: [event: RowDoubleClickedEvent]\n /** 셀 클릭 이벤트 */\n cellClicked: [event: CellClickedEvent]\n /** 선택 변경 이벤트 (체크박스 등) */\n selectionChanged: [event: SelectionChangedEvent]\n /** 셀 값 변경 이벤트 */\n cellValueChanged: [event: CellValueChangedEvent]\n /** 그리드 준비 완료 이벤트 */\n gridReady: [event: GridReadyEvent]\n /** 선택된 행 변경 이벤트 (v-model:selected-rows) */\n 'update:selectedRows': [rows: any[]]\n}>()\n\n// ag-Grid 인스턴스 참조\nconst gridApi = ref<any>(null)\nconst gridColumnApi = ref<any>(null)\n\n// 다크모드 상태\nconst isDarkMode = ref(false)\n\n// 다크모드 감지 함수\nconst detectDarkMode = () => {\n isDarkMode.value = document.documentElement.classList.contains('dark')\n}\n\n// 현재 테마 계산 (다크모드 자동 전환)\nconst currentTheme = computed(() => {\n if (!props.autoDetectDarkMode) {\n return props.theme\n }\n \n const baseTheme = props.theme\n if (isDarkMode.value) {\n // 이미 dark 테마인 경우 그대로 유지, 아니면 -dark 추가\n return baseTheme.includes('-dark') ? baseTheme : `${baseTheme}-dark`\n } else {\n // dark 테마 제거\n return baseTheme.replace(/-dark$/, '')\n }\n})\n\n// Action Buttons Cell Renderer - 함수형으로 DOM 직접 생성\nconst ActionButtonsCellRenderer = (params: ICellRendererParams) => {\n const buttons = props.actionButtons || []\n const rowData = params.data\n \n // 표시할 버튼 필터링\n const visibleButtons = buttons.filter(btn => {\n if (btn.show) {\n return btn.show(rowData)\n }\n return true\n })\n \n if (visibleButtons.length === 0) {\n return ''\n }\n \n // 컨테이너 div 생성\n const container = document.createElement('div')\n container.className = 'flex items-center gap-1'\n \n // 각 버튼 생성\n visibleButtons.forEach((btn) => {\n const button = document.createElement('button')\n button.className = 'px-2 py-1 text-xs border rounded transition-colors'\n \n // styletype에 따른 클래스 추가\n if (btn.styletype === 'danger') {\n button.className += ' bg-red-50 border-red-400 text-red-700 hover:bg-red-100 dark:bg-red-950 dark:border-red-700 dark:text-red-400 dark:hover:bg-red-900'\n } else {\n button.className += ' bg-gray-50 border-gray-400 text-gray-700 hover:bg-gray-100 dark:bg-gray-800 dark:border-gray-600 dark:text-gray-300 dark:hover:bg-gray-700'\n }\n \n // tooltip\n if (btn.tooltip) {\n button.title = btn.tooltip\n }\n \n // 라벨 추가 (텍스트 버튼)\n if (btn.label) {\n button.textContent = btn.label\n } else if (btn.icon) {\n // 라벨이 없으면 기본 텍스트 생성\n if (btn.icon === 'pencil') {\n button.textContent = '수정'\n } else if (btn.icon === 'trash2' || btn.icon === 'trash') {\n button.textContent = '삭제'\n } else if (btn.icon === 'eye') {\n button.textContent = '보기'\n } else if (btn.icon === 'copy') {\n button.textContent = '복사'\n } else if (btn.icon === 'download') {\n button.textContent = '다운로드'\n } else if (btn.icon === 'circleX') {\n button.textContent = '비활성화'\n } else if (btn.icon === 'circleCheckBig') {\n button.textContent = '활성화'\n } else {\n button.textContent = btn.icon\n }\n }\n \n // 클릭 이벤트\n button.addEventListener('click', (e) => {\n e.stopPropagation()\n btn.onClick(rowData)\n })\n \n container.appendChild(button)\n })\n \n return container\n}\n\n// Action Buttons 컬럼 정의\nconst actionButtonsColumn = computed<ColDef | null>(() => {\n if (!props.actionButtons || props.actionButtons.length === 0) {\n return null\n }\n \n return {\n colId: 'actionButtons',\n headerName: '작업',\n field: '_actions',\n width: 120,\n minWidth: 80,\n maxWidth: 200,\n lockPosition: 'left' as const,\n sortable: false,\n filter: false,\n resizable: true,\n suppressNavigable: true,\n suppressHeaderMenuButton: true,\n cellRenderer: ActionButtonsCellRenderer,\n cellStyle: { display: 'flex', justifyContent: 'center', alignItems: 'center' },\n }\n})\n\n// checkbox 활성화 및 추가 컬럼 처리\nconst processedColumnDefs = computed(() => {\n const columns: ColDef[] = []\n \n // 1. Checkbox 컬럼 (최우선)\n if (props.checkbox) {\n columns.push({\n colId: 'rowSelection',\n headerName: '',\n // field와 valueGetter 제거 - AG Grid 공식 방식\n width: 50,\n minWidth: 50,\n maxWidth: 50,\n lockPosition: 'left' as const,\n checkboxSelection: true,\n headerCheckboxSelection: true,\n sortable: false,\n filter: false,\n resizable: false,\n suppressNavigable: true,\n suppressHeaderMenuButton: true,\n cellStyle: { display: 'flex', justifyContent: 'center', alignItems: 'center' },\n })\n }\n \n // 2. Action Buttons 컬럼\n if (actionButtonsColumn.value) {\n columns.push(actionButtonsColumn.value)\n }\n \n // 3. 사용자 정의 컬럼들 (Row Numbers는 AG Grid가 자동으로 추가)\n columns.push(...props.columnDefs)\n \n return columns\n})\n\n// Grid 옵션 설정\nconst gridOptions = computed<GridOptions>(() => {\n const options: GridOptions = {\n // theme 옵션 제거 - 클래스 기반 테마(:class=\"theme\") 사용\n // columnDefs와 rowData는 prop으로 전달하므로 여기서 제거\n pagination: props.pagination,\n rowSelection: props.checkbox ? 'multiple' : undefined,\n // 체크박스 모드일 때 row 클릭으로 선택이 변경되지 않도록 설정\n // 체크박스만으로 선택을 제어하도록 함\n suppressRowClickSelection: props.checkbox,\n\n // Row Numbers (Enterprise) - AG Grid 표준 방식\n rowNumbers: props.rowNumbers,\n\n // Column Hover Highlight\n columnHoverHighlight: props.columnHover,\n\n // Enterprise 기능 옵션\n sideBar: props.enableColumnsToolPanel || props.enableGrouping || props.enablePivot ? {\n toolPanels: [\n {\n id: 'columns',\n labelDefault: 'Columns',\n labelKey: 'columns',\n iconKey: 'columns',\n toolPanel: 'agColumnsToolPanel',\n toolPanelParams: {\n suppressRowGroups: !props.enableGrouping,\n suppressValues: !props.enablePivot,\n suppressPivots: !props.enablePivot,\n suppressPivotMode: !props.enablePivot,\n },\n },\n ],\n defaultToolPanel: '', // 초기에는 접힌 상태\n } : undefined,\n\n // Status Bar (Enterprise)\n statusBar: props.statusBar ? {\n statusPanels: [\n { statusPanel: 'agTotalAndFilteredRowCountComponent', align: 'left' as const },\n { statusPanel: 'agSelectedRowCountComponent', align: 'left' as const },\n { statusPanel: 'agAggregationComponent', align: 'right' as const },\n ],\n } : undefined,\n\n // 그룹핑 기본 설정\n groupDefaultExpanded: props.enableGrouping || props.enableTreeData ? 1 : undefined,\n suppressAggFuncInHeader: false,\n\n // Tree Data 설정 (Enterprise)\n treeData: props.enableTreeData || undefined,\n getDataPath: props.enableTreeData\n ? (props.getDataPath || ((data: any) => data.path || []))\n : undefined,\n autoGroupColumnDef: props.enableTreeData && props.autoGroupColumnDef\n ? props.autoGroupColumnDef\n : undefined,\n }\n\n return options\n})\n\n// Excel 내보내기 함수 (외부에서 사용 가능하도록 expose)\nconst exportToExcel = () => {\n if (gridApi.value && props.enableExcelExport) {\n gridApi.value.exportDataAsExcel({\n fileName: 'grid-export.xlsx',\n })\n }\n}\n\n// 그리드 API를 외부에 노출\ndefineExpose({\n gridApi,\n gridColumnApi,\n exportToExcel,\n})\n\n// Grid ready 이벤트 핸들러\nconst onGridReady = (params: GridReadyEvent) => {\n gridApi.value = params.api\n gridColumnApi.value = params.api // v34에서 columnApi는 deprecated\n emit('gridReady', params)\n}\n\n// 행 클릭 이벤트 핸들러\nconst onRowClicked = (event: RowClickedEvent) => {\n emit('rowClicked', event)\n}\n\n// 행 더블클릭 이벤트 핸들러\nconst onRowDoubleClicked = (event: RowDoubleClickedEvent) => {\n emit('rowDoubleClicked', event)\n}\n\n// 셀 클릭 이벤트 핸들러\nconst onCellClicked = (event: CellClickedEvent) => {\n emit('cellClicked', event)\n}\n\n// 선택 변경 이벤트 핸들러\nconst onSelectionChanged = (event: SelectionChangedEvent) => {\n emit('selectionChanged', event)\n emit('update:selectedRows', event.api.getSelectedRows())\n}\n\n// 셀 값 변경 이벤트 핸들러\nconst onCellValueChanged = (event: CellValueChangedEvent) => {\n emit('cellValueChanged', event)\n}\n\n// MutationObserver로 다크모드 변경 감지\nlet darkModeObserver: MutationObserver | null = null\n\nonMounted(() => {\n if (props.autoDetectDarkMode) {\n // 초기 다크모드 상태 감지\n detectDarkMode()\n \n // MutationObserver로 class 변경 감지\n darkModeObserver = new MutationObserver(() => {\n detectDarkMode()\n })\n \n darkModeObserver.observe(document.documentElement, {\n attributes: true,\n attributeFilter: ['class'],\n })\n }\n})\n\nonUnmounted(() => {\n if (darkModeObserver) {\n darkModeObserver.disconnect()\n }\n})\n\n// columnDefs 변경 감지\nwatch(\n () => props.columnDefs,\n () => {\n if (gridApi.value) {\n gridApi.value.setGridOption('columnDefs', processedColumnDefs.value)\n }\n },\n { deep: true },\n)\n\n// rowData 변경 감지\nwatch(\n () => props.rowData,\n () => {\n if (gridApi.value) {\n gridApi.value.setGridOption('rowData', props.rowData)\n }\n },\n { deep: true },\n)\n</script>\n\n<template>\n <div class=\"ag-grid-container\">\n <AgGridVue\n :column-defs=\"processedColumnDefs\"\n :row-data=\"rowData\"\n :grid-options=\"gridOptions\"\n :class=\"currentTheme\"\n style=\"height: 100%; width: 100%\"\n @grid-ready=\"onGridReady\"\n @row-clicked=\"onRowClicked\"\n @row-double-clicked=\"onRowDoubleClicked\"\n @cell-clicked=\"onCellClicked\"\n @selection-changed=\"onSelectionChanged\"\n @cell-value-changed=\"onCellValueChanged\"\n />\n </div>\n</template>\n\n<style scoped>\n.ag-grid-container {\n width: 100%;\n height: 100%;\n}\n</style>\n"],"names":["ModuleRegistry","AllCommunityModule","AllEnterpriseModule","props","__props","emit","__emit","gridApi","ref","gridColumnApi","isDarkMode","detectDarkMode","currentTheme","computed","baseTheme","ActionButtonsCellRenderer","params","buttons","rowData","visibleButtons","btn","container","button","e","actionButtonsColumn","processedColumnDefs","columns","gridOptions","data","__expose","onGridReady","onRowClicked","event","onRowDoubleClicked","onCellClicked","onSelectionChanged","onCellValueChanged","darkModeObserver","onMounted","onUnmounted","watch","_openBlock","_createElementBlock","_hoisted_1","_createVNode","_unref","AgGridVue"],"mappings":"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"}
1
+ {"version":3,"file":"JGrid.vue2.cjs","sources":["../../../../src/components/atoms/JGrid.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, ref, watch, onMounted, onUnmounted } from 'vue'\nimport { AgGridVue } from 'ag-grid-vue3'\nimport { cn } from '@/lib/utils'\nimport type {\n ColDef,\n GridOptions,\n RowClickedEvent,\n CellClickedEvent,\n SelectionChangedEvent,\n CellValueChangedEvent,\n RowDoubleClickedEvent,\n GridReadyEvent,\n ICellRendererParams,\n} from 'ag-grid-community'\nimport { ModuleRegistry, AllCommunityModule } from 'ag-grid-community'\n// Enterprise 모듈 import (Grouping, Pivot, Excel Export 등)\nimport { AllEnterpriseModule } from 'ag-grid-enterprise'\n// ag-grid.css는 제거 - v34에서 Theming API와 충돌 방지\n// 테마 CSS 파일만 사용 (클래스 기반 테마)\n// v34에서는 dark 테마가 같은 CSS 파일 안에 포함되어 있음\n// 예: ag-theme-quartz.css에 .ag-theme-quartz-dark 클래스 포함\nimport 'ag-grid-community/styles/ag-theme-quartz.css'\nimport 'ag-grid-community/styles/ag-theme-alpine.css'\nimport 'ag-grid-community/styles/ag-theme-balham.css'\n\n// AG Grid 모듈 등록 (Community + Enterprise)\nModuleRegistry.registerModules([AllCommunityModule, AllEnterpriseModule])\n\n/**\n * Action Button 정의 타입\n */\nexport type ActionButton = {\n /** 버튼 아이콘 이름 (lucide) - label이 없을 때 기본 텍스트 생성에 사용 */\n icon?: string\n /** 버튼 라벨 */\n label?: string\n /** 툴팁 텍스트 */\n tooltip?: string\n /** 버튼 클릭 핸들러 (rowData 전달) */\n onClick: (rowData: any) => void\n /** 버튼 스타일 타입 */\n styletype?: 'default' | 'primary' | 'secondary' | 'success' | 'warning' | 'danger'\n /** 조건부 표시 함수 (rowData를 받아 boolean 반환) */\n show?: (rowData: any) => boolean\n}\n\nconst props = withDefaults(\n defineProps<{\n /** 추가 클래스 (외부 커스터마이징용) */\n class?: string\n /** 그리드에 표시할 데이터 배열 */\n rowData: any[]\n /** 컬럼 정의 배열 */\n columnDefs: ColDef[]\n /** ag-Grid 테마 */\n theme?: string\n /** 페이지네이션 활성화 여부 */\n pagination?: boolean\n /** 체크박스 선택 활성화 여부 */\n checkbox?: boolean\n /** 행 번호 표시 여부 (Enterprise) */\n rowNumbers?: boolean\n /** 행별 액션 버튼 목록 */\n actionButtons?: ActionButton[]\n /** 다크모드 자동 감지 여부 */\n autoDetectDarkMode?: boolean\n /** 요약 컬럼 표시 여부 */\n summaryColumn?: boolean\n /** 숨김 컬럼 관리 활성화 여부 */\n hiddenColumn?: boolean\n /** 그룹핑 기능 활성화 여부 (Enterprise) */\n enableGrouping?: boolean\n /** 피벗 기능 활성화 여부 (Enterprise) */\n enablePivot?: boolean\n /** Excel 내보내기 기능 활성화 여부 (Enterprise) */\n enableExcelExport?: boolean\n /** Tree Data 기능 활성화 여부 (Enterprise) */\n enableTreeData?: boolean\n /** Tree Data 계층 경로를 반환하는 함수 */\n getDataPath?: (data: any) => (string | number)[]\n /** Tree Data 그룹 컬럼 정의 */\n autoGroupColumnDef?: ColDef\n /** 선택된 행 데이터 배열 (v-model:selected-rows) */\n selectedRows?: any[]\n /** 컬럼 호버 하이라이트 활성화 여부 */\n columnHover?: boolean\n /** Columns Tool Panel 활성화 여부 (Enterprise) */\n enableColumnsToolPanel?: boolean\n /** Status Bar 활성화 여부 (Enterprise) */\n statusBar?: boolean\n /** 간소화된 Footer 모드 (Status Bar 제거, Pagination만 표시) */\n compactFooter?: boolean\n /** Row Group Panel 표시 여부 ('always' | 'onlyWhenGrouping' | 'never') */\n rowGroupPanelShow?: 'always' | 'onlyWhenGrouping' | 'never'\n /** 그룹 기본 확장 레벨 (-1: 모두 닫힘, 0: 첫 레벨만, 1: 2레벨까지...) */\n groupDefaultExpanded?: number\n /** Pivot Mode Panel 표시 여부 */\n pivotPanelShow?: 'always' | 'onlyWhenPivoting' | 'never'\n /** Pivot Mode 활성화 여부 */\n pivotMode?: boolean\n }>(),\n {\n theme: 'ag-theme-balham',\n pagination: true,\n checkbox: false,\n rowNumbers: true,\n actionButtons: undefined,\n autoDetectDarkMode: true,\n summaryColumn: false,\n hiddenColumn: false,\n enableGrouping: true,\n enablePivot: false,\n enableExcelExport: false,\n enableTreeData: false,\n getDataPath: undefined,\n autoGroupColumnDef: undefined,\n selectedRows: () => [],\n columnHover: true,\n enableColumnsToolPanel: true,\n statusBar: true,\n compactFooter: false,\n rowGroupPanelShow: 'never',\n groupDefaultExpanded: -1,\n pivotPanelShow: 'never',\n pivotMode: false,\n },\n)\n\nconst emit = defineEmits<{\n /** 행 클릭 이벤트 */\n rowClicked: [event: RowClickedEvent]\n /** 행 더블클릭 이벤트 */\n rowDoubleClicked: [event: RowDoubleClickedEvent]\n /** 셀 클릭 이벤트 */\n cellClicked: [event: CellClickedEvent]\n /** 선택 변경 이벤트 (체크박스 등) */\n selectionChanged: [event: SelectionChangedEvent]\n /** 셀 값 변경 이벤트 */\n cellValueChanged: [event: CellValueChangedEvent]\n /** 그리드 준비 완료 이벤트 */\n gridReady: [event: GridReadyEvent]\n /** 선택된 행 변경 이벤트 (v-model:selected-rows) */\n 'update:selectedRows': [rows: any[]]\n}>()\n\n// ag-Grid 인스턴스 참조\nconst gridApi = ref<any>(null)\nconst gridColumnApi = ref<any>(null)\n\n// 다크모드 상태\nconst isDarkMode = ref(false)\n\n// 다크모드 감지 함수\nconst detectDarkMode = () => {\n isDarkMode.value = document.documentElement.classList.contains('dark')\n}\n\n// 현재 테마 계산 (다크모드 자동 전환)\nconst currentTheme = computed(() => {\n if (!props.autoDetectDarkMode) {\n return props.theme\n }\n \n const baseTheme = props.theme\n if (isDarkMode.value) {\n // 이미 dark 테마인 경우 그대로 유지, 아니면 -dark 추가\n return baseTheme.includes('-dark') ? baseTheme : `${baseTheme}-dark`\n } else {\n // dark 테마 제거\n return baseTheme.replace(/-dark$/, '')\n }\n})\n\n// Action Buttons Cell Renderer - 함수형으로 DOM 직접 생성\nconst ActionButtonsCellRenderer = (params: ICellRendererParams) => {\n const buttons = props.actionButtons || []\n const rowData = params.data\n \n // 표시할 버튼 필터링\n const visibleButtons = buttons.filter(btn => {\n if (btn.show) {\n return btn.show(rowData)\n }\n return true\n })\n \n if (visibleButtons.length === 0) {\n return ''\n }\n \n // 컨테이너 div 생성\n const container = document.createElement('div')\n container.className = 'flex items-center gap-1'\n \n // 각 버튼 생성\n visibleButtons.forEach((btn) => {\n const button = document.createElement('button')\n button.className = 'px-2 py-1 text-xs border rounded transition-colors'\n \n // styletype에 따른 클래스 추가\n if (btn.styletype === 'danger') {\n button.className += ' bg-red-50 border-red-400 text-red-700 hover:bg-red-100 dark:bg-red-950 dark:border-red-700 dark:text-red-400 dark:hover:bg-red-900'\n } else {\n button.className += ' bg-gray-50 border-gray-400 text-gray-700 hover:bg-gray-100 dark:bg-gray-800 dark:border-gray-600 dark:text-gray-300 dark:hover:bg-gray-700'\n }\n \n // tooltip\n if (btn.tooltip) {\n button.title = btn.tooltip\n }\n \n // 라벨 추가 (텍스트 버튼)\n if (btn.label) {\n button.textContent = btn.label\n } else if (btn.icon) {\n // 라벨이 없으면 기본 텍스트 생성\n if (btn.icon === 'pencil') {\n button.textContent = '수정'\n } else if (btn.icon === 'trash2' || btn.icon === 'trash') {\n button.textContent = '삭제'\n } else if (btn.icon === 'eye') {\n button.textContent = '보기'\n } else if (btn.icon === 'copy') {\n button.textContent = '복사'\n } else if (btn.icon === 'download') {\n button.textContent = '다운로드'\n } else if (btn.icon === 'circleX') {\n button.textContent = '비활성화'\n } else if (btn.icon === 'circleCheckBig') {\n button.textContent = '활성화'\n } else {\n button.textContent = btn.icon\n }\n }\n \n // 클릭 이벤트\n button.addEventListener('click', (e) => {\n e.stopPropagation()\n btn.onClick(rowData)\n })\n \n container.appendChild(button)\n })\n \n return container\n}\n\n// Action Buttons 컬럼 정의\nconst actionButtonsColumn = computed<ColDef | null>(() => {\n if (!props.actionButtons || props.actionButtons.length === 0) {\n return null\n }\n \n return {\n colId: 'actionButtons',\n headerName: '작업',\n field: '_actions',\n width: 120,\n minWidth: 80,\n maxWidth: 200,\n lockPosition: 'left' as const,\n sortable: false,\n filter: false,\n resizable: true,\n suppressNavigable: true,\n suppressHeaderMenuButton: true,\n cellRenderer: ActionButtonsCellRenderer,\n cellStyle: { display: 'flex', justifyContent: 'center', alignItems: 'center' },\n }\n})\n\n// checkbox 활성화 및 추가 컬럼 처리\nconst processedColumnDefs = computed(() => {\n const columns: ColDef[] = []\n \n // 1. Checkbox 컬럼 (최우선)\n if (props.checkbox) {\n columns.push({\n colId: 'rowSelection',\n headerName: '',\n // field와 valueGetter 제거 - AG Grid 공식 방식\n width: 50,\n minWidth: 50,\n maxWidth: 50,\n lockPosition: 'left' as const,\n checkboxSelection: true,\n headerCheckboxSelection: true,\n sortable: false,\n filter: false,\n resizable: false,\n suppressNavigable: true,\n suppressHeaderMenuButton: true,\n cellStyle: { display: 'flex', justifyContent: 'center', alignItems: 'center' },\n })\n }\n \n // 2. Action Buttons 컬럼\n if (actionButtonsColumn.value) {\n columns.push(actionButtonsColumn.value)\n }\n \n // 3. 사용자 정의 컬럼들 (Row Numbers는 AG Grid가 자동으로 추가)\n columns.push(...props.columnDefs)\n \n return columns\n})\n\n// Grid 옵션 설정\nconst gridOptions = computed<GridOptions>(() => {\n const options: GridOptions = {\n // theme 옵션 제거 - 클래스 기반 테마(:class=\"theme\") 사용\n // columnDefs와 rowData는 prop으로 전달하므로 여기서 제거\n pagination: props.pagination,\n rowSelection: props.checkbox ? 'multiple' : undefined,\n // 체크박스 모드일 때 row 클릭으로 선택이 변경되지 않도록 설정\n // 체크박스만으로 선택을 제어하도록 함\n suppressRowClickSelection: props.checkbox,\n\n // Row Numbers (Enterprise) - AG Grid 표준 방식\n rowNumbers: props.rowNumbers,\n\n // Column Hover Highlight\n columnHoverHighlight: props.columnHover,\n\n // Enterprise 기능 옵션\n sideBar: props.enableColumnsToolPanel || props.enableGrouping || props.enablePivot ? {\n toolPanels: [\n {\n id: 'columns',\n labelDefault: 'Columns',\n labelKey: 'columns',\n iconKey: 'columns',\n toolPanel: 'agColumnsToolPanel',\n toolPanelParams: {\n suppressRowGroups: !props.enableGrouping,\n suppressValues: !props.enablePivot,\n suppressPivots: !props.enablePivot,\n suppressPivotMode: !props.enablePivot,\n },\n },\n ],\n defaultToolPanel: '', // 초기에는 접힌 상태\n } : undefined,\n\n // Status Bar (Enterprise)\n // compactFooter 모드에서는 Status Bar 비활성화\n statusBar: (props.statusBar && !props.compactFooter) ? {\n statusPanels: [\n { statusPanel: 'agTotalAndFilteredRowCountComponent', align: 'left' as const },\n { statusPanel: 'agSelectedRowCountComponent', align: 'left' as const },\n { statusPanel: 'agAggregationComponent', align: 'right' as const },\n ],\n } : undefined,\n\n // Row Group Panel 설정 (Enterprise) - 그리드 상단에 드래그 영역 표시\n rowGroupPanelShow: props.rowGroupPanelShow !== 'never' ? props.rowGroupPanelShow : undefined,\n\n // Pivot Panel 설정 (Enterprise) - 피벗 모드용 드래그 영역\n pivotPanelShow: props.pivotPanelShow !== 'never' ? props.pivotPanelShow : undefined,\n \n // Pivot Mode 활성화\n pivotMode: props.pivotMode,\n\n // 그룹핑 기본 설정\n groupDefaultExpanded: props.groupDefaultExpanded,\n suppressAggFuncInHeader: false,\n\n // Tree Data 설정 (Enterprise)\n treeData: props.enableTreeData || undefined,\n getDataPath: props.enableTreeData\n ? (props.getDataPath || ((data: any) => data.path || []))\n : undefined,\n autoGroupColumnDef: props.enableTreeData && props.autoGroupColumnDef\n ? props.autoGroupColumnDef\n : undefined,\n }\n\n return options\n})\n\n// Excel 내보내기 함수 (외부에서 사용 가능하도록 expose)\nconst exportToExcel = () => {\n if (gridApi.value && props.enableExcelExport) {\n gridApi.value.exportDataAsExcel({\n fileName: 'grid-export.xlsx',\n })\n }\n}\n\n// 그리드 API를 외부에 노출\ndefineExpose({\n gridApi,\n gridColumnApi,\n exportToExcel,\n})\n\n// Grid ready 이벤트 핸들러\nconst onGridReady = (params: GridReadyEvent) => {\n gridApi.value = params.api\n gridColumnApi.value = params.api // v34에서 columnApi는 deprecated\n emit('gridReady', params)\n}\n\n// 행 클릭 이벤트 핸들러\nconst onRowClicked = (event: RowClickedEvent) => {\n emit('rowClicked', event)\n}\n\n// 행 더블클릭 이벤트 핸들러\nconst onRowDoubleClicked = (event: RowDoubleClickedEvent) => {\n emit('rowDoubleClicked', event)\n}\n\n// 셀 클릭 이벤트 핸들러\nconst onCellClicked = (event: CellClickedEvent) => {\n emit('cellClicked', event)\n}\n\n// 선택 변경 이벤트 핸들러\nconst onSelectionChanged = (event: SelectionChangedEvent) => {\n emit('selectionChanged', event)\n emit('update:selectedRows', event.api.getSelectedRows())\n}\n\n// 셀 값 변경 이벤트 핸들러\nconst onCellValueChanged = (event: CellValueChangedEvent) => {\n emit('cellValueChanged', event)\n}\n\n// MutationObserver로 다크모드 변경 감지\nlet darkModeObserver: MutationObserver | null = null\n\nonMounted(() => {\n if (props.autoDetectDarkMode) {\n // 초기 다크모드 상태 감지\n detectDarkMode()\n \n // MutationObserver로 class 변경 감지\n darkModeObserver = new MutationObserver(() => {\n detectDarkMode()\n })\n \n darkModeObserver.observe(document.documentElement, {\n attributes: true,\n attributeFilter: ['class'],\n })\n }\n})\n\nonUnmounted(() => {\n if (darkModeObserver) {\n darkModeObserver.disconnect()\n }\n})\n\n// columnDefs 변경 감지\nwatch(\n () => props.columnDefs,\n () => {\n if (gridApi.value) {\n gridApi.value.setGridOption('columnDefs', processedColumnDefs.value)\n }\n },\n { deep: true },\n)\n\n// rowData 변경 감지\nwatch(\n () => props.rowData,\n () => {\n if (gridApi.value) {\n gridApi.value.setGridOption('rowData', props.rowData)\n }\n },\n { deep: true },\n)\n</script>\n\n<template>\n <div :class=\"cn('ag-grid-container', props.class)\">\n <AgGridVue\n :column-defs=\"processedColumnDefs\"\n :row-data=\"rowData\"\n :grid-options=\"gridOptions\"\n :class=\"currentTheme\"\n style=\"height: 100%; width: 100%\"\n @grid-ready=\"onGridReady\"\n @row-clicked=\"onRowClicked\"\n @row-double-clicked=\"onRowDoubleClicked\"\n @cell-clicked=\"onCellClicked\"\n @selection-changed=\"onSelectionChanged\"\n @cell-value-changed=\"onCellValueChanged\"\n />\n </div>\n</template>\n\n<style scoped>\n.ag-grid-container {\n width: 100%;\n height: 100%;\n}\n\n/* ============================================\n COMPACT FOOTER: Status Bar + Pagination 통합\n ============================================ */\n\n/* Status Bar 높이 줄이기 */\n:deep(.ag-status-bar) {\n min-height: 28px !important;\n height: 28px !important;\n padding: 0 12px !important;\n border-top: 1px solid var(--ag-border-color);\n display: flex;\n align-items: center;\n justify-content: space-between;\n font-size: 0.8125rem;\n}\n\n/* Status Bar 컴포넌트들 높이 조정 */\n:deep(.ag-status-bar-left),\n:deep(.ag-status-bar-center),\n:deep(.ag-status-bar-right) {\n height: 28px;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n/* Status Bar 패널들 간격 조정 */\n:deep(.ag-status-panel) {\n padding: 0;\n height: 28px;\n display: flex;\n align-items: center;\n}\n\n/* Pagination Panel 높이 줄이기 */\n:deep(.ag-paging-panel) {\n min-height: 28px !important;\n height: 28px !important;\n padding: 0 12px !important;\n border-top: 1px solid var(--ag-border-color);\n font-size: 0.8125rem;\n}\n\n/* Pagination 컴포넌트들 높이 조정 */\n:deep(.ag-paging-page-size),\n:deep(.ag-paging-row-summary-panel) {\n height: 28px;\n display: flex;\n align-items: center;\n}\n\n/* Page Size Selector 높이 조정 */\n:deep(.ag-paging-page-size .ag-picker-field) {\n height: 24px;\n min-height: 24px;\n}\n\n:deep(.ag-paging-page-size .ag-picker-field-wrapper) {\n height: 24px;\n padding: 0 4px;\n}\n\n/* Pagination 버튼들 높이 조정 */\n:deep(.ag-paging-button) {\n height: 24px;\n width: 24px;\n padding: 2px;\n}\n\n/* Pagination 버튼 래퍼 */\n:deep(.ag-paging-button-wrapper) {\n height: 28px;\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n/* Row summary 텍스트 */\n:deep(.ag-paging-row-summary-panel-number) {\n line-height: 28px;\n}\n\n/* ========================================\n 패턴 9: AG-Grid 스타일 향상\n ======================================== */\n\n:deep(.ag-root-wrapper) {\n border: 1px solid hsl(var(--border));\n border-radius: 0.375rem;\n}\n\n:deep(.ag-header) {\n background-color: hsl(var(--muted));\n border-bottom: 1px solid hsl(var(--border));\n font-weight: 500;\n}\n\n:deep(.ag-header-cell) {\n color: hsl(var(--foreground));\n font-size: 0.75rem;\n padding: 0.5rem;\n}\n\n:deep(.ag-row) {\n transition: background-color 0.2s ease, border-left 0.2s ease;\n cursor: pointer;\n}\n\n:deep(.ag-row:hover) {\n background-color: hsl(var(--primary) / 0.05) !important;\n}\n\n:deep(.ag-row-selected) {\n background-color: hsl(var(--primary) / 0.1) !important;\n border-left: 2px solid hsl(var(--primary)) !important;\n}\n\n:deep(.ag-row-selected:hover) {\n background-color: hsl(var(--primary) / 0.15) !important;\n}\n\n:deep(.ag-cell) {\n line-height: 1.5;\n padding: 0.5rem;\n border-bottom: 1px solid hsl(var(--border) / 0.5);\n}\n\n:deep(.ag-paging-panel) {\n background-color: hsl(var(--muted) / 0.5);\n border-top: 1px solid hsl(var(--border));\n}\n</style>\n"],"names":["ModuleRegistry","AllCommunityModule","AllEnterpriseModule","props","__props","emit","__emit","gridApi","ref","gridColumnApi","isDarkMode","detectDarkMode","currentTheme","computed","baseTheme","ActionButtonsCellRenderer","params","buttons","rowData","visibleButtons","btn","container","button","e","actionButtonsColumn","processedColumnDefs","columns","gridOptions","data","__expose","onGridReady","onRowClicked","event","onRowDoubleClicked","onCellClicked","onSelectionChanged","onCellValueChanged","darkModeObserver","onMounted","onUnmounted","watch","_createElementBlock","_normalizeClass","_unref","cn","_createVNode","AgGridVue"],"mappings":"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"}