@j-solution/components 1.7.0 → 1.9.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 (207) hide show
  1. package/README.md +413 -415
  2. package/assets/jwms-portal-frontend-Ct2Tc7yj.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 +443 -443
  6. package/components/atoms/JButton.vue.cjs +6 -1
  7. package/components/atoms/JButton.vue.cjs.map +1 -1
  8. package/components/atoms/JButton.vue.js +10 -85
  9. package/components/atoms/JButton.vue.js.map +1 -1
  10. package/components/atoms/JButton.vue2.cjs +1 -1
  11. package/components/atoms/JButton.vue2.cjs.map +1 -1
  12. package/components/atoms/JButton.vue2.js +85 -2
  13. package/components/atoms/JButton.vue2.js.map +1 -1
  14. package/components/atoms/JGrid.vue.cjs +1 -1
  15. package/components/atoms/JGrid.vue.js +1 -1
  16. package/components/atoms/JGrid.vue2.cjs +1 -1
  17. package/components/atoms/JGrid.vue2.cjs.map +1 -1
  18. package/components/atoms/JGrid.vue2.js +39 -35
  19. package/components/atoms/JGrid.vue2.js.map +1 -1
  20. package/components/atoms/JLabel.vue.cjs +1 -1
  21. package/components/atoms/JLabel.vue.cjs.map +1 -1
  22. package/components/atoms/JLabel.vue.js +26 -22
  23. package/components/atoms/JLabel.vue.js.map +1 -1
  24. package/components/atoms/JSectionTitle.vue.cjs +7 -0
  25. package/components/atoms/JSectionTitle.vue.cjs.map +1 -0
  26. package/components/atoms/JSectionTitle.vue.js +13 -0
  27. package/components/atoms/JSectionTitle.vue.js.map +1 -0
  28. package/components/atoms/JSectionTitle.vue2.cjs +2 -0
  29. package/components/atoms/JSectionTitle.vue2.cjs.map +1 -0
  30. package/components/atoms/JSectionTitle.vue2.js +67 -0
  31. package/components/atoms/JSectionTitle.vue2.js.map +1 -0
  32. package/components/atoms/JSplitter.vue.cjs +6 -1
  33. package/components/atoms/JSplitter.vue.cjs.map +1 -1
  34. package/components/atoms/JSplitter.vue.js +10 -59
  35. package/components/atoms/JSplitter.vue.js.map +1 -1
  36. package/components/atoms/JSplitter.vue2.cjs +1 -1
  37. package/components/atoms/JSplitter.vue2.cjs.map +1 -1
  38. package/components/atoms/JSplitter.vue2.js +59 -2
  39. package/components/atoms/JSplitter.vue2.js.map +1 -1
  40. package/components/examples/ExampleCrudPage.vue.cjs +1 -1
  41. package/components/examples/ExampleCrudPage.vue.cjs.map +1 -1
  42. package/components/examples/ExampleCrudPage.vue.js +228 -208
  43. package/components/examples/ExampleCrudPage.vue.js.map +1 -1
  44. package/components/examples/ExampleTabMappingPage.vue.cjs +1 -1
  45. package/components/examples/ExampleTabMappingPage.vue.cjs.map +1 -1
  46. package/components/examples/ExampleTabMappingPage.vue.js +341 -368
  47. package/components/examples/ExampleTabMappingPage.vue.js.map +1 -1
  48. package/components/molecules/JAlert.vue.cjs +1 -1
  49. package/components/molecules/JAlert.vue.cjs.map +1 -1
  50. package/components/molecules/JAlert.vue.js +18 -16
  51. package/components/molecules/JAlert.vue.js.map +1 -1
  52. package/components/molecules/JCard.vue.cjs +1 -1
  53. package/components/molecules/JCard.vue.cjs.map +1 -1
  54. package/components/molecules/JCard.vue.js +55 -39
  55. package/components/molecules/JCard.vue.js.map +1 -1
  56. package/components/molecules/JEmptyState.vue.cjs +7 -0
  57. package/components/molecules/JEmptyState.vue.cjs.map +1 -0
  58. package/components/molecules/JEmptyState.vue.js +13 -0
  59. package/components/molecules/JEmptyState.vue.js.map +1 -0
  60. package/components/molecules/JEmptyState.vue2.cjs +2 -0
  61. package/components/molecules/JEmptyState.vue2.cjs.map +1 -0
  62. package/components/molecules/JEmptyState.vue2.js +127 -0
  63. package/components/molecules/JEmptyState.vue2.js.map +1 -0
  64. package/components/molecules/JFormField.vue.cjs +6 -1
  65. package/components/molecules/JFormField.vue.cjs.map +1 -1
  66. package/components/molecules/JFormField.vue.js +10 -264
  67. package/components/molecules/JFormField.vue.js.map +1 -1
  68. package/components/molecules/JFormField.vue2.cjs +2 -0
  69. package/components/molecules/JFormField.vue2.cjs.map +1 -0
  70. package/components/molecules/JFormField.vue2.js +271 -0
  71. package/components/molecules/JFormField.vue2.js.map +1 -0
  72. package/components/molecules/JTabs.vue.cjs +1 -1
  73. package/components/molecules/JTabs.vue.js +1 -1
  74. package/components/molecules/JTabs.vue2.cjs +1 -1
  75. package/components/molecules/JTabs.vue2.cjs.map +1 -1
  76. package/components/molecules/JTabs.vue2.js +44 -50
  77. package/components/molecules/JTabs.vue2.js.map +1 -1
  78. package/components/molecules/JTitlebar.vue.cjs +1 -1
  79. package/components/molecules/JTitlebar.vue.cjs.map +1 -1
  80. package/components/molecules/JTitlebar.vue.js +23 -20
  81. package/components/molecules/JTitlebar.vue.js.map +1 -1
  82. package/components/organisms/JDynamicForm.vue2.cjs +1 -1
  83. package/components/organisms/JDynamicForm.vue2.cjs.map +1 -1
  84. package/components/organisms/JDynamicForm.vue2.js +35 -32
  85. package/components/organisms/JDynamicForm.vue2.js.map +1 -1
  86. package/components/organisms/JDynamicTabs.vue.cjs +1 -1
  87. package/components/organisms/JDynamicTabs.vue.cjs.map +1 -1
  88. package/components/organisms/JDynamicTabs.vue.js +47 -52
  89. package/components/organisms/JDynamicTabs.vue.js.map +1 -1
  90. package/components/organisms/JFilterBar.vue.cjs +6 -1
  91. package/components/organisms/JFilterBar.vue.cjs.map +1 -1
  92. package/components/organisms/JFilterBar.vue.js +10 -137
  93. package/components/organisms/JFilterBar.vue.js.map +1 -1
  94. package/components/organisms/JFilterBar.vue2.cjs +1 -1
  95. package/components/organisms/JFilterBar.vue2.cjs.map +1 -1
  96. package/components/organisms/JFilterBar.vue2.js +143 -2
  97. package/components/organisms/JFilterBar.vue2.js.map +1 -1
  98. package/components/organisms/JFormModal.vue.cjs +1 -1
  99. package/components/organisms/JFormModal.vue.cjs.map +1 -1
  100. package/components/organisms/JFormModal.vue.js +54 -49
  101. package/components/organisms/JFormModal.vue.js.map +1 -1
  102. package/components/organisms/JHeader.vue.cjs +1 -1
  103. package/components/organisms/JHeader.vue.cjs.map +1 -1
  104. package/components/organisms/JHeader.vue.js +191 -190
  105. package/components/organisms/JHeader.vue.js.map +1 -1
  106. package/components/organisms/JModal.vue.cjs +1 -1
  107. package/components/organisms/JModal.vue.cjs.map +1 -1
  108. package/components/organisms/JModal.vue.js +47 -45
  109. package/components/organisms/JModal.vue.js.map +1 -1
  110. package/components/organisms/JPageContainer.vue.cjs +1 -1
  111. package/components/organisms/JPageContainer.vue.cjs.map +1 -1
  112. package/components/organisms/JPageContainer.vue.js +22 -22
  113. package/components/organisms/JPageContainer.vue.js.map +1 -1
  114. package/components/organisms/JSearchPanel.vue2.cjs +1 -1
  115. package/components/organisms/JSearchPanel.vue2.cjs.map +1 -1
  116. package/components/organisms/JSearchPanel.vue2.js +34 -32
  117. package/components/organisms/JSearchPanel.vue2.js.map +1 -1
  118. package/components/organisms/JShuttle.vue.cjs +7 -0
  119. package/components/organisms/JShuttle.vue.cjs.map +1 -0
  120. package/components/organisms/JShuttle.vue.js +13 -0
  121. package/components/organisms/JShuttle.vue.js.map +1 -0
  122. package/components/organisms/JShuttle.vue2.cjs +2 -0
  123. package/components/organisms/JShuttle.vue2.cjs.map +1 -0
  124. package/components/organisms/JShuttle.vue2.js +216 -0
  125. package/components/organisms/JShuttle.vue2.js.map +1 -0
  126. package/components/organisms/JSidebar/JSidebar.vue.cjs +2 -0
  127. package/components/organisms/JSidebar/JSidebar.vue.cjs.map +1 -0
  128. package/components/organisms/JSidebar/JSidebar.vue.js +189 -0
  129. package/components/organisms/JSidebar/JSidebar.vue.js.map +1 -0
  130. package/components/{molecules/JFormField.vue3.cjs → organisms/JSidebar/JSidebar.vue2.cjs} +2 -2
  131. package/components/organisms/JSidebar/JSidebar.vue2.cjs.map +1 -0
  132. package/components/organisms/JSidebar/JSidebar.vue2.js +5 -0
  133. package/components/organisms/JSidebar/JSidebar.vue2.js.map +1 -0
  134. package/components/organisms/JSidebar/JSidebarGroup.vue.cjs +2 -0
  135. package/components/organisms/JSidebar/JSidebarGroup.vue.cjs.map +1 -0
  136. package/components/organisms/JSidebar/JSidebarGroup.vue.js +89 -0
  137. package/components/organisms/JSidebar/JSidebarGroup.vue.js.map +1 -0
  138. package/components/organisms/JSidebar/JSidebarGroup.vue2.cjs +2 -0
  139. package/components/organisms/JSidebar/JSidebarGroup.vue2.cjs.map +1 -0
  140. package/components/organisms/JSidebar/JSidebarGroup.vue2.js +5 -0
  141. package/components/organisms/JSidebar/JSidebarGroup.vue2.js.map +1 -0
  142. package/components/organisms/JSidebar/JSidebarItem.vue.cjs +2 -0
  143. package/components/organisms/JSidebar/JSidebarItem.vue.cjs.map +1 -0
  144. package/components/organisms/JSidebar/JSidebarItem.vue.js +79 -0
  145. package/components/organisms/JSidebar/JSidebarItem.vue.js.map +1 -0
  146. package/components/organisms/JSidebar/JSidebarItem.vue2.cjs +2 -0
  147. package/components/organisms/JSidebar/JSidebarItem.vue2.cjs.map +1 -0
  148. package/components/organisms/JSidebar/JSidebarItem.vue2.js +5 -0
  149. package/components/organisms/JSidebar/JSidebarItem.vue2.js.map +1 -0
  150. package/components/organisms/JSidebarSimple/JDynamicMenuItem.vue.cjs +1 -1
  151. package/components/organisms/JSidebarSimple/JDynamicMenuItem.vue.cjs.map +1 -1
  152. package/components/organisms/JSidebarSimple/JDynamicMenuItem.vue.js +52 -52
  153. package/components/organisms/JSidebarSimple/JDynamicMenuItem.vue.js.map +1 -1
  154. package/components/shadcn/Card.vue.cjs +1 -1
  155. package/components/shadcn/Card.vue.cjs.map +1 -1
  156. package/components/shadcn/Card.vue.js +1 -1
  157. package/components/shadcn/Card.vue.js.map +1 -1
  158. package/components/shadcn/CardContent.vue.cjs +1 -1
  159. package/components/shadcn/CardContent.vue.cjs.map +1 -1
  160. package/components/shadcn/CardContent.vue.js +4 -4
  161. package/components/shadcn/CardContent.vue.js.map +1 -1
  162. package/components/shadcn/CardHeader.vue.cjs +1 -1
  163. package/components/shadcn/CardHeader.vue.cjs.map +1 -1
  164. package/components/shadcn/CardHeader.vue.js +5 -5
  165. package/components/shadcn/CardHeader.vue.js.map +1 -1
  166. package/components/shadcn/Input.vue.cjs +1 -1
  167. package/components/shadcn/Input.vue.cjs.map +1 -1
  168. package/components/shadcn/Input.vue.js +3 -3
  169. package/components/shadcn/Input.vue.js.map +1 -1
  170. package/components/shadcn/SelectTrigger.vue.cjs +1 -1
  171. package/components/shadcn/SelectTrigger.vue.cjs.map +1 -1
  172. package/components/shadcn/SelectTrigger.vue.js +1 -1
  173. package/components/shadcn/SelectTrigger.vue.js.map +1 -1
  174. package/components/shadcn/TabsContent.vue.cjs +1 -1
  175. package/components/shadcn/TabsContent.vue.cjs.map +1 -1
  176. package/components/shadcn/TabsContent.vue.js +1 -1
  177. package/components/shadcn/TabsContent.vue.js.map +1 -1
  178. package/components/shadcn/TabsList.vue.cjs +1 -1
  179. package/components/shadcn/TabsList.vue.cjs.map +1 -1
  180. package/components/shadcn/TabsList.vue.js +10 -10
  181. package/components/shadcn/TabsList.vue.js.map +1 -1
  182. package/components/shadcn/Textarea.vue.cjs +1 -1
  183. package/components/shadcn/Textarea.vue.cjs.map +1 -1
  184. package/components/shadcn/Textarea.vue.js +1 -1
  185. package/components/shadcn/Textarea.vue.js.map +1 -1
  186. package/components/shadcn/index.cjs +1 -1
  187. package/components/shadcn/index.cjs.map +1 -1
  188. package/components/shadcn/index.js +4 -4
  189. package/components/shadcn/index.js.map +1 -1
  190. package/components/templates/JLayout.vue.cjs.map +1 -1
  191. package/components/templates/JLayout.vue.js.map +1 -1
  192. package/components/templates/JLayoutSimple.vue.cjs +1 -1
  193. package/components/templates/JLayoutSimple.vue.cjs.map +1 -1
  194. package/components/templates/JLayoutSimple.vue.js +36 -30
  195. package/components/templates/JLayoutSimple.vue.js.map +1 -1
  196. package/index.cjs +1 -1
  197. package/index.js +75 -67
  198. package/package.json +1 -1
  199. package/types/index.d.ts +662 -461
  200. package/types/sidebar.types.cjs +2 -0
  201. package/types/sidebar.types.cjs.map +1 -0
  202. package/types/sidebar.types.js +5 -0
  203. package/types/sidebar.types.js.map +1 -0
  204. package/assets/jwms-portal-frontend-CwxPfHfa.css +0 -1
  205. package/components/molecules/JFormField.vue3.cjs.map +0 -1
  206. package/components/molecules/JFormField.vue3.js +0 -6
  207. package/components/molecules/JFormField.vue3.js.map +0 -1
@@ -1,2 +1,7 @@
1
- "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("vue"),f=require("lucide-vue-next");require("../shadcn/index.cjs");const p=require("../shadcn/Button.vue.cjs"),m=e.defineComponent({__name:"JButton",props:{type:{default:"button"},disabled:{type:Boolean,default:!1},loading:{type:Boolean,default:!1},variant:{},size:{},class:{},styletype:{default:"default"}},emits:["click"],setup(l,{emit:r}){const a=l,u=r,s={default:{variant:"default"},primary:{variant:"default"},secondary:{variant:"secondary"},success:{variant:"default",class:"bg-green-600 hover:bg-green-700"},warning:{variant:"default",class:"bg-amber-500 hover:bg-amber-600"},danger:{variant:"destructive"},outline:{variant:"outline"},ghost:{variant:"ghost"},link:{variant:"link"},sm:{variant:"default",size:"sm"},lg:{variant:"default",size:"lg"},icon:{variant:"default",size:"icon"}},n=e.computed(()=>{const t=a.styletype||"default";return s[t]??s.default}),o=e.computed(()=>a.variant||n.value?.variant),c=e.computed(()=>a.size||n.value?.size||"sm"),d=e.computed(()=>[n.value?.class,a.class].filter(Boolean).join(" ")),i=e.computed(()=>a.disabled||a.loading),v=t=>{i.value||u("click",t)};return(t,g)=>(e.openBlock(),e.createBlock(e.unref(p.default),{type:l.type,variant:o.value,size:c.value,class:e.normalizeClass(d.value),disabled:i.value,onClick:v},{default:e.withCtx(()=>[l.loading?(e.openBlock(),e.createBlock(e.unref(f.Loader2),{key:0,class:"mr-2 h-4 w-4 animate-spin"})):e.createCommentVNode("",!0),e.renderSlot(t.$slots,"default")]),_:3},8,["type","variant","size","class","disabled"]))}});exports.default=m;
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("./JButton.vue2.cjs");;/* empty css */const t = (t_comp, t_opts) => {
2
+ const t_merged = t_comp.__vccOpts || t_comp;
3
+ for (const [t_key, t_val] of t_opts)
4
+ t_merged[t_key] = t_val;
5
+ return t_merged;
6
+ };,u=t(e.default,[["__scopeId","data-v-9058e7ee"]]);exports.default=u;
2
7
  //# sourceMappingURL=JButton.vue.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"JButton.vue.cjs","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\r\n :type=\"type\"\r\n :variant=\"finalVariant\"\r\n :size=\"finalSize\"\r\n :class=\"finalClass\"\r\n :disabled=\"isDisabled\"\r\n @click=\"handleClick\"\r\n >\r\n <Loader2 v-if=\"loading\" class=\"mr-2 h-4 w-4 animate-spin\" />\r\n <slot />\r\n </Button>\r\n</template>\r\n\r\n"],"names":["props","__props","emit","__emit","STYLE_PRESETS","preset","computed","styleKey","finalVariant","finalSize","finalClass","isDisabled","handleClick","event","_createBlock","_unref","Button","Loader2","_renderSlot","_ctx"],"mappings":"kdAmBA,MAAMA,EAAQC,EAyBRC,EAAOC,EAOPC,EAA0H,CAC9H,QAAS,CACP,QAAS,SAAA,EAEX,QAAS,CACP,QAAS,SAAA,EAEX,UAAW,CACT,QAAS,WAAA,EAEX,QAAS,CACP,QAAS,UACT,MAAO,iCAAA,EAET,QAAS,CACP,QAAS,UACT,MAAO,iCAAA,EAET,OAAQ,CACN,QAAS,aAAA,EAEX,QAAS,CACP,QAAS,SAAA,EAEX,MAAO,CACL,QAAS,OAAA,EAEX,KAAM,CACJ,QAAS,MAAA,EAEX,GAAI,CACF,QAAS,UACT,KAAM,IAAA,EAER,GAAI,CACF,QAAS,UACT,KAAM,IAAA,EAER,KAAM,CACJ,QAAS,UACT,KAAM,MAAA,CACR,EAGIC,EAASC,EAAAA,SAAS,IAAM,CAC5B,MAAMC,EAAWP,EAAM,WAAa,UACpC,OAAOI,EAAcG,CAAQ,GAAKH,EAAc,OAClD,CAAC,EAEKI,EAAeF,EAAAA,SAAS,IAAMN,EAAM,SAAWK,EAAO,OAAO,OAAO,EACpEI,EAAYH,EAAAA,SAAS,IAAMN,EAAM,MAAQK,EAAO,OAAO,MAAQ,IAAI,EACnEK,EAAaJ,EAAAA,SAAS,IAAM,CAACD,EAAO,OAAO,MAAOL,EAAM,KAAK,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,CAAC,EAExFW,EAAaL,EAAAA,SAAS,IAAMN,EAAM,UAAYA,EAAM,OAAO,EAE3DY,EAAeC,GAAsB,CACpCF,EAAW,OACdT,EAAK,QAASW,CAAK,CAEvB,8BAIEC,EAAAA,YAUSC,EAAAA,MAAAC,EAAAA,OAAA,EAAA,CATN,KAAMf,EAAA,KACN,QAASO,EAAA,MACT,KAAMC,EAAA,MACN,uBAAOC,EAAA,KAAU,EACjB,SAAUC,EAAA,MACV,QAAOC,CAAA,qBAER,IAA4D,CAA7CX,EAAA,uBAAfa,EAAAA,YAA4DC,EAAAA,MAAAE,EAAAA,OAAA,EAAA,OAApC,MAAM,2BAAA,gCAC9BC,aAAQC,EAAA,OAAA,SAAA,CAAA"}
1
+ {"version":3,"file":"JButton.vue.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":""}
@@ -1,88 +1,13 @@
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, s = {
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 s[e] ?? s.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(" ")), i = t(() => a.disabled || a.loading), p = (e) => {
64
- i.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: i.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")
80
- ]),
81
- _: 3
82
- }, 8, ["type", "variant", "size", "class", "disabled"]));
83
- }
84
- });
1
+ import o from "./JButton.vue2.js";
2
+ /* empty css */
3
+ const t = (t_comp, t_opts) => {
4
+ const t_merged = t_comp.__vccOpts || t_comp;
5
+ for (const [t_key, t_val] of t_opts)
6
+ t_merged[t_key] = t_val;
7
+ return t_merged;
8
+ };
9
+ const p = /* @__PURE__ */ t(o, [["__scopeId", "data-v-9058e7ee"]]);
85
10
  export {
86
- x as default
11
+ p as default
87
12
  };
88
13
  //# sourceMappingURL=JButton.vue.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"JButton.vue.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\r\n :type=\"type\"\r\n :variant=\"finalVariant\"\r\n :size=\"finalSize\"\r\n :class=\"finalClass\"\r\n :disabled=\"isDisabled\"\r\n @click=\"handleClick\"\r\n >\r\n <Loader2 v-if=\"loading\" class=\"mr-2 h-4 w-4 animate-spin\" />\r\n <slot />\r\n </Button>\r\n</template>\r\n\r\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,SAAA;AAAA,MAAA;;;;;"}
1
+ {"version":3,"file":"JButton.vue.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("./JButton.vue.cjs");exports.default=e.default;
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("vue"),f=require("lucide-vue-next");require("../shadcn/index.cjs");const p=require("../shadcn/Button.vue.cjs"),m=e.defineComponent({__name:"JButton",props:{type:{default:"button"},disabled:{type:Boolean,default:!1},loading:{type:Boolean,default:!1},variant:{},size:{},class:{},styletype:{default:"default"}},emits:["click"],setup(l,{emit:r}){const t=l,u=r,s={default:{variant:"default"},primary:{variant:"default"},secondary:{variant:"secondary"},success:{variant:"default",class:"bg-green-600 hover:bg-green-700"},warning:{variant:"default",class:"bg-amber-500 hover:bg-amber-600"},danger:{variant:"destructive"},outline:{variant:"outline"},ghost:{variant:"ghost"},link:{variant:"link"},sm:{variant:"default",size:"sm"},lg:{variant:"default",size:"lg"},icon:{variant:"default",size:"icon"}},n=e.computed(()=>{const a=t.styletype||"default";return s[a]??s.default}),o=e.computed(()=>t.variant||n.value?.variant),c=e.computed(()=>t.size||n.value?.size||"sm"),d=e.computed(()=>[n.value?.class,t.class].filter(Boolean).join(" ")),i=e.computed(()=>t.disabled||t.loading),v=a=>{i.value||u("click",a)};return(a,g)=>(e.openBlock(),e.createBlock(e.unref(p.default),{type:l.type,variant:o.value,size:c.value,class:e.normalizeClass(d.value),disabled:i.value,onClick:v},{default:e.withCtx(()=>[l.loading?(e.openBlock(),e.createBlock(e.unref(f.Loader2),{key:0,class:"mr-2 h-4 w-4 animate-spin"})):e.createCommentVNode("",!0),e.renderSlot(a.$slots,"default",{},void 0,!0)]),_:3},8,["type","variant","size","class","disabled"]))}});exports.default=m;
2
2
  //# sourceMappingURL=JButton.vue2.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"JButton.vue2.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":""}
1
+ {"version":3,"file":"JButton.vue2.cjs","sources":["../../../../src/components/atoms/JButton.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport { Loader2 } from 'lucide-vue-next'\nimport { Button, type ButtonVariants } from '@/components/shadcn'\n\ntype StyleType =\n | 'default' // 기본 스타일 (primary)\n | 'primary' // 강조 버튼 (파랑)\n | 'secondary' // 보조 버튼 (회색)\n | 'success' // 성공 버튼 (초록)\n | 'warning' // 경고 버튼 (주황)\n | 'danger' // 위험 버튼 (빨강)\n | 'outline' // 아웃라인 버튼\n | 'ghost' // 고스트 버튼\n | 'link' // 링크 스타일\n | 'sm' // 작은 크기\n | 'lg' // 큰 크기\n | 'icon' // 아이콘 전용\n\nconst props = withDefaults(\n defineProps<{\n /** 버튼 타입 */\n type?: 'button' | 'submit' | 'reset'\n /** 비활성화 상태 */\n disabled?: boolean\n /** 로딩 상태 */\n loading?: boolean\n /** shadcn variant */\n variant?: ButtonVariants['variant']\n /** shadcn size */\n size?: ButtonVariants['size']\n /** 추가 CSS 클래스 */\n class?: string\n /** 스타일 프리셋 (variant + size 조합) */\n styletype?: StyleType\n }>(),\n {\n type: 'button',\n disabled: false,\n loading: false,\n styletype: 'default',\n },\n)\n\nconst emit = defineEmits<{\n click: [event: MouseEvent]\n}>()\n\n/**\n * styletype -> variant/size 매핑\n */\nconst STYLE_PRESETS: Record<StyleType, { variant: ButtonVariants['variant']; size?: ButtonVariants['size']; class?: string }> = {\n default: { \n variant: 'default',\n },\n primary: { \n variant: 'default',\n },\n secondary: { \n variant: 'secondary',\n },\n success: { \n variant: 'default',\n class: 'bg-green-600 hover:bg-green-700',\n },\n warning: { \n variant: 'default',\n class: 'bg-amber-500 hover:bg-amber-600',\n },\n danger: { \n variant: 'destructive',\n },\n outline: { \n variant: 'outline',\n },\n ghost: { \n variant: 'ghost',\n },\n link: { \n variant: 'link',\n },\n sm: { \n variant: 'default',\n size: 'sm',\n },\n lg: { \n variant: 'default',\n size: 'lg',\n },\n icon: { \n variant: 'default',\n size: 'icon',\n },\n}\n\nconst preset = computed(() => {\n const styleKey = props.styletype || 'default'\n return STYLE_PRESETS[styleKey] ?? STYLE_PRESETS.default\n})\n\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\nconst isDisabled = computed(() => props.disabled || props.loading)\n\nconst handleClick = (event: MouseEvent) => {\n if (!isDisabled.value) {\n emit('click', event)\n }\n}\n</script>\n\n<template>\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":"kdAmBA,MAAMA,EAAQC,EAyBRC,EAAOC,EAOPC,EAA0H,CAC9H,QAAS,CACP,QAAS,SAAA,EAEX,QAAS,CACP,QAAS,SAAA,EAEX,UAAW,CACT,QAAS,WAAA,EAEX,QAAS,CACP,QAAS,UACT,MAAO,iCAAA,EAET,QAAS,CACP,QAAS,UACT,MAAO,iCAAA,EAET,OAAQ,CACN,QAAS,aAAA,EAEX,QAAS,CACP,QAAS,SAAA,EAEX,MAAO,CACL,QAAS,OAAA,EAEX,KAAM,CACJ,QAAS,MAAA,EAEX,GAAI,CACF,QAAS,UACT,KAAM,IAAA,EAER,GAAI,CACF,QAAS,UACT,KAAM,IAAA,EAER,KAAM,CACJ,QAAS,UACT,KAAM,MAAA,CACR,EAGIC,EAASC,EAAAA,SAAS,IAAM,CAC5B,MAAMC,EAAWP,EAAM,WAAa,UACpC,OAAOI,EAAcG,CAAQ,GAAKH,EAAc,OAClD,CAAC,EAEKI,EAAeF,EAAAA,SAAS,IAAMN,EAAM,SAAWK,EAAO,OAAO,OAAO,EACpEI,EAAYH,EAAAA,SAAS,IAAMN,EAAM,MAAQK,EAAO,OAAO,MAAQ,IAAI,EACnEK,EAAaJ,EAAAA,SAAS,IAAM,CAACD,EAAO,OAAO,MAAOL,EAAM,KAAK,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,CAAC,EAExFW,EAAaL,EAAAA,SAAS,IAAMN,EAAM,UAAYA,EAAM,OAAO,EAE3DY,EAAeC,GAAsB,CACpCF,EAAW,OACdT,EAAK,QAASW,CAAK,CAEvB,8BAIEC,EAAAA,YAUSC,EAAAA,MAAAC,EAAAA,OAAA,EAAA,CATN,KAAMf,EAAA,KACN,QAASO,EAAA,MACT,KAAMC,EAAA,MACN,uBAAOC,EAAA,KAAU,EACjB,SAAUC,EAAA,MACV,QAAOC,CAAA,qBAER,IAA4D,CAA7CX,EAAA,uBAAfa,EAAAA,YAA4DC,EAAAA,MAAAE,EAAAA,OAAA,EAAA,OAApC,MAAM,2BAAA,gCAC9BC,EAAAA,WAAQC,EAAA,OAAA,UAAA,CAAA,EAAA,OAAA,EAAA,CAAA"}
@@ -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\">\nimport { computed } from 'vue'\nimport { Loader2 } from 'lucide-vue-next'\nimport { Button, type ButtonVariants } from '@/components/shadcn'\n\ntype StyleType =\n | 'default' // 기본 스타일 (primary)\n | 'primary' // 강조 버튼 (파랑)\n | 'secondary' // 보조 버튼 (회색)\n | 'success' // 성공 버튼 (초록)\n | 'warning' // 경고 버튼 (주황)\n | 'danger' // 위험 버튼 (빨강)\n | 'outline' // 아웃라인 버튼\n | 'ghost' // 고스트 버튼\n | 'link' // 링크 스타일\n | 'sm' // 작은 크기\n | 'lg' // 큰 크기\n | 'icon' // 아이콘 전용\n\nconst props = withDefaults(\n defineProps<{\n /** 버튼 타입 */\n type?: 'button' | 'submit' | 'reset'\n /** 비활성화 상태 */\n disabled?: boolean\n /** 로딩 상태 */\n loading?: boolean\n /** shadcn variant */\n variant?: ButtonVariants['variant']\n /** shadcn size */\n size?: ButtonVariants['size']\n /** 추가 CSS 클래스 */\n class?: string\n /** 스타일 프리셋 (variant + size 조합) */\n styletype?: StyleType\n }>(),\n {\n type: 'button',\n disabled: false,\n loading: false,\n styletype: 'default',\n },\n)\n\nconst emit = defineEmits<{\n click: [event: MouseEvent]\n}>()\n\n/**\n * styletype -> variant/size 매핑\n */\nconst STYLE_PRESETS: Record<StyleType, { variant: ButtonVariants['variant']; size?: ButtonVariants['size']; class?: string }> = {\n default: { \n variant: 'default',\n },\n primary: { \n variant: 'default',\n },\n secondary: { \n variant: 'secondary',\n },\n success: { \n variant: 'default',\n class: 'bg-green-600 hover:bg-green-700',\n },\n warning: { \n variant: 'default',\n class: 'bg-amber-500 hover:bg-amber-600',\n },\n danger: { \n variant: 'destructive',\n },\n outline: { \n variant: 'outline',\n },\n ghost: { \n variant: 'ghost',\n },\n link: { \n variant: 'link',\n },\n sm: { \n variant: 'default',\n size: 'sm',\n },\n lg: { \n variant: 'default',\n size: 'lg',\n },\n icon: { \n variant: 'default',\n size: 'icon',\n },\n}\n\nconst preset = computed(() => {\n const styleKey = props.styletype || 'default'\n return STYLE_PRESETS[styleKey] ?? STYLE_PRESETS.default\n})\n\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\nconst isDisabled = computed(() => props.disabled || props.loading)\n\nconst handleClick = (event: MouseEvent) => {\n if (!isDisabled.value) {\n emit('click', event)\n }\n}\n</script>\n\n<template>\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;;;;;"}
@@ -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-3bf78169"]]);exports.default=u;
6
+ };,u=t(e.default,[["__scopeId","data-v-17ece534"]]);exports.default=u;
7
7
  //# sourceMappingURL=JGrid.vue.cjs.map
@@ -6,7 +6,7 @@ const r = (r_comp, r_opts) => {
6
6
  r_merged[r_key] = r_val;
7
7
  return r_merged;
8
8
  };
9
- const p = /* @__PURE__ */ r(o, [["__scopeId", "data-v-3bf78169"]]);
9
+ const p = /* @__PURE__ */ r(o, [["__scopeId", "data-v-17ece534"]]);
10
10
  export {
11
11
  p as default
12
12
  };
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const a=require("vue"),R=require("ag-grid-vue3"),C=require("ag-grid-community"),T=require("ag-grid-enterprise");;/* empty css */;/* empty css */;/* empty css */const N={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},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,T.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",N,[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"])]))}});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 /** 간소화된 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=\"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\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</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":"osDA2BAA,EAAAA,eAAe,gBAAgB,CAACC,EAAAA,mBAAoBC,EAAAA,mBAAmB,CAAC,EAoBxE,MAAMC,EAAQC,EAkFRC,EAAOC,EAkBPC,EAAUC,EAAAA,IAAS,IAAI,EACvBC,EAAgBD,EAAAA,IAAS,IAAI,EAG7BE,EAAaF,EAAAA,IAAI,EAAK,EAGtBG,EAAiB,IAAM,CAC3BD,EAAW,MAAQ,SAAS,gBAAgB,UAAU,SAAS,MAAM,CACvE,EAGME,EAAeC,EAAAA,SAAS,IAAM,CAClC,GAAI,CAACV,EAAM,mBACT,OAAOA,EAAM,MAGf,MAAMW,EAAYX,EAAM,MACxB,OAAIO,EAAW,MAENI,EAAU,SAAS,OAAO,EAAIA,EAAY,GAAGA,CAAS,QAGtDA,EAAU,QAAQ,SAAU,EAAE,CAEzC,CAAC,EAGKC,EAA6BC,GAAgC,CACjE,MAAMC,EAAUd,EAAM,eAAiB,CAAA,EACjCe,EAAUF,EAAO,KAGjBG,EAAiBF,EAAQ,OAAOG,GAChCA,EAAI,KACCA,EAAI,KAAKF,CAAO,EAElB,EACR,EAED,GAAIC,EAAe,SAAW,EAC5B,MAAO,GAIT,MAAME,EAAY,SAAS,cAAc,KAAK,EAC9C,OAAAA,EAAU,UAAY,0BAGtBF,EAAe,QAASC,GAAQ,CAC9B,MAAME,EAAS,SAAS,cAAc,QAAQ,EAC9CA,EAAO,UAAY,qDAGfF,EAAI,YAAc,SACpBE,EAAO,WAAa,sIAEpBA,EAAO,WAAa,8IAIlBF,EAAI,UACNE,EAAO,MAAQF,EAAI,SAIjBA,EAAI,MACNE,EAAO,YAAcF,EAAI,MAChBA,EAAI,OAETA,EAAI,OAAS,SACfE,EAAO,YAAc,KACZF,EAAI,OAAS,UAAYA,EAAI,OAAS,QAC/CE,EAAO,YAAc,KACZF,EAAI,OAAS,MACtBE,EAAO,YAAc,KACZF,EAAI,OAAS,OACtBE,EAAO,YAAc,KACZF,EAAI,OAAS,WACtBE,EAAO,YAAc,OACZF,EAAI,OAAS,UACtBE,EAAO,YAAc,OACZF,EAAI,OAAS,iBACtBE,EAAO,YAAc,MAErBA,EAAO,YAAcF,EAAI,MAK7BE,EAAO,iBAAiB,QAAUC,GAAM,CACtCA,EAAE,gBAAA,EACFH,EAAI,QAAQF,CAAO,CACrB,CAAC,EAEDG,EAAU,YAAYC,CAAM,CAC9B,CAAC,EAEMD,CACT,EAGMG,EAAsBX,EAAAA,SAAwB,IAC9C,CAACV,EAAM,eAAiBA,EAAM,cAAc,SAAW,EAClD,KAGF,CACL,MAAO,gBACP,WAAY,KACZ,MAAO,WACP,MAAO,IACP,SAAU,GACV,SAAU,IACV,aAAc,OACd,SAAU,GACV,OAAQ,GACR,UAAW,GACX,kBAAmB,GACnB,yBAA0B,GAC1B,aAAcY,EACd,UAAW,CAAE,QAAS,OAAQ,eAAgB,SAAU,WAAY,QAAA,CAAS,CAEhF,EAGKU,EAAsBZ,EAAAA,SAAS,IAAM,CACzC,MAAMa,EAAoB,CAAA,EAG1B,OAAIvB,EAAM,UACRuB,EAAQ,KAAK,CACX,MAAO,eACP,WAAY,GAEZ,MAAO,GACP,SAAU,GACV,SAAU,GACV,aAAc,OACd,kBAAmB,GACnB,wBAAyB,GACzB,SAAU,GACV,OAAQ,GACR,UAAW,GACX,kBAAmB,GACnB,yBAA0B,GAC1B,UAAW,CAAE,QAAS,OAAQ,eAAgB,SAAU,WAAY,QAAA,CAAS,CAC9E,EAICF,EAAoB,OACtBE,EAAQ,KAAKF,EAAoB,KAAK,EAIxCE,EAAQ,KAAK,GAAGvB,EAAM,UAAU,EAEzBuB,CACT,CAAC,EAGKC,EAAcd,EAAAA,SAAsB,KACX,CAG3B,WAAYV,EAAM,WAClB,aAAcA,EAAM,SAAW,WAAa,OAG5C,0BAA2BA,EAAM,SAGjC,WAAYA,EAAM,WAGlB,qBAAsBA,EAAM,YAG5B,QAASA,EAAM,wBAA0BA,EAAM,gBAAkBA,EAAM,YAAc,CACnF,WAAY,CACV,CACE,GAAI,UACJ,aAAc,UACd,SAAU,UACV,QAAS,UACT,UAAW,qBACX,gBAAiB,CACf,kBAAmB,CAACA,EAAM,eAC1B,eAAgB,CAACA,EAAM,YACvB,eAAgB,CAACA,EAAM,YACvB,kBAAmB,CAACA,EAAM,WAAA,CAC5B,CACF,EAEF,iBAAkB,EAAA,EAChB,OAIJ,UAAYA,EAAM,WAAa,CAACA,EAAM,cAAiB,CACrD,aAAc,CACZ,CAAE,YAAa,sCAAuC,MAAO,MAAA,EAC7D,CAAE,YAAa,8BAA+B,MAAO,MAAA,EACrD,CAAE,YAAa,yBAA0B,MAAO,OAAA,CAAiB,CACnE,EACE,OAGJ,kBAAmBA,EAAM,oBAAsB,QAAUA,EAAM,kBAAoB,OAGnF,eAAgBA,EAAM,iBAAmB,QAAUA,EAAM,eAAiB,OAG1E,UAAWA,EAAM,UAGjB,qBAAsBA,EAAM,qBAC5B,wBAAyB,GAGzB,SAAUA,EAAM,gBAAkB,OAClC,YAAaA,EAAM,eACdA,EAAM,cAAiByB,GAAcA,EAAK,MAAQ,CAAA,GACnD,OACJ,mBAAoBzB,EAAM,gBAAkBA,EAAM,mBAC9CA,EAAM,mBACN,MAAA,EAIP,EAYD0B,EAAa,CACX,QAAAtB,EACA,cAAAE,EACA,cAZoB,IAAM,CACtBF,EAAQ,OAASJ,EAAM,mBACzBI,EAAQ,MAAM,kBAAkB,CAC9B,SAAU,kBAAA,CACX,CAEL,CAME,CACD,EAGD,MAAMuB,EAAed,GAA2B,CAC9CT,EAAQ,MAAQS,EAAO,IACvBP,EAAc,MAAQO,EAAO,IAC7BX,EAAK,YAAaW,CAAM,CAC1B,EAGMe,EAAgBC,GAA2B,CAC/C3B,EAAK,aAAc2B,CAAK,CAC1B,EAGMC,EAAsBD,GAAiC,CAC3D3B,EAAK,mBAAoB2B,CAAK,CAChC,EAGME,EAAiBF,GAA4B,CACjD3B,EAAK,cAAe2B,CAAK,CAC3B,EAGMG,EAAsBH,GAAiC,CAC3D3B,EAAK,mBAAoB2B,CAAK,EAC9B3B,EAAK,sBAAuB2B,EAAM,IAAI,gBAAA,CAAiB,CACzD,EAGMI,EAAsBJ,GAAiC,CAC3D3B,EAAK,mBAAoB2B,CAAK,CAChC,EAGA,IAAIK,EAA4C,KAEhDC,OAAAA,EAAAA,UAAU,IAAM,CACVnC,EAAM,qBAERQ,EAAA,EAGA0B,EAAmB,IAAI,iBAAiB,IAAM,CAC5C1B,EAAA,CACF,CAAC,EAED0B,EAAiB,QAAQ,SAAS,gBAAiB,CACjD,WAAY,GACZ,gBAAiB,CAAC,OAAO,CAAA,CAC1B,EAEL,CAAC,EAEDE,EAAAA,YAAY,IAAM,CACZF,GACFA,EAAiB,WAAA,CAErB,CAAC,EAGDG,EAAAA,MACE,IAAMrC,EAAM,WACZ,IAAM,CACAI,EAAQ,OACVA,EAAQ,MAAM,cAAc,aAAckB,EAAoB,KAAK,CAEvE,EACA,CAAE,KAAM,EAAA,CAAK,EAIfe,EAAAA,MACE,IAAMrC,EAAM,QACZ,IAAM,CACAI,EAAQ,OACVA,EAAQ,MAAM,cAAc,UAAWJ,EAAM,OAAO,CAExD,EACA,CAAE,KAAM,EAAA,CAAK,wBAKbsC,EAAAA,mBAcM,MAAA,CAdA,MAAKC,EAAAA,eAAEC,QAAAC,EAAAA,EAAA,EAAE,oBAAsBzC,EAAM,KAAK,CAAA,CAAA,GAC9C0C,cAYEF,EAAAA,MAAAG,EAAAA,SAAA,EAAA,CAXC,cAAarB,EAAA,MACb,WAAUrB,EAAA,QACV,eAAcuB,EAAA,MACd,uBAAOf,EAAA,KAAY,EACpB,MAAA,CAAA,OAAA,OAAA,MAAA,MAAA,EACC,YAAAkB,EACA,aAAAC,EACA,mBAAAE,EACA,cAAAC,EACA,mBAAAC,EACA,mBAAAC,CAAA"}
@@ -1,13 +1,15 @@
1
- import { defineComponent as N, ref as d, computed as i, onMounted as T, onUnmounted as A, watch as w, createElementBlock as H, openBlock as _, createVNode as F, unref as V, normalizeClass as I } from "vue";
2
- import { AgGridVue as O } from "ag-grid-vue3";
3
- import { ModuleRegistry as W, AllCommunityModule as z } from "ag-grid-community";
4
- import { AllEnterpriseModule as j } from "ag-grid-enterprise";
1
+ import { defineComponent as A, ref as d, computed as i, onMounted as H, onUnmounted as F, watch as w, createElementBlock as V, openBlock as I, normalizeClass as b, unref as x, createVNode as O } from "vue";
2
+ import { AgGridVue as _ } from "ag-grid-vue3";
3
+ import { cn as W } from "../../lib/utils.js";
4
+ import { ModuleRegistry as z, AllCommunityModule as j } from "ag-grid-community";
5
+ import { AllEnterpriseModule as K } from "ag-grid-enterprise";
5
6
  /* empty css */
6
7
  /* empty css */
7
8
  /* empty css */
8
- const K = { class: "ag-grid-container" }, Z = /* @__PURE__ */ N({
9
+ const ee = /* @__PURE__ */ A({
9
10
  __name: "JGrid",
10
11
  props: {
12
+ class: {},
11
13
  rowData: {},
12
14
  columnDefs: {},
13
15
  theme: { default: "ag-theme-balham" },
@@ -35,24 +37,24 @@ const K = { class: "ag-grid-container" }, Z = /* @__PURE__ */ N({
35
37
  pivotMode: { type: Boolean, default: !1 }
36
38
  },
37
39
  emits: ["rowClicked", "rowDoubleClicked", "cellClicked", "selectionChanged", "cellValueChanged", "gridReady", "update:selectedRows"],
38
- setup(c, { expose: b, emit: x }) {
39
- W.registerModules([z, j]);
40
- const e = c, n = x, l = d(null), p = d(null), f = d(!1), m = () => {
40
+ setup(c, { expose: y, emit: k }) {
41
+ z.registerModules([j, K]);
42
+ const e = c, n = k, l = d(null), p = d(null), f = d(!1), m = () => {
41
43
  f.value = document.documentElement.classList.contains("dark");
42
- }, y = i(() => {
44
+ }, D = i(() => {
43
45
  if (!e.autoDetectDarkMode)
44
46
  return e.theme;
45
47
  const t = e.theme;
46
48
  return f.value ? t.includes("-dark") ? t : `${t}-dark` : t.replace(/-dark$/, "");
47
- }), k = (t) => {
49
+ }), P = (t) => {
48
50
  const s = e.actionButtons || [], v = t.data, C = s.filter((o) => o.show ? o.show(v) : !0);
49
51
  if (C.length === 0)
50
52
  return "";
51
53
  const u = document.createElement("div");
52
54
  return u.className = "flex items-center gap-1", C.forEach((o) => {
53
55
  const a = document.createElement("button");
54
- a.className = "px-2 py-1 text-xs border rounded transition-colors", o.styletype === "danger" ? a.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" : a.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 && (a.title = o.tooltip), o.label ? a.textContent = o.label : o.icon && (o.icon === "pencil" ? a.textContent = "수정" : o.icon === "trash2" || o.icon === "trash" ? a.textContent = "삭제" : o.icon === "eye" ? a.textContent = "보기" : o.icon === "copy" ? a.textContent = "복사" : o.icon === "download" ? a.textContent = "다운로드" : o.icon === "circleX" ? a.textContent = "비활성화" : o.icon === "circleCheckBig" ? a.textContent = "활성화" : a.textContent = o.icon), a.addEventListener("click", (R) => {
55
- R.stopPropagation(), o.onClick(v);
56
+ a.className = "px-2 py-1 text-xs border rounded transition-colors", o.styletype === "danger" ? a.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" : a.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 && (a.title = o.tooltip), o.label ? a.textContent = o.label : o.icon && (o.icon === "pencil" ? a.textContent = "수정" : o.icon === "trash2" || o.icon === "trash" ? a.textContent = "삭제" : o.icon === "eye" ? a.textContent = "보기" : o.icon === "copy" ? a.textContent = "복사" : o.icon === "download" ? a.textContent = "다운로드" : o.icon === "circleX" ? a.textContent = "비활성화" : o.icon === "circleCheckBig" ? a.textContent = "활성화" : a.textContent = o.icon), a.addEventListener("click", (T) => {
57
+ T.stopPropagation(), o.onClick(v);
56
58
  }), u.appendChild(a);
57
59
  }), u;
58
60
  }, g = i(() => !e.actionButtons || e.actionButtons.length === 0 ? null : {
@@ -68,7 +70,7 @@ const K = { class: "ag-grid-container" }, Z = /* @__PURE__ */ N({
68
70
  resizable: !0,
69
71
  suppressNavigable: !0,
70
72
  suppressHeaderMenuButton: !0,
71
- cellRenderer: k,
73
+ cellRenderer: P,
72
74
  cellStyle: { display: "flex", justifyContent: "center", alignItems: "center" }
73
75
  }), h = i(() => {
74
76
  const t = [];
@@ -89,7 +91,7 @@ const K = { class: "ag-grid-container" }, Z = /* @__PURE__ */ N({
89
91
  suppressHeaderMenuButton: !0,
90
92
  cellStyle: { display: "flex", justifyContent: "center", alignItems: "center" }
91
93
  }), g.value && t.push(g.value), t.push(...e.columnDefs), t;
92
- }), D = i(() => ({
94
+ }), B = i(() => ({
93
95
  // theme 옵션 제거 - 클래스 기반 테마(:class="theme") 사용
94
96
  // columnDefs와 rowData는 prop으로 전달하므로 여기서 제거
95
97
  pagination: e.pagination,
@@ -144,7 +146,7 @@ const K = { class: "ag-grid-container" }, Z = /* @__PURE__ */ N({
144
146
  getDataPath: e.enableTreeData ? e.getDataPath || ((s) => s.path || []) : void 0,
145
147
  autoGroupColumnDef: e.enableTreeData && e.autoGroupColumnDef ? e.autoGroupColumnDef : void 0
146
148
  }));
147
- b({
149
+ y({
148
150
  gridApi: l,
149
151
  gridColumnApi: p,
150
152
  exportToExcel: () => {
@@ -153,28 +155,28 @@ const K = { class: "ag-grid-container" }, Z = /* @__PURE__ */ N({
153
155
  });
154
156
  }
155
157
  });
156
- const P = (t) => {
158
+ const E = (t) => {
157
159
  l.value = t.api, p.value = t.api, n("gridReady", t);
158
- }, B = (t) => {
160
+ }, M = (t) => {
159
161
  n("rowClicked", t);
160
- }, E = (t) => {
162
+ }, S = (t) => {
161
163
  n("rowDoubleClicked", t);
162
- }, M = (t) => {
164
+ }, G = (t) => {
163
165
  n("cellClicked", t);
164
- }, S = (t) => {
166
+ }, R = (t) => {
165
167
  n("selectionChanged", t), n("update:selectedRows", t.api.getSelectedRows());
166
- }, G = (t) => {
168
+ }, N = (t) => {
167
169
  n("cellValueChanged", t);
168
170
  };
169
171
  let r = null;
170
- return T(() => {
172
+ return H(() => {
171
173
  e.autoDetectDarkMode && (m(), r = new MutationObserver(() => {
172
174
  m();
173
175
  }), r.observe(document.documentElement, {
174
176
  attributes: !0,
175
177
  attributeFilter: ["class"]
176
178
  }));
177
- }), A(() => {
179
+ }), F(() => {
178
180
  r && r.disconnect();
179
181
  }), w(
180
182
  () => e.columnDefs,
@@ -188,24 +190,26 @@ const K = { class: "ag-grid-container" }, Z = /* @__PURE__ */ N({
188
190
  l.value && l.value.setGridOption("rowData", e.rowData);
189
191
  },
190
192
  { deep: !0 }
191
- ), (t, s) => (_(), H("div", K, [
192
- F(V(O), {
193
+ ), (t, s) => (I(), V("div", {
194
+ class: b(x(W)("ag-grid-container", e.class))
195
+ }, [
196
+ O(x(_), {
193
197
  "column-defs": h.value,
194
198
  "row-data": c.rowData,
195
- "grid-options": D.value,
196
- class: I(y.value),
199
+ "grid-options": B.value,
200
+ class: b(D.value),
197
201
  style: { height: "100%", width: "100%" },
198
- onGridReady: P,
199
- onRowClicked: B,
200
- onRowDoubleClicked: E,
201
- onCellClicked: M,
202
- onSelectionChanged: S,
203
- onCellValueChanged: G
202
+ onGridReady: E,
203
+ onRowClicked: M,
204
+ onRowDoubleClicked: S,
205
+ onCellClicked: G,
206
+ onSelectionChanged: R,
207
+ onCellValueChanged: N
204
208
  }, null, 8, ["column-defs", "row-data", "grid-options", "class"])
205
- ]));
209
+ ], 2));
206
210
  }
207
211
  });
208
212
  export {
209
- Z as default
213
+ ee as default
210
214
  };
211
215
  //# sourceMappingURL=JGrid.vue2.js.map