@j-solution/components 1.6.0 → 1.7.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 (197) hide show
  1. package/README.md +8 -7
  2. package/assets/jwms-portal-frontend-CwxPfHfa.css +1 -0
  3. package/assets/styles/j-components.css +1 -1
  4. package/assets/styles/themes.css +107 -0
  5. package/components/atoms/JAvatar.vue.cjs +1 -1
  6. package/components/atoms/JAvatar.vue.cjs.map +1 -1
  7. package/components/atoms/JAvatar.vue.js +10 -7
  8. package/components/atoms/JAvatar.vue.js.map +1 -1
  9. package/components/atoms/JBadge.vue.cjs +1 -1
  10. package/components/atoms/JBadge.vue.cjs.map +1 -1
  11. package/components/atoms/JBadge.vue.js +7 -6
  12. package/components/atoms/JBadge.vue.js.map +1 -1
  13. package/components/atoms/JButton.vue.cjs +1 -1
  14. package/components/atoms/JButton.vue.cjs.map +1 -1
  15. package/components/atoms/JButton.vue.js +5 -5
  16. package/components/atoms/JButton.vue.js.map +1 -1
  17. package/components/atoms/JDatepicker.vue.cjs +1 -1
  18. package/components/atoms/JDatepicker.vue.cjs.map +1 -1
  19. package/components/atoms/JDatepicker.vue.js +10 -10
  20. package/components/atoms/JDatepicker.vue.js.map +1 -1
  21. package/components/atoms/JEditor.vue.cjs +1 -1
  22. package/components/atoms/JEditor.vue.js +1 -1
  23. package/components/atoms/JEditor.vue2.cjs +1 -1
  24. package/components/atoms/JEditor.vue2.cjs.map +1 -1
  25. package/components/atoms/JEditor.vue2.js +31 -17
  26. package/components/atoms/JEditor.vue2.js.map +1 -1
  27. package/components/atoms/JGrid.vue.cjs +1 -1
  28. package/components/atoms/JGrid.vue.js +2 -2
  29. package/components/atoms/JGrid.vue2.cjs +1 -1
  30. package/components/atoms/JGrid.vue2.cjs.map +1 -1
  31. package/components/atoms/JGrid.vue2.js +45 -33
  32. package/components/atoms/JGrid.vue2.js.map +1 -1
  33. package/components/atoms/JIcon.vue.cjs +1 -1
  34. package/components/atoms/JIcon.vue.cjs.map +1 -1
  35. package/components/atoms/JIcon.vue.js +14 -13
  36. package/components/atoms/JIcon.vue.js.map +1 -1
  37. package/components/atoms/JKbd.vue.cjs +1 -1
  38. package/components/atoms/JKbd.vue.cjs.map +1 -1
  39. package/components/atoms/JKbd.vue.js +13 -10
  40. package/components/atoms/JKbd.vue.js.map +1 -1
  41. package/components/atoms/JLabel.vue.cjs +1 -1
  42. package/components/atoms/JLabel.vue.cjs.map +1 -1
  43. package/components/atoms/JLabel.vue.js +4 -4
  44. package/components/atoms/JLabel.vue.js.map +1 -1
  45. package/components/atoms/JLink.vue.cjs +1 -1
  46. package/components/atoms/JLink.vue.cjs.map +1 -1
  47. package/components/atoms/JLink.vue.js +5 -5
  48. package/components/atoms/JLink.vue.js.map +1 -1
  49. package/components/atoms/JPreview.vue.cjs +1 -1
  50. package/components/atoms/JPreview.vue.js +2 -2
  51. package/components/atoms/JPreview.vue2.cjs +1 -1
  52. package/components/atoms/JPreview.vue2.cjs.map +1 -1
  53. package/components/atoms/JPreview.vue2.js +33 -20
  54. package/components/atoms/JPreview.vue2.js.map +1 -1
  55. package/components/atoms/JProgress.vue.cjs +1 -1
  56. package/components/atoms/JProgress.vue.cjs.map +1 -1
  57. package/components/atoms/JProgress.vue.js +15 -9
  58. package/components/atoms/JProgress.vue.js.map +1 -1
  59. package/components/atoms/JRadio.vue.cjs +1 -1
  60. package/components/atoms/JRadio.vue.cjs.map +1 -1
  61. package/components/atoms/JRadio.vue.js +1 -1
  62. package/components/atoms/JRadio.vue.js.map +1 -1
  63. package/components/atoms/JSearchCombo.vue.cjs +1 -1
  64. package/components/atoms/JSearchCombo.vue.cjs.map +1 -1
  65. package/components/atoms/JSearchCombo.vue.js +38 -37
  66. package/components/atoms/JSearchCombo.vue.js.map +1 -1
  67. package/components/atoms/JSpinner.vue.cjs +1 -1
  68. package/components/atoms/JSpinner.vue.cjs.map +1 -1
  69. package/components/atoms/JSpinner.vue.js +8 -7
  70. package/components/atoms/JSpinner.vue.js.map +1 -1
  71. package/components/atoms/JSplitter.vue.cjs +1 -1
  72. package/components/atoms/JSplitter.vue.cjs.map +1 -1
  73. package/components/atoms/JSplitter.vue.js +32 -27
  74. package/components/atoms/JSplitter.vue.js.map +1 -1
  75. package/components/atoms/JTooltip.vue.cjs +1 -1
  76. package/components/atoms/JTooltip.vue.cjs.map +1 -1
  77. package/components/atoms/JTooltip.vue.js +18 -15
  78. package/components/atoms/JTooltip.vue.js.map +1 -1
  79. package/components/examples/ExampleCrudPage.vue.cjs +2 -0
  80. package/components/examples/ExampleCrudPage.vue.cjs.map +1 -0
  81. package/components/examples/ExampleCrudPage.vue.js +358 -0
  82. package/components/examples/ExampleCrudPage.vue.js.map +1 -0
  83. package/components/examples/ExampleCrudPage.vue2.cjs +2 -0
  84. package/components/examples/ExampleCrudPage.vue2.cjs.map +1 -0
  85. package/components/examples/ExampleCrudPage.vue2.js +5 -0
  86. package/components/examples/ExampleCrudPage.vue2.js.map +1 -0
  87. package/components/examples/ExampleTabMappingPage.vue.cjs +2 -0
  88. package/components/examples/ExampleTabMappingPage.vue.cjs.map +1 -0
  89. package/components/examples/ExampleTabMappingPage.vue.js +522 -0
  90. package/components/examples/ExampleTabMappingPage.vue.js.map +1 -0
  91. package/components/examples/ExampleTabMappingPage.vue2.cjs +2 -0
  92. package/components/examples/ExampleTabMappingPage.vue2.cjs.map +1 -0
  93. package/components/examples/ExampleTabMappingPage.vue2.js +5 -0
  94. package/components/examples/ExampleTabMappingPage.vue2.js.map +1 -0
  95. package/components/molecules/JBreadcrumb.vue.cjs +1 -1
  96. package/components/molecules/JBreadcrumb.vue.cjs.map +1 -1
  97. package/components/molecules/JBreadcrumb.vue.js +3 -3
  98. package/components/molecules/JBreadcrumb.vue.js.map +1 -1
  99. package/components/molecules/JFormField.vue.cjs +1 -1
  100. package/components/molecules/JFormField.vue.cjs.map +1 -1
  101. package/components/molecules/JFormField.vue.js +26 -24
  102. package/components/molecules/JFormField.vue.js.map +1 -1
  103. package/components/molecules/JTabs.vue.cjs +1 -1
  104. package/components/molecules/JTabs.vue.js +1 -1
  105. package/components/molecules/JTabs.vue2.cjs +1 -1
  106. package/components/molecules/JTabs.vue2.cjs.map +1 -1
  107. package/components/molecules/JTabs.vue2.js +7 -7
  108. package/components/molecules/JTabs.vue2.js.map +1 -1
  109. package/components/molecules/JTitlebar.vue.cjs +1 -1
  110. package/components/molecules/JTitlebar.vue.cjs.map +1 -1
  111. package/components/molecules/JTitlebar.vue.js +35 -36
  112. package/components/molecules/JTitlebar.vue.js.map +1 -1
  113. package/components/organisms/JFilterBar.vue.cjs +1 -1
  114. package/components/organisms/JFilterBar.vue.cjs.map +1 -1
  115. package/components/organisms/JFilterBar.vue.js +5 -5
  116. package/components/organisms/JFilterBar.vue.js.map +1 -1
  117. package/components/organisms/JHeader.vue.cjs +1 -1
  118. package/components/organisms/JHeader.vue.cjs.map +1 -1
  119. package/components/organisms/JHeader.vue.js +25 -23
  120. package/components/organisms/JHeader.vue.js.map +1 -1
  121. package/components/organisms/JModal.vue.cjs +1 -1
  122. package/components/organisms/JModal.vue.cjs.map +1 -1
  123. package/components/organisms/JModal.vue.js +30 -27
  124. package/components/organisms/JModal.vue.js.map +1 -1
  125. package/components/organisms/JSidebarAdvanced.vue.cjs +1 -1
  126. package/components/organisms/JSidebarAdvanced.vue.js +7 -7
  127. package/components/organisms/JSidebarAdvanced.vue2.cjs +1 -1
  128. package/components/organisms/JSidebarAdvanced.vue2.cjs.map +1 -1
  129. package/components/organisms/JSidebarAdvanced.vue2.js +40 -40
  130. package/components/organisms/JSidebarAdvanced.vue2.js.map +1 -1
  131. package/components/organisms/JSidebarSimple/JDynamicMenuItem.vue.cjs +1 -1
  132. package/components/organisms/JSidebarSimple/JDynamicMenuItem.vue.cjs.map +1 -1
  133. package/components/organisms/JSidebarSimple/JDynamicMenuItem.vue.js +83 -63
  134. package/components/organisms/JSidebarSimple/JDynamicMenuItem.vue.js.map +1 -1
  135. package/components/organisms/JSidebarSimple.vue.cjs +1 -1
  136. package/components/organisms/JSidebarSimple.vue.js +2 -2
  137. package/components/organisms/JSidebarSimple.vue2.cjs +1 -1
  138. package/components/organisms/JSidebarSimple.vue2.cjs.map +1 -1
  139. package/components/organisms/JSidebarSimple.vue2.js +2 -2
  140. package/components/organisms/JSidebarSimple.vue2.js.map +1 -1
  141. package/components/shadcn/AccordionTrigger.vue.cjs +1 -1
  142. package/components/shadcn/AccordionTrigger.vue.cjs.map +1 -1
  143. package/components/shadcn/AccordionTrigger.vue.js +3 -3
  144. package/components/shadcn/AccordionTrigger.vue.js.map +1 -1
  145. package/components/shadcn/CardContent.vue.cjs +1 -1
  146. package/components/shadcn/CardContent.vue.cjs.map +1 -1
  147. package/components/shadcn/CardContent.vue.js +1 -1
  148. package/components/shadcn/CardContent.vue.js.map +1 -1
  149. package/components/shadcn/CardDescription.vue.cjs +1 -1
  150. package/components/shadcn/CardDescription.vue.cjs.map +1 -1
  151. package/components/shadcn/CardDescription.vue.js +1 -1
  152. package/components/shadcn/CardDescription.vue.js.map +1 -1
  153. package/components/shadcn/CardFooter.vue.cjs +1 -1
  154. package/components/shadcn/CardFooter.vue.cjs.map +1 -1
  155. package/components/shadcn/CardFooter.vue.js +7 -7
  156. package/components/shadcn/CardFooter.vue.js.map +1 -1
  157. package/components/shadcn/CardHeader.vue.cjs +1 -1
  158. package/components/shadcn/CardHeader.vue.cjs.map +1 -1
  159. package/components/shadcn/CardHeader.vue.js +8 -8
  160. package/components/shadcn/CardHeader.vue.js.map +1 -1
  161. package/components/shadcn/CardTitle.vue.cjs +1 -1
  162. package/components/shadcn/CardTitle.vue.cjs.map +1 -1
  163. package/components/shadcn/CardTitle.vue.js +5 -5
  164. package/components/shadcn/CardTitle.vue.js.map +1 -1
  165. package/components/shadcn/Input.vue.cjs +1 -1
  166. package/components/shadcn/Input.vue.cjs.map +1 -1
  167. package/components/shadcn/Input.vue.js +1 -1
  168. package/components/shadcn/Input.vue.js.map +1 -1
  169. package/components/shadcn/SelectTrigger.vue.cjs +1 -1
  170. package/components/shadcn/SelectTrigger.vue.cjs.map +1 -1
  171. package/components/shadcn/SelectTrigger.vue.js +2 -2
  172. package/components/shadcn/SelectTrigger.vue.js.map +1 -1
  173. package/components/shadcn/Switch.vue.cjs +1 -1
  174. package/components/shadcn/Switch.vue.cjs.map +1 -1
  175. package/components/shadcn/Switch.vue.js +2 -2
  176. package/components/shadcn/Switch.vue.js.map +1 -1
  177. package/components/shadcn/TabsList.vue.cjs +1 -1
  178. package/components/shadcn/TabsList.vue.cjs.map +1 -1
  179. package/components/shadcn/TabsList.vue.js +1 -1
  180. package/components/shadcn/TabsList.vue.js.map +1 -1
  181. package/components/shadcn/TabsTrigger.vue.cjs +1 -1
  182. package/components/shadcn/TabsTrigger.vue.cjs.map +1 -1
  183. package/components/shadcn/TabsTrigger.vue.js +4 -4
  184. package/components/shadcn/TabsTrigger.vue.js.map +1 -1
  185. package/components/shadcn/Textarea.vue.cjs +1 -1
  186. package/components/shadcn/Textarea.vue.cjs.map +1 -1
  187. package/components/shadcn/Textarea.vue.js +2 -2
  188. package/components/shadcn/Textarea.vue.js.map +1 -1
  189. package/components/shadcn/index.cjs +1 -1
  190. package/components/shadcn/index.cjs.map +1 -1
  191. package/components/shadcn/index.js +8 -7
  192. package/components/shadcn/index.js.map +1 -1
  193. package/index.cjs +1 -1
  194. package/index.js +76 -72
  195. package/package.json +1 -1
  196. package/types/index.d.ts +742 -15
  197. package/assets/jwms-portal-frontend-DntSIcYt.css +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"JHeader.vue.js","sources":["../../../../src/components/organisms/JHeader.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, ref, onMounted, onUnmounted } from 'vue'\nimport JIcon from '@/components/atoms/JIcon.vue'\nimport JAvatar from '@/components/atoms/JAvatar.vue'\nimport JButton from '@/components/atoms/JButton.vue'\nimport JPopover from '@/components/atoms/JPopover.vue'\nimport { cn } from '@/lib/utils'\nimport type { ContextMenuItem, ContextMenuGroup } from '@/types/context-menu.types'\nimport {\n detectThemeClasses,\n ensureDefaultTheme,\n validateThemeExists,\n getDefaultTheme,\n getStoredTheme,\n setStoredTheme,\n applyTheme,\n} from '@/lib/theme-utils'\n\n// Fallback 로고 이미지 import (logo prop이 없거나 로드 실패 시 사용)\nimport logoFallback from '@/assets/images/logo-fallback.png'\n\n/**\n * JHeader - 상단 헤더 컴포넌트 (organisms)\n * Header Component\n * \n * @description\n * 애플리케이션의 상단 헤더 영역을 담당하는 컴포넌트입니다.\n * 로고, 네비게이션, 검색, 알림, 사용자 메뉴 등을 포함할 수 있습니다.\n * \n * @example\n * ```vue\n * <JHeader\n * logo=\"/logo.png\"\n * :user-menu-items=\"userMenuItems\"\n * @logo-click=\"handleLogoClick\"\n * />\n * ```\n */\n\nexport type HeaderNavItem = {\n /** 라벨 */\n label: string\n /** 링크 URL */\n href?: string\n /** 아이콘 */\n icon?: string\n /** 활성 상태 */\n active?: boolean\n /** 클릭 핸들러 */\n onClick?: () => void\n}\n\nexport type NotificationItem = {\n /** 알림 ID */\n id: string\n /** 알림 제목 */\n title: string\n /** 알림 내용 */\n message?: string\n /** 알림 시간 */\n time?: string\n /** 읽음 상태 */\n read?: boolean\n /** 아이콘 */\n icon?: string\n /** 클릭 핸들러 */\n onClick?: () => void\n}\n\ntype StyleType =\n | 'default' // 기본 스타일\n | 'minimal' // 최소 스타일\n\nconst props = withDefaults(\n defineProps<{\n /** 로고 이미지 URL */\n logo?: string\n /** 로고 텍스트 (기본값, 이미지가 없을 때) */\n logoText?: string\n /** 네비게이션 아이템 목록 */\n navItems?: HeaderNavItem[]\n /** 알림 표시 여부 */\n showNotifications?: boolean\n /** 알림 목록 */\n notifications?: NotificationItem[]\n /** 사용자 아바타 이미지 */\n userAvatar?: string\n /** 사용자 이름 */\n userName?: string\n /** 로그인 상태 */\n isLoggedIn?: boolean\n /** 사용자 이메일 */\n userEmail?: string\n /** 사용자 ID */\n userId?: string\n /** 스타일 타입 */\n styletype?: StyleType\n /** 사이드바 토글 버튼 표시 여부 */\n showSidebarToggle?: boolean\n /** 사이드바 열림 상태 */\n isSidebarOpen?: boolean\n /** 테마 선택기 표시 여부 */\n showThemeSelector?: boolean\n /** 초기 테마 (기본값: 'default' 또는 저장된 테마) */\n defaultTheme?: string\n /** 선택 가능한 테마 목록 (지정하지 않으면 모든 감지된 테마 사용) */\n availableThemes?: string[]\n }>(),\n {\n logoText: 'JWMS Portal', // 기본값: 텍스트 로고\n showNotifications: false,\n notifications: () => [],\n styletype: 'default',\n showSidebarToggle: true,\n isSidebarOpen: true,\n showThemeSelector: true,\n defaultTheme: undefined,\n availableThemes: undefined,\n }\n)\n\nconst emit = defineEmits<{\n /** 로고 클릭 이벤트 */\n logoClick: []\n /** 네비게이션 아이템 클릭 이벤트 */\n navClick: [item: HeaderNavItem, index: number]\n /** 알림 클릭 이벤트 */\n notificationClick: [item: NotificationItem]\n /** 사용자 메뉴 아이템 선택 이벤트 */\n userMenuSelect: [itemId: string]\n /** 사이드바 토글 이벤트 */\n sidebarToggle: []\n /** 로그인 버튼 클릭 이벤트 */\n login: []\n}>()\n\n/**\n * 스타일 프리셋\n */\nconst STYLE_PRESETS: Record<StyleType, {\n containerClass: string\n navItemClass: string\n navItemActiveClass: string\n}> = {\n default: {\n containerClass: 'h-14 px-4 border-b border-border bg-background',\n navItemClass: 'text-sm text-muted-foreground hover:text-foreground transition-colors px-3 py-2 rounded-md hover:bg-accent',\n navItemActiveClass: 'text-foreground font-medium bg-accent',\n },\n minimal: {\n containerClass: 'h-12 px-3 border-b border-border bg-background',\n navItemClass: 'text-xs text-muted-foreground hover:text-foreground transition-colors px-2 py-1 rounded-md hover:bg-accent',\n navItemActiveClass: 'text-foreground font-medium bg-accent',\n },\n}\n\nconst preset = computed(() => {\n return STYLE_PRESETS[props.styletype] ?? STYLE_PRESETS.default\n})\n\n/**\n * 로고 이미지 로드 에러 상태\n * 0: 에러 없음, 1: 첫 번째 이미지(logo) 에러, 2: fallback 이미지도 에러\n */\nconst logoImageError = ref(0)\n\n/**\n * 로고 이미지 경로 계산\n */\nconst logoImageSrc = computed(() => {\n // props.logo가 있으면 사용\n if (props.logo) {\n return props.logo\n }\n return undefined\n})\n\n/**\n * 실제 표시할 로고 이미지 경로\n * 1. props.logo가 있으면 사용\n * 2. logo 에러 시 fallback 이미지\n * 3. fallback도 에러면 undefined (텍스트로 대체)\n */\nconst displayLogoImage = computed(() => {\n // logo prop이 없으면 이미지 표시 안함 (텍스트 사용)\n if (!props.logo) {\n return undefined\n }\n \n // logo 에러가 발생했으면 fallback 사용\n if (logoImageError.value >= 1 && logoFallback) {\n return logoFallback\n }\n \n // 정상적으로 logo 사용\n return logoImageSrc.value\n})\n\n/**\n * 로고 이미지 로드 에러 핸들러\n */\nconst handleLogoError = () => {\n // 첫 번째 이미지(logo) 에러\n if (logoImageError.value === 0) {\n logoImageError.value = 1\n }\n // fallback 이미지도 에러면 2로 설정 (텍스트로 대체)\n else if (logoImageError.value === 1) {\n logoImageError.value = 2\n }\n}\n\n/**\n * 읽지 않은 알림 개수\n */\nconst unreadCount = computed(() => {\n return props.notifications?.filter(n => !n.read).length || 0\n})\n\n/**\n * 고정 사용자 메뉴 아이템\n */\nconst fixedUserMenuItems: ContextMenuItem[] = [\n { id: 'profile', label: '프로필', icon: 'user' },\n { id: 'settings', label: '설정', icon: 'settings' },\n { id: 'separator', label: '', separator: true },\n { id: 'logout', label: '로그아웃', icon: 'logOut' },\n]\n\n/**\n * 사용자 메뉴 아이템을 ContextMenuGroup 형식으로 변환\n */\nconst userMenuGroups = computed<ContextMenuGroup[]>(() => {\n return [{\n items: fixedUserMenuItems\n }]\n})\n\n/**\n * 로고 클릭 핸들러\n */\nconst handleLogoClick = () => {\n emit('logoClick')\n}\n\n/**\n * 네비게이션 아이템 클릭 핸들러\n */\nconst handleNavClick = (item: HeaderNavItem, index: number) => {\n item.onClick?.()\n emit('navClick', item, index)\n}\n\n/**\n * 알림 클릭 핸들러\n */\nconst handleNotificationClick = (item: NotificationItem) => {\n item.onClick?.()\n emit('notificationClick', item)\n}\n\n/**\n * 사용자 메뉴 선택 핸들러\n */\nconst handleUserMenuSelect = (itemId: string) => {\n emit('userMenuSelect', itemId)\n}\n\n/**\n * 로그인 버튼 클릭 핸들러\n */\nconst handleLogin = () => {\n emit('login')\n}\n\n/**\n * 사이드바 토글 핸들러\n */\nconst handleSidebarToggle = () => {\n emit('sidebarToggle')\n}\n\n/**\n * tweakcn 테마 타입 정의 (동적 감지 지원)\n */\ntype ThemeName = string\n\n/**\n * 다크모드 상태를 추적하는 반응형 변수\n * - false: 라이트 모드\n * - true: 다크 모드\n * 초기값은 false(라이트 모드)이며, 컴포넌트 마운트 시 실제 테마로 업데이트됩니다.\n */\nconst isDarkMode = ref(false)\n\n/**\n * 현재 선택된 tweakcn 테마 (디폴트 테마로 초기화)\n */\nconst currentTheme = ref<ThemeName>(getDefaultTheme())\n\n/**\n * 테마 옵션 목록 (동적으로 감지)\n */\nconst themeOptions = ref<ThemeName[]>([])\n\n/**\n * 내부 업데이트 플래그\n * - true: 컴포넌트 내부에서 테마를 변경 중 (MutationObserver가 무시해야 함)\n * - false: 외부에서 테마가 변경됨 (MutationObserver가 동기화해야 함)\n */\nlet isInternalUpdate = false\n\n/**\n * MutationObserver 인스턴스\n */\nlet themeObserver: MutationObserver | null = null\nlet styleObserver: MutationObserver | null = null\n\n/**\n * Storybook 환경인지 확인하는 함수\n * \n * @returns Storybook 환경이면 true, 아니면 false\n */\nconst isStorybook = (): boolean => {\n if (typeof window === 'undefined') return false\n return !!(\n window.location?.href?.includes('storybook') ||\n (window as any).__STORYBOOK_GLOBALS__\n )\n}\n\n/**\n * 테마 목록을 동적으로 감지하고 업데이트합니다.\n */\nconst updateThemeOptions = () => {\n const detectedThemes = detectThemeClasses()\n const ensuredThemes = ensureDefaultTheme(detectedThemes)\n \n // availableThemes prop이 지정되면 필터링\n if (props.availableThemes && props.availableThemes.length > 0) {\n const filtered = ensuredThemes.filter(theme => props.availableThemes!.includes(theme))\n // default는 항상 포함\n themeOptions.value = ensureDefaultTheme(filtered)\n } else {\n themeOptions.value = ensuredThemes\n }\n}\n\n/**\n * localStorage에서 저장된 다크모드 테마를 읽어오는 함수\n * \n * 우선순위:\n * 1. localStorage에 저장된 'theme' 값 (사용자가 이전에 선택한 테마)\n * 2. 시스템 설정 (OS의 다크모드 설정)\n * 3. 기본값 'light' (라이트 모드)\n * \n * @returns 'light' | 'dark' - 적용할 테마\n */\nconst getStoredDarkModeTheme = (): 'light' | 'dark' => {\n if (typeof window === 'undefined') return 'light'\n \n const stored = localStorage.getItem('theme')\n if (stored === 'dark' || stored === 'light') {\n return stored\n }\n \n if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {\n return 'dark'\n }\n \n return 'light'\n}\n\n/**\n * 다크모드 테마를 HTML 문서에 적용하는 함수\n * \n * @param theme - 적용할 테마 ('light' 또는 'dark')\n */\nconst applyDarkModeTheme = (theme: 'light' | 'dark') => {\n isInternalUpdate = true\n \n const root = document.documentElement\n \n if (theme === 'dark') {\n root.classList.add('dark')\n isDarkMode.value = true\n } else {\n root.classList.remove('dark')\n isDarkMode.value = false\n }\n \n localStorage.setItem('theme', theme)\n \n isInternalUpdate = false\n}\n\n/**\n * 테마 토글 버튼 클릭 시 호출되는 핸들러 함수\n */\nconst handleThemeToggle = () => {\n const newTheme = isDarkMode.value ? 'light' : 'dark'\n applyDarkModeTheme(newTheme)\n}\n\n/**\n * 저장된 tweakcn 테마를 가져와서 적용합니다.\n */\nconst getStoredTweakcnTheme = (): ThemeName => {\n // defaultTheme prop이 지정되면 우선 사용\n if (props.defaultTheme) {\n const validated = validateThemeExists(props.defaultTheme)\n return validated\n }\n \n const stored = getStoredTheme('tweakcn-theme')\n if (!stored) {\n return getDefaultTheme()\n }\n \n // 저장된 테마가 유효한지 검증\n const validated = validateThemeExists(stored)\n return validated\n}\n\n/**\n * tweakcn 테마를 HTML 문서에 적용하는 함수\n */\nconst applyTweakcnTheme = (theme: ThemeName): boolean => {\n isInternalUpdate = true\n \n const validatedTheme = validateThemeExists(theme)\n const success = applyTheme(validatedTheme)\n \n if (success) {\n currentTheme.value = validatedTheme\n setStoredTheme(validatedTheme, 'tweakcn-theme')\n \n // 스토리북 환경에서만 전역 상태 동기화\n if (isStorybook()) {\n try {\n const storybookGlobals = (window as any).__STORYBOOK_GLOBALS__\n if (storybookGlobals) {\n storybookGlobals.theme = validatedTheme\n }\n } catch (e) {\n // 무시\n }\n }\n } else {\n // 실패 시 디폴트 테마로 폴백\n const defaultTheme = getDefaultTheme()\n applyTheme(defaultTheme)\n currentTheme.value = defaultTheme\n setStoredTheme(defaultTheme, 'tweakcn-theme')\n }\n \n isInternalUpdate = false\n return success\n}\n\n/**\n * 테마 변경 핸들러\n */\nconst handleThemeChange = (theme: ThemeName | string | number) => {\n applyTweakcnTheme(String(theme))\n}\n\n/**\n * 현재 테마에 따라 표시할 아이콘을 계산하는 computed 속성\n */\nconst themeIcon = computed(() => {\n return isDarkMode.value ? 'sun' : 'moon'\n})\n\n/**\n * 초기화: 저장된 테마 적용 및 테마 목록 감지\n */\nonMounted(() => {\n // 테마 목록 초기 감지\n updateThemeOptions()\n \n // 저장된 다크모드 테마 적용\n const darkModeTheme = getStoredDarkModeTheme()\n applyDarkModeTheme(darkModeTheme)\n \n // 저장된 tweakcn 테마 적용\n const storedTheme = getStoredTweakcnTheme()\n applyTweakcnTheme(storedTheme)\n \n // HTML의 dark 클래스 변경을 감지하여 헤더 컴포넌트 상태를 동기화\n const root = document.documentElement\n \n // 현재 dark 클래스 상태로 초기화\n isDarkMode.value = root.classList.contains('dark')\n \n // MutationObserver로 동적 테마 클래스 감지\n themeObserver = new MutationObserver(() => {\n if (isInternalUpdate) return\n \n // 다크모드 클래스 변경 감지\n const hasDarkClass = root.classList.contains('dark')\n if (hasDarkClass !== isDarkMode.value) {\n isDarkMode.value = hasDarkClass\n localStorage.setItem('theme', hasDarkClass ? 'dark' : 'light')\n }\n \n // 테마 목록 업데이트\n updateThemeOptions()\n \n // 현재 적용된 tweakcn 테마 확인\n const currentThemeClass = Array.from(root.classList).find(cls => cls.startsWith('theme-'))\n if (currentThemeClass) {\n const themeName = currentThemeClass.replace('theme-', '')\n if (themeOptions.value.includes(themeName)) {\n currentTheme.value = themeName\n }\n }\n })\n \n // document.documentElement의 클래스 변경 감지\n themeObserver.observe(document.documentElement, {\n attributes: true,\n attributeFilter: ['class'],\n })\n \n // 스타일시트 변경 감지 (동적으로 추가된 테마 감지)\n styleObserver = new MutationObserver(() => {\n updateThemeOptions()\n })\n \n styleObserver.observe(document.head, {\n childList: true,\n subtree: true,\n })\n \n // 스토리북 환경에서만 다크모드 및 테마 변경 감지 (추가 보완)\n let intervalId: ReturnType<typeof setInterval> | null = null\n \n if (isStorybook()) {\n const checkStorybookGlobals = () => {\n try {\n const storybookGlobals = (window as any).__STORYBOOK_GLOBALS__\n if (storybookGlobals) {\n // 다크모드 동기화\n if (typeof storybookGlobals.darkMode !== 'undefined') {\n const storybookDarkMode = storybookGlobals.darkMode\n if (storybookDarkMode !== isDarkMode.value) {\n applyDarkModeTheme(storybookDarkMode ? 'dark' : 'light')\n }\n }\n \n // tweakcn 테마 동기화\n if (storybookGlobals.theme && storybookGlobals.theme !== currentTheme.value) {\n const storybookTheme = String(storybookGlobals.theme)\n if (themeOptions.value.includes(storybookTheme)) {\n applyTweakcnTheme(storybookTheme)\n }\n }\n }\n } catch (e) {\n // 무시\n }\n }\n \n // 초기 확인\n checkStorybookGlobals()\n \n // 주기적으로 확인 (스토리북이 직접 이벤트를 제공하지 않는 경우)\n intervalId = setInterval(checkStorybookGlobals, 500)\n }\n \n // 컴포넌트 언마운트 시 정리\n onUnmounted(() => {\n if (themeObserver) {\n themeObserver.disconnect()\n themeObserver = null\n }\n if (styleObserver) {\n styleObserver.disconnect()\n styleObserver = null\n }\n if (intervalId) {\n clearInterval(intervalId)\n }\n })\n})\n</script>\n\n<template>\n <header :class=\"cn('flex items-center justify-between w-full', preset.containerClass)\">\n <!-- 왼쪽: 햄버거 메뉴 + 로고 + 네비게이션 -->\n <div class=\"flex items-center gap-6 flex-1\">\n <!-- 햄버거 메뉴 버튼 (사이드바 토글) -->\n <JButton\n v-if=\"showSidebarToggle\"\n variant=\"ghost\"\n size=\"icon\"\n class=\"flex-shrink-0\"\n aria-label=\"사이드바 토글\"\n @click=\"handleSidebarToggle\"\n >\n <JIcon name=\"menu\" size=\"md\" />\n </JButton>\n\n <!-- 로고 -->\n <div\n v-if=\"displayLogoImage || logoText\"\n class=\"flex items-center cursor-pointer\"\n @click=\"handleLogoClick\"\n >\n <!-- 로고 이미지 (logo prop이 있고 에러가 2 미만일 때) -->\n <img\n v-if=\"displayLogoImage && logoImageError < 2\"\n :src=\"displayLogoImage\"\n alt=\"로고\"\n class=\"h-8 w-auto\"\n @error=\"handleLogoError\"\n />\n <!-- 로고 텍스트 (기본 또는 모든 이미지 실패 시) -->\n <span\n v-else-if=\"logoText\"\n class=\"text-lg font-bold text-foreground\"\n >\n {{ logoText }}\n </span>\n </div>\n\n <!-- 네비게이션 -->\n <nav\n v-if=\"navItems && navItems.length > 0\"\n class=\"flex items-center gap-1\"\n >\n <JButton\n v-for=\"(item, index) in navItems\"\n :key=\"index\"\n variant=\"ghost\"\n :class=\"cn(\n preset.navItemClass,\n item.active && preset.navItemActiveClass\n )\"\n @click=\"handleNavClick(item, index)\"\n >\n <JIcon\n v-if=\"item.icon\"\n :name=\"item.icon\"\n size=\"sm\"\n class=\"mr-1.5\"\n />\n {{ item.label }}\n </JButton>\n </nav>\n </div>\n\n <!-- 오른쪽: 테마 선택기 + 알림 + 다크모드 토글 + 사용자 메뉴 -->\n <div class=\"flex items-center gap-3\">\n <!-- tweakcn 테마 선택기 -->\n <JPopover\n v-if=\"showThemeSelector\"\n position=\"bottom\"\n align=\"end\"\n styletype=\"default-sm\"\n >\n <template #trigger>\n <JButton\n variant=\"ghost\"\n size=\"icon\"\n aria-label=\"테마 선택\"\n >\n <JIcon name=\"palette\" size=\"md\" />\n </JButton>\n </template>\n <div class=\"p-2 min-w-[200px]\">\n <div class=\"text-xs font-medium text-muted-foreground px-2 py-1.5 mb-1\">\n 테마 선택\n </div>\n <div class=\"space-y-1\">\n <button\n v-for=\"theme in themeOptions\"\n :key=\"theme\"\n :class=\"cn(\n 'w-full flex items-center gap-2 px-2 py-1.5 text-sm rounded-md transition-colors',\n 'hover:bg-accent hover:text-accent-foreground',\n 'border-0 outline-none text-left',\n currentTheme === theme && 'bg-accent text-accent-foreground font-medium'\n )\"\n @click=\"handleThemeChange(theme)\"\n >\n <JIcon\n v-if=\"currentTheme === theme\"\n name=\"check\"\n size=\"sm\"\n class=\"flex-shrink-0\"\n />\n <span v-else class=\"w-4\" />\n <span class=\"flex-1 capitalize\">{{ theme }}</span>\n </button>\n </div>\n </div>\n </JPopover>\n\n <!-- 알림 -->\n <JPopover\n v-if=\"showNotifications\"\n position=\"bottom\"\n align=\"end\"\n styletype=\"default-sm\"\n >\n <template #trigger>\n <JButton\n variant=\"ghost\"\n size=\"icon\"\n class=\"relative\"\n aria-label=\"알림\"\n >\n <JIcon name=\"circleAlert\" size=\"md\" />\n <span\n v-if=\"unreadCount > 0\"\n class=\"absolute top-0 right-0 h-4 w-4 rounded-full bg-destructive text-destructive-foreground text-xs flex items-center justify-center\"\n >\n {{ unreadCount > 9 ? '9+' : unreadCount }}\n </span>\n </JButton>\n </template>\n <div class=\"p-2\">\n <div\n v-if=\"notifications && notifications.length > 0\"\n class=\"max-h-96 overflow-y-auto space-y-1\"\n >\n <div\n v-for=\"notification in notifications\"\n :key=\"notification.id\"\n :class=\"cn(\n 'p-3 rounded-md cursor-pointer transition-colors',\n !notification.read ? 'bg-accent' : 'hover:bg-accent/50'\n )\"\n @click=\"handleNotificationClick(notification)\"\n >\n <div class=\"flex items-start gap-2\">\n <JIcon\n v-if=\"notification.icon\"\n :name=\"notification.icon\"\n size=\"sm\"\n class=\"mt-0.5 flex-shrink-0\"\n />\n <div class=\"flex-1 min-w-0\">\n <p class=\"text-sm font-medium text-foreground\">\n {{ notification.title }}\n </p>\n <p\n v-if=\"notification.message\"\n class=\"text-xs text-muted-foreground mt-1\"\n >\n {{ notification.message }}\n </p>\n <p\n v-if=\"notification.time\"\n class=\"text-xs text-muted-foreground/60 mt-1\"\n >\n {{ notification.time }}\n </p>\n </div>\n </div>\n </div>\n </div>\n <div\n v-else\n class=\"p-4 text-center text-sm text-muted-foreground\"\n >\n 알림이 없습니다.\n </div>\n </div>\n </JPopover>\n\n <!-- 다크모드 토글 버튼 -->\n <JButton\n variant=\"ghost\"\n size=\"icon\"\n :aria-label=\"isDarkMode ? '라이트 모드로 전환' : '다크 모드로 전환'\"\n @click=\"handleThemeToggle\"\n >\n <JIcon :name=\"themeIcon\" size=\"md\" />\n </JButton>\n\n <!-- 사용자 메뉴 (userName이 있으면 표시) -->\n <JPopover\n v-if=\"userName\"\n position=\"bottom\"\n align=\"end\"\n styletype=\"default-sm\"\n >\n <template #trigger>\n <div class=\"flex items-center gap-2 cursor-pointer hover:opacity-80 transition-opacity\">\n <JAvatar\n :src=\"userAvatar\"\n :fallback=\"userName ? userName[0] : 'U'\"\n size=\"sm\"\n />\n <span\n class=\"text-sm text-foreground hidden sm:inline\"\n >\n {{ userName }}\n </span>\n <JIcon name=\"chevronDown\" size=\"sm\" class=\"text-muted-foreground hidden sm:inline\" />\n </div>\n </template>\n <div class=\"w-full rounded-md overflow-hidden\">\n <!-- 프로필 정보 영역 -->\n <div class=\"px-3 py-2 border-b border-border\">\n <p class=\"text-sm font-medium text-foreground\">{{ userName }}</p>\n <p\n v-if=\"userEmail\"\n class=\"text-xs text-muted-foreground mt-0.5\"\n >\n {{ userEmail }}\n </p>\n </div>\n \n <!-- 메뉴 아이템 -->\n <template v-for=\"(group, groupIndex) in userMenuGroups\" :key=\"groupIndex\">\n <template v-for=\"(item, itemIndex) in group.items\" :key=\"item.id\">\n <button\n v-if=\"!item.separator\"\n :disabled=\"item.disabled\"\n :class=\"cn(\n 'w-full flex items-center gap-2 px-3 py-1.5 text-sm transition-colors',\n item.id === 'logout' \n ? 'text-destructive hover:bg-destructive/10 hover:text-destructive' \n : 'hover:bg-accent hover:text-accent-foreground',\n 'disabled:opacity-50 disabled:pointer-events-none',\n 'border-0 outline-none',\n group.items[itemIndex + 1]?.separator && 'border-b-0'\n )\"\n @click=\"handleUserMenuSelect(item.id)\"\n >\n <JIcon\n v-if=\"item.icon\"\n :name=\"item.icon\"\n size=\"sm\"\n :class=\"cn(\n 'flex-shrink-0',\n item.id === 'logout' && 'text-destructive'\n )\"\n />\n <span class=\"flex-1 text-left truncate\">{{ item.label }}</span>\n </button>\n <div\n v-else-if=\"item.separator && itemIndex > 0\"\n class=\"h-px bg-muted my-1\"\n />\n </template>\n <div\n v-if=\"groupIndex < userMenuGroups.length - 1\"\n class=\"h-px bg-muted my-1\"\n />\n </template>\n </div>\n </JPopover>\n\n <!-- 로그인 버튼 (userName이 없으면 표시) -->\n <JButton\n v-else\n variant=\"ghost\"\n size=\"sm\"\n aria-label=\"로그인\"\n @click=\"handleLogin\"\n >\n <JIcon name=\"logIn\" size=\"sm\" class=\"sm:mr-1.5\" />\n <span class=\"hidden sm:inline\">로그인</span>\n </JButton>\n\n <!-- 커스텀 슬롯 -->\n <slot name=\"actions\" />\n </div>\n </header>\n</template>\n"],"names":["props","__props","emit","__emit","STYLE_PRESETS","preset","computed","logoImageError","ref","logoImageSrc","displayLogoImage","logoFallback","handleLogoError","unreadCount","n","fixedUserMenuItems","userMenuGroups","handleLogoClick","handleNavClick","item","index","handleNotificationClick","handleUserMenuSelect","itemId","handleLogin","handleSidebarToggle","isDarkMode","currentTheme","getDefaultTheme","themeOptions","isInternalUpdate","themeObserver","styleObserver","isStorybook","updateThemeOptions","detectedThemes","detectThemeClasses","ensuredThemes","ensureDefaultTheme","filtered","theme","getStoredDarkModeTheme","stored","applyDarkModeTheme","root","handleThemeToggle","newTheme","getStoredTweakcnTheme","validateThemeExists","getStoredTheme","applyTweakcnTheme","validatedTheme","success","applyTheme","setStoredTheme","storybookGlobals","defaultTheme","handleThemeChange","themeIcon","onMounted","darkModeTheme","storedTheme","hasDarkClass","currentThemeClass","cls","themeName","intervalId","checkStorybookGlobals","storybookDarkMode","storybookTheme","onUnmounted","_createElementBlock","_normalizeClass","_unref","cn","_createElementVNode","_hoisted_1","_createBlock","JButton","_createVNode","JIcon","_hoisted_3","_toDisplayString","_openBlock","_hoisted_4","_Fragment","_renderList","$event","_hoisted_5","JPopover","_hoisted_6","_cache","_hoisted_7","_hoisted_9","_hoisted_10","_hoisted_11","_hoisted_12","_hoisted_13","notification","_hoisted_15","_hoisted_16","_hoisted_17","_hoisted_18","_hoisted_19","_hoisted_20","_hoisted_21","JAvatar","_hoisted_22","_hoisted_23","_hoisted_24","_hoisted_25","_hoisted_26","group","groupIndex","itemIndex","_hoisted_29","_hoisted_28","_hoisted_30","_renderSlot","_ctx"],"mappings":"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"}
1
+ {"version":3,"file":"JHeader.vue.js","sources":["../../../../src/components/organisms/JHeader.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, ref, onMounted, onUnmounted } from 'vue'\nimport JIcon from '@/components/atoms/JIcon.vue'\nimport JAvatar from '@/components/atoms/JAvatar.vue'\nimport JButton from '@/components/atoms/JButton.vue'\nimport JPopover from '@/components/atoms/JPopover.vue'\nimport { cn } from '@/lib/utils'\nimport type { ContextMenuItem, ContextMenuGroup } from '@/types/context-menu.types'\nimport {\n detectThemeClasses,\n ensureDefaultTheme,\n validateThemeExists,\n getDefaultTheme,\n getStoredTheme,\n setStoredTheme,\n applyTheme,\n} from '@/lib/theme-utils'\n\n// Fallback 로고 이미지 import (logo prop이 없거나 로드 실패 시 사용)\nimport logoFallback from '@/assets/images/logo-fallback.png'\n\n/**\n * JHeader - 상단 헤더 컴포넌트 (organisms)\n * Header Component\n * \n * @description\n * 애플리케이션의 상단 헤더 영역을 담당하는 컴포넌트입니다.\n * 로고, 네비게이션, 검색, 알림, 사용자 메뉴 등을 포함할 수 있습니다.\n * \n * @example\n * ```vue\n * <JHeader\n * logo=\"/logo.png\"\n * :user-menu-items=\"userMenuItems\"\n * @logo-click=\"handleLogoClick\"\n * />\n * ```\n */\n\nexport type HeaderNavItem = {\n /** 라벨 */\n label: string\n /** 링크 URL */\n href?: string\n /** 아이콘 */\n icon?: string\n /** 활성 상태 */\n active?: boolean\n /** 클릭 핸들러 */\n onClick?: () => void\n}\n\nexport type NotificationItem = {\n /** 알림 ID */\n id: string\n /** 알림 제목 */\n title: string\n /** 알림 내용 */\n message?: string\n /** 알림 시간 */\n time?: string\n /** 읽음 상태 */\n read?: boolean\n /** 아이콘 */\n icon?: string\n /** 클릭 핸들러 */\n onClick?: () => void\n}\n\ntype StyleType =\n | 'default' // 기본 스타일\n | 'minimal' // 최소 스타일\n\nconst props = withDefaults(\n defineProps<{\n /** 로고 이미지 URL */\n logo?: string\n /** 로고 텍스트 (기본값, 이미지가 없을 때) */\n logoText?: string\n /** 네비게이션 아이템 목록 */\n navItems?: HeaderNavItem[]\n /** 알림 표시 여부 */\n showNotifications?: boolean\n /** 알림 목록 */\n notifications?: NotificationItem[]\n /** 사용자 아바타 이미지 */\n userAvatar?: string\n /** 사용자 이름 */\n userName?: string\n /** 로그인 상태 */\n isLoggedIn?: boolean\n /** 사용자 이메일 */\n userEmail?: string\n /** 사용자 ID */\n userId?: string\n /** 스타일 타입 */\n styletype?: StyleType\n /** 사이드바 토글 버튼 표시 여부 */\n showSidebarToggle?: boolean\n /** 사이드바 열림 상태 */\n isSidebarOpen?: boolean\n /** 테마 선택기 표시 여부 */\n showThemeSelector?: boolean\n /** 초기 테마 (기본값: 'default' 또는 저장된 테마) */\n defaultTheme?: string\n /** 선택 가능한 테마 목록 (지정하지 않으면 모든 감지된 테마 사용) */\n availableThemes?: string[]\n }>(),\n {\n logoText: 'JWMS Portal', // 기본값: 텍스트 로고\n showNotifications: false,\n notifications: () => [],\n styletype: 'default',\n showSidebarToggle: true,\n isSidebarOpen: true,\n showThemeSelector: true,\n defaultTheme: undefined,\n availableThemes: undefined,\n }\n)\n\nconst emit = defineEmits<{\n /** 로고 클릭 이벤트 */\n logoClick: []\n /** 네비게이션 아이템 클릭 이벤트 */\n navClick: [item: HeaderNavItem, index: number]\n /** 알림 클릭 이벤트 */\n notificationClick: [item: NotificationItem]\n /** 사용자 메뉴 아이템 선택 이벤트 */\n userMenuSelect: [itemId: string]\n /** 사이드바 토글 이벤트 */\n sidebarToggle: []\n /** 로그인 버튼 클릭 이벤트 */\n login: []\n}>()\n\n/**\n * 스타일 프리셋\n */\nconst STYLE_PRESETS: Record<StyleType, {\n containerClass: string\n navItemClass: string\n navItemActiveClass: string\n}> = {\n default: {\n containerClass: 'h-10 px-4 border-b border-border bg-background',\n navItemClass: 'text-xs text-muted-foreground hover:text-foreground transition-colors px-3 py-1.5 rounded-md hover:bg-accent',\n navItemActiveClass: 'text-foreground font-medium bg-accent',\n },\n minimal: {\n containerClass: 'h-8 px-3 border-b border-border bg-background',\n navItemClass: 'text-xs text-muted-foreground hover:text-foreground transition-colors px-2 py-1 rounded-md hover:bg-accent',\n navItemActiveClass: 'text-foreground font-medium bg-accent',\n },\n}\n\nconst preset = computed(() => {\n return STYLE_PRESETS[props.styletype] ?? STYLE_PRESETS.default\n})\n\n/**\n * 로고 이미지 로드 에러 상태\n * 0: 에러 없음, 1: 첫 번째 이미지(logo) 에러, 2: fallback 이미지도 에러\n */\nconst logoImageError = ref(0)\n\n/**\n * 로고 이미지 경로 계산\n */\nconst logoImageSrc = computed(() => {\n // props.logo가 있으면 사용\n if (props.logo) {\n return props.logo\n }\n return undefined\n})\n\n/**\n * 실제 표시할 로고 이미지 경로\n * 1. props.logo가 있으면 사용\n * 2. logo 에러 시 fallback 이미지\n * 3. fallback도 에러면 undefined (텍스트로 대체)\n */\nconst displayLogoImage = computed(() => {\n // logo prop이 없으면 이미지 표시 안함 (텍스트 사용)\n if (!props.logo) {\n return undefined\n }\n \n // logo 에러가 발생했으면 fallback 사용\n if (logoImageError.value >= 1 && logoFallback) {\n return logoFallback\n }\n \n // 정상적으로 logo 사용\n return logoImageSrc.value\n})\n\n/**\n * 로고 이미지 로드 에러 핸들러\n */\nconst handleLogoError = () => {\n // 첫 번째 이미지(logo) 에러\n if (logoImageError.value === 0) {\n logoImageError.value = 1\n }\n // fallback 이미지도 에러면 2로 설정 (텍스트로 대체)\n else if (logoImageError.value === 1) {\n logoImageError.value = 2\n }\n}\n\n/**\n * 읽지 않은 알림 개수\n */\nconst unreadCount = computed(() => {\n return props.notifications?.filter(n => !n.read).length || 0\n})\n\n/**\n * 고정 사용자 메뉴 아이템\n */\nconst fixedUserMenuItems: ContextMenuItem[] = [\n { id: 'profile', label: '프로필', icon: 'user' },\n { id: 'settings', label: '설정', icon: 'settings' },\n { id: 'separator', label: '', separator: true },\n { id: 'logout', label: '로그아웃', icon: 'logOut' },\n]\n\n/**\n * 사용자 메뉴 아이템을 ContextMenuGroup 형식으로 변환\n */\nconst userMenuGroups = computed<ContextMenuGroup[]>(() => {\n return [{\n items: fixedUserMenuItems\n }]\n})\n\n/**\n * 로고 클릭 핸들러\n */\nconst handleLogoClick = () => {\n emit('logoClick')\n}\n\n/**\n * 네비게이션 아이템 클릭 핸들러\n */\nconst handleNavClick = (item: HeaderNavItem, index: number) => {\n item.onClick?.()\n emit('navClick', item, index)\n}\n\n/**\n * 알림 클릭 핸들러\n */\nconst handleNotificationClick = (item: NotificationItem) => {\n item.onClick?.()\n emit('notificationClick', item)\n}\n\n/**\n * 사용자 메뉴 선택 핸들러\n */\nconst handleUserMenuSelect = (itemId: string) => {\n emit('userMenuSelect', itemId)\n}\n\n/**\n * 로그인 버튼 클릭 핸들러\n */\nconst handleLogin = () => {\n emit('login')\n}\n\n/**\n * 사이드바 토글 핸들러\n */\nconst handleSidebarToggle = () => {\n emit('sidebarToggle')\n}\n\n/**\n * tweakcn 테마 타입 정의 (동적 감지 지원)\n */\ntype ThemeName = string\n\n/**\n * 다크모드 상태를 추적하는 반응형 변수\n * - false: 라이트 모드\n * - true: 다크 모드\n * 초기값은 false(라이트 모드)이며, 컴포넌트 마운트 시 실제 테마로 업데이트됩니다.\n */\nconst isDarkMode = ref(false)\n\n/**\n * 현재 선택된 tweakcn 테마 (디폴트 테마로 초기화)\n */\nconst currentTheme = ref<ThemeName>(getDefaultTheme())\n\n/**\n * 테마 옵션 목록 (동적으로 감지)\n */\nconst themeOptions = ref<ThemeName[]>([])\n\n/**\n * 내부 업데이트 플래그\n * - true: 컴포넌트 내부에서 테마를 변경 중 (MutationObserver가 무시해야 함)\n * - false: 외부에서 테마가 변경됨 (MutationObserver가 동기화해야 함)\n */\nlet isInternalUpdate = false\n\n/**\n * MutationObserver 인스턴스\n */\nlet themeObserver: MutationObserver | null = null\nlet styleObserver: MutationObserver | null = null\n\n/**\n * Storybook 환경인지 확인하는 함수\n * \n * @returns Storybook 환경이면 true, 아니면 false\n */\nconst isStorybook = (): boolean => {\n if (typeof window === 'undefined') return false\n return !!(\n window.location?.href?.includes('storybook') ||\n (window as any).__STORYBOOK_GLOBALS__\n )\n}\n\n/**\n * 테마 목록을 동적으로 감지하고 업데이트합니다.\n */\nconst updateThemeOptions = () => {\n const detectedThemes = detectThemeClasses()\n const ensuredThemes = ensureDefaultTheme(detectedThemes)\n \n // availableThemes prop이 지정되면 필터링\n if (props.availableThemes && props.availableThemes.length > 0) {\n const filtered = ensuredThemes.filter(theme => props.availableThemes!.includes(theme))\n // default는 항상 포함\n themeOptions.value = ensureDefaultTheme(filtered)\n } else {\n themeOptions.value = ensuredThemes\n }\n}\n\n/**\n * localStorage에서 저장된 다크모드 테마를 읽어오는 함수\n * \n * 우선순위:\n * 1. localStorage에 저장된 'theme' 값 (사용자가 이전에 선택한 테마)\n * 2. 시스템 설정 (OS의 다크모드 설정)\n * 3. 기본값 'light' (라이트 모드)\n * \n * @returns 'light' | 'dark' - 적용할 테마\n */\nconst getStoredDarkModeTheme = (): 'light' | 'dark' => {\n if (typeof window === 'undefined') return 'light'\n \n const stored = localStorage.getItem('theme')\n if (stored === 'dark' || stored === 'light') {\n return stored\n }\n \n if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {\n return 'dark'\n }\n \n return 'light'\n}\n\n/**\n * 다크모드 테마를 HTML 문서에 적용하는 함수\n * \n * @param theme - 적용할 테마 ('light' 또는 'dark')\n */\nconst applyDarkModeTheme = (theme: 'light' | 'dark') => {\n isInternalUpdate = true\n \n const root = document.documentElement\n \n if (theme === 'dark') {\n root.classList.add('dark')\n isDarkMode.value = true\n } else {\n root.classList.remove('dark')\n isDarkMode.value = false\n }\n \n localStorage.setItem('theme', theme)\n \n isInternalUpdate = false\n}\n\n/**\n * 테마 토글 버튼 클릭 시 호출되는 핸들러 함수\n */\nconst handleThemeToggle = () => {\n const newTheme = isDarkMode.value ? 'light' : 'dark'\n applyDarkModeTheme(newTheme)\n}\n\n/**\n * 저장된 tweakcn 테마를 가져와서 적용합니다.\n */\nconst getStoredTweakcnTheme = (): ThemeName => {\n // defaultTheme prop이 지정되면 우선 사용\n if (props.defaultTheme) {\n const validated = validateThemeExists(props.defaultTheme)\n return validated\n }\n \n const stored = getStoredTheme('tweakcn-theme')\n if (!stored) {\n return getDefaultTheme()\n }\n \n // 저장된 테마가 유효한지 검증\n const validated = validateThemeExists(stored)\n return validated\n}\n\n/**\n * tweakcn 테마를 HTML 문서에 적용하는 함수\n */\nconst applyTweakcnTheme = (theme: ThemeName): boolean => {\n isInternalUpdate = true\n \n const validatedTheme = validateThemeExists(theme)\n const success = applyTheme(validatedTheme)\n \n if (success) {\n currentTheme.value = validatedTheme\n setStoredTheme(validatedTheme, 'tweakcn-theme')\n \n // 스토리북 환경에서만 전역 상태 동기화\n if (isStorybook()) {\n try {\n const storybookGlobals = (window as any).__STORYBOOK_GLOBALS__\n if (storybookGlobals) {\n storybookGlobals.theme = validatedTheme\n }\n } catch (e) {\n // 무시\n }\n }\n } else {\n // 실패 시 디폴트 테마로 폴백\n const defaultTheme = getDefaultTheme()\n applyTheme(defaultTheme)\n currentTheme.value = defaultTheme\n setStoredTheme(defaultTheme, 'tweakcn-theme')\n }\n \n isInternalUpdate = false\n return success\n}\n\n/**\n * 테마 변경 핸들러\n */\nconst handleThemeChange = (theme: ThemeName | string | number) => {\n applyTweakcnTheme(String(theme))\n}\n\n/**\n * 현재 테마에 따라 표시할 아이콘을 계산하는 computed 속성\n */\nconst themeIcon = computed(() => {\n return isDarkMode.value ? 'sun' : 'moon'\n})\n\n/**\n * 초기화: 저장된 테마 적용 및 테마 목록 감지\n */\nonMounted(() => {\n // 테마 목록 초기 감지\n updateThemeOptions()\n \n // 저장된 다크모드 테마 적용\n const darkModeTheme = getStoredDarkModeTheme()\n applyDarkModeTheme(darkModeTheme)\n \n // 저장된 tweakcn 테마 적용\n const storedTheme = getStoredTweakcnTheme()\n applyTweakcnTheme(storedTheme)\n \n // HTML의 dark 클래스 변경을 감지하여 헤더 컴포넌트 상태를 동기화\n const root = document.documentElement\n \n // 현재 dark 클래스 상태로 초기화\n isDarkMode.value = root.classList.contains('dark')\n \n // MutationObserver로 동적 테마 클래스 감지\n themeObserver = new MutationObserver(() => {\n if (isInternalUpdate) return\n \n // 다크모드 클래스 변경 감지\n const hasDarkClass = root.classList.contains('dark')\n if (hasDarkClass !== isDarkMode.value) {\n isDarkMode.value = hasDarkClass\n localStorage.setItem('theme', hasDarkClass ? 'dark' : 'light')\n }\n \n // 테마 목록 업데이트\n updateThemeOptions()\n \n // 현재 적용된 tweakcn 테마 확인\n const currentThemeClass = Array.from(root.classList).find(cls => cls.startsWith('theme-'))\n if (currentThemeClass) {\n const themeName = currentThemeClass.replace('theme-', '')\n if (themeOptions.value.includes(themeName)) {\n currentTheme.value = themeName\n }\n }\n })\n \n // document.documentElement의 클래스 변경 감지\n themeObserver.observe(document.documentElement, {\n attributes: true,\n attributeFilter: ['class'],\n })\n \n // 스타일시트 변경 감지 (동적으로 추가된 테마 감지)\n styleObserver = new MutationObserver(() => {\n updateThemeOptions()\n })\n \n styleObserver.observe(document.head, {\n childList: true,\n subtree: true,\n })\n \n // 스토리북 환경에서만 다크모드 및 테마 변경 감지 (추가 보완)\n let intervalId: ReturnType<typeof setInterval> | null = null\n \n if (isStorybook()) {\n const checkStorybookGlobals = () => {\n try {\n const storybookGlobals = (window as any).__STORYBOOK_GLOBALS__\n if (storybookGlobals) {\n // 다크모드 동기화\n if (typeof storybookGlobals.darkMode !== 'undefined') {\n const storybookDarkMode = storybookGlobals.darkMode\n if (storybookDarkMode !== isDarkMode.value) {\n applyDarkModeTheme(storybookDarkMode ? 'dark' : 'light')\n }\n }\n \n // tweakcn 테마 동기화\n if (storybookGlobals.theme && storybookGlobals.theme !== currentTheme.value) {\n const storybookTheme = String(storybookGlobals.theme)\n if (themeOptions.value.includes(storybookTheme)) {\n applyTweakcnTheme(storybookTheme)\n }\n }\n }\n } catch (e) {\n // 무시\n }\n }\n \n // 초기 확인\n checkStorybookGlobals()\n \n // 주기적으로 확인 (스토리북이 직접 이벤트를 제공하지 않는 경우)\n intervalId = setInterval(checkStorybookGlobals, 500)\n }\n \n // 컴포넌트 언마운트 시 정리\n onUnmounted(() => {\n if (themeObserver) {\n themeObserver.disconnect()\n themeObserver = null\n }\n if (styleObserver) {\n styleObserver.disconnect()\n styleObserver = null\n }\n if (intervalId) {\n clearInterval(intervalId)\n }\n })\n})\n</script>\n\n<template>\n <header :class=\"cn('flex items-center justify-between w-full', preset.containerClass)\">\n <!-- 왼쪽: 햄버거 메뉴 + 로고 + 네비게이션 -->\n <div class=\"flex items-center gap-6 flex-1\">\n <!-- 햄버거 메뉴 버튼 (사이드바 토글) -->\n <JButton\n v-if=\"showSidebarToggle\"\n variant=\"ghost\"\n size=\"sm\"\n class=\"flex-shrink-0 w-8 h-8 p-0\"\n aria-label=\"사이드바 토글\"\n @click=\"handleSidebarToggle\"\n >\n <JIcon name=\"menu\" size=\"sm\" />\n </JButton>\n\n <!-- 로고 -->\n <div\n v-if=\"displayLogoImage || logoText\"\n class=\"flex items-center cursor-pointer\"\n @click=\"handleLogoClick\"\n >\n <!-- 로고 이미지 (logo prop이 있고 에러가 2 미만일 때) -->\n <img\n v-if=\"displayLogoImage && logoImageError < 2\"\n :src=\"displayLogoImage\"\n alt=\"로고\"\n class=\"h-6 w-auto\"\n @error=\"handleLogoError\"\n />\n <!-- 로고 텍스트 (기본 또는 모든 이미지 실패 시) -->\n <span\n v-else-if=\"logoText\"\n class=\"text-sm font-bold text-foreground\"\n >\n {{ logoText }}\n </span>\n </div>\n\n <!-- 네비게이션 -->\n <nav\n v-if=\"navItems && navItems.length > 0\"\n class=\"flex items-center gap-1\"\n >\n <JButton\n v-for=\"(item, index) in navItems\"\n :key=\"index\"\n variant=\"ghost\"\n :class=\"cn(\n preset.navItemClass,\n item.active && preset.navItemActiveClass\n )\"\n @click=\"handleNavClick(item, index)\"\n >\n <JIcon\n v-if=\"item.icon\"\n :name=\"item.icon\"\n size=\"sm\"\n class=\"mr-1.5\"\n />\n {{ item.label }}\n </JButton>\n </nav>\n </div>\n\n <!-- 오른쪽: 테마 선택기 + 알림 + 다크모드 토글 + 사용자 메뉴 -->\n <div class=\"flex items-center gap-3\">\n <!-- tweakcn 테마 선택기 -->\n <JPopover\n v-if=\"showThemeSelector\"\n position=\"bottom\"\n align=\"end\"\n styletype=\"default-sm\"\n >\n <template #trigger>\n <JButton\n variant=\"ghost\"\n size=\"sm\"\n class=\"w-8 h-8 p-0\"\n aria-label=\"테마 선택\"\n >\n <JIcon name=\"palette\" size=\"sm\" />\n </JButton>\n </template>\n <div class=\"p-2 min-w-[200px]\">\n <div class=\"text-xs font-medium text-muted-foreground px-2 py-1.5 mb-1\">\n 테마 선택\n </div>\n <div class=\"space-y-1\">\n <button\n v-for=\"theme in themeOptions\"\n :key=\"theme\"\n :class=\"cn(\n 'w-full flex items-center gap-2 px-2 py-1.5 text-xs rounded-md transition-colors',\n 'hover:bg-accent hover:text-accent-foreground',\n 'border-0 outline-none text-left',\n currentTheme === theme && 'bg-accent text-accent-foreground font-medium'\n )\"\n @click=\"handleThemeChange(theme)\"\n >\n <JIcon\n v-if=\"currentTheme === theme\"\n name=\"check\"\n size=\"sm\"\n class=\"flex-shrink-0\"\n />\n <span v-else class=\"w-4\" />\n <span class=\"flex-1 capitalize\">{{ theme }}</span>\n </button>\n </div>\n </div>\n </JPopover>\n\n <!-- 알림 -->\n <JPopover\n v-if=\"showNotifications\"\n position=\"bottom\"\n align=\"end\"\n styletype=\"default-sm\"\n >\n <template #trigger>\n <JButton\n variant=\"ghost\"\n size=\"sm\"\n class=\"relative w-8 h-8 p-0\"\n aria-label=\"알림\"\n >\n <JIcon name=\"circleAlert\" size=\"sm\" />\n <span\n v-if=\"unreadCount > 0\"\n class=\"absolute top-0 right-0 h-4 w-4 rounded-full bg-destructive text-destructive-foreground text-xs flex items-center justify-center\"\n >\n {{ unreadCount > 9 ? '9+' : unreadCount }}\n </span>\n </JButton>\n </template>\n <div class=\"p-2\">\n <div\n v-if=\"notifications && notifications.length > 0\"\n class=\"max-h-96 overflow-y-auto space-y-1\"\n >\n <div\n v-for=\"notification in notifications\"\n :key=\"notification.id\"\n :class=\"cn(\n 'p-3 rounded-md cursor-pointer transition-colors',\n !notification.read ? 'bg-accent' : 'hover:bg-accent/50'\n )\"\n @click=\"handleNotificationClick(notification)\"\n >\n <div class=\"flex items-start gap-2\">\n <JIcon\n v-if=\"notification.icon\"\n :name=\"notification.icon\"\n size=\"sm\"\n class=\"mt-0.5 flex-shrink-0\"\n />\n <div class=\"flex-1 min-w-0\">\n <p class=\"text-xs font-medium text-foreground\">\n {{ notification.title }}\n </p>\n <p\n v-if=\"notification.message\"\n class=\"text-xs text-muted-foreground mt-1\"\n >\n {{ notification.message }}\n </p>\n <p\n v-if=\"notification.time\"\n class=\"text-xs text-muted-foreground/60 mt-1\"\n >\n {{ notification.time }}\n </p>\n </div>\n </div>\n </div>\n </div>\n <div\n v-else\n class=\"p-4 text-center text-xs text-muted-foreground\"\n >\n 알림이 없습니다.\n </div>\n </div>\n </JPopover>\n\n <!-- 다크모드 토글 버튼 -->\n <JButton\n variant=\"ghost\"\n size=\"sm\"\n class=\"w-8 h-8 p-0\"\n :aria-label=\"isDarkMode ? '라이트 모드로 전환' : '다크 모드로 전환'\"\n @click=\"handleThemeToggle\"\n >\n <JIcon :name=\"themeIcon\" size=\"sm\" />\n </JButton>\n\n <!-- 커스텀 툴바 슬롯 (다크모드 토글 버튼 우측) -->\n <slot name=\"toolbar\" />\n\n <!-- 사용자 메뉴 (userName이 있으면 표시) -->\n <JPopover\n v-if=\"userName\"\n position=\"bottom\"\n align=\"end\"\n styletype=\"default-sm\"\n >\n <template #trigger>\n <div class=\"flex items-center gap-2 cursor-pointer hover:opacity-80 transition-opacity\">\n <JAvatar\n :src=\"userAvatar\"\n :fallback=\"userName ? userName[0] : 'U'\"\n size=\"xs\"\n />\n <span\n class=\"text-xs text-foreground hidden sm:inline\"\n >\n {{ userName }}\n </span>\n <JIcon name=\"chevronDown\" size=\"sm\" class=\"text-muted-foreground hidden sm:inline\" />\n </div>\n </template>\n <div class=\"w-full rounded-md overflow-hidden\">\n <!-- 프로필 정보 영역 -->\n <div class=\"px-3 py-1.5 border-b border-border\">\n <p class=\"text-xs font-medium text-foreground\">{{ userName }}</p>\n <p\n v-if=\"userEmail\"\n class=\"text-xs text-muted-foreground mt-0.5\"\n >\n {{ userEmail }}\n </p>\n </div>\n \n <!-- 메뉴 아이템 -->\n <template v-for=\"(group, groupIndex) in userMenuGroups\" :key=\"groupIndex\">\n <template v-for=\"(item, itemIndex) in group.items\" :key=\"item.id\">\n <button\n v-if=\"!item.separator\"\n :disabled=\"item.disabled\"\n :class=\"cn(\n 'w-full flex items-center gap-2 px-3 py-1.5 text-xs transition-colors',\n item.id === 'logout' \n ? 'text-destructive hover:bg-destructive/10 hover:text-destructive' \n : 'hover:bg-accent hover:text-accent-foreground',\n 'disabled:opacity-50 disabled:pointer-events-none',\n 'border-0 outline-none',\n group.items[itemIndex + 1]?.separator && 'border-b-0'\n )\"\n @click=\"handleUserMenuSelect(item.id)\"\n >\n <JIcon\n v-if=\"item.icon\"\n :name=\"item.icon\"\n size=\"sm\"\n :class=\"cn(\n 'flex-shrink-0',\n item.id === 'logout' && 'text-destructive'\n )\"\n />\n <span class=\"flex-1 text-left truncate\">{{ item.label }}</span>\n </button>\n <div\n v-else-if=\"item.separator && itemIndex > 0\"\n class=\"h-px bg-muted my-1\"\n />\n </template>\n <div\n v-if=\"groupIndex < userMenuGroups.length - 1\"\n class=\"h-px bg-muted my-1\"\n />\n </template>\n </div>\n </JPopover>\n\n <!-- 로그인 버튼 (userName이 없으면 표시) -->\n <JButton\n v-else\n variant=\"ghost\"\n size=\"sm\"\n aria-label=\"로그인\"\n @click=\"handleLogin\"\n >\n <JIcon name=\"logIn\" size=\"sm\" class=\"sm:mr-1.5\" />\n <span class=\"hidden sm:inline\">로그인</span>\n </JButton>\n </div>\n </header>\n</template>\n"],"names":["props","__props","emit","__emit","STYLE_PRESETS","preset","computed","logoImageError","ref","logoImageSrc","displayLogoImage","logoFallback","handleLogoError","unreadCount","n","fixedUserMenuItems","userMenuGroups","handleLogoClick","handleNavClick","item","index","handleNotificationClick","handleUserMenuSelect","itemId","handleLogin","handleSidebarToggle","isDarkMode","currentTheme","getDefaultTheme","themeOptions","isInternalUpdate","themeObserver","styleObserver","isStorybook","updateThemeOptions","detectedThemes","detectThemeClasses","ensuredThemes","ensureDefaultTheme","filtered","theme","getStoredDarkModeTheme","stored","applyDarkModeTheme","root","handleThemeToggle","newTheme","getStoredTweakcnTheme","validateThemeExists","getStoredTheme","applyTweakcnTheme","validatedTheme","success","applyTheme","setStoredTheme","storybookGlobals","defaultTheme","handleThemeChange","themeIcon","onMounted","darkModeTheme","storedTheme","hasDarkClass","currentThemeClass","cls","themeName","intervalId","checkStorybookGlobals","storybookDarkMode","storybookTheme","onUnmounted","_createElementBlock","_normalizeClass","_unref","cn","_createElementVNode","_hoisted_1","_createBlock","JButton","_createVNode","JIcon","_hoisted_3","_toDisplayString","_openBlock","_hoisted_4","_Fragment","_renderList","$event","_hoisted_5","JPopover","_hoisted_6","_cache","_hoisted_7","_hoisted_9","_hoisted_10","_hoisted_11","_hoisted_12","_hoisted_13","notification","_hoisted_15","_hoisted_16","_hoisted_17","_hoisted_18","_hoisted_19","_hoisted_20","_renderSlot","_ctx","_hoisted_21","JAvatar","_hoisted_22","_hoisted_23","_hoisted_24","_hoisted_25","_hoisted_26","group","groupIndex","itemIndex","_hoisted_29","_hoisted_28","_hoisted_30"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("vue");require("../shadcn/index.cjs");const i=require("../atoms/JButton.vue.cjs");require("lucide-vue-next");require("clsx");require("tailwind-merge");require("@internationalized/date");require("md-editor-v3");;/* empty css */;/* empty css */require("../shadcn/badge-variants.cjs");require("@vueuse/core");require("reka-ui");;/* empty css */require("../shadcn/avatar-variants.cjs");require("dompurify");;/* empty css */require("ag-grid-vue3");require("ag-grid-community");require("ag-grid-enterprise");;/* empty css */;/* empty css */;/* empty css */;/* empty css */require("vue-sonner");const q=require("../molecules/JFormField.vue.cjs");;/* empty css */;/* empty css */;/* empty css */;/* empty css */const y=require("../shadcn/Dialog.vue.cjs"),v=require("../shadcn/DialogContent.vue.cjs"),x=require("../shadcn/DialogHeader.vue.cjs"),_=require("../shadcn/DialogTitle.vue.cjs"),g=require("../shadcn/DialogBody.vue.cjs"),F=require("../shadcn/DialogFooter.vue.cjs"),V={class:"space-y-4"},b={key:0,class:"text-sm text-muted-foreground"},C={key:1},h=e.defineComponent({__name:"JModal",props:{open:{type:Boolean,default:!1},title:{},description:{},size:{default:"md"},showFormField:{type:Boolean,default:!1},formFieldLabel:{},formFieldError:{},formFieldRequired:{type:Boolean},formFieldInputType:{default:"text"},formFieldInputPlaceholder:{},formFieldValue:{},formFieldType:{default:"input"},buttonType:{default:"OkCancel"},confirmText:{default:"확인"},cancelText:{default:"취소"},confirmVariant:{default:"default"},confirmDisabled:{type:Boolean,default:!1},disabled:{type:Boolean,default:!1}},emits:["update:open","confirm","cancel"],setup(t,{emit:d}){const l=t,u=d,a=e.ref(l.formFieldValue||""),c=e.computed(()=>`modal-input-${Math.random().toString(36).substr(2,9)}`),s=e.computed(()=>({sm:"!max-w-sm",md:"!max-w-md",lg:"!max-w-2xl",xl:"!max-w-4xl","2xl":"!max-w-6xl",full:"!max-w-[95vw]"})[l.size]);e.watch(()=>l.formFieldValue,r=>{r!==void 0&&(a.value=r)});const f=r=>{u("update:open",r)},o=()=>{const r=l.showFormField?a.value:void 0;u("confirm",r)},m=()=>{u("cancel"),a.value=l.formFieldValue||""};return(r,n)=>(e.openBlock(),e.createBlock(e.unref(y.default),{open:t.open,"onUpdate:open":f,class:e.normalizeClass(s.value)},{default:e.withCtx(()=>[e.createVNode(e.unref(v.default),null,{default:e.withCtx(()=>[t.title?(e.openBlock(),e.createBlock(e.unref(x.default),{key:0,class:"bg-muted/50 border-b"},{default:e.withCtx(()=>[e.createVNode(e.unref(_.default),null,{default:e.withCtx(()=>[e.createTextVNode(e.toDisplayString(t.title),1)]),_:1})]),_:1})):e.createCommentVNode("",!0),e.createVNode(e.unref(g.default),null,{default:e.withCtx(()=>[e.createElementVNode("div",V,[t.description?(e.openBlock(),e.createElementBlock("p",b,e.toDisplayString(t.description),1)):e.createCommentVNode("",!0),t.showFormField?(e.openBlock(),e.createElementBlock("div",C,[e.createVNode(e.unref(q.default),{label:t.formFieldLabel,"error-msg":t.formFieldError,required:t.formFieldRequired,type:t.formFieldType,id:c.value,modelValue:a.value,"onUpdate:modelValue":n[0]||(n[0]=p=>a.value=p),"input-type":t.formFieldInputType,placeholder:t.formFieldInputPlaceholder,disabled:t.disabled},null,8,["label","error-msg","required","type","id","modelValue","input-type","placeholder","disabled"])])):e.createCommentVNode("",!0),e.renderSlot(r.$slots,"body")])]),_:3}),e.createVNode(e.unref(F.default),null,{default:e.withCtx(()=>[t.buttonType==="OkCancel"?(e.openBlock(),e.createElementBlock(e.Fragment,{key:0},[e.createVNode(e.unref(i.default),{variant:"outline",onClick:m},{default:e.withCtx(()=>[e.createTextVNode(e.toDisplayString(t.cancelText),1)]),_:1}),e.createVNode(e.unref(i.default),{variant:t.confirmVariant,disabled:t.confirmDisabled,onClick:o},{default:e.withCtx(()=>[e.createTextVNode(e.toDisplayString(t.confirmText),1)]),_:1},8,["variant","disabled"])],64)):t.buttonType==="Ok"?(e.openBlock(),e.createBlock(e.unref(i.default),{key:1,variant:t.confirmVariant,disabled:t.confirmDisabled,onClick:o,class:"w-full"},{default:e.withCtx(()=>[e.createTextVNode(e.toDisplayString(t.confirmText),1)]),_:1},8,["variant","disabled"])):e.createCommentVNode("",!0)]),_:1})]),_:3})]),_:3},8,["open","class"]))}});exports.default=h;
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("vue");require("../shadcn/index.cjs");const i=require("../atoms/JButton.vue.cjs");require("lucide-vue-next");require("clsx");require("tailwind-merge");require("@internationalized/date");require("md-editor-v3");;/* empty css */;/* empty css */require("../shadcn/badge-variants.cjs");require("@vueuse/core");require("reka-ui");;/* empty css */require("../shadcn/avatar-variants.cjs");require("dompurify");;/* empty css */require("ag-grid-vue3");require("ag-grid-community");require("ag-grid-enterprise");;/* empty css */;/* empty css */;/* empty css */;/* empty css */require("vue-sonner");const q=require("../molecules/JFormField.vue.cjs");;/* empty css */;/* empty css */;/* empty css */;/* empty css */const y=require("../shadcn/Dialog.vue.cjs"),v=require("../shadcn/DialogContent.vue.cjs"),x=require("../shadcn/DialogHeader.vue.cjs"),_=require("../shadcn/DialogTitle.vue.cjs"),g=require("../shadcn/DialogBody.vue.cjs"),F=require("../shadcn/DialogFooter.vue.cjs"),V={class:"space-y-4"},b={key:0,class:"text-sm text-muted-foreground"},C={key:1},h=e.defineComponent({__name:"JModal",props:{open:{type:Boolean,default:!1},title:{},description:{},size:{default:"md"},showFormField:{type:Boolean,default:!1},formFieldLabel:{},formFieldError:{},formFieldRequired:{type:Boolean},formFieldInputType:{default:"text"},formFieldInputPlaceholder:{},formFieldValue:{},formFieldType:{default:"input"},buttonType:{default:"OkCancel"},confirmText:{default:"확인"},cancelText:{default:"취소"},confirmVariant:{default:"default"},confirmDisabled:{type:Boolean,default:!1},disabled:{type:Boolean,default:!1}},emits:["update:open","confirm","cancel"],setup(t,{emit:d}){const l=t,u=d,a=e.ref(l.formFieldValue||""),c=e.computed(()=>`modal-input-${Math.random().toString(36).substr(2,9)}`),s=e.computed(()=>({sm:"!max-w-sm",md:"!max-w-md",lg:"!max-w-2xl",xl:"!max-w-4xl","2xl":"!max-w-6xl",full:"!max-w-[95vw]"})[l.size]);e.watch(()=>l.formFieldValue,r=>{r!==void 0&&(a.value=r)});const f=r=>{u("update:open",r)},o=()=>{const r=l.showFormField?a.value:void 0;u("confirm",r)},m=()=>{u("cancel"),a.value=l.formFieldValue||""};return(r,n)=>(e.openBlock(),e.createBlock(e.unref(y.default),{open:t.open,"onUpdate:open":f,class:e.normalizeClass(s.value)},{default:e.withCtx(()=>[e.createVNode(e.unref(v.default),null,{default:e.withCtx(()=>[t.title?(e.openBlock(),e.createBlock(e.unref(x.default),{key:0,class:"bg-muted/50 border-b"},{default:e.withCtx(()=>[e.createVNode(e.unref(_.default),null,{default:e.withCtx(()=>[e.createTextVNode(e.toDisplayString(t.title),1)]),_:1})]),_:1})):e.createCommentVNode("",!0),e.createVNode(e.unref(g.default),null,{default:e.withCtx(()=>[e.createElementVNode("div",V,[t.description?(e.openBlock(),e.createElementBlock("p",b,e.toDisplayString(t.description),1)):e.createCommentVNode("",!0),t.showFormField?(e.openBlock(),e.createElementBlock("div",C,[e.createVNode(e.unref(q.default),{label:t.formFieldLabel,"error-msg":t.formFieldError,required:t.formFieldRequired,type:t.formFieldType,id:c.value,modelValue:a.value,"onUpdate:modelValue":n[0]||(n[0]=p=>a.value=p),"input-type":t.formFieldInputType,placeholder:t.formFieldInputPlaceholder,disabled:t.disabled},null,8,["label","error-msg","required","type","id","modelValue","input-type","placeholder","disabled"])])):e.createCommentVNode("",!0),e.renderSlot(r.$slots,"body")])]),_:3}),e.createVNode(e.unref(F.default),null,{default:e.withCtx(()=>[t.buttonType==="OkCancel"?(e.openBlock(),e.createElementBlock(e.Fragment,{key:0},[e.createVNode(e.unref(i.default),{variant:"outline",size:"sm",onClick:m},{default:e.withCtx(()=>[e.createTextVNode(e.toDisplayString(t.cancelText),1)]),_:1}),e.createVNode(e.unref(i.default),{variant:t.confirmVariant,disabled:t.confirmDisabled,size:"sm",onClick:o},{default:e.withCtx(()=>[e.createTextVNode(e.toDisplayString(t.confirmText),1)]),_:1},8,["variant","disabled"])],64)):t.buttonType==="Ok"?(e.openBlock(),e.createBlock(e.unref(i.default),{key:1,variant:t.confirmVariant,disabled:t.confirmDisabled,size:"sm",onClick:o,class:"w-full"},{default:e.withCtx(()=>[e.createTextVNode(e.toDisplayString(t.confirmText),1)]),_:1},8,["variant","disabled"])):e.createCommentVNode("",!0)]),_:1})]),_:3})]),_:3},8,["open","class"]))}});exports.default=h;
2
2
  //# sourceMappingURL=JModal.vue.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"JModal.vue.cjs","sources":["../../../../src/components/organisms/JModal.vue"],"sourcesContent":["<template>\r\n <Dialog\r\n :open=\"open\"\r\n @update:open=\"onOpenChange\"\r\n :class=\"sizeClass\"\r\n >\r\n <DialogContent>\r\n <!-- Header -->\r\n <DialogHeader v-if=\"title\" class=\"bg-muted/50 border-b\">\r\n <DialogTitle>\r\n {{ title }}\r\n </DialogTitle>\r\n </DialogHeader>\r\n\r\n <!-- Body -->\r\n <DialogBody>\r\n <div class=\"space-y-4\">\r\n <!-- Description -->\r\n <p v-if=\"description\" class=\"text-sm text-muted-foreground\">\r\n {{ description }}\r\n </p>\r\n\r\n <!-- JFormField가 있는 경우 -->\r\n <div v-if=\"showFormField\">\r\n <JFormField\r\n :label=\"formFieldLabel\"\r\n :error-msg=\"formFieldError\"\r\n :required=\"formFieldRequired\"\r\n :type=\"formFieldType\"\r\n :id=\"inputId\"\r\n v-model=\"inputValue\"\r\n :input-type=\"formFieldInputType\"\r\n :placeholder=\"formFieldInputPlaceholder\"\r\n :disabled=\"disabled\"\r\n />\r\n </div>\r\n\r\n <!-- 커스텀 컨텐츠 슬롯 -->\r\n <slot name=\"body\" />\r\n </div>\r\n </DialogBody>\r\n\r\n <!-- Footer -->\r\n <DialogFooter>\r\n <!-- 확인/취소 버튼 -->\r\n <template v-if=\"buttonType === 'OkCancel'\">\r\n <JButton\r\n variant=\"outline\"\r\n @click=\"handleCancel\"\r\n >\r\n {{ cancelText }}\r\n </JButton>\r\n <JButton\r\n :variant=\"confirmVariant\"\r\n :disabled=\"confirmDisabled\"\r\n @click=\"handleConfirm\"\r\n >\r\n {{ confirmText }}\r\n </JButton>\r\n </template>\r\n \r\n <!-- 확인 버튼만 -->\r\n <template v-else-if=\"buttonType === 'Ok'\">\r\n <JButton\r\n :variant=\"confirmVariant\"\r\n :disabled=\"confirmDisabled\"\r\n @click=\"handleConfirm\"\r\n class=\"w-full\"\r\n >\r\n {{ confirmText }}\r\n </JButton>\r\n </template>\r\n </DialogFooter>\r\n </DialogContent>\r\n </Dialog>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport { computed, ref, watch } from 'vue'\r\nimport {\r\n Dialog,\r\n DialogBody,\r\n DialogContent,\r\n DialogFooter,\r\n DialogHeader,\r\n DialogTitle,\r\n} from '@/components/shadcn'\r\nimport { JButton } from '@/components/atoms'\r\nimport { JFormField } from '@/components/molecules'\r\n\r\nexport interface JModalProps {\r\n // 모달 표시 여부\r\n open: boolean\r\n // 헤더\r\n title?: string\r\n description?: string\r\n // 모달 사이즈\r\n size?: 'sm' | 'md' | 'lg' | 'xl' | '2xl' | 'full'\r\n // 폼 필드 (JFormField)\r\n showFormField?: boolean\r\n formFieldLabel?: string\r\n formFieldError?: string\r\n formFieldRequired?: boolean\r\n // 입력 필드 설정\r\n formFieldInputType?: 'text' | 'email' | 'password' | 'number' | 'tel' | 'url'\r\n formFieldInputPlaceholder?: string\r\n formFieldValue?: string\r\n formFieldType?: 'input' | 'textarea' | 'checkbox' | 'switch' | 'combo' | 'radio' | 'searchCombo' | 'datepicker'\r\n // 버튼 설정\r\n buttonType?: 'Ok' | 'OkCancel'\r\n confirmText?: string\r\n cancelText?: string\r\n confirmVariant?: 'default' | 'destructive' | 'outline' | 'secondary' | 'ghost' | 'link'\r\n confirmDisabled?: boolean\r\n // 기타\r\n disabled?: boolean\r\n}\r\n\r\nconst props = withDefaults(defineProps<JModalProps>(), {\r\n open: false,\r\n size: 'md',\r\n showFormField: false,\r\n formFieldInputType: 'text',\r\n formFieldType: 'input',\r\n buttonType: 'OkCancel',\r\n confirmText: '확인',\r\n cancelText: '취소',\r\n confirmVariant: 'default',\r\n confirmDisabled: false,\r\n disabled: false,\r\n})\r\n\r\nconst emit = defineEmits<{\r\n 'update:open': [value: boolean]\r\n 'confirm': [value?: string]\r\n 'cancel': []\r\n}>()\r\n\r\n// 입력값 관리\r\nconst inputValue = ref(props.formFieldValue || '')\r\n\r\n// 입력 필드 ID 생성\r\nconst inputId = computed(() => `modal-input-${Math.random().toString(36).substr(2, 9)}`)\r\n\r\n// 사이즈 클래스 계산\r\nconst sizeClass = computed(() => {\r\n // Dialog.vue에 기본 max-w-lg가 하드코딩되어 있어 !max-w-*로 오버라이드\r\n const sizeMap: Record<NonNullable<JModalProps['size']>, string> = {\r\n 'sm': '!max-w-sm',\r\n 'md': '!max-w-md',\r\n 'lg': '!max-w-2xl',\r\n 'xl': '!max-w-4xl',\r\n '2xl': '!max-w-6xl',\r\n 'full': '!max-w-[95vw]'\r\n }\r\n return sizeMap[props.size]\r\n})\r\n\r\n// props.formFieldValue 변경 감지\r\nwatch(() => props.formFieldValue, (newValue) => {\r\n if (newValue !== undefined) {\r\n inputValue.value = newValue\r\n }\r\n})\r\n\r\n// 모달 열기/닫기 핸들러\r\nconst onOpenChange = (value: boolean) => {\r\n emit('update:open', value)\r\n}\r\n\r\n// 확인 버튼 핸들러\r\nconst handleConfirm = () => {\r\n const value = props.showFormField ? inputValue.value : undefined\r\n emit('confirm', value)\r\n}\r\n\r\n// 취소 버튼 핸들러\r\nconst handleCancel = () => {\r\n emit('cancel')\r\n // 입력값 초기화\r\n inputValue.value = props.formFieldValue || ''\r\n}\r\n</script>\r\n"],"names":["props","__props","emit","__emit","inputValue","ref","inputId","computed","sizeClass","watch","newValue","onOpenChange","value","handleConfirm","handleCancel","_createBlock","_unref","Dialog","_createVNode","DialogContent","DialogHeader","DialogTitle","DialogBody","_createElementVNode","_hoisted_1","_createElementBlock","_hoisted_2","_toDisplayString","_hoisted_3","JFormField","$event","_renderSlot","_ctx","DialogFooter","_Fragment","JButton"],"mappings":"61EAsHA,MAAMA,EAAQC,EAcRC,EAAOC,EAOPC,EAAaC,EAAAA,IAAIL,EAAM,gBAAkB,EAAE,EAG3CM,EAAUC,EAAAA,SAAS,IAAM,eAAe,KAAK,OAAA,EAAS,SAAS,EAAE,EAAE,OAAO,EAAG,CAAC,CAAC,EAAE,EAGjFC,EAAYD,EAAAA,SAAS,KAEyC,CAChE,GAAM,YACN,GAAM,YACN,GAAM,aACN,GAAM,aACN,MAAO,aACP,KAAQ,eAAA,GAEKP,EAAM,IAAI,CAC1B,EAGDS,EAAAA,MAAM,IAAMT,EAAM,eAAiBU,GAAa,CAC1CA,IAAa,SACfN,EAAW,MAAQM,EAEvB,CAAC,EAGD,MAAMC,EAAgBC,GAAmB,CACvCV,EAAK,cAAeU,CAAK,CAC3B,EAGMC,EAAgB,IAAM,CAC1B,MAAMD,EAAQZ,EAAM,cAAgBI,EAAW,MAAQ,OACvDF,EAAK,UAAWU,CAAK,CACvB,EAGME,EAAe,IAAM,CACzBZ,EAAK,QAAQ,EAEbE,EAAW,MAAQJ,EAAM,gBAAkB,EAC7C,8BApLEe,EAAAA,YAyESC,EAAAA,MAAAC,EAAAA,OAAA,EAAA,CAxEN,KAAMhB,EAAA,KACN,gBAAaU,EACb,uBAAOH,EAAA,KAAS,CAAA,qBAEjB,IAmEgB,CAnEhBU,EAAAA,YAmEgBF,EAAAA,MAAAG,SAAA,EAAA,KAAA,mBAjEd,IAIe,CAJKlB,EAAA,qBAApBc,EAAAA,YAIeC,EAAAA,MAAAI,EAAAA,OAAA,EAAA,OAJY,MAAM,sBAAA,qBAC/B,IAEc,CAFdF,EAAAA,YAEcF,EAAAA,MAAAK,SAAA,EAAA,KAAA,mBADZ,IAAW,qCAARpB,EAAA,KAAK,EAAA,CAAA,CAAA,8CAKZiB,EAAAA,YAyBaF,EAAAA,MAAAM,SAAA,EAAA,KAAA,mBAxBX,IAuBM,CAvBNC,EAAAA,mBAuBM,MAvBNC,EAuBM,CArBKvB,EAAA,2BAATwB,EAAAA,mBAEI,IAFJC,EAEIC,EAAAA,gBADC1B,EAAA,WAAW,EAAA,CAAA,+BAILA,EAAA,6BAAXwB,EAAAA,mBAYM,MAAAG,EAAA,CAXJV,cAUEF,EAAAA,MAAAa,EAAAA,OAAA,EAAA,CATC,MAAO5B,EAAA,eACP,YAAWA,EAAA,eACX,SAAUA,EAAA,kBACV,KAAMA,EAAA,cACN,GAAIK,EAAA,iBACIF,EAAA,2CAAAA,EAAU,MAAA0B,GAClB,aAAY7B,EAAA,mBACZ,YAAaA,EAAA,0BACb,SAAUA,EAAA,QAAA,yIAKf8B,aAAoBC,EAAA,OAAA,MAAA,CAAA,WAKxBd,EAAAA,YA6BeF,EAAAA,MAAAiB,SAAA,EAAA,KAAA,mBA3Bb,IAcW,CAdKhC,EAAA,aAAU,0BAA1BwB,EAAAA,mBAcWS,WAAA,CAAA,IAAA,GAAA,CAbThB,cAKUF,EAAAA,MAAAmB,EAAAA,OAAA,EAAA,CAJR,QAAQ,UACP,QAAOrB,CAAA,qBAER,IAAgB,qCAAbb,EAAA,UAAU,EAAA,CAAA,CAAA,SAEfiB,cAMUF,EAAAA,MAAAmB,EAAAA,OAAA,EAAA,CALP,QAASlC,EAAA,eACT,SAAUA,EAAA,gBACV,QAAOY,CAAA,qBAER,IAAiB,qCAAdZ,EAAA,WAAW,EAAA,CAAA,CAAA,wCAKGA,EAAA,aAAU,oBAC7Bc,EAAAA,YAOUC,QAAAmB,EAAAA,OAAA,EAAA,OANP,QAASlC,EAAA,eACT,SAAUA,EAAA,gBACV,QAAOY,EACR,MAAM,QAAA,qBAEN,IAAiB,qCAAdZ,EAAA,WAAW,EAAA,CAAA,CAAA"}
1
+ {"version":3,"file":"JModal.vue.cjs","sources":["../../../../src/components/organisms/JModal.vue"],"sourcesContent":["<template>\r\n <Dialog\r\n :open=\"open\"\r\n @update:open=\"onOpenChange\"\r\n :class=\"sizeClass\"\r\n >\r\n <DialogContent>\r\n <!-- Header -->\r\n <DialogHeader v-if=\"title\" class=\"bg-muted/50 border-b\">\r\n <DialogTitle>\r\n {{ title }}\r\n </DialogTitle>\r\n </DialogHeader>\r\n\r\n <!-- Body -->\r\n <DialogBody>\r\n <div class=\"space-y-4\">\r\n <!-- Description -->\r\n <p v-if=\"description\" class=\"text-sm text-muted-foreground\">\r\n {{ description }}\r\n </p>\r\n\r\n <!-- JFormField가 있는 경우 -->\r\n <div v-if=\"showFormField\">\r\n <JFormField\r\n :label=\"formFieldLabel\"\r\n :error-msg=\"formFieldError\"\r\n :required=\"formFieldRequired\"\r\n :type=\"formFieldType\"\r\n :id=\"inputId\"\r\n v-model=\"inputValue\"\r\n :input-type=\"formFieldInputType\"\r\n :placeholder=\"formFieldInputPlaceholder\"\r\n :disabled=\"disabled\"\r\n />\r\n </div>\r\n\r\n <!-- 커스텀 컨텐츠 슬롯 -->\r\n <slot name=\"body\" />\r\n </div>\r\n </DialogBody>\r\n\r\n <!-- Footer -->\r\n <DialogFooter>\r\n <!-- 확인/취소 버튼 -->\n <template v-if=\"buttonType === 'OkCancel'\">\n <JButton\n variant=\"outline\"\n size=\"sm\"\n @click=\"handleCancel\"\n >\n {{ cancelText }}\n </JButton>\n <JButton\n :variant=\"confirmVariant\"\n :disabled=\"confirmDisabled\"\n size=\"sm\"\n @click=\"handleConfirm\"\n >\n {{ confirmText }}\n </JButton>\n </template>\n \n <!-- 확인 버튼만 -->\n <template v-else-if=\"buttonType === 'Ok'\">\n <JButton\n :variant=\"confirmVariant\"\n :disabled=\"confirmDisabled\"\n size=\"sm\"\n @click=\"handleConfirm\"\n class=\"w-full\"\n >\n {{ confirmText }}\n </JButton>\n </template>\n </DialogFooter>\r\n </DialogContent>\r\n </Dialog>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport { computed, ref, watch } from 'vue'\r\nimport {\r\n Dialog,\r\n DialogBody,\r\n DialogContent,\r\n DialogFooter,\r\n DialogHeader,\r\n DialogTitle,\r\n} from '@/components/shadcn'\r\nimport { JButton } from '@/components/atoms'\r\nimport { JFormField } from '@/components/molecules'\r\n\r\nexport interface JModalProps {\r\n // 모달 표시 여부\r\n open: boolean\r\n // 헤더\r\n title?: string\r\n description?: string\r\n // 모달 사이즈\r\n size?: 'sm' | 'md' | 'lg' | 'xl' | '2xl' | 'full'\r\n // 폼 필드 (JFormField)\r\n showFormField?: boolean\r\n formFieldLabel?: string\r\n formFieldError?: string\r\n formFieldRequired?: boolean\r\n // 입력 필드 설정\r\n formFieldInputType?: 'text' | 'email' | 'password' | 'number' | 'tel' | 'url'\r\n formFieldInputPlaceholder?: string\r\n formFieldValue?: string\r\n formFieldType?: 'input' | 'textarea' | 'checkbox' | 'switch' | 'combo' | 'radio' | 'searchCombo' | 'datepicker'\r\n // 버튼 설정\r\n buttonType?: 'Ok' | 'OkCancel'\r\n confirmText?: string\r\n cancelText?: string\r\n confirmVariant?: 'default' | 'destructive' | 'outline' | 'secondary' | 'ghost' | 'link'\r\n confirmDisabled?: boolean\r\n // 기타\r\n disabled?: boolean\r\n}\r\n\r\nconst props = withDefaults(defineProps<JModalProps>(), {\r\n open: false,\r\n size: 'md',\r\n showFormField: false,\r\n formFieldInputType: 'text',\r\n formFieldType: 'input',\r\n buttonType: 'OkCancel',\r\n confirmText: '확인',\r\n cancelText: '취소',\r\n confirmVariant: 'default',\r\n confirmDisabled: false,\r\n disabled: false,\r\n})\r\n\r\nconst emit = defineEmits<{\r\n 'update:open': [value: boolean]\r\n 'confirm': [value?: string]\r\n 'cancel': []\r\n}>()\r\n\r\n// 입력값 관리\r\nconst inputValue = ref(props.formFieldValue || '')\r\n\r\n// 입력 필드 ID 생성\r\nconst inputId = computed(() => `modal-input-${Math.random().toString(36).substr(2, 9)}`)\r\n\r\n// 사이즈 클래스 계산\r\nconst sizeClass = computed(() => {\r\n // Dialog.vue에 기본 max-w-lg가 하드코딩되어 있어 !max-w-*로 오버라이드\r\n const sizeMap: Record<NonNullable<JModalProps['size']>, string> = {\r\n 'sm': '!max-w-sm',\r\n 'md': '!max-w-md',\r\n 'lg': '!max-w-2xl',\r\n 'xl': '!max-w-4xl',\r\n '2xl': '!max-w-6xl',\r\n 'full': '!max-w-[95vw]'\r\n }\r\n return sizeMap[props.size]\r\n})\r\n\r\n// props.formFieldValue 변경 감지\r\nwatch(() => props.formFieldValue, (newValue) => {\r\n if (newValue !== undefined) {\r\n inputValue.value = newValue\r\n }\r\n})\r\n\r\n// 모달 열기/닫기 핸들러\r\nconst onOpenChange = (value: boolean) => {\r\n emit('update:open', value)\r\n}\r\n\r\n// 확인 버튼 핸들러\r\nconst handleConfirm = () => {\r\n const value = props.showFormField ? inputValue.value : undefined\r\n emit('confirm', value)\r\n}\r\n\r\n// 취소 버튼 핸들러\r\nconst handleCancel = () => {\r\n emit('cancel')\r\n // 입력값 초기화\r\n inputValue.value = props.formFieldValue || ''\r\n}\r\n</script>\r\n"],"names":["props","__props","emit","__emit","inputValue","ref","inputId","computed","sizeClass","watch","newValue","onOpenChange","value","handleConfirm","handleCancel","_createBlock","_unref","Dialog","_createVNode","DialogContent","DialogHeader","DialogTitle","DialogBody","_createElementVNode","_hoisted_1","_createElementBlock","_hoisted_2","_toDisplayString","_hoisted_3","JFormField","$event","_renderSlot","_ctx","DialogFooter","_Fragment","JButton"],"mappings":"61EAyHA,MAAMA,EAAQC,EAcRC,EAAOC,EAOPC,EAAaC,EAAAA,IAAIL,EAAM,gBAAkB,EAAE,EAG3CM,EAAUC,EAAAA,SAAS,IAAM,eAAe,KAAK,OAAA,EAAS,SAAS,EAAE,EAAE,OAAO,EAAG,CAAC,CAAC,EAAE,EAGjFC,EAAYD,EAAAA,SAAS,KAEyC,CAChE,GAAM,YACN,GAAM,YACN,GAAM,aACN,GAAM,aACN,MAAO,aACP,KAAQ,eAAA,GAEKP,EAAM,IAAI,CAC1B,EAGDS,EAAAA,MAAM,IAAMT,EAAM,eAAiBU,GAAa,CAC1CA,IAAa,SACfN,EAAW,MAAQM,EAEvB,CAAC,EAGD,MAAMC,EAAgBC,GAAmB,CACvCV,EAAK,cAAeU,CAAK,CAC3B,EAGMC,EAAgB,IAAM,CAC1B,MAAMD,EAAQZ,EAAM,cAAgBI,EAAW,MAAQ,OACvDF,EAAK,UAAWU,CAAK,CACvB,EAGME,EAAe,IAAM,CACzBZ,EAAK,QAAQ,EAEbE,EAAW,MAAQJ,EAAM,gBAAkB,EAC7C,8BAvLEe,EAAAA,YA4ESC,EAAAA,MAAAC,EAAAA,OAAA,EAAA,CA3EN,KAAMhB,EAAA,KACN,gBAAaU,EACb,uBAAOH,EAAA,KAAS,CAAA,qBAEjB,IAsEgB,CAtEhBU,EAAAA,YAsEgBF,EAAAA,MAAAG,SAAA,EAAA,KAAA,mBApEd,IAIe,CAJKlB,EAAA,qBAApBc,EAAAA,YAIeC,EAAAA,MAAAI,EAAAA,OAAA,EAAA,OAJY,MAAM,sBAAA,qBAC/B,IAEc,CAFdF,EAAAA,YAEcF,EAAAA,MAAAK,SAAA,EAAA,KAAA,mBADZ,IAAW,qCAARpB,EAAA,KAAK,EAAA,CAAA,CAAA,8CAKZiB,EAAAA,YAyBaF,EAAAA,MAAAM,SAAA,EAAA,KAAA,mBAxBX,IAuBM,CAvBNC,EAAAA,mBAuBM,MAvBNC,EAuBM,CArBKvB,EAAA,2BAATwB,EAAAA,mBAEI,IAFJC,EAEIC,EAAAA,gBADC1B,EAAA,WAAW,EAAA,CAAA,+BAILA,EAAA,6BAAXwB,EAAAA,mBAYM,MAAAG,EAAA,CAXJV,cAUEF,EAAAA,MAAAa,EAAAA,OAAA,EAAA,CATC,MAAO5B,EAAA,eACP,YAAWA,EAAA,eACX,SAAUA,EAAA,kBACV,KAAMA,EAAA,cACN,GAAIK,EAAA,iBACIF,EAAA,2CAAAA,EAAU,MAAA0B,GAClB,aAAY7B,EAAA,mBACZ,YAAaA,EAAA,0BACb,SAAUA,EAAA,QAAA,yIAKf8B,aAAoBC,EAAA,OAAA,MAAA,CAAA,WAKxBd,EAAAA,YAgCeF,EAAAA,MAAAiB,SAAA,EAAA,KAAA,mBA9Bb,IAgBW,CAhBKhC,EAAA,aAAU,0BAA1BwB,EAAAA,mBAgBWS,WAAA,CAAA,IAAA,GAAA,CAfThB,cAMUF,EAAAA,MAAAmB,EAAAA,OAAA,EAAA,CALR,QAAQ,UACR,KAAK,KACJ,QAAOrB,CAAA,qBAER,IAAgB,qCAAbb,EAAA,UAAU,EAAA,CAAA,CAAA,SAEfiB,cAOUF,EAAAA,MAAAmB,EAAAA,OAAA,EAAA,CANP,QAASlC,EAAA,eACT,SAAUA,EAAA,gBACX,KAAK,KACJ,QAAOY,CAAA,qBAER,IAAiB,qCAAdZ,EAAA,WAAW,EAAA,CAAA,CAAA,wCAKGA,EAAA,aAAU,oBAC7Bc,EAAAA,YAQUC,QAAAmB,EAAAA,OAAA,EAAA,OAPP,QAASlC,EAAA,eACT,SAAUA,EAAA,gBACX,KAAK,KACJ,QAAOY,EACR,MAAM,QAAA,qBAEN,IAAiB,qCAAdZ,EAAA,WAAW,EAAA,CAAA,CAAA"}
@@ -1,4 +1,4 @@
1
- import { defineComponent as T, ref as w, computed as F, watch as $, createBlock as c, openBlock as a, unref as t, normalizeClass as g, withCtx as o, createVNode as i, createCommentVNode as d, createTextVNode as f, toDisplayString as n, createElementVNode as B, createElementBlock as s, renderSlot as z, Fragment as I } from "vue";
1
+ import { defineComponent as T, ref as w, computed as F, watch as $, createBlock as c, openBlock as a, unref as t, normalizeClass as g, withCtx as i, createVNode as o, createCommentVNode as d, createTextVNode as f, toDisplayString as n, createElementVNode as z, createElementBlock as s, renderSlot as B, Fragment as I } from "vue";
2
2
  import "../shadcn/index.js";
3
3
  import p from "../atoms/JButton.vue.js";
4
4
  import "lucide-vue-next";
@@ -61,40 +61,40 @@ const L = { class: "space-y-4" }, P = {
61
61
  },
62
62
  emits: ["update:open", "confirm", "cancel"],
63
63
  setup(e, { emit: x }) {
64
- const r = e, u = x, m = w(r.formFieldValue || ""), v = F(() => `modal-input-${Math.random().toString(36).substr(2, 9)}`), h = F(() => ({
64
+ const m = e, u = x, r = w(m.formFieldValue || ""), v = F(() => `modal-input-${Math.random().toString(36).substr(2, 9)}`), h = F(() => ({
65
65
  sm: "!max-w-sm",
66
66
  md: "!max-w-md",
67
67
  lg: "!max-w-2xl",
68
68
  xl: "!max-w-4xl",
69
69
  "2xl": "!max-w-6xl",
70
70
  full: "!max-w-[95vw]"
71
- })[r.size]);
72
- $(() => r.formFieldValue, (l) => {
73
- l !== void 0 && (m.value = l);
71
+ })[m.size]);
72
+ $(() => m.formFieldValue, (l) => {
73
+ l !== void 0 && (r.value = l);
74
74
  });
75
75
  const k = (l) => {
76
76
  u("update:open", l);
77
77
  }, y = () => {
78
- const l = r.showFormField ? m.value : void 0;
78
+ const l = m.showFormField ? r.value : void 0;
79
79
  u("confirm", l);
80
80
  }, V = () => {
81
- u("cancel"), m.value = r.formFieldValue || "";
81
+ u("cancel"), r.value = m.formFieldValue || "";
82
82
  };
83
83
  return (l, b) => (a(), c(t(D), {
84
84
  open: e.open,
85
85
  "onUpdate:open": k,
86
86
  class: g(h.value)
87
87
  }, {
88
- default: o(() => [
89
- i(t(E), null, {
90
- default: o(() => [
88
+ default: i(() => [
89
+ o(t(E), null, {
90
+ default: i(() => [
91
91
  e.title ? (a(), c(t(M), {
92
92
  key: 0,
93
93
  class: "bg-muted/50 border-b"
94
94
  }, {
95
- default: o(() => [
96
- i(t(N), null, {
97
- default: o(() => [
95
+ default: i(() => [
96
+ o(t(N), null, {
97
+ default: i(() => [
98
98
  f(n(e.title), 1)
99
99
  ]),
100
100
  _: 1
@@ -102,47 +102,49 @@ const L = { class: "space-y-4" }, P = {
102
102
  ]),
103
103
  _: 1
104
104
  })) : d("", !0),
105
- i(t(O), null, {
106
- default: o(() => [
107
- B("div", L, [
105
+ o(t(O), null, {
106
+ default: i(() => [
107
+ z("div", L, [
108
108
  e.description ? (a(), s("p", P, n(e.description), 1)) : d("", !0),
109
109
  e.showFormField ? (a(), s("div", R, [
110
- i(t(q), {
110
+ o(t(q), {
111
111
  label: e.formFieldLabel,
112
112
  "error-msg": e.formFieldError,
113
113
  required: e.formFieldRequired,
114
114
  type: e.formFieldType,
115
115
  id: v.value,
116
- modelValue: m.value,
117
- "onUpdate:modelValue": b[0] || (b[0] = (C) => m.value = C),
116
+ modelValue: r.value,
117
+ "onUpdate:modelValue": b[0] || (b[0] = (C) => r.value = C),
118
118
  "input-type": e.formFieldInputType,
119
119
  placeholder: e.formFieldInputPlaceholder,
120
120
  disabled: e.disabled
121
121
  }, null, 8, ["label", "error-msg", "required", "type", "id", "modelValue", "input-type", "placeholder", "disabled"])
122
122
  ])) : d("", !0),
123
- z(l.$slots, "body")
123
+ B(l.$slots, "body")
124
124
  ])
125
125
  ]),
126
126
  _: 3
127
127
  }),
128
- i(t(S), null, {
129
- default: o(() => [
128
+ o(t(S), null, {
129
+ default: i(() => [
130
130
  e.buttonType === "OkCancel" ? (a(), s(I, { key: 0 }, [
131
- i(t(p), {
131
+ o(t(p), {
132
132
  variant: "outline",
133
+ size: "sm",
133
134
  onClick: V
134
135
  }, {
135
- default: o(() => [
136
+ default: i(() => [
136
137
  f(n(e.cancelText), 1)
137
138
  ]),
138
139
  _: 1
139
140
  }),
140
- i(t(p), {
141
+ o(t(p), {
141
142
  variant: e.confirmVariant,
142
143
  disabled: e.confirmDisabled,
144
+ size: "sm",
143
145
  onClick: y
144
146
  }, {
145
- default: o(() => [
147
+ default: i(() => [
146
148
  f(n(e.confirmText), 1)
147
149
  ]),
148
150
  _: 1
@@ -151,10 +153,11 @@ const L = { class: "space-y-4" }, P = {
151
153
  key: 1,
152
154
  variant: e.confirmVariant,
153
155
  disabled: e.confirmDisabled,
156
+ size: "sm",
154
157
  onClick: y,
155
158
  class: "w-full"
156
159
  }, {
157
- default: o(() => [
160
+ default: i(() => [
158
161
  f(n(e.confirmText), 1)
159
162
  ]),
160
163
  _: 1
@@ -1 +1 @@
1
- {"version":3,"file":"JModal.vue.js","sources":["../../../../src/components/organisms/JModal.vue"],"sourcesContent":["<template>\r\n <Dialog\r\n :open=\"open\"\r\n @update:open=\"onOpenChange\"\r\n :class=\"sizeClass\"\r\n >\r\n <DialogContent>\r\n <!-- Header -->\r\n <DialogHeader v-if=\"title\" class=\"bg-muted/50 border-b\">\r\n <DialogTitle>\r\n {{ title }}\r\n </DialogTitle>\r\n </DialogHeader>\r\n\r\n <!-- Body -->\r\n <DialogBody>\r\n <div class=\"space-y-4\">\r\n <!-- Description -->\r\n <p v-if=\"description\" class=\"text-sm text-muted-foreground\">\r\n {{ description }}\r\n </p>\r\n\r\n <!-- JFormField가 있는 경우 -->\r\n <div v-if=\"showFormField\">\r\n <JFormField\r\n :label=\"formFieldLabel\"\r\n :error-msg=\"formFieldError\"\r\n :required=\"formFieldRequired\"\r\n :type=\"formFieldType\"\r\n :id=\"inputId\"\r\n v-model=\"inputValue\"\r\n :input-type=\"formFieldInputType\"\r\n :placeholder=\"formFieldInputPlaceholder\"\r\n :disabled=\"disabled\"\r\n />\r\n </div>\r\n\r\n <!-- 커스텀 컨텐츠 슬롯 -->\r\n <slot name=\"body\" />\r\n </div>\r\n </DialogBody>\r\n\r\n <!-- Footer -->\r\n <DialogFooter>\r\n <!-- 확인/취소 버튼 -->\r\n <template v-if=\"buttonType === 'OkCancel'\">\r\n <JButton\r\n variant=\"outline\"\r\n @click=\"handleCancel\"\r\n >\r\n {{ cancelText }}\r\n </JButton>\r\n <JButton\r\n :variant=\"confirmVariant\"\r\n :disabled=\"confirmDisabled\"\r\n @click=\"handleConfirm\"\r\n >\r\n {{ confirmText }}\r\n </JButton>\r\n </template>\r\n \r\n <!-- 확인 버튼만 -->\r\n <template v-else-if=\"buttonType === 'Ok'\">\r\n <JButton\r\n :variant=\"confirmVariant\"\r\n :disabled=\"confirmDisabled\"\r\n @click=\"handleConfirm\"\r\n class=\"w-full\"\r\n >\r\n {{ confirmText }}\r\n </JButton>\r\n </template>\r\n </DialogFooter>\r\n </DialogContent>\r\n </Dialog>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport { computed, ref, watch } from 'vue'\r\nimport {\r\n Dialog,\r\n DialogBody,\r\n DialogContent,\r\n DialogFooter,\r\n DialogHeader,\r\n DialogTitle,\r\n} from '@/components/shadcn'\r\nimport { JButton } from '@/components/atoms'\r\nimport { JFormField } from '@/components/molecules'\r\n\r\nexport interface JModalProps {\r\n // 모달 표시 여부\r\n open: boolean\r\n // 헤더\r\n title?: string\r\n description?: string\r\n // 모달 사이즈\r\n size?: 'sm' | 'md' | 'lg' | 'xl' | '2xl' | 'full'\r\n // 폼 필드 (JFormField)\r\n showFormField?: boolean\r\n formFieldLabel?: string\r\n formFieldError?: string\r\n formFieldRequired?: boolean\r\n // 입력 필드 설정\r\n formFieldInputType?: 'text' | 'email' | 'password' | 'number' | 'tel' | 'url'\r\n formFieldInputPlaceholder?: string\r\n formFieldValue?: string\r\n formFieldType?: 'input' | 'textarea' | 'checkbox' | 'switch' | 'combo' | 'radio' | 'searchCombo' | 'datepicker'\r\n // 버튼 설정\r\n buttonType?: 'Ok' | 'OkCancel'\r\n confirmText?: string\r\n cancelText?: string\r\n confirmVariant?: 'default' | 'destructive' | 'outline' | 'secondary' | 'ghost' | 'link'\r\n confirmDisabled?: boolean\r\n // 기타\r\n disabled?: boolean\r\n}\r\n\r\nconst props = withDefaults(defineProps<JModalProps>(), {\r\n open: false,\r\n size: 'md',\r\n showFormField: false,\r\n formFieldInputType: 'text',\r\n formFieldType: 'input',\r\n buttonType: 'OkCancel',\r\n confirmText: '확인',\r\n cancelText: '취소',\r\n confirmVariant: 'default',\r\n confirmDisabled: false,\r\n disabled: false,\r\n})\r\n\r\nconst emit = defineEmits<{\r\n 'update:open': [value: boolean]\r\n 'confirm': [value?: string]\r\n 'cancel': []\r\n}>()\r\n\r\n// 입력값 관리\r\nconst inputValue = ref(props.formFieldValue || '')\r\n\r\n// 입력 필드 ID 생성\r\nconst inputId = computed(() => `modal-input-${Math.random().toString(36).substr(2, 9)}`)\r\n\r\n// 사이즈 클래스 계산\r\nconst sizeClass = computed(() => {\r\n // Dialog.vue에 기본 max-w-lg가 하드코딩되어 있어 !max-w-*로 오버라이드\r\n const sizeMap: Record<NonNullable<JModalProps['size']>, string> = {\r\n 'sm': '!max-w-sm',\r\n 'md': '!max-w-md',\r\n 'lg': '!max-w-2xl',\r\n 'xl': '!max-w-4xl',\r\n '2xl': '!max-w-6xl',\r\n 'full': '!max-w-[95vw]'\r\n }\r\n return sizeMap[props.size]\r\n})\r\n\r\n// props.formFieldValue 변경 감지\r\nwatch(() => props.formFieldValue, (newValue) => {\r\n if (newValue !== undefined) {\r\n inputValue.value = newValue\r\n }\r\n})\r\n\r\n// 모달 열기/닫기 핸들러\r\nconst onOpenChange = (value: boolean) => {\r\n emit('update:open', value)\r\n}\r\n\r\n// 확인 버튼 핸들러\r\nconst handleConfirm = () => {\r\n const value = props.showFormField ? inputValue.value : undefined\r\n emit('confirm', value)\r\n}\r\n\r\n// 취소 버튼 핸들러\r\nconst handleCancel = () => {\r\n emit('cancel')\r\n // 입력값 초기화\r\n inputValue.value = props.formFieldValue || ''\r\n}\r\n</script>\r\n"],"names":["props","__props","emit","__emit","inputValue","ref","inputId","computed","sizeClass","watch","newValue","onOpenChange","value","handleConfirm","handleCancel","_createBlock","_unref","Dialog","_createVNode","DialogContent","DialogHeader","DialogTitle","DialogBody","_createElementVNode","_hoisted_1","_createElementBlock","_hoisted_2","_toDisplayString","_hoisted_3","JFormField","$event","_renderSlot","_ctx","DialogFooter","_Fragment","JButton"],"mappings":"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"}
1
+ {"version":3,"file":"JModal.vue.js","sources":["../../../../src/components/organisms/JModal.vue"],"sourcesContent":["<template>\r\n <Dialog\r\n :open=\"open\"\r\n @update:open=\"onOpenChange\"\r\n :class=\"sizeClass\"\r\n >\r\n <DialogContent>\r\n <!-- Header -->\r\n <DialogHeader v-if=\"title\" class=\"bg-muted/50 border-b\">\r\n <DialogTitle>\r\n {{ title }}\r\n </DialogTitle>\r\n </DialogHeader>\r\n\r\n <!-- Body -->\r\n <DialogBody>\r\n <div class=\"space-y-4\">\r\n <!-- Description -->\r\n <p v-if=\"description\" class=\"text-sm text-muted-foreground\">\r\n {{ description }}\r\n </p>\r\n\r\n <!-- JFormField가 있는 경우 -->\r\n <div v-if=\"showFormField\">\r\n <JFormField\r\n :label=\"formFieldLabel\"\r\n :error-msg=\"formFieldError\"\r\n :required=\"formFieldRequired\"\r\n :type=\"formFieldType\"\r\n :id=\"inputId\"\r\n v-model=\"inputValue\"\r\n :input-type=\"formFieldInputType\"\r\n :placeholder=\"formFieldInputPlaceholder\"\r\n :disabled=\"disabled\"\r\n />\r\n </div>\r\n\r\n <!-- 커스텀 컨텐츠 슬롯 -->\r\n <slot name=\"body\" />\r\n </div>\r\n </DialogBody>\r\n\r\n <!-- Footer -->\r\n <DialogFooter>\r\n <!-- 확인/취소 버튼 -->\n <template v-if=\"buttonType === 'OkCancel'\">\n <JButton\n variant=\"outline\"\n size=\"sm\"\n @click=\"handleCancel\"\n >\n {{ cancelText }}\n </JButton>\n <JButton\n :variant=\"confirmVariant\"\n :disabled=\"confirmDisabled\"\n size=\"sm\"\n @click=\"handleConfirm\"\n >\n {{ confirmText }}\n </JButton>\n </template>\n \n <!-- 확인 버튼만 -->\n <template v-else-if=\"buttonType === 'Ok'\">\n <JButton\n :variant=\"confirmVariant\"\n :disabled=\"confirmDisabled\"\n size=\"sm\"\n @click=\"handleConfirm\"\n class=\"w-full\"\n >\n {{ confirmText }}\n </JButton>\n </template>\n </DialogFooter>\r\n </DialogContent>\r\n </Dialog>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport { computed, ref, watch } from 'vue'\r\nimport {\r\n Dialog,\r\n DialogBody,\r\n DialogContent,\r\n DialogFooter,\r\n DialogHeader,\r\n DialogTitle,\r\n} from '@/components/shadcn'\r\nimport { JButton } from '@/components/atoms'\r\nimport { JFormField } from '@/components/molecules'\r\n\r\nexport interface JModalProps {\r\n // 모달 표시 여부\r\n open: boolean\r\n // 헤더\r\n title?: string\r\n description?: string\r\n // 모달 사이즈\r\n size?: 'sm' | 'md' | 'lg' | 'xl' | '2xl' | 'full'\r\n // 폼 필드 (JFormField)\r\n showFormField?: boolean\r\n formFieldLabel?: string\r\n formFieldError?: string\r\n formFieldRequired?: boolean\r\n // 입력 필드 설정\r\n formFieldInputType?: 'text' | 'email' | 'password' | 'number' | 'tel' | 'url'\r\n formFieldInputPlaceholder?: string\r\n formFieldValue?: string\r\n formFieldType?: 'input' | 'textarea' | 'checkbox' | 'switch' | 'combo' | 'radio' | 'searchCombo' | 'datepicker'\r\n // 버튼 설정\r\n buttonType?: 'Ok' | 'OkCancel'\r\n confirmText?: string\r\n cancelText?: string\r\n confirmVariant?: 'default' | 'destructive' | 'outline' | 'secondary' | 'ghost' | 'link'\r\n confirmDisabled?: boolean\r\n // 기타\r\n disabled?: boolean\r\n}\r\n\r\nconst props = withDefaults(defineProps<JModalProps>(), {\r\n open: false,\r\n size: 'md',\r\n showFormField: false,\r\n formFieldInputType: 'text',\r\n formFieldType: 'input',\r\n buttonType: 'OkCancel',\r\n confirmText: '확인',\r\n cancelText: '취소',\r\n confirmVariant: 'default',\r\n confirmDisabled: false,\r\n disabled: false,\r\n})\r\n\r\nconst emit = defineEmits<{\r\n 'update:open': [value: boolean]\r\n 'confirm': [value?: string]\r\n 'cancel': []\r\n}>()\r\n\r\n// 입력값 관리\r\nconst inputValue = ref(props.formFieldValue || '')\r\n\r\n// 입력 필드 ID 생성\r\nconst inputId = computed(() => `modal-input-${Math.random().toString(36).substr(2, 9)}`)\r\n\r\n// 사이즈 클래스 계산\r\nconst sizeClass = computed(() => {\r\n // Dialog.vue에 기본 max-w-lg가 하드코딩되어 있어 !max-w-*로 오버라이드\r\n const sizeMap: Record<NonNullable<JModalProps['size']>, string> = {\r\n 'sm': '!max-w-sm',\r\n 'md': '!max-w-md',\r\n 'lg': '!max-w-2xl',\r\n 'xl': '!max-w-4xl',\r\n '2xl': '!max-w-6xl',\r\n 'full': '!max-w-[95vw]'\r\n }\r\n return sizeMap[props.size]\r\n})\r\n\r\n// props.formFieldValue 변경 감지\r\nwatch(() => props.formFieldValue, (newValue) => {\r\n if (newValue !== undefined) {\r\n inputValue.value = newValue\r\n }\r\n})\r\n\r\n// 모달 열기/닫기 핸들러\r\nconst onOpenChange = (value: boolean) => {\r\n emit('update:open', value)\r\n}\r\n\r\n// 확인 버튼 핸들러\r\nconst handleConfirm = () => {\r\n const value = props.showFormField ? inputValue.value : undefined\r\n emit('confirm', value)\r\n}\r\n\r\n// 취소 버튼 핸들러\r\nconst handleCancel = () => {\r\n emit('cancel')\r\n // 입력값 초기화\r\n inputValue.value = props.formFieldValue || ''\r\n}\r\n</script>\r\n"],"names":["props","__props","emit","__emit","inputValue","ref","inputId","computed","sizeClass","watch","newValue","onOpenChange","value","handleConfirm","handleCancel","_createBlock","_unref","Dialog","_createVNode","DialogContent","DialogHeader","DialogTitle","DialogBody","_createElementVNode","_hoisted_1","_createElementBlock","_hoisted_2","_toDisplayString","_hoisted_3","JFormField","$event","_renderSlot","_ctx","DialogFooter","_Fragment","JButton"],"mappings":"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"}
@@ -3,5 +3,5 @@
3
3
  for (const [t_key, t_val] of t_opts)
4
4
  t_merged[t_key] = t_val;
5
5
  return t_merged;
6
- };,u=t(e.default,[["__scopeId","data-v-a4482a84"]]);exports.default=u;
6
+ };,u=t(e.default,[["__scopeId","data-v-63f4ba27"]]);exports.default=u;
7
7
  //# sourceMappingURL=JSidebarAdvanced.vue.cjs.map
@@ -1,12 +1,12 @@
1
- import a from "./JSidebarAdvanced.vue2.js";
1
+ import o from "./JSidebarAdvanced.vue2.js";
2
2
  /* empty css */
3
- const o = (o_comp, o_opts) => {
4
- const o_merged = o_comp.__vccOpts || o_comp;
5
- for (const [o_key, o_val] of o_opts)
6
- o_merged[o_key] = o_val;
7
- return o_merged;
3
+ const a = (a_comp, a_opts) => {
4
+ const a_merged = a_comp.__vccOpts || a_comp;
5
+ for (const [a_key, a_val] of a_opts)
6
+ a_merged[a_key] = a_val;
7
+ return a_merged;
8
8
  };
9
- const e = /* @__PURE__ */ o(a, [["__scopeId", "data-v-a4482a84"]]);
9
+ const e = /* @__PURE__ */ a(o, [["__scopeId", "data-v-63f4ba27"]]);
10
10
  export {
11
11
  e as default
12
12
  };
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("vue"),T=require("vue-router"),I=require("./JSidebarSimple/JDynamicMenuItem.vue.cjs"),L=require("../atoms/JInput.vue.cjs"),S=require("../atoms/JIcon.vue.cjs"),y=require("../../lib/utils.cjs"),z={class:"relative"},q={key:1,class:"text-center py-8 text-muted-foreground"},P={key:1,class:"text-center py-8 text-muted-foreground"},J=e.defineComponent({__name:"JSidebarAdvanced",props:{menuItems:{},permissions:{default:()=>[]},favorites:{default:()=>[]},styletype:{default:"minimal"},class:{},width:{default:"280px"},isVisible:{type:Boolean,default:!0}},emits:["menuClick","favoriteChange"],setup(u,{emit:V}){const l=u,b=V,w=T.useRoute(),m=e.ref("menu"),o=e.ref(""),C=e.computed(()=>w.path),f=e.ref(new Set),p=e.computed(()=>{if(!Array.isArray(l.favorites)||l.favorites.length===0)return[];if(!Array.isArray(l.menuItems)||l.menuItems.length===0)return[];const t=r=>{const n=[];if(!Array.isArray(r))return n;for(const a of r){const s=a.menuKey||a.label;if(Array.isArray(l.favorites)&&l.favorites.includes(s)&&a.menuType==="L"&&n.push({...a,children:void 0}),a.children&&Array.isArray(a.children)&&a.children.length>0){const i=t(a.children);n.push(...i)}}return n};return t(l.menuItems)}),h=e.computed(()=>{if(!Array.isArray(l.menuItems)||l.menuItems.length===0)return[];if(!o.value||o.value.trim()==="")return l.menuItems;const t=o.value.toLowerCase().trim(),r=n=>{const a=[];if(!Array.isArray(n))return a;for(const s of n){const v=s.label?.toLowerCase().includes(t)??!1;let i;s.children&&Array.isArray(s.children)&&s.children.length>0&&(i=r(s.children)),(v||Array.isArray(i)&&i.length>0)&&a.push({...s,children:i})}return a};return r(l.menuItems)});e.watch(()=>h.value,t=>{if(!o.value||o.value.trim()==="")return;(a=>{const s=new Set,v=i=>{if(Array.isArray(i)){for(const d of i)if(d.children&&Array.isArray(d.children)&&d.children.length>0){const N=d.menuKey||d.label;s.add(N),v(d.children)}}};return v(a),s})(t).forEach(a=>{f.value.add(a)})},{immediate:!1});const k=e.computed(()=>{if(!Array.isArray(p.value)||p.value.length===0)return[];if(!o.value||o.value.trim()==="")return p.value;const t=o.value.toLowerCase().trim();return p.value.filter(r=>r.label?.toLowerCase().includes(t)??!1)}),x=t=>{m.value!==t&&(m.value=t,o.value="")},g=(t,r)=>{t&&(r?f.value.add(t):f.value.delete(t))},E=t=>{b("menuClick",t)},_=t=>{if(!t)return;const r=l.favorites?.includes(t)??!1;b("favoriteChange",t,!r)},A=(t,r)=>{for(const n of t){if((n.menuKey||n.label)===r)return n;if(n.children&&n.children.length>0){const s=A(n.children,r);if(s)return s}}return null},F=t=>!t||!l.favorites?.includes(t)?!1:A(l.menuItems,t)?.menuType==="L",B={default:{containerClass:"h-full bg-background border-r border-border flex flex-col",tabContainerClass:"flex border-b border-border",tabButtonClass:"flex-1 px-4 py-2 text-sm font-medium transition-colors border-b-2 hover:bg-accent/50",searchContainerClass:"p-2 border-b border-border",menuContainerClass:"flex-1 overflow-y-auto p-2 space-y-1"},minimal:{containerClass:"h-full bg-background border-r border-border flex flex-col",tabContainerClass:"flex border-b border-border pt-[8px]",tabButtonClass:"flex-1 px-2 py-[6.5px] text-xs font-medium transition-colors border-b-2",searchContainerClass:"p-1 border-b border-border",menuContainerClass:"flex-1 overflow-y-auto p-1 space-y-1"}},c=e.computed(()=>B[l.styletype]??B.default),M=e.computed(()=>y.cn(c.value.containerClass,l.class));return(t,r)=>(e.openBlock(),e.createBlock(e.Transition,{name:"slide"},{default:e.withCtx(()=>[e.withDirectives(e.createElementVNode("aside",{class:e.normalizeClass(M.value),style:e.normalizeStyle({width:u.width})},[e.createElementVNode("div",{class:e.normalizeClass(c.value.tabContainerClass)},[e.createElementVNode("button",{class:e.normalizeClass(e.unref(y.cn)(c.value.tabButtonClass,m.value==="menu"?"border-primary text-primary":"border-transparent text-muted-foreground hover:text-foreground")),onClick:r[0]||(r[0]=n=>x("menu"))}," 기본메뉴 ",2),e.createElementVNode("button",{class:e.normalizeClass(e.unref(y.cn)(c.value.tabButtonClass,m.value==="favorites"?"border-primary text-primary":"border-transparent text-muted-foreground hover:text-foreground")),onClick:r[1]||(r[1]=n=>x("favorites"))}," 즐겨찾기 ",2)],2),e.createElementVNode("div",{class:e.normalizeClass(c.value.searchContainerClass)},[e.createElementVNode("div",z,[e.createVNode(S.default,{name:"search",size:"sm",class:"absolute left-2 top-1/2 -translate-y-1/2 text-muted-foreground"}),e.createVNode(L.default,{modelValue:o.value,"onUpdate:modelValue":r[2]||(r[2]=n=>o.value=n),placeholder:"메뉴 검색...",class:e.normalizeClass(e.unref(y.cn)("pl-8",l.styletype==="minimal"&&"h-8 text-xs"))},null,8,["modelValue","class"])])],2),e.createElementVNode("div",{class:e.normalizeClass(c.value.menuContainerClass)},[m.value==="menu"?(e.openBlock(),e.createElementBlock(e.Fragment,{key:0},[h.value.length>0?(e.openBlock(!0),e.createElementBlock(e.Fragment,{key:0},e.renderList(h.value,(n,a)=>(e.openBlock(),e.createElementBlock("div",{key:n.menuKey||n.label||a,class:"flex items-center group"},[e.createVNode(I.default,{item:n,level:0,permissions:u.permissions,"active-path":C.value,"expanded-keys":f.value,favorites:u.favorites,"on-favorite-toggle":_,"is-favorite":F,styletype:u.styletype,class:"flex-1",onMenuClick:E,onExpandChange:g},null,8,["item","permissions","active-path","expanded-keys","favorites","styletype"])]))),128)):(e.openBlock(),e.createElementBlock("div",q,[...r[3]||(r[3]=[e.createElementVNode("p",null,"검색 결과가 없습니다.",-1)])]))],64)):(e.openBlock(),e.createElementBlock(e.Fragment,{key:1},[k.value.length>0?(e.openBlock(!0),e.createElementBlock(e.Fragment,{key:0},e.renderList(k.value,(n,a)=>(e.openBlock(),e.createBlock(I.default,{key:n.menuKey||n.label||a,item:n,level:0,permissions:u.permissions,"active-path":C.value,"expanded-keys":f.value,styletype:u.styletype,onMenuClick:E,onExpandChange:g},null,8,["item","permissions","active-path","expanded-keys","styletype"]))),128)):(e.openBlock(),e.createElementBlock("div",P,[...r[4]||(r[4]=[e.createElementVNode("p",null,"즐겨찾기가 없습니다.",-1)])]))],64))],2)],6),[[e.vShow,l.isVisible]])]),_:1}))}});exports.default=J;
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("vue"),T=require("vue-router"),I=require("./JSidebarSimple/JDynamicMenuItem.vue.cjs"),L=require("../atoms/JInput.vue.cjs"),S=require("../atoms/JIcon.vue.cjs"),p=require("../../lib/utils.cjs"),z={class:"relative"},q={key:1,class:"text-center py-8 text-muted-foreground"},P={key:1,class:"text-center py-8 text-muted-foreground"},J=e.defineComponent({__name:"JSidebarAdvanced",props:{menuItems:{},permissions:{default:()=>[]},favorites:{default:()=>[]},styletype:{default:"minimal"},class:{},width:{default:"280px"},isVisible:{type:Boolean,default:!0}},emits:["menuClick","favoriteChange"],setup(u,{emit:V}){const s=u,b=V,w=T.useRoute(),m=e.ref("menu"),o=e.ref(""),C=e.computed(()=>w.path),f=e.ref(new Set),y=e.computed(()=>{if(!Array.isArray(s.favorites)||s.favorites.length===0)return[];if(!Array.isArray(s.menuItems)||s.menuItems.length===0)return[];const t=r=>{const n=[];if(!Array.isArray(r))return n;for(const a of r){const l=a.menuKey||a.label;if(Array.isArray(s.favorites)&&s.favorites.includes(l)&&a.menuType==="L"&&n.push({...a,children:void 0}),a.children&&Array.isArray(a.children)&&a.children.length>0){const i=t(a.children);n.push(...i)}}return n};return t(s.menuItems)}),h=e.computed(()=>{if(!Array.isArray(s.menuItems)||s.menuItems.length===0)return[];if(!o.value||o.value.trim()==="")return s.menuItems;const t=o.value.toLowerCase().trim(),r=n=>{const a=[];if(!Array.isArray(n))return a;for(const l of n){const v=l.label?.toLowerCase().includes(t)??!1;let i;l.children&&Array.isArray(l.children)&&l.children.length>0&&(i=r(l.children)),(v||Array.isArray(i)&&i.length>0)&&a.push({...l,children:i})}return a};return r(s.menuItems)});e.watch(()=>h.value,t=>{if(!o.value||o.value.trim()==="")return;(a=>{const l=new Set,v=i=>{if(Array.isArray(i)){for(const d of i)if(d.children&&Array.isArray(d.children)&&d.children.length>0){const N=d.menuKey||d.label;l.add(N),v(d.children)}}};return v(a),l})(t).forEach(a=>{f.value.add(a)})},{immediate:!1});const x=e.computed(()=>{if(!Array.isArray(y.value)||y.value.length===0)return[];if(!o.value||o.value.trim()==="")return y.value;const t=o.value.toLowerCase().trim();return y.value.filter(r=>r.label?.toLowerCase().includes(t)??!1)}),k=t=>{m.value!==t&&(m.value=t,o.value="")},g=(t,r)=>{t&&(r?f.value.add(t):f.value.delete(t))},E=t=>{b("menuClick",t)},_=t=>{if(!t)return;const r=s.favorites?.includes(t)??!1;b("favoriteChange",t,!r)},A=(t,r)=>{for(const n of t){if((n.menuKey||n.label)===r)return n;if(n.children&&n.children.length>0){const l=A(n.children,r);if(l)return l}}return null},F=t=>!t||!s.favorites?.includes(t)?!1:A(s.menuItems,t)?.menuType==="L",B={default:{containerClass:"h-full bg-background border-r border-border flex flex-col",tabContainerClass:"flex border-b border-border",tabButtonClass:"flex-1 px-3 py-1.5 text-xs font-medium transition-colors border-b-2 hover:bg-accent/50",searchContainerClass:"p-1.5 border-b border-border",menuContainerClass:"flex-1 overflow-y-auto p-1.5 space-y-0.5"},minimal:{containerClass:"h-full bg-background border-r border-border flex flex-col",tabContainerClass:"flex border-b border-border",tabButtonClass:"flex-1 px-2 py-1 text-xs font-medium transition-colors border-b-2",searchContainerClass:"p-1 border-b border-border",menuContainerClass:"flex-1 overflow-y-auto p-1 space-y-0.5"}},c=e.computed(()=>B[s.styletype]??B.default),M=e.computed(()=>p.cn(c.value.containerClass,s.class));return(t,r)=>(e.openBlock(),e.createBlock(e.Transition,{name:"slide"},{default:e.withCtx(()=>[e.withDirectives(e.createElementVNode("aside",{class:e.normalizeClass(M.value),style:e.normalizeStyle({width:u.width})},[e.createElementVNode("div",{class:e.normalizeClass(c.value.tabContainerClass)},[e.createElementVNode("button",{class:e.normalizeClass(e.unref(p.cn)(c.value.tabButtonClass,m.value==="menu"?"border-primary text-primary":"border-transparent text-muted-foreground hover:text-foreground")),onClick:r[0]||(r[0]=n=>k("menu"))}," 기본메뉴 ",2),e.createElementVNode("button",{class:e.normalizeClass(e.unref(p.cn)(c.value.tabButtonClass,m.value==="favorites"?"border-primary text-primary":"border-transparent text-muted-foreground hover:text-foreground")),onClick:r[1]||(r[1]=n=>k("favorites"))}," 즐겨찾기 ",2)],2),e.createElementVNode("div",{class:e.normalizeClass(c.value.searchContainerClass)},[e.createElementVNode("div",z,[e.createVNode(S.default,{name:"search",size:"sm",class:"absolute left-2 top-1/2 -translate-y-1/2 text-muted-foreground"}),e.createVNode(L.default,{modelValue:o.value,"onUpdate:modelValue":r[2]||(r[2]=n=>o.value=n),placeholder:"메뉴 검색...",class:e.normalizeClass(e.unref(p.cn)("pl-8",s.styletype==="minimal"&&"h-8 text-xs"))},null,8,["modelValue","class"])])],2),e.createElementVNode("div",{class:e.normalizeClass(c.value.menuContainerClass)},[m.value==="menu"?(e.openBlock(),e.createElementBlock(e.Fragment,{key:0},[h.value.length>0?(e.openBlock(!0),e.createElementBlock(e.Fragment,{key:0},e.renderList(h.value,(n,a)=>(e.openBlock(),e.createElementBlock("div",{key:n.menuKey||n.label||a,class:"flex items-center group"},[e.createVNode(I.default,{item:n,level:0,permissions:u.permissions,"active-path":C.value,"expanded-keys":f.value,favorites:u.favorites,"on-favorite-toggle":_,"is-favorite":F,styletype:u.styletype,class:"flex-1",onMenuClick:E,onExpandChange:g},null,8,["item","permissions","active-path","expanded-keys","favorites","styletype"])]))),128)):(e.openBlock(),e.createElementBlock("div",q,[...r[3]||(r[3]=[e.createElementVNode("p",{class:"text-xs"},"검색 결과가 없습니다.",-1)])]))],64)):(e.openBlock(),e.createElementBlock(e.Fragment,{key:1},[x.value.length>0?(e.openBlock(!0),e.createElementBlock(e.Fragment,{key:0},e.renderList(x.value,(n,a)=>(e.openBlock(),e.createBlock(I.default,{key:n.menuKey||n.label||a,item:n,level:0,permissions:u.permissions,"active-path":C.value,"expanded-keys":f.value,styletype:u.styletype,onMenuClick:E,onExpandChange:g},null,8,["item","permissions","active-path","expanded-keys","styletype"]))),128)):(e.openBlock(),e.createElementBlock("div",P,[...r[4]||(r[4]=[e.createElementVNode("p",{class:"text-xs"},"즐겨찾기가 없습니다.",-1)])]))],64))],2)],6),[[e.vShow,s.isVisible]])]),_:1}))}});exports.default=J;
2
2
  //# sourceMappingURL=JSidebarAdvanced.vue2.cjs.map