@j-solution/components 1.9.0 → 1.9.1

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 (205) hide show
  1. package/README.md +6 -5
  2. package/assets/{jwms-portal-frontend-Ct2Tc7yj.css → jwms-portal-frontend-Di6lStzZ.css} +1 -1
  3. package/assets/styles/j-components.css +1 -1
  4. package/assets/styles/main.css +29 -29
  5. package/components/atoms/JAvatar.vue.cjs.map +1 -1
  6. package/components/atoms/JAvatar.vue.js.map +1 -1
  7. package/components/atoms/JBadge.vue.cjs.map +1 -1
  8. package/components/atoms/JBadge.vue.js.map +1 -1
  9. package/components/atoms/JCombo.vue.cjs.map +1 -1
  10. package/components/atoms/JCombo.vue.js.map +1 -1
  11. package/components/atoms/JDatepicker.vue.cjs.map +1 -1
  12. package/components/atoms/JDatepicker.vue.js.map +1 -1
  13. package/components/atoms/JDivider.vue.cjs.map +1 -1
  14. package/components/atoms/JDivider.vue.js.map +1 -1
  15. package/components/atoms/JEditor.vue.cjs +1 -1
  16. package/components/atoms/JEditor.vue.js +2 -2
  17. package/components/atoms/JEditor.vue2.cjs.map +1 -1
  18. package/components/atoms/JEditor.vue2.js.map +1 -1
  19. package/components/atoms/JGrid.vue.cjs +1 -1
  20. package/components/atoms/JGrid.vue.js +2 -2
  21. package/components/atoms/JGrid.vue2.cjs +1 -1
  22. package/components/atoms/JGrid.vue2.cjs.map +1 -1
  23. package/components/atoms/JGrid.vue2.js +72 -85
  24. package/components/atoms/JGrid.vue2.js.map +1 -1
  25. package/components/atoms/JIcon.vue.cjs.map +1 -1
  26. package/components/atoms/JIcon.vue.js.map +1 -1
  27. package/components/atoms/JImage.vue.cjs.map +1 -1
  28. package/components/atoms/JImage.vue.js.map +1 -1
  29. package/components/atoms/JKbd.vue.cjs.map +1 -1
  30. package/components/atoms/JKbd.vue.js.map +1 -1
  31. package/components/atoms/JPreview.vue.cjs +1 -1
  32. package/components/atoms/JPreview.vue.js +7 -7
  33. package/components/atoms/JPreview.vue2.cjs.map +1 -1
  34. package/components/atoms/JPreview.vue2.js.map +1 -1
  35. package/components/atoms/JProgress.vue.cjs.map +1 -1
  36. package/components/atoms/JProgress.vue.js.map +1 -1
  37. package/components/atoms/JRadio.vue.cjs.map +1 -1
  38. package/components/atoms/JRadio.vue.js.map +1 -1
  39. package/components/atoms/JSearchCombo.vue.cjs.map +1 -1
  40. package/components/atoms/JSearchCombo.vue.js.map +1 -1
  41. package/components/atoms/JSectionTitle.vue2.cjs +1 -1
  42. package/components/atoms/JSectionTitle.vue2.cjs.map +1 -1
  43. package/components/atoms/JSectionTitle.vue2.js +5 -8
  44. package/components/atoms/JSectionTitle.vue2.js.map +1 -1
  45. package/components/atoms/JSpinner.vue.cjs.map +1 -1
  46. package/components/atoms/JSpinner.vue.js.map +1 -1
  47. package/components/atoms/JToast.vue.cjs.map +1 -1
  48. package/components/atoms/JToast.vue.js.map +1 -1
  49. package/components/atoms/JTooltip.vue.cjs.map +1 -1
  50. package/components/atoms/JTooltip.vue.js.map +1 -1
  51. package/components/molecules/JAlert.vue.cjs +1 -1
  52. package/components/molecules/JAlert.vue.cjs.map +1 -1
  53. package/components/molecules/JAlert.vue.js +2 -5
  54. package/components/molecules/JAlert.vue.js.map +1 -1
  55. package/components/molecules/JBreadcrumb.vue.cjs.map +1 -1
  56. package/components/molecules/JBreadcrumb.vue.js.map +1 -1
  57. package/components/molecules/JEmptyState.vue2.cjs +1 -1
  58. package/components/molecules/JEmptyState.vue2.cjs.map +1 -1
  59. package/components/molecules/JEmptyState.vue2.js +15 -18
  60. package/components/molecules/JEmptyState.vue2.js.map +1 -1
  61. package/components/molecules/JFormField.vue2.cjs +1 -1
  62. package/components/molecules/JFormField.vue2.cjs.map +1 -1
  63. package/components/molecules/JFormField.vue2.js +2 -5
  64. package/components/molecules/JFormField.vue2.js.map +1 -1
  65. package/components/molecules/JTitlebar.vue.cjs +1 -1
  66. package/components/molecules/JTitlebar.vue.cjs.map +1 -1
  67. package/components/molecules/JTitlebar.vue.js +16 -19
  68. package/components/molecules/JTitlebar.vue.js.map +1 -1
  69. package/components/organisms/JDynamicForm.vue2.cjs +1 -1
  70. package/components/organisms/JDynamicForm.vue2.cjs.map +1 -1
  71. package/components/organisms/JDynamicForm.vue2.js +2 -5
  72. package/components/organisms/JDynamicForm.vue2.js.map +1 -1
  73. package/components/organisms/JFilterBar.vue.cjs +1 -1
  74. package/components/organisms/JFilterBar.vue.js +2 -2
  75. package/components/organisms/JFilterBar.vue2.cjs.map +1 -1
  76. package/components/organisms/JFilterBar.vue2.js.map +1 -1
  77. package/components/organisms/JFormModal.vue.cjs +1 -1
  78. package/components/organisms/JFormModal.vue.cjs.map +1 -1
  79. package/components/organisms/JFormModal.vue.js +14 -17
  80. package/components/organisms/JFormModal.vue.js.map +1 -1
  81. package/components/organisms/JModal.vue.cjs +1 -1
  82. package/components/organisms/JModal.vue.cjs.map +1 -1
  83. package/components/organisms/JModal.vue.js +2 -5
  84. package/components/organisms/JModal.vue.js.map +1 -1
  85. package/components/organisms/JSearchPanel.vue2.cjs +1 -1
  86. package/components/organisms/JSearchPanel.vue2.cjs.map +1 -1
  87. package/components/organisms/JSearchPanel.vue2.js +20 -23
  88. package/components/organisms/JSearchPanel.vue2.js.map +1 -1
  89. package/components/organisms/JSidebar/JSidebar.vue.cjs.map +1 -1
  90. package/components/organisms/JSidebar/JSidebar.vue.js.map +1 -1
  91. package/components/organisms/JSidebar/JSidebarGroup.vue.cjs.map +1 -1
  92. package/components/organisms/JSidebar/JSidebarGroup.vue.js.map +1 -1
  93. package/components/organisms/JSidebar/JSidebarItem.vue.cjs.map +1 -1
  94. package/components/organisms/JSidebar/JSidebarItem.vue.js.map +1 -1
  95. package/components/organisms/JSidebarAdvanced.vue.cjs +1 -1
  96. package/components/organisms/JSidebarAdvanced.vue.js +7 -7
  97. package/components/organisms/JSidebarAdvanced.vue2.cjs.map +1 -1
  98. package/components/organisms/JSidebarAdvanced.vue2.js.map +1 -1
  99. package/components/organisms/JSidebarSimple.vue.cjs +1 -1
  100. package/components/organisms/JSidebarSimple.vue.js +2 -2
  101. package/components/organisms/JSidebarSimple.vue2.cjs.map +1 -1
  102. package/components/organisms/JSidebarSimple.vue2.js.map +1 -1
  103. package/components/shadcn/AccordionTrigger.vue.cjs.map +1 -1
  104. package/components/shadcn/AccordionTrigger.vue.js.map +1 -1
  105. package/components/shadcn/CardDescription.vue.cjs.map +1 -1
  106. package/components/shadcn/CardDescription.vue.js.map +1 -1
  107. package/components/shadcn/CardFooter.vue.cjs.map +1 -1
  108. package/components/shadcn/CardFooter.vue.js.map +1 -1
  109. package/components/shadcn/CardTitle.vue.cjs.map +1 -1
  110. package/components/shadcn/CardTitle.vue.js.map +1 -1
  111. package/components/shadcn/Checkbox.vue.cjs.map +1 -1
  112. package/components/shadcn/Checkbox.vue.js.map +1 -1
  113. package/components/shadcn/Combobox.vue.cjs.map +1 -1
  114. package/components/shadcn/Combobox.vue.js.map +1 -1
  115. package/components/shadcn/ComboboxAnchor.vue.cjs.map +1 -1
  116. package/components/shadcn/ComboboxAnchor.vue.js.map +1 -1
  117. package/components/shadcn/ComboboxEmpty.vue.cjs.map +1 -1
  118. package/components/shadcn/ComboboxEmpty.vue.js.map +1 -1
  119. package/components/shadcn/ComboboxGroup.vue.cjs.map +1 -1
  120. package/components/shadcn/ComboboxGroup.vue.js.map +1 -1
  121. package/components/shadcn/ComboboxInput.vue.cjs.map +1 -1
  122. package/components/shadcn/ComboboxInput.vue.js.map +1 -1
  123. package/components/shadcn/ComboboxItem.vue.cjs.map +1 -1
  124. package/components/shadcn/ComboboxItem.vue.js.map +1 -1
  125. package/components/shadcn/ComboboxList.vue.cjs.map +1 -1
  126. package/components/shadcn/ComboboxList.vue.js.map +1 -1
  127. package/components/shadcn/ComboboxTrigger.vue.cjs.map +1 -1
  128. package/components/shadcn/ComboboxTrigger.vue.js.map +1 -1
  129. package/components/shadcn/ContextMenu.vue.cjs.map +1 -1
  130. package/components/shadcn/ContextMenu.vue.js.map +1 -1
  131. package/components/shadcn/ContextMenuContent.vue.cjs.map +1 -1
  132. package/components/shadcn/ContextMenuContent.vue.js.map +1 -1
  133. package/components/shadcn/ContextMenuGroup.vue.cjs.map +1 -1
  134. package/components/shadcn/ContextMenuGroup.vue.js.map +1 -1
  135. package/components/shadcn/ContextMenuItem.vue.cjs.map +1 -1
  136. package/components/shadcn/ContextMenuItem.vue.js.map +1 -1
  137. package/components/shadcn/ContextMenuLabel.vue.cjs.map +1 -1
  138. package/components/shadcn/ContextMenuLabel.vue.js.map +1 -1
  139. package/components/shadcn/ContextMenuSeparator.vue.cjs.map +1 -1
  140. package/components/shadcn/ContextMenuSeparator.vue.js.map +1 -1
  141. package/components/shadcn/ContextMenuSub.vue.cjs.map +1 -1
  142. package/components/shadcn/ContextMenuSub.vue.js.map +1 -1
  143. package/components/shadcn/ContextMenuSubContent.vue.cjs.map +1 -1
  144. package/components/shadcn/ContextMenuSubContent.vue.js.map +1 -1
  145. package/components/shadcn/ContextMenuSubTrigger.vue.cjs.map +1 -1
  146. package/components/shadcn/ContextMenuSubTrigger.vue.js.map +1 -1
  147. package/components/shadcn/ContextMenuTrigger.vue.cjs.map +1 -1
  148. package/components/shadcn/ContextMenuTrigger.vue.js.map +1 -1
  149. package/components/shadcn/Field.vue.cjs.map +1 -1
  150. package/components/shadcn/Field.vue.js.map +1 -1
  151. package/components/shadcn/FieldContent.vue.cjs.map +1 -1
  152. package/components/shadcn/FieldContent.vue.js.map +1 -1
  153. package/components/shadcn/FieldDescription.vue.cjs.map +1 -1
  154. package/components/shadcn/FieldDescription.vue.js.map +1 -1
  155. package/components/shadcn/FieldError.vue.cjs.map +1 -1
  156. package/components/shadcn/FieldError.vue.js.map +1 -1
  157. package/components/shadcn/FieldGroup.vue.cjs.map +1 -1
  158. package/components/shadcn/FieldGroup.vue.js.map +1 -1
  159. package/components/shadcn/FieldLabel.vue.cjs.map +1 -1
  160. package/components/shadcn/FieldLabel.vue.js.map +1 -1
  161. package/components/shadcn/Label.vue.cjs.map +1 -1
  162. package/components/shadcn/Label.vue.js.map +1 -1
  163. package/components/shadcn/RadioGroup.vue.cjs.map +1 -1
  164. package/components/shadcn/RadioGroup.vue.js.map +1 -1
  165. package/components/shadcn/RadioGroupItem.vue.cjs.map +1 -1
  166. package/components/shadcn/RadioGroupItem.vue.js.map +1 -1
  167. package/components/shadcn/Select.vue.cjs.map +1 -1
  168. package/components/shadcn/Select.vue.js.map +1 -1
  169. package/components/shadcn/SelectContent.vue.cjs.map +1 -1
  170. package/components/shadcn/SelectContent.vue.js.map +1 -1
  171. package/components/shadcn/SelectGroup.vue.cjs.map +1 -1
  172. package/components/shadcn/SelectGroup.vue.js.map +1 -1
  173. package/components/shadcn/SelectItem.vue.cjs.map +1 -1
  174. package/components/shadcn/SelectItem.vue.js.map +1 -1
  175. package/components/shadcn/SelectLabel.vue.cjs.map +1 -1
  176. package/components/shadcn/SelectLabel.vue.js.map +1 -1
  177. package/components/shadcn/SelectScrollDownButton.vue2.cjs.map +1 -1
  178. package/components/shadcn/SelectScrollDownButton.vue2.js.map +1 -1
  179. package/components/shadcn/SelectScrollUpButton.vue2.cjs.map +1 -1
  180. package/components/shadcn/SelectScrollUpButton.vue2.js.map +1 -1
  181. package/components/shadcn/SelectValue.vue.cjs.map +1 -1
  182. package/components/shadcn/SelectValue.vue.js.map +1 -1
  183. package/components/shadcn/Separator.vue.cjs.map +1 -1
  184. package/components/shadcn/Separator.vue.js.map +1 -1
  185. package/components/shadcn/Switch.vue.cjs.map +1 -1
  186. package/components/shadcn/Switch.vue.js.map +1 -1
  187. package/components/shadcn/Tabs.vue.cjs.map +1 -1
  188. package/components/shadcn/Tabs.vue.js.map +1 -1
  189. package/components/shadcn/TabsTrigger.vue.cjs.map +1 -1
  190. package/components/shadcn/TabsTrigger.vue.js.map +1 -1
  191. package/components/shadcn/Toaster.vue.cjs.map +1 -1
  192. package/components/shadcn/Toaster.vue.js.map +1 -1
  193. package/components/shadcn/resizable/ResizableHandle.vue.cjs.map +1 -1
  194. package/components/shadcn/resizable/ResizableHandle.vue.js.map +1 -1
  195. package/components/shadcn/resizable/ResizablePanelGroup.vue.cjs.map +1 -1
  196. package/components/shadcn/resizable/ResizablePanelGroup.vue.js.map +1 -1
  197. package/lib/styleTypePreset.cjs.map +1 -1
  198. package/lib/styleTypePreset.js.map +1 -1
  199. package/lib/theme-utils.cjs.map +1 -1
  200. package/lib/theme-utils.js.map +1 -1
  201. package/package.json +1 -1
  202. package/tailwind.config.js +81 -81
  203. package/types/index.d.ts +0 -46
  204. package/types/sidebar.types.cjs.map +1 -1
  205. package/types/sidebar.types.js.map +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"JIcon.vue.js","sources":["../../../../src/components/atoms/JIcon.vue"],"sourcesContent":["<script setup lang=\"ts\">\r\nimport { computed } from 'vue'\r\nimport { \r\n House, \r\n User, \r\n Settings, \r\n Search, \r\n Plus, \r\n Minus, \r\n SquarePen, \r\n Trash2, \r\n Save, \r\n Download,\r\n Upload,\r\n Eye,\r\n EyeOff,\r\n Heart,\r\n Star,\r\n Check,\r\n X,\r\n CircleAlert,\r\n Info,\r\n ChevronDown,\r\n ChevronUp,\r\n ChevronLeft,\r\n ChevronRight,\r\n Menu,\r\n Ellipsis,\r\n EllipsisVertical,\r\n Palette,\r\n // WMS 핵심 아이콘들\r\n Package,\r\n PackageCheck,\r\n PackageX,\r\n Truck,\r\n Warehouse,\r\n Boxes,\r\n Archive,\r\n ClipboardList,\r\n ClipboardCheck,\r\n FileText,\r\n ChartBar,\r\n TrendingUp,\r\n TrendingDown,\r\n Calendar,\r\n Clock,\r\n MapPin,\r\n Table,\r\n List,\r\n ListFilter,\r\n ArrowUpWideNarrow,\r\n ArrowDownWideNarrow,\r\n Scale,\r\n // 추가 아이콘들\r\n Server,\r\n Database,\r\n Link,\r\n ArrowLeftRight,\r\n CircleQuestionMark,\r\n Monitor,\r\n Users,\r\n Code,\r\n FileKey,\r\n Cpu,\r\n Rocket,\r\n FileSpreadsheet,\r\n Activity,\r\n MessageCircle,\r\n Book,\r\n LogIn,\r\n LogOut,\r\n // 편집 관련\r\n Copy,\r\n Clipboard,\r\n Undo2,\r\n Redo2,\r\n Pencil,\r\n // 파일/폴더 관련\r\n Folder,\r\n FolderPlus,\r\n FolderOpen,\r\n FilePlus,\r\n FileSearch,\r\n FilePen,\r\n FileMinus,\r\n // 통신/알림 관련\r\n Mail,\r\n Send,\r\n Phone,\r\n Bell,\r\n BellOff,\r\n MessageSquare,\r\n // 화살표/방향 관련\r\n ArrowUp,\r\n ArrowDown,\r\n ArrowLeft,\r\n ArrowRight,\r\n RotateCw,\r\n RotateCcw,\r\n RefreshCw,\r\n Move,\r\n // 상태/피드백 관련\r\n CircleCheckBig,\r\n CircleX,\r\n Circle,\r\n // 보안 관련\r\n Lock,\r\n LockOpen,\r\n Shield,\r\n ShieldCheck,\r\n ShieldAlert,\r\n // 사용자 관리 관련\r\n UserPlus,\r\n UserMinus,\r\n UserCheck,\r\n UserX,\r\n CircleUser,\r\n // 액션 관련\r\n Power,\r\n Zap,\r\n Target,\r\n Flag,\r\n Funnel,\r\n // 조직/팀 관련\r\n Building,\r\n Briefcase,\r\n Globe,\r\n // 기타 유용한 아이콘\r\n Printer,\r\n Share2,\r\n ExternalLink,\r\n Maximize2,\r\n Minimize2,\r\n MoveVertical,\r\n MoveHorizontal,\r\n Sun,\r\n Moon,\r\n type LucideIcon\r\n} from 'lucide-vue-next'\r\n\r\n// 확장 가능한 아이콘 타입\r\ntype BaseIconName = \r\n | 'house' | 'user' | 'settings' | 'search' | 'plus' | 'minus'\r\n | 'squarePen' | 'trash2' | 'save' | 'download' | 'upload'\r\n | 'eye' | 'eyeOff' | 'heart' | 'star' | 'check' | 'x'\r\n | 'circleAlert' | 'info' | 'chevronDown' | 'chevronUp'\r\n | 'chevronLeft' | 'chevronRight' | 'menu' | 'ellipsis' | 'ellipsisVertical'\r\n | 'palette'\r\n // WMS 핵심 아이콘들\r\n | 'package' | 'packageCheck' | 'packageX'\r\n | 'truck' | 'warehouse' | 'boxes'\r\n | 'archive' | 'clipboardList' | 'clipboardCheck'\r\n | 'fileText' | 'chartBar'\r\n | 'trendingUp' | 'trendingDown' | 'calendar' | 'clock'\r\n | 'mapPin' | 'table' | 'list' | 'listFilter'\r\n | 'arrowUpWideNarrow' | 'arrowDownWideNarrow' | 'scale'\r\n // 추가 아이콘들\r\n | 'server' | 'database' | 'link' | 'arrowLeftRight' | 'circleQuestionMark'\r\n | 'monitor' | 'users' | 'code' | 'fileKey' | 'cpu'\r\n | 'rocket' | 'fileSpreadsheet' | 'activity' | 'messageCircle' | 'book'\r\n // 인증 관련 아이콘들\r\n | 'logIn' | 'logOut'\r\n // 편집 관련 아이콘들\r\n | 'copy' | 'clipboard' | 'undo2' | 'redo2' | 'pencil'\r\n // 파일/폴더 관련 아이콘들\r\n | 'folder' | 'folderPlus' | 'folderOpen' | 'filePlus' | 'fileSearch' | 'filePen' | 'fileMinus'\r\n // 통신/알림 관련 아이콘들\r\n | 'mail' | 'send' | 'phone' | 'bell' | 'bellOff' | 'messageSquare'\r\n // 화살표/방향 관련 아이콘들\r\n | 'arrowUp' | 'arrowDown' | 'arrowLeft' | 'arrowRight' | 'rotateCw' | 'rotateCcw' | 'refreshCw' | 'move'\r\n // 상태/피드백 관련 아이콘들\r\n | 'circleCheckBig' | 'circleX' | 'circle'\r\n // 보안 관련 아이콘들\r\n | 'lock' | 'lockOpen' | 'shield' | 'shieldCheck' | 'shieldAlert'\r\n // 사용자 관리 관련 아이콘들\r\n | 'userPlus' | 'userMinus' | 'userCheck' | 'userX' | 'circleUser'\r\n // 액션 관련 아이콘들\r\n | 'power' | 'zap' | 'target' | 'flag' | 'funnel'\r\n // 조직/팀 관련 아이콘들\r\n | 'building' | 'briefcase' | 'globe'\r\n // 기타 유용한 아이콘들\r\n | 'printer' | 'share2' | 'externalLink' | 'maximize2' | 'minimize2' | 'moveVertical' | 'moveHorizontal'\r\n | 'sun' | 'moon'\r\n\r\n// 커스텀 아이콘 확장을 위한 타입\r\ntype CustomIconName = string // 나중에 확장 가능\r\n\r\ntype IconName = BaseIconName | CustomIconName\r\n\r\ntype StyleType =\r\n | 'default' // 기본 스타일\r\n | 'primary' // 강조 스타일 (파랑)\r\n | 'success' // 성공 스타일 (초록)\r\n | 'warning' // 경고 스타일 (주황)\r\n | 'danger' // 위험 스타일 (빨강)\r\n\r\ntype SizeType = 'xs' | 'sm' | 'md' | 'lg' | 'xl'\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n name: IconName\r\n size?: SizeType\r\n color?: string\r\n class?: string\r\n /** 스타일 프리셋 */\r\n styletype?: StyleType\r\n /** 접근성 라벨 */\r\n ariaLabel?: string\r\n /** 접근성 역할 */\r\n role?: string\r\n }>(),\r\n {\n size: 'sm',\n styletype: 'default',\n role: 'img',\n },\n)\r\n\r\n/**\r\n * 기본 아이콘 매핑 (타입 안전)\r\n */\r\nconst baseIconMap: Record<BaseIconName, LucideIcon> = {\r\n house: House,\r\n user: User,\r\n settings: Settings,\r\n search: Search,\r\n plus: Plus,\r\n minus: Minus,\r\n squarePen: SquarePen,\r\n trash2: Trash2,\r\n save: Save,\r\n download: Download,\r\n upload: Upload,\r\n eye: Eye,\r\n eyeOff: EyeOff,\r\n heart: Heart,\r\n star: Star,\r\n check: Check,\r\n x: X,\r\n circleAlert: CircleAlert,\r\n info: Info,\r\n chevronDown: ChevronDown,\r\n chevronUp: ChevronUp,\r\n chevronLeft: ChevronLeft,\r\n chevronRight: ChevronRight,\r\n menu: Menu,\r\n ellipsis: Ellipsis,\r\n ellipsisVertical: EllipsisVertical,\r\n palette: Palette,\r\n // WMS 핵심 아이콘들\r\n package: Package,\r\n packageCheck: PackageCheck,\r\n packageX: PackageX,\r\n truck: Truck,\r\n warehouse: Warehouse,\r\n boxes: Boxes,\r\n archive: Archive,\r\n clipboardList: ClipboardList,\r\n clipboardCheck: ClipboardCheck,\r\n fileText: FileText,\r\n chartBar: ChartBar,\r\n trendingUp: TrendingUp,\r\n trendingDown: TrendingDown,\r\n calendar: Calendar,\r\n clock: Clock,\r\n mapPin: MapPin,\r\n table: Table,\r\n list: List,\r\n listFilter: ListFilter,\r\n arrowUpWideNarrow: ArrowUpWideNarrow,\r\n arrowDownWideNarrow: ArrowDownWideNarrow,\r\n scale: Scale,\r\n // 추가 아이콘들\r\n server: Server,\r\n database: Database,\r\n link: Link,\r\n arrowLeftRight: ArrowLeftRight,\r\n circleQuestionMark: CircleQuestionMark,\r\n monitor: Monitor,\r\n users: Users,\r\n code: Code,\r\n fileKey: FileKey,\r\n cpu: Cpu,\r\n rocket: Rocket,\r\n fileSpreadsheet: FileSpreadsheet,\r\n activity: Activity,\r\n messageCircle: MessageCircle,\r\n book: Book,\r\n // 인증 관련 아이콘들\r\n logIn: LogIn,\r\n logOut: LogOut,\r\n // 편집 관련 아이콘들\r\n copy: Copy,\r\n clipboard: Clipboard,\r\n undo2: Undo2,\r\n redo2: Redo2,\r\n pencil: Pencil,\r\n // 파일/폴더 관련 아이콘들\r\n folder: Folder,\r\n folderPlus: FolderPlus,\r\n folderOpen: FolderOpen,\r\n filePlus: FilePlus,\r\n fileSearch: FileSearch,\r\n filePen: FilePen,\r\n fileMinus: FileMinus,\r\n // 통신/알림 관련 아이콘들\r\n mail: Mail,\r\n send: Send,\r\n phone: Phone,\r\n bell: Bell,\r\n bellOff: BellOff,\r\n messageSquare: MessageSquare,\r\n // 화살표/방향 관련 아이콘들\r\n arrowUp: ArrowUp,\r\n arrowDown: ArrowDown,\r\n arrowLeft: ArrowLeft,\r\n arrowRight: ArrowRight,\r\n rotateCw: RotateCw,\r\n rotateCcw: RotateCcw,\r\n refreshCw: RefreshCw,\r\n move: Move,\r\n // 상태/피드백 관련 아이콘들\r\n circleCheckBig: CircleCheckBig,\r\n circleX: CircleX,\r\n circle: Circle,\r\n // 보안 관련 아이콘들\r\n lock: Lock,\r\n lockOpen: LockOpen,\r\n shield: Shield,\r\n shieldCheck: ShieldCheck,\r\n shieldAlert: ShieldAlert,\r\n // 사용자 관리 관련 아이콘들\r\n userPlus: UserPlus,\r\n userMinus: UserMinus,\r\n userCheck: UserCheck,\r\n userX: UserX,\r\n circleUser: CircleUser,\r\n // 액션 관련 아이콘들\r\n power: Power,\r\n zap: Zap,\r\n target: Target,\r\n flag: Flag,\r\n funnel: Funnel,\r\n // 조직/팀 관련 아이콘들\r\n building: Building,\r\n briefcase: Briefcase,\r\n globe: Globe,\r\n // 기타 유용한 아이콘들\r\n printer: Printer,\r\n share2: Share2,\r\n externalLink: ExternalLink,\r\n maximize2: Maximize2,\r\n minimize2: Minimize2,\r\n moveVertical: MoveVertical,\r\n moveHorizontal: MoveHorizontal,\r\n sun: Sun,\r\n moon: Moon,\r\n}\r\n\r\n/**\r\n * 동적 아이콘 로딩을 위한 함수 (나중에 확장 가능)\r\n * 현재는 사용하지 않지만 향후 커스텀 아이콘 지원을 위해 준비\r\n */\r\n// const loadCustomIcon = async (iconName: string): Promise<LucideIcon | null> => {\r\n// try {\r\n// // 나중에 다른 아이콘 라이브러리나 커스텀 아이콘을 동적으로 로드할 수 있음\r\n// // 예: const { [iconName]: IconComponent } = await import('@/assets/icons')\r\n// return null\r\n// } catch {\r\n// return null\r\n// }\r\n// }\r\n\r\n/**\r\n * size -> 실제 크기 매핑\r\n */\r\nconst SIZE_PRESETS: Record<SizeType, number> = {\n xs: 12,\n sm: 16,\n md: 20,\n lg: 24,\n xl: 32,\n}\n\r\n/**\r\n * styletype -> color, class 매핑\r\n */\r\nconst STYLE_PRESETS: Record<StyleType, { color?: string; class: string }> = {\r\n default: { class: '' },\r\n primary: { \r\n color: '#3b82f6',\r\n class: '',\r\n },\r\n success: { \r\n color: '#10b981',\r\n class: '',\r\n },\r\n warning: { \r\n color: '#f59e0b',\r\n class: '',\r\n },\r\n danger: { \r\n color: '#ef4444',\r\n class: '',\r\n },\r\n}\r\n\r\n/** 최종 바인딩: 직접 넘긴 props가 있으면 styletype 기본값과 병합 */\r\nconst mapped = computed(() => {\r\n const stylePreset = STYLE_PRESETS[props.styletype!]\r\n const sizePreset = SIZE_PRESETS[props.size!]\r\n const finalClass = [stylePreset.class, props.class].filter(Boolean).join(' ')\r\n const ariaLabel = props.ariaLabel || props.name\r\n \r\n return {\r\n size: sizePreset,\r\n color: props.color || stylePreset.color, // props.color가 있으면 우선 사용, 없으면 stylePreset.color 사용\r\n class: finalClass,\r\n 'aria-label': ariaLabel,\r\n 'aria-hidden': !ariaLabel,\r\n role: props.role,\r\n }\r\n})\r\n\r\n/** 현재 아이콘 컴포넌트 */\r\nconst IconComponent = computed(() => {\r\n // 기본 아이콘 먼저 확인\r\n if (props.name in baseIconMap) {\r\n return baseIconMap[props.name as BaseIconName]\r\n }\r\n \r\n // 커스텀 아이콘은 나중에 확장\r\n // return loadCustomIcon(props.name)\r\n \r\n // 기본값으로 house 아이콘 반환\r\n return House\r\n})\r\n</script>\r\n\r\n<template>\r\n <component \r\n :is=\"IconComponent\" \r\n v-bind=\"mapped\"\r\n />\r\n</template>"],"names":["props","__props","baseIconMap","House","User","Settings","Search","Plus","Minus","SquarePen","Trash2","Save","Download","Upload","Eye","EyeOff","Heart","Star","Check","X","CircleAlert","Info","ChevronDown","ChevronUp","ChevronLeft","ChevronRight","Menu","Ellipsis","EllipsisVertical","Palette","Package","PackageCheck","PackageX","Truck","Warehouse","Boxes","Archive","ClipboardList","ClipboardCheck","FileText","ChartBar","TrendingUp","TrendingDown","Calendar","Clock","MapPin","Table","List","ListFilter","ArrowUpWideNarrow","ArrowDownWideNarrow","Scale","Server","Database","Link","ArrowLeftRight","CircleQuestionMark","Monitor","Users","Code","FileKey","Cpu","Rocket","FileSpreadsheet","Activity","MessageCircle","Book","LogIn","LogOut","Copy","Clipboard","Undo2","Redo2","Pencil","Folder","FolderPlus","FolderOpen","FilePlus","FileSearch","FilePen","FileMinus","Mail","Send","Phone","Bell","BellOff","MessageSquare","ArrowUp","ArrowDown","ArrowLeft","ArrowRight","RotateCw","RotateCcw","RefreshCw","Move","CircleCheckBig","CircleX","Circle","Lock","LockOpen","Shield","ShieldCheck","ShieldAlert","UserPlus","UserMinus","UserCheck","UserX","CircleUser","Power","Zap","Target","Flag","Funnel","Building","Briefcase","Globe","Printer","Share2","ExternalLink","Maximize2","Minimize2","MoveVertical","MoveHorizontal","Sun","Moon","SIZE_PRESETS","STYLE_PRESETS","mapped","computed","stylePreset","sizePreset","finalClass","ariaLabel","IconComponent","_createBlock","_resolveDynamicComponent","_normalizeProps","_guardReactiveProps"],"mappings":";;;;;;;;;;;;;;AAsMA,UAAMA,IAAQC,GAuBRC,IAAgD;AAAA,MACpD,OAAOC;AAAA,MACP,MAAMC;AAAA,MACN,UAAUC;AAAA,MACV,QAAQC;AAAA,MACR,MAAMC;AAAA,MACN,OAAOC;AAAA,MACP,WAAWC;AAAA,MACX,QAAQC;AAAA,MACR,MAAMC;AAAA,MACN,UAAUC;AAAA,MACV,QAAQC;AAAA,MACR,KAAKC;AAAA,MACL,QAAQC;AAAA,MACR,OAAOC;AAAA,MACP,MAAMC;AAAA,MACN,OAAOC;AAAA,MACP,GAAGC;AAAA,MACH,aAAaC;AAAA,MACb,MAAMC;AAAA,MACN,aAAaC;AAAA,MACb,WAAWC;AAAA,MACX,aAAaC;AAAA,MACb,cAAcC;AAAA,MACd,MAAMC;AAAA,MACN,UAAUC;AAAA,MACV,kBAAkBC;AAAA,MAClB,SAASC;AAAA;AAAA,MAET,SAASC;AAAA,MACT,cAAcC;AAAA,MACd,UAAUC;AAAA,MACV,OAAOC;AAAA,MACP,WAAWC;AAAA,MACX,OAAOC;AAAA,MACP,SAASC;AAAA,MACT,eAAeC;AAAA,MACf,gBAAgBC;AAAA,MAChB,UAAUC;AAAA,MACV,UAAUC;AAAA,MACV,YAAYC;AAAA,MACZ,cAAcC;AAAA,MACd,UAAUC;AAAA,MACV,OAAOC;AAAA,MACP,QAAQC;AAAA,MACR,OAAOC;AAAA,MACP,MAAMC;AAAA,MACN,YAAYC;AAAA,MACZ,mBAAmBC;AAAA,MACnB,qBAAqBC;AAAA,MACrB,OAAOC;AAAA;AAAA,MAEP,QAAQC;AAAA,MACR,UAAUC;AAAA,MACV,MAAMC;AAAA,MACN,gBAAgBC;AAAA,MAChB,oBAAoBC;AAAA,MACpB,SAASC;AAAA,MACT,OAAOC;AAAA,MACP,MAAMC;AAAA,MACN,SAASC;AAAA,MACT,KAAKC;AAAA,MACL,QAAQC;AAAA,MACR,iBAAiBC;AAAA,MACjB,UAAUC;AAAA,MACV,eAAeC;AAAA,MACf,MAAMC;AAAA;AAAA,MAEN,OAAOC;AAAA,MACP,QAAQC;AAAA;AAAA,MAER,MAAMC;AAAA,MACN,WAAWC;AAAA,MACX,OAAOC;AAAA,MACP,OAAOC;AAAA,MACP,QAAQC;AAAA;AAAA,MAER,QAAQC;AAAA,MACR,YAAYC;AAAA,MACZ,YAAYC;AAAA,MACZ,UAAUC;AAAA,MACV,YAAYC;AAAA,MACZ,SAASC;AAAA,MACT,WAAWC;AAAA;AAAA,MAEX,MAAMC;AAAA,MACN,MAAMC;AAAA,MACN,OAAOC;AAAA,MACP,MAAMC;AAAA,MACN,SAASC;AAAA,MACT,eAAeC;AAAA;AAAA,MAEf,SAASC;AAAA,MACT,WAAWC;AAAA,MACX,WAAWC;AAAA,MACX,YAAYC;AAAA,MACZ,UAAUC;AAAA,MACV,WAAWC;AAAA,MACX,WAAWC;AAAA,MACX,MAAMC;AAAA;AAAA,MAEN,gBAAgBC;AAAA,MAChB,SAASC;AAAA,MACT,QAAQC;AAAA;AAAA,MAER,MAAMC;AAAA,MACN,UAAUC;AAAA,MACV,QAAQC;AAAA,MACR,aAAaC;AAAA,MACb,aAAaC;AAAA;AAAA,MAEb,UAAUC;AAAA,MACV,WAAWC;AAAA,MACX,WAAWC;AAAA,MACX,OAAOC;AAAA,MACP,YAAYC;AAAA;AAAA,MAEZ,OAAOC;AAAA,MACP,KAAKC;AAAA,MACL,QAAQC;AAAA,MACR,MAAMC;AAAA,MACN,QAAQC;AAAA;AAAA,MAER,UAAUC;AAAA,MACV,WAAWC;AAAA,MACX,OAAOC;AAAA;AAAA,MAEP,SAASC;AAAA,MACT,QAAQC;AAAA,MACR,cAAcC;AAAA,MACd,WAAWC;AAAA,MACX,WAAWC;AAAA,MACX,cAAcC;AAAA,MACd,gBAAgBC;AAAA,MAChB,KAAKC;AAAA,MACL,MAAMC;AAAA,IAAA,GAoBFC,IAAyC;AAAA,MAC7C,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,IAAI;AAAA,IAAA,GAMAC,IAAsE;AAAA,MAC1E,SAAS,EAAE,OAAO,GAAA;AAAA,MAClB,SAAS;AAAA,QACP,OAAO;AAAA,QACP,OAAO;AAAA,MAAA;AAAA,MAET,SAAS;AAAA,QACP,OAAO;AAAA,QACP,OAAO;AAAA,MAAA;AAAA,MAET,SAAS;AAAA,QACP,OAAO;AAAA,QACP,OAAO;AAAA,MAAA;AAAA,MAET,QAAQ;AAAA,QACN,OAAO;AAAA,QACP,OAAO;AAAA,MAAA;AAAA,IACT,GAIIC,IAASC,EAAS,MAAM;AAC5B,YAAMC,IAAcH,EAAc9H,EAAM,SAAU,GAC5CkI,IAAaL,EAAa7H,EAAM,IAAK,GACrCmI,IAAa,CAACF,EAAY,OAAOjI,EAAM,KAAK,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GACtEoI,IAAYpI,EAAM,aAAaA,EAAM;AAE3C,aAAO;AAAA,QACL,MAAMkI;AAAA,QACN,OAAOlI,EAAM,SAASiI,EAAY;AAAA;AAAA,QAClC,OAAOE;AAAA,QACP,cAAcC;AAAA,QACd,eAAe,CAACA;AAAA,QAChB,MAAMpI,EAAM;AAAA,MAAA;AAAA,IAEhB,CAAC,GAGKqI,IAAgBL,EAAS,MAEzBhI,EAAM,QAAQE,IACTA,EAAYF,EAAM,IAAoB,IAOxCG,CACR;2BAICmI,EAGEC,EAFKF,EAAA,KAAa,GAAAG,EAAAC,EACVV,EAAA,KAAM,CAAA,GAAA,MAAA,EAAA;AAAA;;"}
1
+ {"version":3,"file":"JIcon.vue.js","sources":["../../../../src/components/atoms/JIcon.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport { \n House, \n User, \n Settings, \n Search, \n Plus, \n Minus, \n SquarePen, \n Trash2, \n Save, \n Download,\n Upload,\n Eye,\n EyeOff,\n Heart,\n Star,\n Check,\n X,\n CircleAlert,\n Info,\n ChevronDown,\n ChevronUp,\n ChevronLeft,\n ChevronRight,\n Menu,\n Ellipsis,\n EllipsisVertical,\n Palette,\n // WMS 핵심 아이콘들\n Package,\n PackageCheck,\n PackageX,\n Truck,\n Warehouse,\n Boxes,\n Archive,\n ClipboardList,\n ClipboardCheck,\n FileText,\n ChartBar,\n TrendingUp,\n TrendingDown,\n Calendar,\n Clock,\n MapPin,\n Table,\n List,\n ListFilter,\n ArrowUpWideNarrow,\n ArrowDownWideNarrow,\n Scale,\n // 추가 아이콘들\n Server,\n Database,\n Link,\n ArrowLeftRight,\n CircleQuestionMark,\n Monitor,\n Users,\n Code,\n FileKey,\n Cpu,\n Rocket,\n FileSpreadsheet,\n Activity,\n MessageCircle,\n Book,\n LogIn,\n LogOut,\n // 편집 관련\n Copy,\n Clipboard,\n Undo2,\n Redo2,\n Pencil,\n // 파일/폴더 관련\n Folder,\n FolderPlus,\n FolderOpen,\n FilePlus,\n FileSearch,\n FilePen,\n FileMinus,\n // 통신/알림 관련\n Mail,\n Send,\n Phone,\n Bell,\n BellOff,\n MessageSquare,\n // 화살표/방향 관련\n ArrowUp,\n ArrowDown,\n ArrowLeft,\n ArrowRight,\n RotateCw,\n RotateCcw,\n RefreshCw,\n Move,\n // 상태/피드백 관련\n CircleCheckBig,\n CircleX,\n Circle,\n // 보안 관련\n Lock,\n LockOpen,\n Shield,\n ShieldCheck,\n ShieldAlert,\n // 사용자 관리 관련\n UserPlus,\n UserMinus,\n UserCheck,\n UserX,\n CircleUser,\n // 액션 관련\n Power,\n Zap,\n Target,\n Flag,\n Funnel,\n // 조직/팀 관련\n Building,\n Briefcase,\n Globe,\n // 기타 유용한 아이콘\n Printer,\n Share2,\n ExternalLink,\n Maximize2,\n Minimize2,\n MoveVertical,\n MoveHorizontal,\n Sun,\n Moon,\n type LucideIcon\n} from 'lucide-vue-next'\n\n// 확장 가능한 아이콘 타입\ntype BaseIconName = \n | 'house' | 'user' | 'settings' | 'search' | 'plus' | 'minus'\n | 'squarePen' | 'trash2' | 'save' | 'download' | 'upload'\n | 'eye' | 'eyeOff' | 'heart' | 'star' | 'check' | 'x'\n | 'circleAlert' | 'info' | 'chevronDown' | 'chevronUp'\n | 'chevronLeft' | 'chevronRight' | 'menu' | 'ellipsis' | 'ellipsisVertical'\n | 'palette'\n // WMS 핵심 아이콘들\n | 'package' | 'packageCheck' | 'packageX'\n | 'truck' | 'warehouse' | 'boxes'\n | 'archive' | 'clipboardList' | 'clipboardCheck'\n | 'fileText' | 'chartBar'\n | 'trendingUp' | 'trendingDown' | 'calendar' | 'clock'\n | 'mapPin' | 'table' | 'list' | 'listFilter'\n | 'arrowUpWideNarrow' | 'arrowDownWideNarrow' | 'scale'\n // 추가 아이콘들\n | 'server' | 'database' | 'link' | 'arrowLeftRight' | 'circleQuestionMark'\n | 'monitor' | 'users' | 'code' | 'fileKey' | 'cpu'\n | 'rocket' | 'fileSpreadsheet' | 'activity' | 'messageCircle' | 'book'\n // 인증 관련 아이콘들\n | 'logIn' | 'logOut'\n // 편집 관련 아이콘들\n | 'copy' | 'clipboard' | 'undo2' | 'redo2' | 'pencil'\n // 파일/폴더 관련 아이콘들\n | 'folder' | 'folderPlus' | 'folderOpen' | 'filePlus' | 'fileSearch' | 'filePen' | 'fileMinus'\n // 통신/알림 관련 아이콘들\n | 'mail' | 'send' | 'phone' | 'bell' | 'bellOff' | 'messageSquare'\n // 화살표/방향 관련 아이콘들\n | 'arrowUp' | 'arrowDown' | 'arrowLeft' | 'arrowRight' | 'rotateCw' | 'rotateCcw' | 'refreshCw' | 'move'\n // 상태/피드백 관련 아이콘들\n | 'circleCheckBig' | 'circleX' | 'circle'\n // 보안 관련 아이콘들\n | 'lock' | 'lockOpen' | 'shield' | 'shieldCheck' | 'shieldAlert'\n // 사용자 관리 관련 아이콘들\n | 'userPlus' | 'userMinus' | 'userCheck' | 'userX' | 'circleUser'\n // 액션 관련 아이콘들\n | 'power' | 'zap' | 'target' | 'flag' | 'funnel'\n // 조직/팀 관련 아이콘들\n | 'building' | 'briefcase' | 'globe'\n // 기타 유용한 아이콘들\n | 'printer' | 'share2' | 'externalLink' | 'maximize2' | 'minimize2' | 'moveVertical' | 'moveHorizontal'\n | 'sun' | 'moon'\n\n// 커스텀 아이콘 확장을 위한 타입\ntype CustomIconName = string // 나중에 확장 가능\n\ntype IconName = BaseIconName | CustomIconName\n\ntype StyleType =\n | 'default' // 기본 스타일\n | 'primary' // 강조 스타일 (파랑)\n | 'success' // 성공 스타일 (초록)\n | 'warning' // 경고 스타일 (주황)\n | 'danger' // 위험 스타일 (빨강)\n\ntype SizeType = 'xs' | 'sm' | 'md' | 'lg' | 'xl'\n\nconst props = withDefaults(\n defineProps<{\n name: IconName\n size?: SizeType\n color?: string\n class?: string\n /** 스타일 프리셋 */\n styletype?: StyleType\n /** 접근성 라벨 */\n ariaLabel?: string\n /** 접근성 역할 */\n role?: string\n }>(),\n {\n size: 'sm',\n styletype: 'default',\n role: 'img',\n },\n)\n\n/**\n * 기본 아이콘 매핑 (타입 안전)\n */\nconst baseIconMap: Record<BaseIconName, LucideIcon> = {\n house: House,\n user: User,\n settings: Settings,\n search: Search,\n plus: Plus,\n minus: Minus,\n squarePen: SquarePen,\n trash2: Trash2,\n save: Save,\n download: Download,\n upload: Upload,\n eye: Eye,\n eyeOff: EyeOff,\n heart: Heart,\n star: Star,\n check: Check,\n x: X,\n circleAlert: CircleAlert,\n info: Info,\n chevronDown: ChevronDown,\n chevronUp: ChevronUp,\n chevronLeft: ChevronLeft,\n chevronRight: ChevronRight,\n menu: Menu,\n ellipsis: Ellipsis,\n ellipsisVertical: EllipsisVertical,\n palette: Palette,\n // WMS 핵심 아이콘들\n package: Package,\n packageCheck: PackageCheck,\n packageX: PackageX,\n truck: Truck,\n warehouse: Warehouse,\n boxes: Boxes,\n archive: Archive,\n clipboardList: ClipboardList,\n clipboardCheck: ClipboardCheck,\n fileText: FileText,\n chartBar: ChartBar,\n trendingUp: TrendingUp,\n trendingDown: TrendingDown,\n calendar: Calendar,\n clock: Clock,\n mapPin: MapPin,\n table: Table,\n list: List,\n listFilter: ListFilter,\n arrowUpWideNarrow: ArrowUpWideNarrow,\n arrowDownWideNarrow: ArrowDownWideNarrow,\n scale: Scale,\n // 추가 아이콘들\n server: Server,\n database: Database,\n link: Link,\n arrowLeftRight: ArrowLeftRight,\n circleQuestionMark: CircleQuestionMark,\n monitor: Monitor,\n users: Users,\n code: Code,\n fileKey: FileKey,\n cpu: Cpu,\n rocket: Rocket,\n fileSpreadsheet: FileSpreadsheet,\n activity: Activity,\n messageCircle: MessageCircle,\n book: Book,\n // 인증 관련 아이콘들\n logIn: LogIn,\n logOut: LogOut,\n // 편집 관련 아이콘들\n copy: Copy,\n clipboard: Clipboard,\n undo2: Undo2,\n redo2: Redo2,\n pencil: Pencil,\n // 파일/폴더 관련 아이콘들\n folder: Folder,\n folderPlus: FolderPlus,\n folderOpen: FolderOpen,\n filePlus: FilePlus,\n fileSearch: FileSearch,\n filePen: FilePen,\n fileMinus: FileMinus,\n // 통신/알림 관련 아이콘들\n mail: Mail,\n send: Send,\n phone: Phone,\n bell: Bell,\n bellOff: BellOff,\n messageSquare: MessageSquare,\n // 화살표/방향 관련 아이콘들\n arrowUp: ArrowUp,\n arrowDown: ArrowDown,\n arrowLeft: ArrowLeft,\n arrowRight: ArrowRight,\n rotateCw: RotateCw,\n rotateCcw: RotateCcw,\n refreshCw: RefreshCw,\n move: Move,\n // 상태/피드백 관련 아이콘들\n circleCheckBig: CircleCheckBig,\n circleX: CircleX,\n circle: Circle,\n // 보안 관련 아이콘들\n lock: Lock,\n lockOpen: LockOpen,\n shield: Shield,\n shieldCheck: ShieldCheck,\n shieldAlert: ShieldAlert,\n // 사용자 관리 관련 아이콘들\n userPlus: UserPlus,\n userMinus: UserMinus,\n userCheck: UserCheck,\n userX: UserX,\n circleUser: CircleUser,\n // 액션 관련 아이콘들\n power: Power,\n zap: Zap,\n target: Target,\n flag: Flag,\n funnel: Funnel,\n // 조직/팀 관련 아이콘들\n building: Building,\n briefcase: Briefcase,\n globe: Globe,\n // 기타 유용한 아이콘들\n printer: Printer,\n share2: Share2,\n externalLink: ExternalLink,\n maximize2: Maximize2,\n minimize2: Minimize2,\n moveVertical: MoveVertical,\n moveHorizontal: MoveHorizontal,\n sun: Sun,\n moon: Moon,\n}\n\n/**\n * 동적 아이콘 로딩을 위한 함수 (나중에 확장 가능)\n * 현재는 사용하지 않지만 향후 커스텀 아이콘 지원을 위해 준비\n */\n// const loadCustomIcon = async (iconName: string): Promise<LucideIcon | null> => {\n// try {\n// // 나중에 다른 아이콘 라이브러리나 커스텀 아이콘을 동적으로 로드할 수 있음\n// // 예: const { [iconName]: IconComponent } = await import('@/assets/icons')\n// return null\n// } catch {\n// return null\n// }\n// }\n\n/**\n * size -> 실제 크기 매핑\n */\nconst SIZE_PRESETS: Record<SizeType, number> = {\n xs: 12,\n sm: 16,\n md: 20,\n lg: 24,\n xl: 32,\n}\n\n/**\n * styletype -> color, class 매핑\n */\nconst STYLE_PRESETS: Record<StyleType, { color?: string; class: string }> = {\n default: { class: '' },\n primary: { \n color: '#3b82f6',\n class: '',\n },\n success: { \n color: '#10b981',\n class: '',\n },\n warning: { \n color: '#f59e0b',\n class: '',\n },\n danger: { \n color: '#ef4444',\n class: '',\n },\n}\n\n/** 최종 바인딩: 직접 넘긴 props가 있으면 styletype 기본값과 병합 */\nconst mapped = computed(() => {\n const stylePreset = STYLE_PRESETS[props.styletype!]\n const sizePreset = SIZE_PRESETS[props.size!]\n const finalClass = [stylePreset.class, props.class].filter(Boolean).join(' ')\n const ariaLabel = props.ariaLabel || props.name\n \n return {\n size: sizePreset,\n color: props.color || stylePreset.color, // props.color가 있으면 우선 사용, 없으면 stylePreset.color 사용\n class: finalClass,\n 'aria-label': ariaLabel,\n 'aria-hidden': !ariaLabel,\n role: props.role,\n }\n})\n\n/** 현재 아이콘 컴포넌트 */\nconst IconComponent = computed(() => {\n // 기본 아이콘 먼저 확인\n if (props.name in baseIconMap) {\n return baseIconMap[props.name as BaseIconName]\n }\n \n // 커스텀 아이콘은 나중에 확장\n // return loadCustomIcon(props.name)\n \n // 기본값으로 house 아이콘 반환\n return House\n})\n</script>\n\n<template>\n <component \n :is=\"IconComponent\" \n v-bind=\"mapped\"\n />\n</template>"],"names":["props","__props","baseIconMap","House","User","Settings","Search","Plus","Minus","SquarePen","Trash2","Save","Download","Upload","Eye","EyeOff","Heart","Star","Check","X","CircleAlert","Info","ChevronDown","ChevronUp","ChevronLeft","ChevronRight","Menu","Ellipsis","EllipsisVertical","Palette","Package","PackageCheck","PackageX","Truck","Warehouse","Boxes","Archive","ClipboardList","ClipboardCheck","FileText","ChartBar","TrendingUp","TrendingDown","Calendar","Clock","MapPin","Table","List","ListFilter","ArrowUpWideNarrow","ArrowDownWideNarrow","Scale","Server","Database","Link","ArrowLeftRight","CircleQuestionMark","Monitor","Users","Code","FileKey","Cpu","Rocket","FileSpreadsheet","Activity","MessageCircle","Book","LogIn","LogOut","Copy","Clipboard","Undo2","Redo2","Pencil","Folder","FolderPlus","FolderOpen","FilePlus","FileSearch","FilePen","FileMinus","Mail","Send","Phone","Bell","BellOff","MessageSquare","ArrowUp","ArrowDown","ArrowLeft","ArrowRight","RotateCw","RotateCcw","RefreshCw","Move","CircleCheckBig","CircleX","Circle","Lock","LockOpen","Shield","ShieldCheck","ShieldAlert","UserPlus","UserMinus","UserCheck","UserX","CircleUser","Power","Zap","Target","Flag","Funnel","Building","Briefcase","Globe","Printer","Share2","ExternalLink","Maximize2","Minimize2","MoveVertical","MoveHorizontal","Sun","Moon","SIZE_PRESETS","STYLE_PRESETS","mapped","computed","stylePreset","sizePreset","finalClass","ariaLabel","IconComponent","_createBlock","_resolveDynamicComponent","_normalizeProps","_guardReactiveProps"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"JImage.vue.cjs","sources":["../../../../src/components/atoms/JImage.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, ref } from 'vue'\n\ntype StyleType = 'default' | 'primary' | 'secondary' | 'muted' | 'sm' | 'lg' | 'rounded'\n\nconst props = withDefaults(\n defineProps<{\n /** 이미지 소스 */\n src?: string\n /** 이미지 너비 */\n width?: string | number\n /** 이미지 높이 */\n height?: string | number\n /** 이미지 대체 텍스트 */\n alt?: string\n /** 이미지 스타일 테마 */\n styletype?: StyleType\n /** 에러 메시지 */\n errorText?: string\n /** 플레이스홀더 텍스트 */\n placeholder?: string\n /** 클릭 가능 여부 */\n clickable?: boolean\n /** 추가 CSS 클래스 */\n class?: string\n }>(),\n {\n styletype: 'default',\n alt: '',\n errorText: '',\n placeholder: '이미지를 불러올 수 없습니다',\n clickable: false,\n },\n)\n\nconst emit = defineEmits<{\n 'click': [event: MouseEvent]\n 'mouseover': [event: MouseEvent]\n 'mouseout': [event: MouseEvent]\n}>()\n\nconst STYLE_PRESETS: Record<StyleType, { class?: string }> = {\n default: { class: '' },\n primary: { class: 'border-primary border-2' },\n secondary: { class: 'border-secondary border-2' },\n muted: { class: 'border-muted border-2' },\n sm: { class: 'w-8 h-8' },\n lg: { class: 'w-16 h-16' },\n rounded: { class: 'rounded-full' },\n}\n\nconst isError = ref(false)\nconst isLoading = ref(false) // 초기 로딩 상태를 false로 변경\n\nconst imageStyle = computed(() => {\n const style: Record<string, string> = {}\n \n if (props.width) {\n style.width = typeof props.width === 'number' ? `${props.width}px` : props.width\n }\n \n if (props.height) {\n style.height = typeof props.height === 'number' ? `${props.height}px` : props.height\n }\n \n return style\n})\n\nconst imageClass = computed(() => {\n const styleKey = props.styletype || 'default'\n const preset = STYLE_PRESETS[styleKey] ?? STYLE_PRESETS.default\n \n const classes = [\n 'object-cover',\n styleKey === 'rounded' ? 'rounded-full' : 'rounded-md',\n preset?.class,\n props.clickable ? 'cursor-pointer hover:opacity-80 transition-opacity' : '',\n props.class\n ].filter(Boolean).join(' ')\n\n return classes\n})\n\nconst handleClick = (event: MouseEvent) => {\n if (props.clickable) {\n emit('click', event)\n }\n}\n\nconst handleMouseOver = (event: MouseEvent) => {\n emit('mouseover', event)\n}\n\nconst handleMouseOut = (event: MouseEvent) => {\n emit('mouseout', event)\n}\n\nconst handleImageLoad = () => {\n isLoading.value = false\n isError.value = false\n}\n\nconst handleImageError = () => {\n isLoading.value = false\n isError.value = true\n}\n</script>\n\n<template>\n <div class=\"inline-block\">\n <!-- 로딩 상태 -->\n <div v-if=\"isLoading\" class=\"flex items-center justify-center bg-muted rounded-md\" :style=\"imageStyle\">\n <div class=\"text-muted-foreground text-sm\">로딩 중...</div>\n </div>\n \n <!-- 에러 상태 -->\n <div v-else-if=\"isError\" class=\"flex items-center justify-center bg-muted rounded-md text-center\" :style=\"imageStyle\">\n <div class=\"text-muted-foreground text-sm\">\n {{ errorText || placeholder }}\n </div>\n </div>\n \n <!-- 이미지 표시 -->\n <img \n v-else \n :src=\"src\"\n :alt=\"alt\"\n :style=\"imageStyle\"\n :class=\"imageClass\"\n @load=\"handleImageLoad\" \n @error=\"handleImageError\"\n @click=\"handleClick\"\n @mouseover=\"handleMouseOver\"\n @mouseout=\"handleMouseOut\"\n />\n </div>\n</template>\n"],"names":["props","__props","emit","__emit","STYLE_PRESETS","isError","ref","isLoading","imageStyle","computed","style","imageClass","styleKey","preset","handleClick","event","handleMouseOver","handleMouseOut","handleImageLoad","handleImageError","_openBlock","_createElementBlock","_hoisted_1","_createElementVNode","_hoisted_2","_toDisplayString"],"mappings":"ifAKA,MAAMA,EAAQC,EA8BRC,EAAOC,EAMPC,EAAuD,CAC3D,QAAS,CAAE,MAAO,EAAA,EAClB,QAAS,CAAE,MAAO,yBAAA,EAClB,UAAW,CAAE,MAAO,2BAAA,EACpB,MAAO,CAAE,MAAO,uBAAA,EAChB,GAAI,CAAE,MAAO,SAAA,EACb,GAAI,CAAE,MAAO,WAAA,EACb,QAAS,CAAE,MAAO,cAAA,CAAe,EAG7BC,EAAUC,EAAAA,IAAI,EAAK,EACnBC,EAAYD,EAAAA,IAAI,EAAK,EAErBE,EAAaC,EAAAA,SAAS,IAAM,CAChC,MAAMC,EAAgC,CAAA,EAEtC,OAAIV,EAAM,QACRU,EAAM,MAAQ,OAAOV,EAAM,OAAU,SAAW,GAAGA,EAAM,KAAK,KAAOA,EAAM,OAGzEA,EAAM,SACRU,EAAM,OAAS,OAAOV,EAAM,QAAW,SAAW,GAAGA,EAAM,MAAM,KAAOA,EAAM,QAGzEU,CACT,CAAC,EAEKC,EAAaF,EAAAA,SAAS,IAAM,CAChC,MAAMG,EAAWZ,EAAM,WAAa,UAC9Ba,EAAST,EAAcQ,CAAQ,GAAKR,EAAc,QAUxD,MARgB,CACd,eACAQ,IAAa,UAAY,eAAiB,aAC1CC,GAAQ,MACRb,EAAM,UAAY,qDAAuD,GACzEA,EAAM,KAAA,EACN,OAAO,OAAO,EAAE,KAAK,GAAG,CAG5B,CAAC,EAEKc,EAAeC,GAAsB,CACrCf,EAAM,WACRE,EAAK,QAASa,CAAK,CAEvB,EAEMC,EAAmBD,GAAsB,CAC7Cb,EAAK,YAAaa,CAAK,CACzB,EAEME,EAAkBF,GAAsB,CAC5Cb,EAAK,WAAYa,CAAK,CACxB,EAEMG,EAAkB,IAAM,CAC5BX,EAAU,MAAQ,GAClBF,EAAQ,MAAQ,EAClB,EAEMc,EAAmB,IAAM,CAC7BZ,EAAU,MAAQ,GAClBF,EAAQ,MAAQ,EAClB,gBAIEe,YAAA,EAAAC,qBA0BM,MA1BNC,EA0BM,CAxBOf,EAAA,qBAAXc,EAAAA,mBAEM,MAAA,OAFgB,MAAM,uDAAwD,uBAAOb,EAAA,KAAU,CAAA,mBACnGe,EAAAA,mBAAwD,MAAA,CAAnD,MAAM,+BAAA,EAAgC,UAAO,EAAA,CAAA,QAIpClB,EAAA,qBAAhBgB,EAAAA,mBAIM,MAAA,OAJmB,MAAM,mEAAoE,uBAAOb,EAAA,KAAU,CAAA,GAClHe,qBAEM,MAFNC,EAEMC,EAAAA,gBADDxB,EAAA,WAAaA,EAAA,WAAW,EAAA,CAAA,CAAA,qBAK/BoB,EAAAA,mBAWE,MAAA,OATC,IAAKpB,EAAA,IACL,IAAKA,EAAA,IACL,uBAAOO,EAAA,KAAU,EACjB,uBAAOG,EAAA,KAAU,EACjB,OAAMO,EACN,QAAOC,EACP,QAAOL,EACP,YAAWE,EACX,WAAUC,CAAA"}
1
+ {"version":3,"file":"JImage.vue.cjs","sources":["../../../../src/components/atoms/JImage.vue"],"sourcesContent":["<script setup lang=\"ts\">\r\nimport { computed, ref } from 'vue'\r\n\r\ntype StyleType = 'default' | 'primary' | 'secondary' | 'muted' | 'sm' | 'lg' | 'rounded'\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n /** 이미지 소스 */\r\n src?: string\r\n /** 이미지 너비 */\r\n width?: string | number\r\n /** 이미지 높이 */\r\n height?: string | number\r\n /** 이미지 대체 텍스트 */\r\n alt?: string\r\n /** 이미지 스타일 테마 */\r\n styletype?: StyleType\r\n /** 에러 메시지 */\r\n errorText?: string\r\n /** 플레이스홀더 텍스트 */\r\n placeholder?: string\r\n /** 클릭 가능 여부 */\r\n clickable?: boolean\r\n /** 추가 CSS 클래스 */\r\n class?: string\r\n }>(),\r\n {\r\n styletype: 'default',\r\n alt: '',\r\n errorText: '',\r\n placeholder: '이미지를 불러올 수 없습니다',\r\n clickable: false,\r\n },\r\n)\r\n\r\nconst emit = defineEmits<{\r\n 'click': [event: MouseEvent]\r\n 'mouseover': [event: MouseEvent]\r\n 'mouseout': [event: MouseEvent]\r\n}>()\r\n\r\nconst STYLE_PRESETS: Record<StyleType, { class?: string }> = {\r\n default: { class: '' },\r\n primary: { class: 'border-primary border-2' },\r\n secondary: { class: 'border-secondary border-2' },\r\n muted: { class: 'border-muted border-2' },\r\n sm: { class: 'w-8 h-8' },\r\n lg: { class: 'w-16 h-16' },\r\n rounded: { class: 'rounded-full' },\r\n}\r\n\r\nconst isError = ref(false)\r\nconst isLoading = ref(false) // 초기 로딩 상태를 false로 변경\r\n\r\nconst imageStyle = computed(() => {\r\n const style: Record<string, string> = {}\r\n \r\n if (props.width) {\r\n style.width = typeof props.width === 'number' ? `${props.width}px` : props.width\r\n }\r\n \r\n if (props.height) {\r\n style.height = typeof props.height === 'number' ? `${props.height}px` : props.height\r\n }\r\n \r\n return style\r\n})\r\n\r\nconst imageClass = computed(() => {\r\n const styleKey = props.styletype || 'default'\r\n const preset = STYLE_PRESETS[styleKey] ?? STYLE_PRESETS.default\r\n \r\n const classes = [\r\n 'object-cover',\r\n styleKey === 'rounded' ? 'rounded-full' : 'rounded-md',\r\n preset?.class,\r\n props.clickable ? 'cursor-pointer hover:opacity-80 transition-opacity' : '',\r\n props.class\r\n ].filter(Boolean).join(' ')\r\n\r\n return classes\r\n})\r\n\r\nconst handleClick = (event: MouseEvent) => {\r\n if (props.clickable) {\r\n emit('click', event)\r\n }\r\n}\r\n\r\nconst handleMouseOver = (event: MouseEvent) => {\r\n emit('mouseover', event)\r\n}\r\n\r\nconst handleMouseOut = (event: MouseEvent) => {\r\n emit('mouseout', event)\r\n}\r\n\r\nconst handleImageLoad = () => {\r\n isLoading.value = false\r\n isError.value = false\r\n}\r\n\r\nconst handleImageError = () => {\r\n isLoading.value = false\r\n isError.value = true\r\n}\r\n</script>\r\n\r\n<template>\r\n <div class=\"inline-block\">\r\n <!-- 로딩 상태 -->\r\n <div v-if=\"isLoading\" class=\"flex items-center justify-center bg-muted rounded-md\" :style=\"imageStyle\">\r\n <div class=\"text-muted-foreground text-sm\">로딩 중...</div>\r\n </div>\r\n \r\n <!-- 에러 상태 -->\r\n <div v-else-if=\"isError\" class=\"flex items-center justify-center bg-muted rounded-md text-center\" :style=\"imageStyle\">\r\n <div class=\"text-muted-foreground text-sm\">\r\n {{ errorText || placeholder }}\r\n </div>\r\n </div>\r\n \r\n <!-- 이미지 표시 -->\r\n <img \r\n v-else \r\n :src=\"src\"\r\n :alt=\"alt\"\r\n :style=\"imageStyle\"\r\n :class=\"imageClass\"\r\n @load=\"handleImageLoad\" \r\n @error=\"handleImageError\"\r\n @click=\"handleClick\"\r\n @mouseover=\"handleMouseOver\"\r\n @mouseout=\"handleMouseOut\"\r\n />\r\n </div>\r\n</template>\r\n"],"names":["props","__props","emit","__emit","STYLE_PRESETS","isError","ref","isLoading","imageStyle","computed","style","imageClass","styleKey","preset","handleClick","event","handleMouseOver","handleMouseOut","handleImageLoad","handleImageError","_openBlock","_createElementBlock","_hoisted_1","_createElementVNode","_hoisted_2","_toDisplayString"],"mappings":"ifAKA,MAAMA,EAAQC,EA8BRC,EAAOC,EAMPC,EAAuD,CAC3D,QAAS,CAAE,MAAO,EAAA,EAClB,QAAS,CAAE,MAAO,yBAAA,EAClB,UAAW,CAAE,MAAO,2BAAA,EACpB,MAAO,CAAE,MAAO,uBAAA,EAChB,GAAI,CAAE,MAAO,SAAA,EACb,GAAI,CAAE,MAAO,WAAA,EACb,QAAS,CAAE,MAAO,cAAA,CAAe,EAG7BC,EAAUC,EAAAA,IAAI,EAAK,EACnBC,EAAYD,EAAAA,IAAI,EAAK,EAErBE,EAAaC,EAAAA,SAAS,IAAM,CAChC,MAAMC,EAAgC,CAAA,EAEtC,OAAIV,EAAM,QACRU,EAAM,MAAQ,OAAOV,EAAM,OAAU,SAAW,GAAGA,EAAM,KAAK,KAAOA,EAAM,OAGzEA,EAAM,SACRU,EAAM,OAAS,OAAOV,EAAM,QAAW,SAAW,GAAGA,EAAM,MAAM,KAAOA,EAAM,QAGzEU,CACT,CAAC,EAEKC,EAAaF,EAAAA,SAAS,IAAM,CAChC,MAAMG,EAAWZ,EAAM,WAAa,UAC9Ba,EAAST,EAAcQ,CAAQ,GAAKR,EAAc,QAUxD,MARgB,CACd,eACAQ,IAAa,UAAY,eAAiB,aAC1CC,GAAQ,MACRb,EAAM,UAAY,qDAAuD,GACzEA,EAAM,KAAA,EACN,OAAO,OAAO,EAAE,KAAK,GAAG,CAG5B,CAAC,EAEKc,EAAeC,GAAsB,CACrCf,EAAM,WACRE,EAAK,QAASa,CAAK,CAEvB,EAEMC,EAAmBD,GAAsB,CAC7Cb,EAAK,YAAaa,CAAK,CACzB,EAEME,EAAkBF,GAAsB,CAC5Cb,EAAK,WAAYa,CAAK,CACxB,EAEMG,EAAkB,IAAM,CAC5BX,EAAU,MAAQ,GAClBF,EAAQ,MAAQ,EAClB,EAEMc,EAAmB,IAAM,CAC7BZ,EAAU,MAAQ,GAClBF,EAAQ,MAAQ,EAClB,gBAIEe,YAAA,EAAAC,qBA0BM,MA1BNC,EA0BM,CAxBOf,EAAA,qBAAXc,EAAAA,mBAEM,MAAA,OAFgB,MAAM,uDAAwD,uBAAOb,EAAA,KAAU,CAAA,mBACnGe,EAAAA,mBAAwD,MAAA,CAAnD,MAAM,+BAAA,EAAgC,UAAO,EAAA,CAAA,QAIpClB,EAAA,qBAAhBgB,EAAAA,mBAIM,MAAA,OAJmB,MAAM,mEAAoE,uBAAOb,EAAA,KAAU,CAAA,GAClHe,qBAEM,MAFNC,EAEMC,EAAAA,gBADDxB,EAAA,WAAaA,EAAA,WAAW,EAAA,CAAA,CAAA,qBAK/BoB,EAAAA,mBAWE,MAAA,OATC,IAAKpB,EAAA,IACL,IAAKA,EAAA,IACL,uBAAOO,EAAA,KAAU,EACjB,uBAAOG,EAAA,KAAU,EACjB,OAAMO,EACN,QAAOC,EACP,QAAOL,EACP,YAAWE,EACX,WAAUC,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"JImage.vue.js","sources":["../../../../src/components/atoms/JImage.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, ref } from 'vue'\n\ntype StyleType = 'default' | 'primary' | 'secondary' | 'muted' | 'sm' | 'lg' | 'rounded'\n\nconst props = withDefaults(\n defineProps<{\n /** 이미지 소스 */\n src?: string\n /** 이미지 너비 */\n width?: string | number\n /** 이미지 높이 */\n height?: string | number\n /** 이미지 대체 텍스트 */\n alt?: string\n /** 이미지 스타일 테마 */\n styletype?: StyleType\n /** 에러 메시지 */\n errorText?: string\n /** 플레이스홀더 텍스트 */\n placeholder?: string\n /** 클릭 가능 여부 */\n clickable?: boolean\n /** 추가 CSS 클래스 */\n class?: string\n }>(),\n {\n styletype: 'default',\n alt: '',\n errorText: '',\n placeholder: '이미지를 불러올 수 없습니다',\n clickable: false,\n },\n)\n\nconst emit = defineEmits<{\n 'click': [event: MouseEvent]\n 'mouseover': [event: MouseEvent]\n 'mouseout': [event: MouseEvent]\n}>()\n\nconst STYLE_PRESETS: Record<StyleType, { class?: string }> = {\n default: { class: '' },\n primary: { class: 'border-primary border-2' },\n secondary: { class: 'border-secondary border-2' },\n muted: { class: 'border-muted border-2' },\n sm: { class: 'w-8 h-8' },\n lg: { class: 'w-16 h-16' },\n rounded: { class: 'rounded-full' },\n}\n\nconst isError = ref(false)\nconst isLoading = ref(false) // 초기 로딩 상태를 false로 변경\n\nconst imageStyle = computed(() => {\n const style: Record<string, string> = {}\n \n if (props.width) {\n style.width = typeof props.width === 'number' ? `${props.width}px` : props.width\n }\n \n if (props.height) {\n style.height = typeof props.height === 'number' ? `${props.height}px` : props.height\n }\n \n return style\n})\n\nconst imageClass = computed(() => {\n const styleKey = props.styletype || 'default'\n const preset = STYLE_PRESETS[styleKey] ?? STYLE_PRESETS.default\n \n const classes = [\n 'object-cover',\n styleKey === 'rounded' ? 'rounded-full' : 'rounded-md',\n preset?.class,\n props.clickable ? 'cursor-pointer hover:opacity-80 transition-opacity' : '',\n props.class\n ].filter(Boolean).join(' ')\n\n return classes\n})\n\nconst handleClick = (event: MouseEvent) => {\n if (props.clickable) {\n emit('click', event)\n }\n}\n\nconst handleMouseOver = (event: MouseEvent) => {\n emit('mouseover', event)\n}\n\nconst handleMouseOut = (event: MouseEvent) => {\n emit('mouseout', event)\n}\n\nconst handleImageLoad = () => {\n isLoading.value = false\n isError.value = false\n}\n\nconst handleImageError = () => {\n isLoading.value = false\n isError.value = true\n}\n</script>\n\n<template>\n <div class=\"inline-block\">\n <!-- 로딩 상태 -->\n <div v-if=\"isLoading\" class=\"flex items-center justify-center bg-muted rounded-md\" :style=\"imageStyle\">\n <div class=\"text-muted-foreground text-sm\">로딩 중...</div>\n </div>\n \n <!-- 에러 상태 -->\n <div v-else-if=\"isError\" class=\"flex items-center justify-center bg-muted rounded-md text-center\" :style=\"imageStyle\">\n <div class=\"text-muted-foreground text-sm\">\n {{ errorText || placeholder }}\n </div>\n </div>\n \n <!-- 이미지 표시 -->\n <img \n v-else \n :src=\"src\"\n :alt=\"alt\"\n :style=\"imageStyle\"\n :class=\"imageClass\"\n @load=\"handleImageLoad\" \n @error=\"handleImageError\"\n @click=\"handleClick\"\n @mouseover=\"handleMouseOver\"\n @mouseout=\"handleMouseOut\"\n />\n </div>\n</template>\n"],"names":["props","__props","emit","__emit","STYLE_PRESETS","isError","ref","isLoading","imageStyle","computed","style","imageClass","styleKey","preset","handleClick","event","handleMouseOver","handleMouseOut","handleImageLoad","handleImageError","_openBlock","_createElementBlock","_hoisted_1","_createElementVNode","_hoisted_2","_toDisplayString"],"mappings":";;;;;;;;;;;;;;;;AAKA,UAAMA,IAAQC,GA8BRC,IAAOC,GAMPC,IAAuD;AAAA,MAC3D,SAAS,EAAE,OAAO,GAAA;AAAA,MAClB,SAAS,EAAE,OAAO,0BAAA;AAAA,MAClB,WAAW,EAAE,OAAO,4BAAA;AAAA,MACpB,OAAO,EAAE,OAAO,wBAAA;AAAA,MAChB,IAAI,EAAE,OAAO,UAAA;AAAA,MACb,IAAI,EAAE,OAAO,YAAA;AAAA,MACb,SAAS,EAAE,OAAO,eAAA;AAAA,IAAe,GAG7BC,IAAUC,EAAI,EAAK,GACnBC,IAAYD,EAAI,EAAK,GAErBE,IAAaC,EAAS,MAAM;AAChC,YAAMC,IAAgC,CAAA;AAEtC,aAAIV,EAAM,UACRU,EAAM,QAAQ,OAAOV,EAAM,SAAU,WAAW,GAAGA,EAAM,KAAK,OAAOA,EAAM,QAGzEA,EAAM,WACRU,EAAM,SAAS,OAAOV,EAAM,UAAW,WAAW,GAAGA,EAAM,MAAM,OAAOA,EAAM,SAGzEU;AAAA,IACT,CAAC,GAEKC,IAAaF,EAAS,MAAM;AAChC,YAAMG,IAAWZ,EAAM,aAAa,WAC9Ba,IAAST,EAAcQ,CAAQ,KAAKR,EAAc;AAUxD,aARgB;AAAA,QACd;AAAA,QACAQ,MAAa,YAAY,iBAAiB;AAAA,QAC1CC,GAAQ;AAAA,QACRb,EAAM,YAAY,uDAAuD;AAAA,QACzEA,EAAM;AAAA,MAAA,EACN,OAAO,OAAO,EAAE,KAAK,GAAG;AAAA,IAG5B,CAAC,GAEKc,IAAc,CAACC,MAAsB;AACzC,MAAIf,EAAM,aACRE,EAAK,SAASa,CAAK;AAAA,IAEvB,GAEMC,IAAkB,CAACD,MAAsB;AAC7C,MAAAb,EAAK,aAAaa,CAAK;AAAA,IACzB,GAEME,IAAiB,CAACF,MAAsB;AAC5C,MAAAb,EAAK,YAAYa,CAAK;AAAA,IACxB,GAEMG,IAAkB,MAAM;AAC5B,MAAAX,EAAU,QAAQ,IAClBF,EAAQ,QAAQ;AAAA,IAClB,GAEMc,IAAmB,MAAM;AAC7B,MAAAZ,EAAU,QAAQ,IAClBF,EAAQ,QAAQ;AAAA,IAClB;sBAIEe,EAAA,GAAAC,EA0BM,OA1BNC,GA0BM;AAAA,MAxBOf,EAAA,cAAXc,EAEM,OAAA;AAAA;QAFgB,OAAM;AAAA,QAAwD,SAAOb,EAAA,KAAU;AAAA,MAAA;QACnGe,EAAwD,OAAA,EAAnD,OAAM,gCAAA,GAAgC,WAAO,EAAA;AAAA,MAAA,WAIpClB,EAAA,cAAhBgB,EAIM,OAAA;AAAA;QAJmB,OAAM;AAAA,QAAoE,SAAOb,EAAA,KAAU;AAAA,MAAA;QAClHe,EAEM,OAFNC,GAEMC,EADDxB,EAAA,aAAaA,EAAA,WAAW,GAAA,CAAA;AAAA,MAAA,eAK/BoB,EAWE,OAAA;AAAA;QATC,KAAKpB,EAAA;AAAA,QACL,KAAKA,EAAA;AAAA,QACL,SAAOO,EAAA,KAAU;AAAA,QACjB,SAAOG,EAAA,KAAU;AAAA,QACjB,QAAMO;AAAA,QACN,SAAOC;AAAA,QACP,SAAOL;AAAA,QACP,aAAWE;AAAA,QACX,YAAUC;AAAA,MAAA;;;;"}
1
+ {"version":3,"file":"JImage.vue.js","sources":["../../../../src/components/atoms/JImage.vue"],"sourcesContent":["<script setup lang=\"ts\">\r\nimport { computed, ref } from 'vue'\r\n\r\ntype StyleType = 'default' | 'primary' | 'secondary' | 'muted' | 'sm' | 'lg' | 'rounded'\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n /** 이미지 소스 */\r\n src?: string\r\n /** 이미지 너비 */\r\n width?: string | number\r\n /** 이미지 높이 */\r\n height?: string | number\r\n /** 이미지 대체 텍스트 */\r\n alt?: string\r\n /** 이미지 스타일 테마 */\r\n styletype?: StyleType\r\n /** 에러 메시지 */\r\n errorText?: string\r\n /** 플레이스홀더 텍스트 */\r\n placeholder?: string\r\n /** 클릭 가능 여부 */\r\n clickable?: boolean\r\n /** 추가 CSS 클래스 */\r\n class?: string\r\n }>(),\r\n {\r\n styletype: 'default',\r\n alt: '',\r\n errorText: '',\r\n placeholder: '이미지를 불러올 수 없습니다',\r\n clickable: false,\r\n },\r\n)\r\n\r\nconst emit = defineEmits<{\r\n 'click': [event: MouseEvent]\r\n 'mouseover': [event: MouseEvent]\r\n 'mouseout': [event: MouseEvent]\r\n}>()\r\n\r\nconst STYLE_PRESETS: Record<StyleType, { class?: string }> = {\r\n default: { class: '' },\r\n primary: { class: 'border-primary border-2' },\r\n secondary: { class: 'border-secondary border-2' },\r\n muted: { class: 'border-muted border-2' },\r\n sm: { class: 'w-8 h-8' },\r\n lg: { class: 'w-16 h-16' },\r\n rounded: { class: 'rounded-full' },\r\n}\r\n\r\nconst isError = ref(false)\r\nconst isLoading = ref(false) // 초기 로딩 상태를 false로 변경\r\n\r\nconst imageStyle = computed(() => {\r\n const style: Record<string, string> = {}\r\n \r\n if (props.width) {\r\n style.width = typeof props.width === 'number' ? `${props.width}px` : props.width\r\n }\r\n \r\n if (props.height) {\r\n style.height = typeof props.height === 'number' ? `${props.height}px` : props.height\r\n }\r\n \r\n return style\r\n})\r\n\r\nconst imageClass = computed(() => {\r\n const styleKey = props.styletype || 'default'\r\n const preset = STYLE_PRESETS[styleKey] ?? STYLE_PRESETS.default\r\n \r\n const classes = [\r\n 'object-cover',\r\n styleKey === 'rounded' ? 'rounded-full' : 'rounded-md',\r\n preset?.class,\r\n props.clickable ? 'cursor-pointer hover:opacity-80 transition-opacity' : '',\r\n props.class\r\n ].filter(Boolean).join(' ')\r\n\r\n return classes\r\n})\r\n\r\nconst handleClick = (event: MouseEvent) => {\r\n if (props.clickable) {\r\n emit('click', event)\r\n }\r\n}\r\n\r\nconst handleMouseOver = (event: MouseEvent) => {\r\n emit('mouseover', event)\r\n}\r\n\r\nconst handleMouseOut = (event: MouseEvent) => {\r\n emit('mouseout', event)\r\n}\r\n\r\nconst handleImageLoad = () => {\r\n isLoading.value = false\r\n isError.value = false\r\n}\r\n\r\nconst handleImageError = () => {\r\n isLoading.value = false\r\n isError.value = true\r\n}\r\n</script>\r\n\r\n<template>\r\n <div class=\"inline-block\">\r\n <!-- 로딩 상태 -->\r\n <div v-if=\"isLoading\" class=\"flex items-center justify-center bg-muted rounded-md\" :style=\"imageStyle\">\r\n <div class=\"text-muted-foreground text-sm\">로딩 중...</div>\r\n </div>\r\n \r\n <!-- 에러 상태 -->\r\n <div v-else-if=\"isError\" class=\"flex items-center justify-center bg-muted rounded-md text-center\" :style=\"imageStyle\">\r\n <div class=\"text-muted-foreground text-sm\">\r\n {{ errorText || placeholder }}\r\n </div>\r\n </div>\r\n \r\n <!-- 이미지 표시 -->\r\n <img \r\n v-else \r\n :src=\"src\"\r\n :alt=\"alt\"\r\n :style=\"imageStyle\"\r\n :class=\"imageClass\"\r\n @load=\"handleImageLoad\" \r\n @error=\"handleImageError\"\r\n @click=\"handleClick\"\r\n @mouseover=\"handleMouseOver\"\r\n @mouseout=\"handleMouseOut\"\r\n />\r\n </div>\r\n</template>\r\n"],"names":["props","__props","emit","__emit","STYLE_PRESETS","isError","ref","isLoading","imageStyle","computed","style","imageClass","styleKey","preset","handleClick","event","handleMouseOver","handleMouseOut","handleImageLoad","handleImageError","_openBlock","_createElementBlock","_hoisted_1","_createElementVNode","_hoisted_2","_toDisplayString"],"mappings":";;;;;;;;;;;;;;;;AAKA,UAAMA,IAAQC,GA8BRC,IAAOC,GAMPC,IAAuD;AAAA,MAC3D,SAAS,EAAE,OAAO,GAAA;AAAA,MAClB,SAAS,EAAE,OAAO,0BAAA;AAAA,MAClB,WAAW,EAAE,OAAO,4BAAA;AAAA,MACpB,OAAO,EAAE,OAAO,wBAAA;AAAA,MAChB,IAAI,EAAE,OAAO,UAAA;AAAA,MACb,IAAI,EAAE,OAAO,YAAA;AAAA,MACb,SAAS,EAAE,OAAO,eAAA;AAAA,IAAe,GAG7BC,IAAUC,EAAI,EAAK,GACnBC,IAAYD,EAAI,EAAK,GAErBE,IAAaC,EAAS,MAAM;AAChC,YAAMC,IAAgC,CAAA;AAEtC,aAAIV,EAAM,UACRU,EAAM,QAAQ,OAAOV,EAAM,SAAU,WAAW,GAAGA,EAAM,KAAK,OAAOA,EAAM,QAGzEA,EAAM,WACRU,EAAM,SAAS,OAAOV,EAAM,UAAW,WAAW,GAAGA,EAAM,MAAM,OAAOA,EAAM,SAGzEU;AAAA,IACT,CAAC,GAEKC,IAAaF,EAAS,MAAM;AAChC,YAAMG,IAAWZ,EAAM,aAAa,WAC9Ba,IAAST,EAAcQ,CAAQ,KAAKR,EAAc;AAUxD,aARgB;AAAA,QACd;AAAA,QACAQ,MAAa,YAAY,iBAAiB;AAAA,QAC1CC,GAAQ;AAAA,QACRb,EAAM,YAAY,uDAAuD;AAAA,QACzEA,EAAM;AAAA,MAAA,EACN,OAAO,OAAO,EAAE,KAAK,GAAG;AAAA,IAG5B,CAAC,GAEKc,IAAc,CAACC,MAAsB;AACzC,MAAIf,EAAM,aACRE,EAAK,SAASa,CAAK;AAAA,IAEvB,GAEMC,IAAkB,CAACD,MAAsB;AAC7C,MAAAb,EAAK,aAAaa,CAAK;AAAA,IACzB,GAEME,IAAiB,CAACF,MAAsB;AAC5C,MAAAb,EAAK,YAAYa,CAAK;AAAA,IACxB,GAEMG,IAAkB,MAAM;AAC5B,MAAAX,EAAU,QAAQ,IAClBF,EAAQ,QAAQ;AAAA,IAClB,GAEMc,IAAmB,MAAM;AAC7B,MAAAZ,EAAU,QAAQ,IAClBF,EAAQ,QAAQ;AAAA,IAClB;sBAIEe,EAAA,GAAAC,EA0BM,OA1BNC,GA0BM;AAAA,MAxBOf,EAAA,cAAXc,EAEM,OAAA;AAAA;QAFgB,OAAM;AAAA,QAAwD,SAAOb,EAAA,KAAU;AAAA,MAAA;QACnGe,EAAwD,OAAA,EAAnD,OAAM,gCAAA,GAAgC,WAAO,EAAA;AAAA,MAAA,WAIpClB,EAAA,cAAhBgB,EAIM,OAAA;AAAA;QAJmB,OAAM;AAAA,QAAoE,SAAOb,EAAA,KAAU;AAAA,MAAA;QAClHe,EAEM,OAFNC,GAEMC,EADDxB,EAAA,aAAaA,EAAA,WAAW,GAAA,CAAA;AAAA,MAAA,eAK/BoB,EAWE,OAAA;AAAA;QATC,KAAKpB,EAAA;AAAA,QACL,KAAKA,EAAA;AAAA,QACL,SAAOO,EAAA,KAAU;AAAA,QACjB,SAAOG,EAAA,KAAU;AAAA,QACjB,QAAMO;AAAA,QACN,SAAOC;AAAA,QACP,SAAOL;AAAA,QACP,aAAWE;AAAA,QACX,YAAUC;AAAA,MAAA;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"JKbd.vue.cjs","sources":["../../../../src/components/atoms/JKbd.vue"],"sourcesContent":["<script setup lang=\"ts\">\r\nimport { computed } from 'vue'\r\nimport Kbd from '@/components/shadcn/Kbd.vue'\r\n\r\ntype StyleType =\r\n | 'default' // 기본 스타일\r\n | 'primary' // 강조 스타일 (파랑)\r\n | 'success' // 성공 스타일 (초록)\r\n | 'warning' // 경고 스타일 (주황)\r\n | 'danger' // 위험 스타일 (빨강)\r\n\r\ntype SizeType = 'xs' | 'sm' | 'md' | 'lg'\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n class?: string\r\n /** 스타일 프리셋 */\r\n styletype?: StyleType\r\n /** 키보드 키 크기 */\r\n size?: SizeType\r\n }>(),\r\n {\n styletype: 'default',\n size: 'sm',\n },\n)\r\n\r\n/**\r\n * styletype -> class 매핑\r\n */\r\nconst STYLE_PRESETS: Record<StyleType, { class: string }> = {\r\n default: { class: '' },\r\n primary: { \r\n class: 'bg-blue-100 text-blue-800 border-blue-200',\r\n },\r\n success: { \r\n class: 'bg-green-100 text-green-800 border-green-200',\r\n },\r\n warning: { \r\n class: 'bg-amber-100 text-amber-800 border-amber-200',\r\n },\r\n danger: { \r\n class: 'bg-red-100 text-red-800 border-red-200',\r\n },\r\n}\r\n\r\n/**\r\n * size -> class 매핑\r\n */\r\nconst SIZE_PRESETS: Record<SizeType, { class: string }> = {\n xs: { \n class: 'h-3.5 px-0.5 text-[10px] min-w-[14px]',\n },\n sm: { \n class: 'h-4 px-1 text-xs min-w-[16px]',\n },\n md: { \n class: 'h-5 px-1.5 text-xs',\n },\n lg: { \n class: 'h-6 px-2 text-sm',\n },\n}\n\r\n/** 최종 바인딩: styletype과 size를 병합하여 최종 클래스 생성 */\r\nconst mapped = computed(() => {\r\n const stylePreset = STYLE_PRESETS[props.styletype!]\r\n const sizePreset = SIZE_PRESETS[props.size!]\r\n const finalClass = [stylePreset.class, sizePreset.class, props.class].filter(Boolean).join(' ')\r\n \r\n return {\r\n class: finalClass,\r\n }\r\n})\r\n</script>\r\n\r\n<template>\r\n <Kbd v-bind=\"mapped\">\r\n <slot />\r\n </Kbd>\r\n</template>\r\n"],"names":["props","__props","STYLE_PRESETS","SIZE_PRESETS","mapped","computed","stylePreset","sizePreset","_openBlock","_createBlock","Kbd","_renderSlot","_ctx"],"mappings":"qRAaA,MAAMA,EAAQC,EAiBRC,EAAsD,CAC1D,QAAS,CAAE,MAAO,EAAA,EAClB,QAAS,CACP,MAAO,2CAAA,EAET,QAAS,CACP,MAAO,8CAAA,EAET,QAAS,CACP,MAAO,8CAAA,EAET,OAAQ,CACN,MAAO,wCAAA,CACT,EAMIC,EAAoD,CACxD,GAAI,CACF,MAAO,uCAAA,EAET,GAAI,CACF,MAAO,+BAAA,EAET,GAAI,CACF,MAAO,oBAAA,EAET,GAAI,CACF,MAAO,kBAAA,CACT,EAIIC,EAASC,EAAAA,SAAS,IAAM,CAC5B,MAAMC,EAAcJ,EAAcF,EAAM,SAAU,EAC5CO,EAAaJ,EAAaH,EAAM,IAAK,EAG3C,MAAO,CACL,MAHiB,CAACM,EAAY,MAAOC,EAAW,MAAOP,EAAM,KAAK,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,CAGrF,CAEX,CAAC,gBAICQ,EAAAA,UAAA,EAAAC,EAAAA,YAEMC,EAAAA,8CAFON,EAAA,KAAM,CAAA,EAAA,mBACjB,IAAQ,CAARO,aAAQC,EAAA,OAAA,SAAA,CAAA"}
1
+ {"version":3,"file":"JKbd.vue.cjs","sources":["../../../../src/components/atoms/JKbd.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport Kbd from '@/components/shadcn/Kbd.vue'\n\ntype StyleType =\n | 'default' // 기본 스타일\n | 'primary' // 강조 스타일 (파랑)\n | 'success' // 성공 스타일 (초록)\n | 'warning' // 경고 스타일 (주황)\n | 'danger' // 위험 스타일 (빨강)\n\ntype SizeType = 'xs' | 'sm' | 'md' | 'lg'\n\nconst props = withDefaults(\n defineProps<{\n class?: string\n /** 스타일 프리셋 */\n styletype?: StyleType\n /** 키보드 키 크기 */\n size?: SizeType\n }>(),\n {\n styletype: 'default',\n size: 'sm',\n },\n)\n\n/**\n * styletype -> class 매핑\n */\nconst STYLE_PRESETS: Record<StyleType, { class: string }> = {\n default: { class: '' },\n primary: { \n class: 'bg-blue-100 text-blue-800 border-blue-200',\n },\n success: { \n class: 'bg-green-100 text-green-800 border-green-200',\n },\n warning: { \n class: 'bg-amber-100 text-amber-800 border-amber-200',\n },\n danger: { \n class: 'bg-red-100 text-red-800 border-red-200',\n },\n}\n\n/**\n * size -> class 매핑\n */\nconst SIZE_PRESETS: Record<SizeType, { class: string }> = {\n xs: { \n class: 'h-3.5 px-0.5 text-[10px] min-w-[14px]',\n },\n sm: { \n class: 'h-4 px-1 text-xs min-w-[16px]',\n },\n md: { \n class: 'h-5 px-1.5 text-xs',\n },\n lg: { \n class: 'h-6 px-2 text-sm',\n },\n}\n\n/** 최종 바인딩: styletype과 size를 병합하여 최종 클래스 생성 */\nconst mapped = computed(() => {\n const stylePreset = STYLE_PRESETS[props.styletype!]\n const sizePreset = SIZE_PRESETS[props.size!]\n const finalClass = [stylePreset.class, sizePreset.class, props.class].filter(Boolean).join(' ')\n \n return {\n class: finalClass,\n }\n})\n</script>\n\n<template>\n <Kbd v-bind=\"mapped\">\n <slot />\n </Kbd>\n</template>\n"],"names":["props","__props","STYLE_PRESETS","SIZE_PRESETS","mapped","computed","stylePreset","sizePreset","_openBlock","_createBlock","Kbd","_renderSlot","_ctx"],"mappings":"qRAaA,MAAMA,EAAQC,EAiBRC,EAAsD,CAC1D,QAAS,CAAE,MAAO,EAAA,EAClB,QAAS,CACP,MAAO,2CAAA,EAET,QAAS,CACP,MAAO,8CAAA,EAET,QAAS,CACP,MAAO,8CAAA,EAET,OAAQ,CACN,MAAO,wCAAA,CACT,EAMIC,EAAoD,CACxD,GAAI,CACF,MAAO,uCAAA,EAET,GAAI,CACF,MAAO,+BAAA,EAET,GAAI,CACF,MAAO,oBAAA,EAET,GAAI,CACF,MAAO,kBAAA,CACT,EAIIC,EAASC,EAAAA,SAAS,IAAM,CAC5B,MAAMC,EAAcJ,EAAcF,EAAM,SAAU,EAC5CO,EAAaJ,EAAaH,EAAM,IAAK,EAG3C,MAAO,CACL,MAHiB,CAACM,EAAY,MAAOC,EAAW,MAAOP,EAAM,KAAK,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,CAGrF,CAEX,CAAC,gBAICQ,EAAAA,UAAA,EAAAC,EAAAA,YAEMC,EAAAA,8CAFON,EAAA,KAAM,CAAA,EAAA,mBACjB,IAAQ,CAARO,aAAQC,EAAA,OAAA,SAAA,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"JKbd.vue.js","sources":["../../../../src/components/atoms/JKbd.vue"],"sourcesContent":["<script setup lang=\"ts\">\r\nimport { computed } from 'vue'\r\nimport Kbd from '@/components/shadcn/Kbd.vue'\r\n\r\ntype StyleType =\r\n | 'default' // 기본 스타일\r\n | 'primary' // 강조 스타일 (파랑)\r\n | 'success' // 성공 스타일 (초록)\r\n | 'warning' // 경고 스타일 (주황)\r\n | 'danger' // 위험 스타일 (빨강)\r\n\r\ntype SizeType = 'xs' | 'sm' | 'md' | 'lg'\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n class?: string\r\n /** 스타일 프리셋 */\r\n styletype?: StyleType\r\n /** 키보드 키 크기 */\r\n size?: SizeType\r\n }>(),\r\n {\n styletype: 'default',\n size: 'sm',\n },\n)\r\n\r\n/**\r\n * styletype -> class 매핑\r\n */\r\nconst STYLE_PRESETS: Record<StyleType, { class: string }> = {\r\n default: { class: '' },\r\n primary: { \r\n class: 'bg-blue-100 text-blue-800 border-blue-200',\r\n },\r\n success: { \r\n class: 'bg-green-100 text-green-800 border-green-200',\r\n },\r\n warning: { \r\n class: 'bg-amber-100 text-amber-800 border-amber-200',\r\n },\r\n danger: { \r\n class: 'bg-red-100 text-red-800 border-red-200',\r\n },\r\n}\r\n\r\n/**\r\n * size -> class 매핑\r\n */\r\nconst SIZE_PRESETS: Record<SizeType, { class: string }> = {\n xs: { \n class: 'h-3.5 px-0.5 text-[10px] min-w-[14px]',\n },\n sm: { \n class: 'h-4 px-1 text-xs min-w-[16px]',\n },\n md: { \n class: 'h-5 px-1.5 text-xs',\n },\n lg: { \n class: 'h-6 px-2 text-sm',\n },\n}\n\r\n/** 최종 바인딩: styletype과 size를 병합하여 최종 클래스 생성 */\r\nconst mapped = computed(() => {\r\n const stylePreset = STYLE_PRESETS[props.styletype!]\r\n const sizePreset = SIZE_PRESETS[props.size!]\r\n const finalClass = [stylePreset.class, sizePreset.class, props.class].filter(Boolean).join(' ')\r\n \r\n return {\r\n class: finalClass,\r\n }\r\n})\r\n</script>\r\n\r\n<template>\r\n <Kbd v-bind=\"mapped\">\r\n <slot />\r\n </Kbd>\r\n</template>\r\n"],"names":["props","__props","STYLE_PRESETS","SIZE_PRESETS","mapped","computed","stylePreset","sizePreset","_openBlock","_createBlock","Kbd","_renderSlot","_ctx"],"mappings":";;;;;;;;;;AAaA,UAAMA,IAAQC,GAiBRC,IAAsD;AAAA,MAC1D,SAAS,EAAE,OAAO,GAAA;AAAA,MAClB,SAAS;AAAA,QACP,OAAO;AAAA,MAAA;AAAA,MAET,SAAS;AAAA,QACP,OAAO;AAAA,MAAA;AAAA,MAET,SAAS;AAAA,QACP,OAAO;AAAA,MAAA;AAAA,MAET,QAAQ;AAAA,QACN,OAAO;AAAA,MAAA;AAAA,IACT,GAMIC,IAAoD;AAAA,MACxD,IAAI;AAAA,QACF,OAAO;AAAA,MAAA;AAAA,MAET,IAAI;AAAA,QACF,OAAO;AAAA,MAAA;AAAA,MAET,IAAI;AAAA,QACF,OAAO;AAAA,MAAA;AAAA,MAET,IAAI;AAAA,QACF,OAAO;AAAA,MAAA;AAAA,IACT,GAIIC,IAASC,EAAS,MAAM;AAC5B,YAAMC,IAAcJ,EAAcF,EAAM,SAAU,GAC5CO,IAAaJ,EAAaH,EAAM,IAAK;AAG3C,aAAO;AAAA,QACL,OAHiB,CAACM,EAAY,OAAOC,EAAW,OAAOP,EAAM,KAAK,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAAA,MAGrF;AAAA,IAEX,CAAC;sBAICQ,EAAA,GAAAC,EAEMC,OAFON,EAAA,KAAM,CAAA,GAAA;AAAA,iBACjB,MAAQ;AAAA,QAARO,EAAQC,EAAA,QAAA,SAAA;AAAA,MAAA;;;;;"}
1
+ {"version":3,"file":"JKbd.vue.js","sources":["../../../../src/components/atoms/JKbd.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport Kbd from '@/components/shadcn/Kbd.vue'\n\ntype StyleType =\n | 'default' // 기본 스타일\n | 'primary' // 강조 스타일 (파랑)\n | 'success' // 성공 스타일 (초록)\n | 'warning' // 경고 스타일 (주황)\n | 'danger' // 위험 스타일 (빨강)\n\ntype SizeType = 'xs' | 'sm' | 'md' | 'lg'\n\nconst props = withDefaults(\n defineProps<{\n class?: string\n /** 스타일 프리셋 */\n styletype?: StyleType\n /** 키보드 키 크기 */\n size?: SizeType\n }>(),\n {\n styletype: 'default',\n size: 'sm',\n },\n)\n\n/**\n * styletype -> class 매핑\n */\nconst STYLE_PRESETS: Record<StyleType, { class: string }> = {\n default: { class: '' },\n primary: { \n class: 'bg-blue-100 text-blue-800 border-blue-200',\n },\n success: { \n class: 'bg-green-100 text-green-800 border-green-200',\n },\n warning: { \n class: 'bg-amber-100 text-amber-800 border-amber-200',\n },\n danger: { \n class: 'bg-red-100 text-red-800 border-red-200',\n },\n}\n\n/**\n * size -> class 매핑\n */\nconst SIZE_PRESETS: Record<SizeType, { class: string }> = {\n xs: { \n class: 'h-3.5 px-0.5 text-[10px] min-w-[14px]',\n },\n sm: { \n class: 'h-4 px-1 text-xs min-w-[16px]',\n },\n md: { \n class: 'h-5 px-1.5 text-xs',\n },\n lg: { \n class: 'h-6 px-2 text-sm',\n },\n}\n\n/** 최종 바인딩: styletype과 size를 병합하여 최종 클래스 생성 */\nconst mapped = computed(() => {\n const stylePreset = STYLE_PRESETS[props.styletype!]\n const sizePreset = SIZE_PRESETS[props.size!]\n const finalClass = [stylePreset.class, sizePreset.class, props.class].filter(Boolean).join(' ')\n \n return {\n class: finalClass,\n }\n})\n</script>\n\n<template>\n <Kbd v-bind=\"mapped\">\n <slot />\n </Kbd>\n</template>\n"],"names":["props","__props","STYLE_PRESETS","SIZE_PRESETS","mapped","computed","stylePreset","sizePreset","_openBlock","_createBlock","Kbd","_renderSlot","_ctx"],"mappings":";;;;;;;;;;AAaA,UAAMA,IAAQC,GAiBRC,IAAsD;AAAA,MAC1D,SAAS,EAAE,OAAO,GAAA;AAAA,MAClB,SAAS;AAAA,QACP,OAAO;AAAA,MAAA;AAAA,MAET,SAAS;AAAA,QACP,OAAO;AAAA,MAAA;AAAA,MAET,SAAS;AAAA,QACP,OAAO;AAAA,MAAA;AAAA,MAET,QAAQ;AAAA,QACN,OAAO;AAAA,MAAA;AAAA,IACT,GAMIC,IAAoD;AAAA,MACxD,IAAI;AAAA,QACF,OAAO;AAAA,MAAA;AAAA,MAET,IAAI;AAAA,QACF,OAAO;AAAA,MAAA;AAAA,MAET,IAAI;AAAA,QACF,OAAO;AAAA,MAAA;AAAA,MAET,IAAI;AAAA,QACF,OAAO;AAAA,MAAA;AAAA,IACT,GAIIC,IAASC,EAAS,MAAM;AAC5B,YAAMC,IAAcJ,EAAcF,EAAM,SAAU,GAC5CO,IAAaJ,EAAaH,EAAM,IAAK;AAG3C,aAAO;AAAA,QACL,OAHiB,CAACM,EAAY,OAAOC,EAAW,OAAOP,EAAM,KAAK,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAAA,MAGrF;AAAA,IAEX,CAAC;sBAICQ,EAAA,GAAAC,EAEMC,OAFON,EAAA,KAAM,CAAA,GAAA;AAAA,iBACjB,MAAQ;AAAA,QAARO,EAAQC,EAAA,QAAA,SAAA;AAAA,MAAA;;;;;"}
@@ -3,5 +3,5 @@
3
3
  for (const [t_key, t_val] of t_opts)
4
4
  t_merged[t_key] = t_val;
5
5
  return t_merged;
6
- };,u=t(e.default,[["__scopeId","data-v-0ce9f9f8"]]);exports.default=u;
6
+ };,u=t(e.default,[["__scopeId","data-v-d2791ee0"]]);exports.default=u;
7
7
  //# sourceMappingURL=JPreview.vue.cjs.map
@@ -1,13 +1,13 @@
1
1
  import o from "./JPreview.vue2.js";
2
2
  /* empty css */
3
- const r = (r_comp, r_opts) => {
4
- const r_merged = r_comp.__vccOpts || r_comp;
5
- for (const [r_key, r_val] of r_opts)
6
- r_merged[r_key] = r_val;
7
- return r_merged;
3
+ const e = (e_comp, e_opts) => {
4
+ const e_merged = e_comp.__vccOpts || e_comp;
5
+ for (const [e_key, e_val] of e_opts)
6
+ e_merged[e_key] = e_val;
7
+ return e_merged;
8
8
  };
9
- const m = /* @__PURE__ */ r(o, [["__scopeId", "data-v-0ce9f9f8"]]);
9
+ const p = /* @__PURE__ */ e(o, [["__scopeId", "data-v-d2791ee0"]]);
10
10
  export {
11
- m as default
11
+ p as default
12
12
  };
13
13
  //# sourceMappingURL=JPreview.vue.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"JPreview.vue2.cjs","sources":["../../../../src/components/atoms/JPreview.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ref, computed, onMounted, onUnmounted } from 'vue'\nimport { MdPreview } from 'md-editor-v3'\nimport 'md-editor-v3/lib/style.css'\nimport DOMPurify from 'dompurify'\n\nconst props = withDefaults(\n defineProps<{\n /** 마크다운 또는 HTML 내용 */\n modelValue?: string\n /** 테마 (light/dark) - 설정하지 않으면 자동으로 다크모드 감지 */\n theme?: 'light' | 'dark'\n /** 추가 CSS 클래스 */\n class?: string\n }>(),\n {\n modelValue: '',\n },\n)\n\n// 다크모드 상태\nconst isDarkMode = ref(false)\n\n// 다크모드 감지 함수\nconst detectDarkMode = () => {\n isDarkMode.value = document.documentElement.classList.contains('dark')\n}\n\n// 현재 테마 계산 (props.theme이 있으면 그것 사용, 없으면 자동 감지)\nconst currentTheme = computed(() => {\n if (props.theme) {\n return props.theme\n }\n return isDarkMode.value ? 'dark' : 'light'\n})\n\n// MutationObserver로 다크모드 변경 감지\nlet darkModeObserver: MutationObserver | null = null\n\nonMounted(() => {\n // 초기 다크모드 상태 감지\n detectDarkMode()\n \n // MutationObserver로 class 변경 감지\n darkModeObserver = new MutationObserver(() => {\n detectDarkMode()\n })\n \n darkModeObserver.observe(document.documentElement, {\n attributes: true,\n attributeFilter: ['class'],\n })\n})\n\nonUnmounted(() => {\n if (darkModeObserver) {\n darkModeObserver.disconnect()\n }\n})\n\r\n/**\r\n * 콘텐츠 타입 자동 감지\r\n */\r\nfunction detectContentType(content: string): 'markdown' | 'html' {\r\n const trimmed = content.trim()\r\n \r\n // HTML 문서 시작 태그 확인\r\n if (\r\n trimmed.startsWith('<!DOCTYPE html') ||\r\n trimmed.startsWith('<!doctype html') ||\r\n trimmed.startsWith('<!DOCTYPE HTML') ||\r\n trimmed.startsWith('<!DOCTYPE Html') ||\r\n trimmed.startsWith('<html') ||\r\n trimmed.startsWith('<HTML') ||\r\n trimmed.startsWith('<Html')\r\n ) {\r\n return 'html'\r\n }\r\n \r\n return 'markdown'\r\n}\r\n\r\nconst contentType = computed(() => detectContentType(props.modelValue || ''))\r\n\r\nconst sanitizedHtml = computed(() => {\r\n if (contentType.value === 'html') {\r\n return DOMPurify.sanitize(props.modelValue || '', {\r\n ALLOWED_TAGS: [\r\n 'p', 'br', 'strong', 'em', 'u', 's', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6',\r\n 'ul', 'ol', 'li', 'blockquote', 'pre', 'code', 'a', 'img', 'table', 'thead',\r\n 'tbody', 'tr', 'th', 'td', 'div', 'span', 'hr', 'blockquote', 'del', 'ins',\r\n 'sub', 'sup', 'kbd', 'mark', 'abbr', 'dfn', 'cite', 'q', 'samp', 'var',\r\n 'time', 'b', 'i', 'small', 'big', 'center', 'font', 'strike', 'tt',\r\n 'html', 'head', 'body', 'title', 'meta', 'link', 'style', 'script', 'noscript'\r\n ],\r\n ALLOWED_ATTR: [\r\n 'href', 'src', 'alt', 'title', 'width', 'height', 'class', 'id', 'style',\r\n 'target', 'rel', 'type', 'charset', 'name', 'content', 'http-equiv', 'lang'\r\n ],\r\n ALLOW_DATA_ATTR: false,\r\n })\r\n }\r\n return ''\r\n})\r\n</script>\r\n\r\n<template>\n <div :class=\"['j-preview-wrapper', props.class]\">\n <!-- HTML 렌더링 -->\n <div\n v-if=\"contentType === 'html'\"\n :class=\"['j-preview-html', currentTheme === 'dark' ? 'dark' : '']\"\n v-html=\"sanitizedHtml\"\n />\n \n <!-- 마크다운 렌더링 -->\n <MdPreview\n v-else\n :model-value=\"modelValue\"\n :theme=\"currentTheme\"\n :preview-class-name=\"'j-preview-markdown'\"\n language=\"en-US\"\n />\n </div>\n</template>\n\r\n<style scoped>\r\n.j-preview-wrapper {\r\n @apply w-full;\r\n}\r\n\r\n.j-preview-html {\r\n @apply prose prose-slate max-w-none;\r\n}\r\n\r\n.j-preview-html.dark {\r\n @apply prose-invert;\r\n}\r\n\r\n:deep(.j-preview-markdown) {\r\n @apply w-full;\r\n}\r\n</style>\r\n"],"names":["props","__props","isDarkMode","ref","detectDarkMode","currentTheme","computed","darkModeObserver","onMounted","onUnmounted","detectContentType","content","trimmed","contentType","sanitizedHtml","DOMPurify","_createElementBlock","_normalizeClass","_createBlock","_unref","MdPreview"],"mappings":"4aAMA,MAAMA,EAAQC,EAeRC,EAAaC,EAAAA,IAAI,EAAK,EAGtBC,EAAiB,IAAM,CAC3BF,EAAW,MAAQ,SAAS,gBAAgB,UAAU,SAAS,MAAM,CACvE,EAGMG,EAAeC,EAAAA,SAAS,IACxBN,EAAM,MACDA,EAAM,MAERE,EAAW,MAAQ,OAAS,OACpC,EAGD,IAAIK,EAA4C,KAEhDC,EAAAA,UAAU,IAAM,CAEdJ,EAAA,EAGAG,EAAmB,IAAI,iBAAiB,IAAM,CAC5CH,EAAA,CACF,CAAC,EAEDG,EAAiB,QAAQ,SAAS,gBAAiB,CACjD,WAAY,GACZ,gBAAiB,CAAC,OAAO,CAAA,CAC1B,CACH,CAAC,EAEDE,EAAAA,YAAY,IAAM,CACZF,GACFA,EAAiB,WAAA,CAErB,CAAC,EAKD,SAASG,EAAkBC,EAAsC,CAC/D,MAAMC,EAAUD,EAAQ,KAAA,EAGxB,OACEC,EAAQ,WAAW,gBAAgB,GACnCA,EAAQ,WAAW,gBAAgB,GACnCA,EAAQ,WAAW,gBAAgB,GACnCA,EAAQ,WAAW,gBAAgB,GACnCA,EAAQ,WAAW,OAAO,GAC1BA,EAAQ,WAAW,OAAO,GAC1BA,EAAQ,WAAW,OAAO,EAEnB,OAGF,UACT,CAEA,MAAMC,EAAcP,EAAAA,SAAS,IAAMI,EAAkBV,EAAM,YAAc,EAAE,CAAC,EAEtEc,EAAgBR,EAAAA,SAAS,IACzBO,EAAY,QAAU,OACjBE,EAAU,SAASf,EAAM,YAAc,GAAI,CAChD,aAAc,CACZ,IAAK,KAAM,SAAU,KAAM,IAAK,IAAK,KAAM,KAAM,KAAM,KAAM,KAAM,KACnE,KAAM,KAAM,KAAM,aAAc,MAAO,OAAQ,IAAK,MAAO,QAAS,QACpE,QAAS,KAAM,KAAM,KAAM,MAAO,OAAQ,KAAM,aAAc,MAAO,MACrE,MAAO,MAAO,MAAO,OAAQ,OAAQ,MAAO,OAAQ,IAAK,OAAQ,MACjE,OAAQ,IAAK,IAAK,QAAS,MAAO,SAAU,OAAQ,SAAU,KAC9D,OAAQ,OAAQ,OAAQ,QAAS,OAAQ,OAAQ,QAAS,SAAU,UAAA,EAEtE,aAAc,CACZ,OAAQ,MAAO,MAAO,QAAS,QAAS,SAAU,QAAS,KAAM,QACjE,SAAU,MAAO,OAAQ,UAAW,OAAQ,UAAW,aAAc,MAAA,EAEvE,gBAAiB,EAAA,CAClB,EAEI,EACR,8BAICgB,EAAAA,mBAgBM,MAAA,CAhBA,MAAKC,EAAAA,eAAA,CAAA,oBAAwBjB,EAAM,KAAK,CAAA,CAAA,GAGpCa,EAAA,QAAW,sBADnBG,EAAAA,mBAIE,MAAA,OAFC,yCAA0BX,EAAA,QAAY,OAAA,OAAA,EAAA,CAAA,EACvC,UAAQS,EAAA,KAAA,6BAIVI,EAAAA,YAMEC,QAAAC,EAAAA,SAAA,EAAA,OAJC,cAAanB,EAAA,WACb,MAAOI,EAAA,MACP,qBAAoB,qBACrB,SAAS,OAAA"}
1
+ {"version":3,"file":"JPreview.vue2.cjs","sources":["../../../../src/components/atoms/JPreview.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ref, computed, onMounted, onUnmounted } from 'vue'\nimport { MdPreview } from 'md-editor-v3'\nimport 'md-editor-v3/lib/style.css'\nimport DOMPurify from 'dompurify'\n\nconst props = withDefaults(\n defineProps<{\n /** 마크다운 또는 HTML 내용 */\n modelValue?: string\n /** 테마 (light/dark) - 설정하지 않으면 자동으로 다크모드 감지 */\n theme?: 'light' | 'dark'\n /** 추가 CSS 클래스 */\n class?: string\n }>(),\n {\n modelValue: '',\n },\n)\n\n// 다크모드 상태\nconst isDarkMode = ref(false)\n\n// 다크모드 감지 함수\nconst detectDarkMode = () => {\n isDarkMode.value = document.documentElement.classList.contains('dark')\n}\n\n// 현재 테마 계산 (props.theme이 있으면 그것 사용, 없으면 자동 감지)\nconst currentTheme = computed(() => {\n if (props.theme) {\n return props.theme\n }\n return isDarkMode.value ? 'dark' : 'light'\n})\n\n// MutationObserver로 다크모드 변경 감지\nlet darkModeObserver: MutationObserver | null = null\n\nonMounted(() => {\n // 초기 다크모드 상태 감지\n detectDarkMode()\n \n // MutationObserver로 class 변경 감지\n darkModeObserver = new MutationObserver(() => {\n detectDarkMode()\n })\n \n darkModeObserver.observe(document.documentElement, {\n attributes: true,\n attributeFilter: ['class'],\n })\n})\n\nonUnmounted(() => {\n if (darkModeObserver) {\n darkModeObserver.disconnect()\n }\n})\n\n/**\n * 콘텐츠 타입 자동 감지\n */\nfunction detectContentType(content: string): 'markdown' | 'html' {\n const trimmed = content.trim()\n \n // HTML 문서 시작 태그 확인\n if (\n trimmed.startsWith('<!DOCTYPE html') ||\n trimmed.startsWith('<!doctype html') ||\n trimmed.startsWith('<!DOCTYPE HTML') ||\n trimmed.startsWith('<!DOCTYPE Html') ||\n trimmed.startsWith('<html') ||\n trimmed.startsWith('<HTML') ||\n trimmed.startsWith('<Html')\n ) {\n return 'html'\n }\n \n return 'markdown'\n}\n\nconst contentType = computed(() => detectContentType(props.modelValue || ''))\n\nconst sanitizedHtml = computed(() => {\n if (contentType.value === 'html') {\n return DOMPurify.sanitize(props.modelValue || '', {\n ALLOWED_TAGS: [\n 'p', 'br', 'strong', 'em', 'u', 's', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6',\n 'ul', 'ol', 'li', 'blockquote', 'pre', 'code', 'a', 'img', 'table', 'thead',\n 'tbody', 'tr', 'th', 'td', 'div', 'span', 'hr', 'blockquote', 'del', 'ins',\n 'sub', 'sup', 'kbd', 'mark', 'abbr', 'dfn', 'cite', 'q', 'samp', 'var',\n 'time', 'b', 'i', 'small', 'big', 'center', 'font', 'strike', 'tt',\n 'html', 'head', 'body', 'title', 'meta', 'link', 'style', 'script', 'noscript'\n ],\n ALLOWED_ATTR: [\n 'href', 'src', 'alt', 'title', 'width', 'height', 'class', 'id', 'style',\n 'target', 'rel', 'type', 'charset', 'name', 'content', 'http-equiv', 'lang'\n ],\n ALLOW_DATA_ATTR: false,\n })\n }\n return ''\n})\n</script>\n\n<template>\n <div :class=\"['j-preview-wrapper', props.class]\">\n <!-- HTML 렌더링 -->\n <div\n v-if=\"contentType === 'html'\"\n :class=\"['j-preview-html', currentTheme === 'dark' ? 'dark' : '']\"\n v-html=\"sanitizedHtml\"\n />\n \n <!-- 마크다운 렌더링 -->\n <MdPreview\n v-else\n :model-value=\"modelValue\"\n :theme=\"currentTheme\"\n :preview-class-name=\"'j-preview-markdown'\"\n language=\"en-US\"\n />\n </div>\n</template>\n\n<style scoped>\n.j-preview-wrapper {\n @apply w-full;\n}\n\n.j-preview-html {\n @apply prose prose-slate max-w-none;\n}\n\n.j-preview-html.dark {\n @apply prose-invert;\n}\n\n:deep(.j-preview-markdown) {\n @apply w-full;\n}\n</style>\n"],"names":["props","__props","isDarkMode","ref","detectDarkMode","currentTheme","computed","darkModeObserver","onMounted","onUnmounted","detectContentType","content","trimmed","contentType","sanitizedHtml","DOMPurify","_createElementBlock","_normalizeClass","_createBlock","_unref","MdPreview"],"mappings":"4aAMA,MAAMA,EAAQC,EAeRC,EAAaC,EAAAA,IAAI,EAAK,EAGtBC,EAAiB,IAAM,CAC3BF,EAAW,MAAQ,SAAS,gBAAgB,UAAU,SAAS,MAAM,CACvE,EAGMG,EAAeC,EAAAA,SAAS,IACxBN,EAAM,MACDA,EAAM,MAERE,EAAW,MAAQ,OAAS,OACpC,EAGD,IAAIK,EAA4C,KAEhDC,EAAAA,UAAU,IAAM,CAEdJ,EAAA,EAGAG,EAAmB,IAAI,iBAAiB,IAAM,CAC5CH,EAAA,CACF,CAAC,EAEDG,EAAiB,QAAQ,SAAS,gBAAiB,CACjD,WAAY,GACZ,gBAAiB,CAAC,OAAO,CAAA,CAC1B,CACH,CAAC,EAEDE,EAAAA,YAAY,IAAM,CACZF,GACFA,EAAiB,WAAA,CAErB,CAAC,EAKD,SAASG,EAAkBC,EAAsC,CAC/D,MAAMC,EAAUD,EAAQ,KAAA,EAGxB,OACEC,EAAQ,WAAW,gBAAgB,GACnCA,EAAQ,WAAW,gBAAgB,GACnCA,EAAQ,WAAW,gBAAgB,GACnCA,EAAQ,WAAW,gBAAgB,GACnCA,EAAQ,WAAW,OAAO,GAC1BA,EAAQ,WAAW,OAAO,GAC1BA,EAAQ,WAAW,OAAO,EAEnB,OAGF,UACT,CAEA,MAAMC,EAAcP,EAAAA,SAAS,IAAMI,EAAkBV,EAAM,YAAc,EAAE,CAAC,EAEtEc,EAAgBR,EAAAA,SAAS,IACzBO,EAAY,QAAU,OACjBE,EAAU,SAASf,EAAM,YAAc,GAAI,CAChD,aAAc,CACZ,IAAK,KAAM,SAAU,KAAM,IAAK,IAAK,KAAM,KAAM,KAAM,KAAM,KAAM,KACnE,KAAM,KAAM,KAAM,aAAc,MAAO,OAAQ,IAAK,MAAO,QAAS,QACpE,QAAS,KAAM,KAAM,KAAM,MAAO,OAAQ,KAAM,aAAc,MAAO,MACrE,MAAO,MAAO,MAAO,OAAQ,OAAQ,MAAO,OAAQ,IAAK,OAAQ,MACjE,OAAQ,IAAK,IAAK,QAAS,MAAO,SAAU,OAAQ,SAAU,KAC9D,OAAQ,OAAQ,OAAQ,QAAS,OAAQ,OAAQ,QAAS,SAAU,UAAA,EAEtE,aAAc,CACZ,OAAQ,MAAO,MAAO,QAAS,QAAS,SAAU,QAAS,KAAM,QACjE,SAAU,MAAO,OAAQ,UAAW,OAAQ,UAAW,aAAc,MAAA,EAEvE,gBAAiB,EAAA,CAClB,EAEI,EACR,8BAICgB,EAAAA,mBAgBM,MAAA,CAhBA,MAAKC,EAAAA,eAAA,CAAA,oBAAwBjB,EAAM,KAAK,CAAA,CAAA,GAGpCa,EAAA,QAAW,sBADnBG,EAAAA,mBAIE,MAAA,OAFC,yCAA0BX,EAAA,QAAY,OAAA,OAAA,EAAA,CAAA,EACvC,UAAQS,EAAA,KAAA,6BAIVI,EAAAA,YAMEC,QAAAC,EAAAA,SAAA,EAAA,OAJC,cAAanB,EAAA,WACb,MAAOI,EAAA,MACP,qBAAoB,qBACrB,SAAS,OAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"JPreview.vue2.js","sources":["../../../../src/components/atoms/JPreview.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ref, computed, onMounted, onUnmounted } from 'vue'\nimport { MdPreview } from 'md-editor-v3'\nimport 'md-editor-v3/lib/style.css'\nimport DOMPurify from 'dompurify'\n\nconst props = withDefaults(\n defineProps<{\n /** 마크다운 또는 HTML 내용 */\n modelValue?: string\n /** 테마 (light/dark) - 설정하지 않으면 자동으로 다크모드 감지 */\n theme?: 'light' | 'dark'\n /** 추가 CSS 클래스 */\n class?: string\n }>(),\n {\n modelValue: '',\n },\n)\n\n// 다크모드 상태\nconst isDarkMode = ref(false)\n\n// 다크모드 감지 함수\nconst detectDarkMode = () => {\n isDarkMode.value = document.documentElement.classList.contains('dark')\n}\n\n// 현재 테마 계산 (props.theme이 있으면 그것 사용, 없으면 자동 감지)\nconst currentTheme = computed(() => {\n if (props.theme) {\n return props.theme\n }\n return isDarkMode.value ? 'dark' : 'light'\n})\n\n// MutationObserver로 다크모드 변경 감지\nlet darkModeObserver: MutationObserver | null = null\n\nonMounted(() => {\n // 초기 다크모드 상태 감지\n detectDarkMode()\n \n // MutationObserver로 class 변경 감지\n darkModeObserver = new MutationObserver(() => {\n detectDarkMode()\n })\n \n darkModeObserver.observe(document.documentElement, {\n attributes: true,\n attributeFilter: ['class'],\n })\n})\n\nonUnmounted(() => {\n if (darkModeObserver) {\n darkModeObserver.disconnect()\n }\n})\n\r\n/**\r\n * 콘텐츠 타입 자동 감지\r\n */\r\nfunction detectContentType(content: string): 'markdown' | 'html' {\r\n const trimmed = content.trim()\r\n \r\n // HTML 문서 시작 태그 확인\r\n if (\r\n trimmed.startsWith('<!DOCTYPE html') ||\r\n trimmed.startsWith('<!doctype html') ||\r\n trimmed.startsWith('<!DOCTYPE HTML') ||\r\n trimmed.startsWith('<!DOCTYPE Html') ||\r\n trimmed.startsWith('<html') ||\r\n trimmed.startsWith('<HTML') ||\r\n trimmed.startsWith('<Html')\r\n ) {\r\n return 'html'\r\n }\r\n \r\n return 'markdown'\r\n}\r\n\r\nconst contentType = computed(() => detectContentType(props.modelValue || ''))\r\n\r\nconst sanitizedHtml = computed(() => {\r\n if (contentType.value === 'html') {\r\n return DOMPurify.sanitize(props.modelValue || '', {\r\n ALLOWED_TAGS: [\r\n 'p', 'br', 'strong', 'em', 'u', 's', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6',\r\n 'ul', 'ol', 'li', 'blockquote', 'pre', 'code', 'a', 'img', 'table', 'thead',\r\n 'tbody', 'tr', 'th', 'td', 'div', 'span', 'hr', 'blockquote', 'del', 'ins',\r\n 'sub', 'sup', 'kbd', 'mark', 'abbr', 'dfn', 'cite', 'q', 'samp', 'var',\r\n 'time', 'b', 'i', 'small', 'big', 'center', 'font', 'strike', 'tt',\r\n 'html', 'head', 'body', 'title', 'meta', 'link', 'style', 'script', 'noscript'\r\n ],\r\n ALLOWED_ATTR: [\r\n 'href', 'src', 'alt', 'title', 'width', 'height', 'class', 'id', 'style',\r\n 'target', 'rel', 'type', 'charset', 'name', 'content', 'http-equiv', 'lang'\r\n ],\r\n ALLOW_DATA_ATTR: false,\r\n })\r\n }\r\n return ''\r\n})\r\n</script>\r\n\r\n<template>\n <div :class=\"['j-preview-wrapper', props.class]\">\n <!-- HTML 렌더링 -->\n <div\n v-if=\"contentType === 'html'\"\n :class=\"['j-preview-html', currentTheme === 'dark' ? 'dark' : '']\"\n v-html=\"sanitizedHtml\"\n />\n \n <!-- 마크다운 렌더링 -->\n <MdPreview\n v-else\n :model-value=\"modelValue\"\n :theme=\"currentTheme\"\n :preview-class-name=\"'j-preview-markdown'\"\n language=\"en-US\"\n />\n </div>\n</template>\n\r\n<style scoped>\r\n.j-preview-wrapper {\r\n @apply w-full;\r\n}\r\n\r\n.j-preview-html {\r\n @apply prose prose-slate max-w-none;\r\n}\r\n\r\n.j-preview-html.dark {\r\n @apply prose-invert;\r\n}\r\n\r\n:deep(.j-preview-markdown) {\r\n @apply w-full;\r\n}\r\n</style>\r\n"],"names":["props","__props","isDarkMode","ref","detectDarkMode","currentTheme","computed","darkModeObserver","onMounted","onUnmounted","detectContentType","content","trimmed","contentType","sanitizedHtml","DOMPurify","_createElementBlock","_normalizeClass","_createBlock","_unref","MdPreview"],"mappings":"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"}
1
+ {"version":3,"file":"JPreview.vue2.js","sources":["../../../../src/components/atoms/JPreview.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ref, computed, onMounted, onUnmounted } from 'vue'\nimport { MdPreview } from 'md-editor-v3'\nimport 'md-editor-v3/lib/style.css'\nimport DOMPurify from 'dompurify'\n\nconst props = withDefaults(\n defineProps<{\n /** 마크다운 또는 HTML 내용 */\n modelValue?: string\n /** 테마 (light/dark) - 설정하지 않으면 자동으로 다크모드 감지 */\n theme?: 'light' | 'dark'\n /** 추가 CSS 클래스 */\n class?: string\n }>(),\n {\n modelValue: '',\n },\n)\n\n// 다크모드 상태\nconst isDarkMode = ref(false)\n\n// 다크모드 감지 함수\nconst detectDarkMode = () => {\n isDarkMode.value = document.documentElement.classList.contains('dark')\n}\n\n// 현재 테마 계산 (props.theme이 있으면 그것 사용, 없으면 자동 감지)\nconst currentTheme = computed(() => {\n if (props.theme) {\n return props.theme\n }\n return isDarkMode.value ? 'dark' : 'light'\n})\n\n// MutationObserver로 다크모드 변경 감지\nlet darkModeObserver: MutationObserver | null = null\n\nonMounted(() => {\n // 초기 다크모드 상태 감지\n detectDarkMode()\n \n // MutationObserver로 class 변경 감지\n darkModeObserver = new MutationObserver(() => {\n detectDarkMode()\n })\n \n darkModeObserver.observe(document.documentElement, {\n attributes: true,\n attributeFilter: ['class'],\n })\n})\n\nonUnmounted(() => {\n if (darkModeObserver) {\n darkModeObserver.disconnect()\n }\n})\n\n/**\n * 콘텐츠 타입 자동 감지\n */\nfunction detectContentType(content: string): 'markdown' | 'html' {\n const trimmed = content.trim()\n \n // HTML 문서 시작 태그 확인\n if (\n trimmed.startsWith('<!DOCTYPE html') ||\n trimmed.startsWith('<!doctype html') ||\n trimmed.startsWith('<!DOCTYPE HTML') ||\n trimmed.startsWith('<!DOCTYPE Html') ||\n trimmed.startsWith('<html') ||\n trimmed.startsWith('<HTML') ||\n trimmed.startsWith('<Html')\n ) {\n return 'html'\n }\n \n return 'markdown'\n}\n\nconst contentType = computed(() => detectContentType(props.modelValue || ''))\n\nconst sanitizedHtml = computed(() => {\n if (contentType.value === 'html') {\n return DOMPurify.sanitize(props.modelValue || '', {\n ALLOWED_TAGS: [\n 'p', 'br', 'strong', 'em', 'u', 's', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6',\n 'ul', 'ol', 'li', 'blockquote', 'pre', 'code', 'a', 'img', 'table', 'thead',\n 'tbody', 'tr', 'th', 'td', 'div', 'span', 'hr', 'blockquote', 'del', 'ins',\n 'sub', 'sup', 'kbd', 'mark', 'abbr', 'dfn', 'cite', 'q', 'samp', 'var',\n 'time', 'b', 'i', 'small', 'big', 'center', 'font', 'strike', 'tt',\n 'html', 'head', 'body', 'title', 'meta', 'link', 'style', 'script', 'noscript'\n ],\n ALLOWED_ATTR: [\n 'href', 'src', 'alt', 'title', 'width', 'height', 'class', 'id', 'style',\n 'target', 'rel', 'type', 'charset', 'name', 'content', 'http-equiv', 'lang'\n ],\n ALLOW_DATA_ATTR: false,\n })\n }\n return ''\n})\n</script>\n\n<template>\n <div :class=\"['j-preview-wrapper', props.class]\">\n <!-- HTML 렌더링 -->\n <div\n v-if=\"contentType === 'html'\"\n :class=\"['j-preview-html', currentTheme === 'dark' ? 'dark' : '']\"\n v-html=\"sanitizedHtml\"\n />\n \n <!-- 마크다운 렌더링 -->\n <MdPreview\n v-else\n :model-value=\"modelValue\"\n :theme=\"currentTheme\"\n :preview-class-name=\"'j-preview-markdown'\"\n language=\"en-US\"\n />\n </div>\n</template>\n\n<style scoped>\n.j-preview-wrapper {\n @apply w-full;\n}\n\n.j-preview-html {\n @apply prose prose-slate max-w-none;\n}\n\n.j-preview-html.dark {\n @apply prose-invert;\n}\n\n:deep(.j-preview-markdown) {\n @apply w-full;\n}\n</style>\n"],"names":["props","__props","isDarkMode","ref","detectDarkMode","currentTheme","computed","darkModeObserver","onMounted","onUnmounted","detectContentType","content","trimmed","contentType","sanitizedHtml","DOMPurify","_createElementBlock","_normalizeClass","_createBlock","_unref","MdPreview"],"mappings":";;;;;;;;;;;;AAMA,UAAMA,IAAQC,GAeRC,IAAaC,EAAI,EAAK,GAGtBC,IAAiB,MAAM;AAC3B,MAAAF,EAAW,QAAQ,SAAS,gBAAgB,UAAU,SAAS,MAAM;AAAA,IACvE,GAGMG,IAAeC,EAAS,MACxBN,EAAM,QACDA,EAAM,QAERE,EAAW,QAAQ,SAAS,OACpC;AAGD,QAAIK,IAA4C;AAEhD,IAAAC,EAAU,MAAM;AAEd,MAAAJ,EAAA,GAGAG,IAAmB,IAAI,iBAAiB,MAAM;AAC5C,QAAAH,EAAA;AAAA,MACF,CAAC,GAEDG,EAAiB,QAAQ,SAAS,iBAAiB;AAAA,QACjD,YAAY;AAAA,QACZ,iBAAiB,CAAC,OAAO;AAAA,MAAA,CAC1B;AAAA,IACH,CAAC,GAEDE,EAAY,MAAM;AAChB,MAAIF,KACFA,EAAiB,WAAA;AAAA,IAErB,CAAC;AAKD,aAASG,EAAkBC,GAAsC;AAC/D,YAAMC,IAAUD,EAAQ,KAAA;AAGxB,aACEC,EAAQ,WAAW,gBAAgB,KACnCA,EAAQ,WAAW,gBAAgB,KACnCA,EAAQ,WAAW,gBAAgB,KACnCA,EAAQ,WAAW,gBAAgB,KACnCA,EAAQ,WAAW,OAAO,KAC1BA,EAAQ,WAAW,OAAO,KAC1BA,EAAQ,WAAW,OAAO,IAEnB,SAGF;AAAA,IACT;AAEA,UAAMC,IAAcP,EAAS,MAAMI,EAAkBV,EAAM,cAAc,EAAE,CAAC,GAEtEc,IAAgBR,EAAS,MACzBO,EAAY,UAAU,SACjBE,EAAU,SAASf,EAAM,cAAc,IAAI;AAAA,MAChD,cAAc;AAAA,QACZ;AAAA,QAAK;AAAA,QAAM;AAAA,QAAU;AAAA,QAAM;AAAA,QAAK;AAAA,QAAK;AAAA,QAAM;AAAA,QAAM;AAAA,QAAM;AAAA,QAAM;AAAA,QAAM;AAAA,QACnE;AAAA,QAAM;AAAA,QAAM;AAAA,QAAM;AAAA,QAAc;AAAA,QAAO;AAAA,QAAQ;AAAA,QAAK;AAAA,QAAO;AAAA,QAAS;AAAA,QACpE;AAAA,QAAS;AAAA,QAAM;AAAA,QAAM;AAAA,QAAM;AAAA,QAAO;AAAA,QAAQ;AAAA,QAAM;AAAA,QAAc;AAAA,QAAO;AAAA,QACrE;AAAA,QAAO;AAAA,QAAO;AAAA,QAAO;AAAA,QAAQ;AAAA,QAAQ;AAAA,QAAO;AAAA,QAAQ;AAAA,QAAK;AAAA,QAAQ;AAAA,QACjE;AAAA,QAAQ;AAAA,QAAK;AAAA,QAAK;AAAA,QAAS;AAAA,QAAO;AAAA,QAAU;AAAA,QAAQ;AAAA,QAAU;AAAA,QAC9D;AAAA,QAAQ;AAAA,QAAQ;AAAA,QAAQ;AAAA,QAAS;AAAA,QAAQ;AAAA,QAAQ;AAAA,QAAS;AAAA,QAAU;AAAA,MAAA;AAAA,MAEtE,cAAc;AAAA,QACZ;AAAA,QAAQ;AAAA,QAAO;AAAA,QAAO;AAAA,QAAS;AAAA,QAAS;AAAA,QAAU;AAAA,QAAS;AAAA,QAAM;AAAA,QACjE;AAAA,QAAU;AAAA,QAAO;AAAA,QAAQ;AAAA,QAAW;AAAA,QAAQ;AAAA,QAAW;AAAA,QAAc;AAAA,MAAA;AAAA,MAEvE,iBAAiB;AAAA,IAAA,CAClB,IAEI,EACR;2BAICgB,EAgBM,OAAA;AAAA,MAhBA,OAAKC,EAAA,CAAA,qBAAwBjB,EAAM,KAAK,CAAA;AAAA,IAAA;MAGpCa,EAAA,UAAW,eADnBG,EAIE,OAAA;AAAA;QAFC,4BAA0BX,EAAA,UAAY,SAAA,SAAA,EAAA,CAAA;AAAA,QACvC,WAAQS,EAAA;AAAA,MAAA,yBAIVI,EAMEC,EAAAC,CAAA,GAAA;AAAA;QAJC,eAAanB,EAAA;AAAA,QACb,OAAOI,EAAA;AAAA,QACP,sBAAoB;AAAA,QACrB,UAAS;AAAA,MAAA;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"JProgress.vue.cjs","sources":["../../../../src/components/atoms/JProgress.vue"],"sourcesContent":["<script setup lang=\"ts\">\r\nimport { computed } from 'vue'\r\nimport Progress from '@/components/shadcn/Progress.vue'\r\n\r\ntype StyleType =\r\n | 'default' // 기본 스타일\r\n | 'primary' // 강조 스타일 (파랑)\r\n | 'success' // 성공 스타일 (초록)\r\n | 'warning' // 경고 스타일 (주황)\r\n | 'danger' // 위험 스타일 (빨강)\r\n\r\ntype SizeType = 'xs' | 'sm' | 'md' | 'lg'\n\r\ntype VariantType = 'linear' | 'circular'\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n value?: number\r\n max?: number\r\n class?: string\r\n /** 스타일 프리셋 */\r\n styletype?: StyleType\r\n /** 크기 프리셋 */\r\n size?: SizeType\r\n /** 라벨 텍스트 */\r\n label?: string\r\n /** 진행률 퍼센트 표시 여부 */\r\n showLabel?: boolean\r\n /** 설명 텍스트 */\r\n description?: string\r\n /** 프로그레스 바 모양 */\r\n variant?: VariantType\r\n /** 무한 로딩 애니메이션 여부 */\r\n indeterminate?: boolean\r\n }>(),\r\n {\n value: 0,\n max: 100,\n styletype: 'default',\n size: 'sm',\n label: '',\n showLabel: true,\n description: '',\n variant: 'linear',\n indeterminate: false,\n },\r\n)\r\n\r\n/**\r\n * styletype -> class 매핑\r\n */\r\nconst STYLE_PRESETS: Record<StyleType, { class: string }> = {\r\n default: { class: '' },\r\n primary: { \r\n class: '[&>div]:bg-blue-500',\r\n },\r\n success: { \r\n class: '[&>div]:bg-green-500',\r\n },\r\n warning: { \r\n class: '[&>div]:bg-amber-500',\r\n },\r\n danger: { \r\n class: '[&>div]:bg-red-500',\r\n },\r\n}\r\n\r\n/**\r\n * size -> class 매핑\r\n */\r\nconst SIZE_PRESETS: Record<SizeType, { class: string }> = {\n xs: { \n class: 'h-1',\n },\n sm: { \n class: 'h-2',\n },\n md: { \n class: 'h-3',\n },\n lg: { \n class: 'h-4',\n },\n}\n\r\n/**\r\n * variant -> size 매핑 (circular용)\r\n */\r\nconst CIRCULAR_SIZE_PRESETS: Record<SizeType, { size: number }> = {\n xs: { \n size: 48,\n },\n sm: { \n size: 60,\n },\n md: { \n size: 72,\n },\n lg: { \n size: 88,\n },\n}\r\n\r\n/** 진행률 퍼센트 계산 */\r\nconst percentage = computed(() => {\r\n return Math.round((props.value! / props.max!) * 100)\r\n})\r\n\r\n/** 최종 바인딩: 직접 넘긴 class가 있으면 styletype과 size 기본값과 병합 */\r\nconst mapped = computed(() => {\r\n const stylePreset = STYLE_PRESETS[props.styletype!]\r\n const sizePreset = SIZE_PRESETS[props.size!]\r\n const finalClass = [stylePreset.class, sizePreset.class, props.class].filter(Boolean).join(' ')\r\n \r\n return {\r\n modelValue: props.value,\r\n max: props.max,\r\n class: finalClass,\r\n }\r\n})\r\n\r\n/** 원형 프로그레스 바 스타일 계산 */\r\nconst circularStyle = computed(() => {\r\n const sizePreset = CIRCULAR_SIZE_PRESETS[props.size!]\r\n \r\n // 색상 추출 - linear와 동일한 색상 사용\r\n let color = '#000000' // default: 검은색 (linear의 기본 색상과 동일)\r\n if (props.styletype === 'primary') color = '#3b82f6' // blue-500\r\n else if (props.styletype === 'success') color = '#10b981' // green-500\r\n else if (props.styletype === 'warning') color = '#f59e0b' // amber-500\r\n else if (props.styletype === 'danger') color = '#ef4444' // red-500\r\n \r\n return {\r\n size: sizePreset.size,\r\n color,\r\n }\r\n})\r\n\r\n/** indeterminate 상태에서 표시할 텍스트 */\r\nconst indeterminateText = computed(() => {\r\n return props.indeterminate ? '로딩 중...' : `${percentage.value}%`\r\n})\r\n\r\n/** Linear indeterminate 색상 계산 */\r\nconst linearIndeterminateColor = computed(() => {\r\n let color = '#000000' // default: 검은색\r\n if (props.styletype === 'primary') color = '#3b82f6' // blue-500\r\n else if (props.styletype === 'success') color = '#10b981' // green-500\r\n else if (props.styletype === 'warning') color = '#f59e0b' // amber-500\r\n else if (props.styletype === 'danger') color = '#ef4444' // red-500\r\n \r\n return color\r\n})\r\n</script>\r\n\r\n<template>\r\n <div class=\"space-y-2\">\r\n <!-- Linear Progress용 상단 라벨 -->\r\n <div v-if=\"props.variant === 'linear' && (props.label || props.showLabel || props.indeterminate)\" class=\"flex justify-between items-center\">\r\n <p v-if=\"props.label\" class=\"text-sm font-medium text-gray-700\">\r\n {{ props.label }}\r\n </p>\r\n <p v-if=\"props.showLabel || props.indeterminate\" class=\"text-sm font-medium text-gray-600\">\r\n {{ indeterminateText }}\r\n </p>\r\n </div>\r\n \r\n <!-- Circular Progress용 상단 라벨 -->\r\n <div v-if=\"props.variant === 'circular' && props.label\" class=\"text-center mb-2\">\r\n <p class=\"text-sm font-medium text-gray-700\">{{ props.label }}</p>\r\n </div>\r\n \r\n <!-- Linear Progress -->\r\n <div v-if=\"props.variant === 'linear'\">\r\n <!-- Indeterminate Linear -->\r\n <div v-if=\"props.indeterminate\" class=\"relative overflow-hidden rounded-full bg-gray-200\" :class=\"SIZE_PRESETS[props.size!].class\">\r\n <div \r\n class=\"absolute h-full w-full animate-pulse\"\r\n :style=\"{ backgroundColor: linearIndeterminateColor }\"\r\n />\r\n <div \r\n class=\"absolute h-full w-1/3 animate-[indeterminate-linear_2s_infinite]\"\r\n :style=\"{ backgroundColor: linearIndeterminateColor }\"\r\n />\r\n </div>\r\n <!-- Determinate Linear -->\r\n <Progress v-else v-bind=\"mapped\" />\r\n </div>\r\n \r\n <!-- Circular Progress -->\r\n <div v-else-if=\"props.variant === 'circular'\" class=\"flex justify-center\">\r\n <div class=\"relative\" :style=\"{ width: circularStyle.size + 'px', height: circularStyle.size + 'px' }\">\r\n <!-- Indeterminate Circular -->\r\n <div v-if=\"props.indeterminate\">\r\n <svg class=\"w-full h-full animate-spin\" viewBox=\"0 0 100 100\">\r\n <circle\r\n cx=\"50\"\r\n cy=\"50\"\r\n r=\"45\"\r\n stroke=\"#e5e7eb\"\r\n stroke-width=\"8\"\r\n fill=\"none\"\r\n />\r\n <circle\r\n cx=\"50\"\r\n cy=\"50\"\r\n r=\"45\"\r\n :stroke=\"circularStyle.color\"\r\n stroke-width=\"8\"\r\n fill=\"none\"\r\n stroke-linecap=\"round\"\r\n stroke-dasharray=\"70 213\"\r\n stroke-dashoffset=\"0\"\r\n class=\"animate-[indeterminate-circular_2s_ease-in-out_infinite]\"\r\n />\r\n </svg>\r\n </div>\r\n <!-- Determinate Circular -->\r\n <div v-else>\r\n <svg class=\"w-full h-full transform -rotate-90\" viewBox=\"0 0 100 100\">\r\n <!-- Background circle -->\r\n <circle\r\n cx=\"50\"\r\n cy=\"50\"\r\n r=\"45\"\r\n stroke=\"#e5e7eb\"\r\n stroke-width=\"8\"\r\n fill=\"none\"\r\n />\r\n <!-- Progress circle -->\r\n <circle\r\n cx=\"50\"\r\n cy=\"50\"\r\n r=\"45\"\r\n :stroke=\"circularStyle.color\"\r\n stroke-width=\"8\"\r\n fill=\"none\"\r\n stroke-linecap=\"round\"\r\n :stroke-dasharray=\"283\"\r\n :stroke-dashoffset=\"283 - (283 * percentage / 100)\"\r\n class=\"transition-all duration-300 ease-in-out\"\r\n />\r\n </svg>\r\n </div>\r\n <!-- Center text -->\r\n <div v-if=\"props.showLabel || props.indeterminate\" class=\"absolute inset-0 flex items-center justify-center\">\r\n <span class=\"text-sm font-medium text-gray-700\">{{ indeterminateText }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n \r\n <!-- Circular Progress용 하단 description -->\r\n <div v-if=\"props.variant === 'circular' && props.description\" class=\"text-center mt-2\">\r\n <p class=\"text-xs text-gray-500\">{{ props.description }}</p>\r\n </div>\r\n \r\n <!-- Linear Progress용 하단 description -->\r\n <p v-if=\"props.variant === 'linear' && props.description\" class=\"text-xs text-gray-500\">\r\n {{ props.description }}\r\n </p>\r\n </div>\r\n</template>\r\n\r\n<style>\r\n@keyframes indeterminate-linear {\r\n 0% {\r\n transform: translateX(-100%);\r\n }\r\n 100% {\r\n transform: translateX(400%);\r\n }\r\n}\r\n\r\n@keyframes indeterminate-circular {\r\n 0% {\r\n stroke-dasharray: 70 213;\r\n stroke-dashoffset: 0;\r\n }\r\n 50% {\r\n stroke-dasharray: 140 143;\r\n stroke-dashoffset: -70;\r\n }\r\n 100% {\r\n stroke-dasharray: 70 213;\r\n stroke-dashoffset: -213;\r\n }\r\n}\r\n</style>\r\n"],"names":["props","__props","STYLE_PRESETS","SIZE_PRESETS","CIRCULAR_SIZE_PRESETS","percentage","computed","mapped","stylePreset","sizePreset","finalClass","circularStyle","color","indeterminateText","linearIndeterminateColor","_openBlock","_createElementBlock","_hoisted_1","_hoisted_2","_hoisted_3","_toDisplayString","_hoisted_4","_hoisted_5","_createElementVNode","_hoisted_6","_hoisted_7","_normalizeClass","_createBlock","Progress","_hoisted_8","_hoisted_9","_hoisted_10","_hoisted_12","_hoisted_13","_hoisted_15","_hoisted_16","_hoisted_17","_hoisted_18","_hoisted_19"],"mappings":"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"}
1
+ {"version":3,"file":"JProgress.vue.cjs","sources":["../../../../src/components/atoms/JProgress.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport Progress from '@/components/shadcn/Progress.vue'\n\ntype StyleType =\n | 'default' // 기본 스타일\n | 'primary' // 강조 스타일 (파랑)\n | 'success' // 성공 스타일 (초록)\n | 'warning' // 경고 스타일 (주황)\n | 'danger' // 위험 스타일 (빨강)\n\ntype SizeType = 'xs' | 'sm' | 'md' | 'lg'\n\ntype VariantType = 'linear' | 'circular'\n\nconst props = withDefaults(\n defineProps<{\n value?: number\n max?: number\n class?: string\n /** 스타일 프리셋 */\n styletype?: StyleType\n /** 크기 프리셋 */\n size?: SizeType\n /** 라벨 텍스트 */\n label?: string\n /** 진행률 퍼센트 표시 여부 */\n showLabel?: boolean\n /** 설명 텍스트 */\n description?: string\n /** 프로그레스 바 모양 */\n variant?: VariantType\n /** 무한 로딩 애니메이션 여부 */\n indeterminate?: boolean\n }>(),\n {\n value: 0,\n max: 100,\n styletype: 'default',\n size: 'sm',\n label: '',\n showLabel: true,\n description: '',\n variant: 'linear',\n indeterminate: false,\n },\n)\n\n/**\n * styletype -> class 매핑\n */\nconst STYLE_PRESETS: Record<StyleType, { class: string }> = {\n default: { class: '' },\n primary: { \n class: '[&>div]:bg-blue-500',\n },\n success: { \n class: '[&>div]:bg-green-500',\n },\n warning: { \n class: '[&>div]:bg-amber-500',\n },\n danger: { \n class: '[&>div]:bg-red-500',\n },\n}\n\n/**\n * size -> class 매핑\n */\nconst SIZE_PRESETS: Record<SizeType, { class: string }> = {\n xs: { \n class: 'h-1',\n },\n sm: { \n class: 'h-2',\n },\n md: { \n class: 'h-3',\n },\n lg: { \n class: 'h-4',\n },\n}\n\n/**\n * variant -> size 매핑 (circular용)\n */\nconst CIRCULAR_SIZE_PRESETS: Record<SizeType, { size: number }> = {\n xs: { \n size: 48,\n },\n sm: { \n size: 60,\n },\n md: { \n size: 72,\n },\n lg: { \n size: 88,\n },\n}\n\n/** 진행률 퍼센트 계산 */\nconst percentage = computed(() => {\n return Math.round((props.value! / props.max!) * 100)\n})\n\n/** 최종 바인딩: 직접 넘긴 class가 있으면 styletype과 size 기본값과 병합 */\nconst mapped = computed(() => {\n const stylePreset = STYLE_PRESETS[props.styletype!]\n const sizePreset = SIZE_PRESETS[props.size!]\n const finalClass = [stylePreset.class, sizePreset.class, props.class].filter(Boolean).join(' ')\n \n return {\n modelValue: props.value,\n max: props.max,\n class: finalClass,\n }\n})\n\n/** 원형 프로그레스 바 스타일 계산 */\nconst circularStyle = computed(() => {\n const sizePreset = CIRCULAR_SIZE_PRESETS[props.size!]\n \n // 색상 추출 - linear와 동일한 색상 사용\n let color = '#000000' // default: 검은색 (linear의 기본 색상과 동일)\n if (props.styletype === 'primary') color = '#3b82f6' // blue-500\n else if (props.styletype === 'success') color = '#10b981' // green-500\n else if (props.styletype === 'warning') color = '#f59e0b' // amber-500\n else if (props.styletype === 'danger') color = '#ef4444' // red-500\n \n return {\n size: sizePreset.size,\n color,\n }\n})\n\n/** indeterminate 상태에서 표시할 텍스트 */\nconst indeterminateText = computed(() => {\n return props.indeterminate ? '로딩 중...' : `${percentage.value}%`\n})\n\n/** Linear indeterminate 색상 계산 */\nconst linearIndeterminateColor = computed(() => {\n let color = '#000000' // default: 검은색\n if (props.styletype === 'primary') color = '#3b82f6' // blue-500\n else if (props.styletype === 'success') color = '#10b981' // green-500\n else if (props.styletype === 'warning') color = '#f59e0b' // amber-500\n else if (props.styletype === 'danger') color = '#ef4444' // red-500\n \n return color\n})\n</script>\n\n<template>\n <div class=\"space-y-2\">\n <!-- Linear Progress용 상단 라벨 -->\n <div v-if=\"props.variant === 'linear' && (props.label || props.showLabel || props.indeterminate)\" class=\"flex justify-between items-center\">\n <p v-if=\"props.label\" class=\"text-sm font-medium text-gray-700\">\n {{ props.label }}\n </p>\n <p v-if=\"props.showLabel || props.indeterminate\" class=\"text-sm font-medium text-gray-600\">\n {{ indeterminateText }}\n </p>\n </div>\n \n <!-- Circular Progress용 상단 라벨 -->\n <div v-if=\"props.variant === 'circular' && props.label\" class=\"text-center mb-2\">\n <p class=\"text-sm font-medium text-gray-700\">{{ props.label }}</p>\n </div>\n \n <!-- Linear Progress -->\n <div v-if=\"props.variant === 'linear'\">\n <!-- Indeterminate Linear -->\n <div v-if=\"props.indeterminate\" class=\"relative overflow-hidden rounded-full bg-gray-200\" :class=\"SIZE_PRESETS[props.size!].class\">\n <div \n class=\"absolute h-full w-full animate-pulse\"\n :style=\"{ backgroundColor: linearIndeterminateColor }\"\n />\n <div \n class=\"absolute h-full w-1/3 animate-[indeterminate-linear_2s_infinite]\"\n :style=\"{ backgroundColor: linearIndeterminateColor }\"\n />\n </div>\n <!-- Determinate Linear -->\n <Progress v-else v-bind=\"mapped\" />\n </div>\n \n <!-- Circular Progress -->\n <div v-else-if=\"props.variant === 'circular'\" class=\"flex justify-center\">\n <div class=\"relative\" :style=\"{ width: circularStyle.size + 'px', height: circularStyle.size + 'px' }\">\n <!-- Indeterminate Circular -->\n <div v-if=\"props.indeterminate\">\n <svg class=\"w-full h-full animate-spin\" viewBox=\"0 0 100 100\">\n <circle\n cx=\"50\"\n cy=\"50\"\n r=\"45\"\n stroke=\"#e5e7eb\"\n stroke-width=\"8\"\n fill=\"none\"\n />\n <circle\n cx=\"50\"\n cy=\"50\"\n r=\"45\"\n :stroke=\"circularStyle.color\"\n stroke-width=\"8\"\n fill=\"none\"\n stroke-linecap=\"round\"\n stroke-dasharray=\"70 213\"\n stroke-dashoffset=\"0\"\n class=\"animate-[indeterminate-circular_2s_ease-in-out_infinite]\"\n />\n </svg>\n </div>\n <!-- Determinate Circular -->\n <div v-else>\n <svg class=\"w-full h-full transform -rotate-90\" viewBox=\"0 0 100 100\">\n <!-- Background circle -->\n <circle\n cx=\"50\"\n cy=\"50\"\n r=\"45\"\n stroke=\"#e5e7eb\"\n stroke-width=\"8\"\n fill=\"none\"\n />\n <!-- Progress circle -->\n <circle\n cx=\"50\"\n cy=\"50\"\n r=\"45\"\n :stroke=\"circularStyle.color\"\n stroke-width=\"8\"\n fill=\"none\"\n stroke-linecap=\"round\"\n :stroke-dasharray=\"283\"\n :stroke-dashoffset=\"283 - (283 * percentage / 100)\"\n class=\"transition-all duration-300 ease-in-out\"\n />\n </svg>\n </div>\n <!-- Center text -->\n <div v-if=\"props.showLabel || props.indeterminate\" class=\"absolute inset-0 flex items-center justify-center\">\n <span class=\"text-sm font-medium text-gray-700\">{{ indeterminateText }}</span>\n </div>\n </div>\n </div>\n \n <!-- Circular Progress용 하단 description -->\n <div v-if=\"props.variant === 'circular' && props.description\" class=\"text-center mt-2\">\n <p class=\"text-xs text-gray-500\">{{ props.description }}</p>\n </div>\n \n <!-- Linear Progress용 하단 description -->\n <p v-if=\"props.variant === 'linear' && props.description\" class=\"text-xs text-gray-500\">\n {{ props.description }}\n </p>\n </div>\n</template>\n\n<style>\n@keyframes indeterminate-linear {\n 0% {\n transform: translateX(-100%);\n }\n 100% {\n transform: translateX(400%);\n }\n}\n\n@keyframes indeterminate-circular {\n 0% {\n stroke-dasharray: 70 213;\n stroke-dashoffset: 0;\n }\n 50% {\n stroke-dasharray: 140 143;\n stroke-dashoffset: -70;\n }\n 100% {\n stroke-dasharray: 70 213;\n stroke-dashoffset: -213;\n }\n}\n</style>\n"],"names":["props","__props","STYLE_PRESETS","SIZE_PRESETS","CIRCULAR_SIZE_PRESETS","percentage","computed","mapped","stylePreset","sizePreset","finalClass","circularStyle","color","indeterminateText","linearIndeterminateColor","_openBlock","_createElementBlock","_hoisted_1","_hoisted_2","_hoisted_3","_toDisplayString","_hoisted_4","_hoisted_5","_createElementVNode","_hoisted_6","_hoisted_7","_normalizeClass","_createBlock","Progress","_hoisted_8","_hoisted_9","_hoisted_10","_hoisted_12","_hoisted_13","_hoisted_15","_hoisted_16","_hoisted_17","_hoisted_18","_hoisted_19"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"JProgress.vue.js","sources":["../../../../src/components/atoms/JProgress.vue"],"sourcesContent":["<script setup lang=\"ts\">\r\nimport { computed } from 'vue'\r\nimport Progress from '@/components/shadcn/Progress.vue'\r\n\r\ntype StyleType =\r\n | 'default' // 기본 스타일\r\n | 'primary' // 강조 스타일 (파랑)\r\n | 'success' // 성공 스타일 (초록)\r\n | 'warning' // 경고 스타일 (주황)\r\n | 'danger' // 위험 스타일 (빨강)\r\n\r\ntype SizeType = 'xs' | 'sm' | 'md' | 'lg'\n\r\ntype VariantType = 'linear' | 'circular'\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n value?: number\r\n max?: number\r\n class?: string\r\n /** 스타일 프리셋 */\r\n styletype?: StyleType\r\n /** 크기 프리셋 */\r\n size?: SizeType\r\n /** 라벨 텍스트 */\r\n label?: string\r\n /** 진행률 퍼센트 표시 여부 */\r\n showLabel?: boolean\r\n /** 설명 텍스트 */\r\n description?: string\r\n /** 프로그레스 바 모양 */\r\n variant?: VariantType\r\n /** 무한 로딩 애니메이션 여부 */\r\n indeterminate?: boolean\r\n }>(),\r\n {\n value: 0,\n max: 100,\n styletype: 'default',\n size: 'sm',\n label: '',\n showLabel: true,\n description: '',\n variant: 'linear',\n indeterminate: false,\n },\r\n)\r\n\r\n/**\r\n * styletype -> class 매핑\r\n */\r\nconst STYLE_PRESETS: Record<StyleType, { class: string }> = {\r\n default: { class: '' },\r\n primary: { \r\n class: '[&>div]:bg-blue-500',\r\n },\r\n success: { \r\n class: '[&>div]:bg-green-500',\r\n },\r\n warning: { \r\n class: '[&>div]:bg-amber-500',\r\n },\r\n danger: { \r\n class: '[&>div]:bg-red-500',\r\n },\r\n}\r\n\r\n/**\r\n * size -> class 매핑\r\n */\r\nconst SIZE_PRESETS: Record<SizeType, { class: string }> = {\n xs: { \n class: 'h-1',\n },\n sm: { \n class: 'h-2',\n },\n md: { \n class: 'h-3',\n },\n lg: { \n class: 'h-4',\n },\n}\n\r\n/**\r\n * variant -> size 매핑 (circular용)\r\n */\r\nconst CIRCULAR_SIZE_PRESETS: Record<SizeType, { size: number }> = {\n xs: { \n size: 48,\n },\n sm: { \n size: 60,\n },\n md: { \n size: 72,\n },\n lg: { \n size: 88,\n },\n}\r\n\r\n/** 진행률 퍼센트 계산 */\r\nconst percentage = computed(() => {\r\n return Math.round((props.value! / props.max!) * 100)\r\n})\r\n\r\n/** 최종 바인딩: 직접 넘긴 class가 있으면 styletype과 size 기본값과 병합 */\r\nconst mapped = computed(() => {\r\n const stylePreset = STYLE_PRESETS[props.styletype!]\r\n const sizePreset = SIZE_PRESETS[props.size!]\r\n const finalClass = [stylePreset.class, sizePreset.class, props.class].filter(Boolean).join(' ')\r\n \r\n return {\r\n modelValue: props.value,\r\n max: props.max,\r\n class: finalClass,\r\n }\r\n})\r\n\r\n/** 원형 프로그레스 바 스타일 계산 */\r\nconst circularStyle = computed(() => {\r\n const sizePreset = CIRCULAR_SIZE_PRESETS[props.size!]\r\n \r\n // 색상 추출 - linear와 동일한 색상 사용\r\n let color = '#000000' // default: 검은색 (linear의 기본 색상과 동일)\r\n if (props.styletype === 'primary') color = '#3b82f6' // blue-500\r\n else if (props.styletype === 'success') color = '#10b981' // green-500\r\n else if (props.styletype === 'warning') color = '#f59e0b' // amber-500\r\n else if (props.styletype === 'danger') color = '#ef4444' // red-500\r\n \r\n return {\r\n size: sizePreset.size,\r\n color,\r\n }\r\n})\r\n\r\n/** indeterminate 상태에서 표시할 텍스트 */\r\nconst indeterminateText = computed(() => {\r\n return props.indeterminate ? '로딩 중...' : `${percentage.value}%`\r\n})\r\n\r\n/** Linear indeterminate 색상 계산 */\r\nconst linearIndeterminateColor = computed(() => {\r\n let color = '#000000' // default: 검은색\r\n if (props.styletype === 'primary') color = '#3b82f6' // blue-500\r\n else if (props.styletype === 'success') color = '#10b981' // green-500\r\n else if (props.styletype === 'warning') color = '#f59e0b' // amber-500\r\n else if (props.styletype === 'danger') color = '#ef4444' // red-500\r\n \r\n return color\r\n})\r\n</script>\r\n\r\n<template>\r\n <div class=\"space-y-2\">\r\n <!-- Linear Progress용 상단 라벨 -->\r\n <div v-if=\"props.variant === 'linear' && (props.label || props.showLabel || props.indeterminate)\" class=\"flex justify-between items-center\">\r\n <p v-if=\"props.label\" class=\"text-sm font-medium text-gray-700\">\r\n {{ props.label }}\r\n </p>\r\n <p v-if=\"props.showLabel || props.indeterminate\" class=\"text-sm font-medium text-gray-600\">\r\n {{ indeterminateText }}\r\n </p>\r\n </div>\r\n \r\n <!-- Circular Progress용 상단 라벨 -->\r\n <div v-if=\"props.variant === 'circular' && props.label\" class=\"text-center mb-2\">\r\n <p class=\"text-sm font-medium text-gray-700\">{{ props.label }}</p>\r\n </div>\r\n \r\n <!-- Linear Progress -->\r\n <div v-if=\"props.variant === 'linear'\">\r\n <!-- Indeterminate Linear -->\r\n <div v-if=\"props.indeterminate\" class=\"relative overflow-hidden rounded-full bg-gray-200\" :class=\"SIZE_PRESETS[props.size!].class\">\r\n <div \r\n class=\"absolute h-full w-full animate-pulse\"\r\n :style=\"{ backgroundColor: linearIndeterminateColor }\"\r\n />\r\n <div \r\n class=\"absolute h-full w-1/3 animate-[indeterminate-linear_2s_infinite]\"\r\n :style=\"{ backgroundColor: linearIndeterminateColor }\"\r\n />\r\n </div>\r\n <!-- Determinate Linear -->\r\n <Progress v-else v-bind=\"mapped\" />\r\n </div>\r\n \r\n <!-- Circular Progress -->\r\n <div v-else-if=\"props.variant === 'circular'\" class=\"flex justify-center\">\r\n <div class=\"relative\" :style=\"{ width: circularStyle.size + 'px', height: circularStyle.size + 'px' }\">\r\n <!-- Indeterminate Circular -->\r\n <div v-if=\"props.indeterminate\">\r\n <svg class=\"w-full h-full animate-spin\" viewBox=\"0 0 100 100\">\r\n <circle\r\n cx=\"50\"\r\n cy=\"50\"\r\n r=\"45\"\r\n stroke=\"#e5e7eb\"\r\n stroke-width=\"8\"\r\n fill=\"none\"\r\n />\r\n <circle\r\n cx=\"50\"\r\n cy=\"50\"\r\n r=\"45\"\r\n :stroke=\"circularStyle.color\"\r\n stroke-width=\"8\"\r\n fill=\"none\"\r\n stroke-linecap=\"round\"\r\n stroke-dasharray=\"70 213\"\r\n stroke-dashoffset=\"0\"\r\n class=\"animate-[indeterminate-circular_2s_ease-in-out_infinite]\"\r\n />\r\n </svg>\r\n </div>\r\n <!-- Determinate Circular -->\r\n <div v-else>\r\n <svg class=\"w-full h-full transform -rotate-90\" viewBox=\"0 0 100 100\">\r\n <!-- Background circle -->\r\n <circle\r\n cx=\"50\"\r\n cy=\"50\"\r\n r=\"45\"\r\n stroke=\"#e5e7eb\"\r\n stroke-width=\"8\"\r\n fill=\"none\"\r\n />\r\n <!-- Progress circle -->\r\n <circle\r\n cx=\"50\"\r\n cy=\"50\"\r\n r=\"45\"\r\n :stroke=\"circularStyle.color\"\r\n stroke-width=\"8\"\r\n fill=\"none\"\r\n stroke-linecap=\"round\"\r\n :stroke-dasharray=\"283\"\r\n :stroke-dashoffset=\"283 - (283 * percentage / 100)\"\r\n class=\"transition-all duration-300 ease-in-out\"\r\n />\r\n </svg>\r\n </div>\r\n <!-- Center text -->\r\n <div v-if=\"props.showLabel || props.indeterminate\" class=\"absolute inset-0 flex items-center justify-center\">\r\n <span class=\"text-sm font-medium text-gray-700\">{{ indeterminateText }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n \r\n <!-- Circular Progress용 하단 description -->\r\n <div v-if=\"props.variant === 'circular' && props.description\" class=\"text-center mt-2\">\r\n <p class=\"text-xs text-gray-500\">{{ props.description }}</p>\r\n </div>\r\n \r\n <!-- Linear Progress용 하단 description -->\r\n <p v-if=\"props.variant === 'linear' && props.description\" class=\"text-xs text-gray-500\">\r\n {{ props.description }}\r\n </p>\r\n </div>\r\n</template>\r\n\r\n<style>\r\n@keyframes indeterminate-linear {\r\n 0% {\r\n transform: translateX(-100%);\r\n }\r\n 100% {\r\n transform: translateX(400%);\r\n }\r\n}\r\n\r\n@keyframes indeterminate-circular {\r\n 0% {\r\n stroke-dasharray: 70 213;\r\n stroke-dashoffset: 0;\r\n }\r\n 50% {\r\n stroke-dasharray: 140 143;\r\n stroke-dashoffset: -70;\r\n }\r\n 100% {\r\n stroke-dasharray: 70 213;\r\n stroke-dashoffset: -213;\r\n }\r\n}\r\n</style>\r\n"],"names":["props","__props","STYLE_PRESETS","SIZE_PRESETS","CIRCULAR_SIZE_PRESETS","percentage","computed","mapped","stylePreset","sizePreset","finalClass","circularStyle","color","indeterminateText","linearIndeterminateColor","_openBlock","_createElementBlock","_hoisted_1","_hoisted_2","_hoisted_3","_toDisplayString","_hoisted_4","_hoisted_5","_createElementVNode","_hoisted_6","_hoisted_7","_normalizeClass","_createBlock","Progress","_hoisted_8","_hoisted_9","_hoisted_10","_hoisted_12","_hoisted_13","_hoisted_15","_hoisted_16","_hoisted_17","_hoisted_18","_hoisted_19"],"mappings":"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"}
1
+ {"version":3,"file":"JProgress.vue.js","sources":["../../../../src/components/atoms/JProgress.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport Progress from '@/components/shadcn/Progress.vue'\n\ntype StyleType =\n | 'default' // 기본 스타일\n | 'primary' // 강조 스타일 (파랑)\n | 'success' // 성공 스타일 (초록)\n | 'warning' // 경고 스타일 (주황)\n | 'danger' // 위험 스타일 (빨강)\n\ntype SizeType = 'xs' | 'sm' | 'md' | 'lg'\n\ntype VariantType = 'linear' | 'circular'\n\nconst props = withDefaults(\n defineProps<{\n value?: number\n max?: number\n class?: string\n /** 스타일 프리셋 */\n styletype?: StyleType\n /** 크기 프리셋 */\n size?: SizeType\n /** 라벨 텍스트 */\n label?: string\n /** 진행률 퍼센트 표시 여부 */\n showLabel?: boolean\n /** 설명 텍스트 */\n description?: string\n /** 프로그레스 바 모양 */\n variant?: VariantType\n /** 무한 로딩 애니메이션 여부 */\n indeterminate?: boolean\n }>(),\n {\n value: 0,\n max: 100,\n styletype: 'default',\n size: 'sm',\n label: '',\n showLabel: true,\n description: '',\n variant: 'linear',\n indeterminate: false,\n },\n)\n\n/**\n * styletype -> class 매핑\n */\nconst STYLE_PRESETS: Record<StyleType, { class: string }> = {\n default: { class: '' },\n primary: { \n class: '[&>div]:bg-blue-500',\n },\n success: { \n class: '[&>div]:bg-green-500',\n },\n warning: { \n class: '[&>div]:bg-amber-500',\n },\n danger: { \n class: '[&>div]:bg-red-500',\n },\n}\n\n/**\n * size -> class 매핑\n */\nconst SIZE_PRESETS: Record<SizeType, { class: string }> = {\n xs: { \n class: 'h-1',\n },\n sm: { \n class: 'h-2',\n },\n md: { \n class: 'h-3',\n },\n lg: { \n class: 'h-4',\n },\n}\n\n/**\n * variant -> size 매핑 (circular용)\n */\nconst CIRCULAR_SIZE_PRESETS: Record<SizeType, { size: number }> = {\n xs: { \n size: 48,\n },\n sm: { \n size: 60,\n },\n md: { \n size: 72,\n },\n lg: { \n size: 88,\n },\n}\n\n/** 진행률 퍼센트 계산 */\nconst percentage = computed(() => {\n return Math.round((props.value! / props.max!) * 100)\n})\n\n/** 최종 바인딩: 직접 넘긴 class가 있으면 styletype과 size 기본값과 병합 */\nconst mapped = computed(() => {\n const stylePreset = STYLE_PRESETS[props.styletype!]\n const sizePreset = SIZE_PRESETS[props.size!]\n const finalClass = [stylePreset.class, sizePreset.class, props.class].filter(Boolean).join(' ')\n \n return {\n modelValue: props.value,\n max: props.max,\n class: finalClass,\n }\n})\n\n/** 원형 프로그레스 바 스타일 계산 */\nconst circularStyle = computed(() => {\n const sizePreset = CIRCULAR_SIZE_PRESETS[props.size!]\n \n // 색상 추출 - linear와 동일한 색상 사용\n let color = '#000000' // default: 검은색 (linear의 기본 색상과 동일)\n if (props.styletype === 'primary') color = '#3b82f6' // blue-500\n else if (props.styletype === 'success') color = '#10b981' // green-500\n else if (props.styletype === 'warning') color = '#f59e0b' // amber-500\n else if (props.styletype === 'danger') color = '#ef4444' // red-500\n \n return {\n size: sizePreset.size,\n color,\n }\n})\n\n/** indeterminate 상태에서 표시할 텍스트 */\nconst indeterminateText = computed(() => {\n return props.indeterminate ? '로딩 중...' : `${percentage.value}%`\n})\n\n/** Linear indeterminate 색상 계산 */\nconst linearIndeterminateColor = computed(() => {\n let color = '#000000' // default: 검은색\n if (props.styletype === 'primary') color = '#3b82f6' // blue-500\n else if (props.styletype === 'success') color = '#10b981' // green-500\n else if (props.styletype === 'warning') color = '#f59e0b' // amber-500\n else if (props.styletype === 'danger') color = '#ef4444' // red-500\n \n return color\n})\n</script>\n\n<template>\n <div class=\"space-y-2\">\n <!-- Linear Progress용 상단 라벨 -->\n <div v-if=\"props.variant === 'linear' && (props.label || props.showLabel || props.indeterminate)\" class=\"flex justify-between items-center\">\n <p v-if=\"props.label\" class=\"text-sm font-medium text-gray-700\">\n {{ props.label }}\n </p>\n <p v-if=\"props.showLabel || props.indeterminate\" class=\"text-sm font-medium text-gray-600\">\n {{ indeterminateText }}\n </p>\n </div>\n \n <!-- Circular Progress용 상단 라벨 -->\n <div v-if=\"props.variant === 'circular' && props.label\" class=\"text-center mb-2\">\n <p class=\"text-sm font-medium text-gray-700\">{{ props.label }}</p>\n </div>\n \n <!-- Linear Progress -->\n <div v-if=\"props.variant === 'linear'\">\n <!-- Indeterminate Linear -->\n <div v-if=\"props.indeterminate\" class=\"relative overflow-hidden rounded-full bg-gray-200\" :class=\"SIZE_PRESETS[props.size!].class\">\n <div \n class=\"absolute h-full w-full animate-pulse\"\n :style=\"{ backgroundColor: linearIndeterminateColor }\"\n />\n <div \n class=\"absolute h-full w-1/3 animate-[indeterminate-linear_2s_infinite]\"\n :style=\"{ backgroundColor: linearIndeterminateColor }\"\n />\n </div>\n <!-- Determinate Linear -->\n <Progress v-else v-bind=\"mapped\" />\n </div>\n \n <!-- Circular Progress -->\n <div v-else-if=\"props.variant === 'circular'\" class=\"flex justify-center\">\n <div class=\"relative\" :style=\"{ width: circularStyle.size + 'px', height: circularStyle.size + 'px' }\">\n <!-- Indeterminate Circular -->\n <div v-if=\"props.indeterminate\">\n <svg class=\"w-full h-full animate-spin\" viewBox=\"0 0 100 100\">\n <circle\n cx=\"50\"\n cy=\"50\"\n r=\"45\"\n stroke=\"#e5e7eb\"\n stroke-width=\"8\"\n fill=\"none\"\n />\n <circle\n cx=\"50\"\n cy=\"50\"\n r=\"45\"\n :stroke=\"circularStyle.color\"\n stroke-width=\"8\"\n fill=\"none\"\n stroke-linecap=\"round\"\n stroke-dasharray=\"70 213\"\n stroke-dashoffset=\"0\"\n class=\"animate-[indeterminate-circular_2s_ease-in-out_infinite]\"\n />\n </svg>\n </div>\n <!-- Determinate Circular -->\n <div v-else>\n <svg class=\"w-full h-full transform -rotate-90\" viewBox=\"0 0 100 100\">\n <!-- Background circle -->\n <circle\n cx=\"50\"\n cy=\"50\"\n r=\"45\"\n stroke=\"#e5e7eb\"\n stroke-width=\"8\"\n fill=\"none\"\n />\n <!-- Progress circle -->\n <circle\n cx=\"50\"\n cy=\"50\"\n r=\"45\"\n :stroke=\"circularStyle.color\"\n stroke-width=\"8\"\n fill=\"none\"\n stroke-linecap=\"round\"\n :stroke-dasharray=\"283\"\n :stroke-dashoffset=\"283 - (283 * percentage / 100)\"\n class=\"transition-all duration-300 ease-in-out\"\n />\n </svg>\n </div>\n <!-- Center text -->\n <div v-if=\"props.showLabel || props.indeterminate\" class=\"absolute inset-0 flex items-center justify-center\">\n <span class=\"text-sm font-medium text-gray-700\">{{ indeterminateText }}</span>\n </div>\n </div>\n </div>\n \n <!-- Circular Progress용 하단 description -->\n <div v-if=\"props.variant === 'circular' && props.description\" class=\"text-center mt-2\">\n <p class=\"text-xs text-gray-500\">{{ props.description }}</p>\n </div>\n \n <!-- Linear Progress용 하단 description -->\n <p v-if=\"props.variant === 'linear' && props.description\" class=\"text-xs text-gray-500\">\n {{ props.description }}\n </p>\n </div>\n</template>\n\n<style>\n@keyframes indeterminate-linear {\n 0% {\n transform: translateX(-100%);\n }\n 100% {\n transform: translateX(400%);\n }\n}\n\n@keyframes indeterminate-circular {\n 0% {\n stroke-dasharray: 70 213;\n stroke-dashoffset: 0;\n }\n 50% {\n stroke-dasharray: 140 143;\n stroke-dashoffset: -70;\n }\n 100% {\n stroke-dasharray: 70 213;\n stroke-dashoffset: -213;\n }\n}\n</style>\n"],"names":["props","__props","STYLE_PRESETS","SIZE_PRESETS","CIRCULAR_SIZE_PRESETS","percentage","computed","mapped","stylePreset","sizePreset","finalClass","circularStyle","color","indeterminateText","linearIndeterminateColor","_openBlock","_createElementBlock","_hoisted_1","_hoisted_2","_hoisted_3","_toDisplayString","_hoisted_4","_hoisted_5","_createElementVNode","_hoisted_6","_hoisted_7","_normalizeClass","_createBlock","Progress","_hoisted_8","_hoisted_9","_hoisted_10","_hoisted_12","_hoisted_13","_hoisted_15","_hoisted_16","_hoisted_17","_hoisted_18","_hoisted_19"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAeA,UAAMA,IAAQC,GAoCRC,IAAsD;AAAA,MAC1D,SAAS,EAAE,OAAO,GAAA;AAAA,MAClB,SAAS;AAAA,QACP,OAAO;AAAA,MAAA;AAAA,MAET,SAAS;AAAA,QACP,OAAO;AAAA,MAAA;AAAA,MAET,SAAS;AAAA,QACP,OAAO;AAAA,MAAA;AAAA,MAET,QAAQ;AAAA,QACN,OAAO;AAAA,MAAA;AAAA,IACT,GAMIC,IAAoD;AAAA,MACxD,IAAI;AAAA,QACF,OAAO;AAAA,MAAA;AAAA,MAET,IAAI;AAAA,QACF,OAAO;AAAA,MAAA;AAAA,MAET,IAAI;AAAA,QACF,OAAO;AAAA,MAAA;AAAA,MAET,IAAI;AAAA,QACF,OAAO;AAAA,MAAA;AAAA,IACT,GAMIC,IAA4D;AAAA,MAChE,IAAI;AAAA,QACF,MAAM;AAAA,MAAA;AAAA,MAER,IAAI;AAAA,QACF,MAAM;AAAA,MAAA;AAAA,MAER,IAAI;AAAA,QACF,MAAM;AAAA,MAAA;AAAA,MAER,IAAI;AAAA,QACF,MAAM;AAAA,MAAA;AAAA,IACR,GAIIC,IAAaC,EAAS,MACnB,KAAK,MAAON,EAAM,QAASA,EAAM,MAAQ,GAAG,CACpD,GAGKO,IAASD,EAAS,MAAM;AAC5B,YAAME,IAAcN,EAAcF,EAAM,SAAU,GAC5CS,IAAaN,EAAaH,EAAM,IAAK,GACrCU,IAAa,CAACF,EAAY,OAAOC,EAAW,OAAOT,EAAM,KAAK,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAE9F,aAAO;AAAA,QACL,YAAYA,EAAM;AAAA,QAClB,KAAKA,EAAM;AAAA,QACX,OAAOU;AAAA,MAAA;AAAA,IAEX,CAAC,GAGKC,IAAgBL,EAAS,MAAM;AACnC,YAAMG,IAAaL,EAAsBJ,EAAM,IAAK;AAGpD,UAAIY,IAAQ;AACZ,aAAIZ,EAAM,cAAc,YAAWY,IAAQ,YAClCZ,EAAM,cAAc,YAAWY,IAAQ,YACvCZ,EAAM,cAAc,YAAWY,IAAQ,YACvCZ,EAAM,cAAc,aAAUY,IAAQ,YAExC;AAAA,QACL,MAAMH,EAAW;AAAA,QACjB,OAAAG;AAAA,MAAA;AAAA,IAEJ,CAAC,GAGKC,IAAoBP,EAAS,MAC1BN,EAAM,gBAAgB,YAAY,GAAGK,EAAW,KAAK,GAC7D,GAGKS,IAA2BR,EAAS,MAAM;AAC9C,UAAIM,IAAQ;AACZ,aAAIZ,EAAM,cAAc,YAAWY,IAAQ,YAClCZ,EAAM,cAAc,YAAWY,IAAQ,YACvCZ,EAAM,cAAc,YAAWY,IAAQ,YACvCZ,EAAM,cAAc,aAAUY,IAAQ,YAExCA;AAAA,IACT,CAAC;sBAICG,EAAA,GAAAC,EAwGM,OAxGNC,GAwGM;AAAA,MAtGOjB,EAAM,YAAO,aAAkBA,EAAM,SAASA,EAAM,aAAaA,EAAM,kBAAlFe,EAAA,GAAAC,EAOM,OAPNE,GAOM;AAAA,QANKlB,EAAM,SAAfe,EAAA,GAAAC,EAEI,KAFJG,GAEIC,EADCpB,EAAM,KAAK,GAAA,CAAA;QAEPA,EAAM,aAAaA,EAAM,sBAAlCgB,EAEI,KAFJK,GAEID,EADCP,EAAA,KAAiB,GAAA,CAAA;;MAKbb,EAAM,YAAO,cAAmBA,EAAM,SAAjDe,KAAAC,EAEM,OAFNM,GAEM;AAAA,QADJC,EAAkE,KAAlEC,GAAkEJ,EAAlBpB,EAAM,KAAK,GAAA,CAAA;AAAA,MAAA;MAIlDA,EAAM,YAAO,iBAAxBgB,EAcM,OAAAS,GAAA;AAAA,QAZOzB,EAAM,sBAAjBgB,EASM,OAAA;AAAA;UAT0B,OAAKU,EAAA,CAAC,qDAA4DvB,EAAaH,EAAM,IAAI,EAAG,KAAK,CAAA;AAAA,QAAA;UAC/HuB,EAGE,OAAA;AAAA,YAFA,OAAM;AAAA,YACL,4BAA0BT,EAAA,OAAwB;AAAA,UAAA;UAErDS,EAGE,OAAA;AAAA,YAFA,OAAM;AAAA,YACL,4BAA0BT,EAAA,OAAwB;AAAA,UAAA;kBAIvDC,KAAAY,EAAmCC,mBAAVrB,EAAA,KAAM,CAAA,GAAA,MAAA,EAAA;AAAA,MAAA,MAIjBP,EAAM,YAAO,cAA7Be,EAAA,GAAAC,EA2DM,OA3DNa,GA2DM;AAAA,QA1DJN,EAyDM,OAAA;AAAA,UAzDD,OAAM;AAAA,UAAY,kBAAgBZ,EAAA,MAAc,OAAI,MAAA,QAAiBA,EAAA,MAAc,OAAI,MAAA;AAAA,QAAA;UAE/EX,EAAM,sBAAjBgB,EAuBM,OAAAc,GAAA;AAAA,aAtBJf,KAAAC,EAqBM,OArBNe,GAqBM;AAAA,8BApBJR,EAOE,UAAA;AAAA,gBANA,IAAG;AAAA,gBACH,IAAG;AAAA,gBACH,GAAE;AAAA,gBACF,QAAO;AAAA,gBACP,gBAAa;AAAA,gBACb,MAAK;AAAA,cAAA;cAEPA,EAWE,UAAA;AAAA,gBAVA,IAAG;AAAA,gBACH,IAAG;AAAA,gBACH,GAAE;AAAA,gBACD,QAAQZ,EAAA,MAAc;AAAA,gBACvB,gBAAa;AAAA,gBACb,MAAK;AAAA,gBACL,kBAAe;AAAA,gBACf,oBAAiB;AAAA,gBACjB,qBAAkB;AAAA,gBAClB,OAAM;AAAA,cAAA;;sBAKZK,EAyBM,OAAAgB,GAAA;AAAA,aAxBJjB,KAAAC,EAuBM,OAvBNiB,GAuBM;AAAA,8BArBJV,EAOE,UAAA;AAAA,gBANA,IAAG;AAAA,gBACH,IAAG;AAAA,gBACH,GAAE;AAAA,gBACF,QAAO;AAAA,gBACP,gBAAa;AAAA,gBACb,MAAK;AAAA,cAAA;cAGPA,EAWE,UAAA;AAAA,gBAVA,IAAG;AAAA,gBACH,IAAG;AAAA,gBACH,GAAE;AAAA,gBACD,QAAQZ,EAAA,MAAc;AAAA,gBACvB,gBAAa;AAAA,gBACb,MAAK;AAAA,gBACL,kBAAe;AAAA,gBACd,oBAAkB;AAAA,gBAClB,iCAAgCN,EAAA,QAAU;AAAA,gBAC3C,OAAM;AAAA,cAAA;;;UAKDL,EAAM,aAAaA,EAAM,iBAApCe,KAAAC,EAEM,OAFNkB,GAEM;AAAA,YADJX,EAA8E,QAA9EY,GAA8Ef,EAA3BP,EAAA,KAAiB,GAAA,CAAA;AAAA,UAAA;;;MAM/Db,EAAM,YAAO,cAAmBA,EAAM,eAAjDe,KAAAC,EAEM,OAFNoB,GAEM;AAAA,QADJb,EAA4D,KAA5Dc,GAA4DjB,EAAxBpB,EAAM,WAAW,GAAA,CAAA;AAAA,MAAA;MAI9CA,EAAM,YAAO,YAAiBA,EAAM,eAA7Ce,EAAA,GAAAC,EAEI,KAFJsB,GAEIlB,EADCpB,EAAM,WAAW,GAAA,CAAA;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"JRadio.vue.cjs","sources":["../../../../src/components/atoms/JRadio.vue"],"sourcesContent":["<script setup lang=\"ts\">\r\nimport { computed } from 'vue'\r\nimport { RadioGroup, RadioGroupItem } from '@/components/shadcn'\r\n\r\nexport interface Option {\r\n value: string | number\r\n label: string\r\n disabled?: boolean\r\n}\r\n\r\ntype StyleType =\r\n | 'default' // 기본 스타일\r\n | 'primary' // 강조 스타일 (파랑)\r\n | 'success' // 성공 스타일 (초록)\r\n | 'danger' // 위험 스타일 (빨강)\r\n | 'sm' // 작은 크기\r\n | 'lg' // 큰 크기\r\n | 'horizontal' // 가로 배치\r\n | 'vertical' // 세로 배치\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n modelValue?: string | number\r\n options?: Option[]\r\n disabled?: boolean\r\n required?: boolean\r\n name?: string\r\n id?: string\r\n class?: string\r\n /** 스타일 프리셋 */\r\n styletype?: StyleType\r\n }>(),\r\n {\r\n options: () => [],\r\n disabled: false,\r\n required: false,\r\n styletype: 'default',\r\n },\r\n)\r\n\r\nconst emit = defineEmits<{\r\n 'update:modelValue': [value: string | number]\r\n 'change': [value: string | number]\r\n}>()\r\n\r\n/**\r\n * styletype -> class 매핑\r\n */\r\nconst STYLE_PRESETS: Record<StyleType, { groupClass: string; itemClass: string }> = {\r\n default: { \r\n groupClass: '',\r\n itemClass: '',\r\n },\r\n primary: { \r\n groupClass: '',\r\n itemClass: 'border-blue-500 text-blue-500',\r\n },\r\n success: { \r\n groupClass: '',\r\n itemClass: 'border-green-500 text-green-600',\r\n },\r\n danger: { \r\n groupClass: '',\r\n itemClass: 'border-destructive text-destructive',\r\n },\r\n sm: { \r\n groupClass: '',\r\n itemClass: 'h-3.5 w-3.5',\r\n },\r\n lg: { \r\n groupClass: '',\r\n itemClass: 'h-5 w-5',\r\n },\r\n horizontal: { \r\n groupClass: 'flex flex-row gap-4',\r\n itemClass: '',\r\n },\r\n vertical: { \r\n groupClass: 'grid gap-2',\r\n itemClass: '',\r\n },\r\n}\r\n\r\nconst groupClass = computed(() => {\r\n const styleKey = props.styletype || 'default'\r\n const preset = STYLE_PRESETS[styleKey] ?? STYLE_PRESETS.default\r\n return [preset?.groupClass, props.class].filter(Boolean).join(' ')\r\n})\r\n\r\nconst itemClass = computed(() => {\r\n const styleKey = props.styletype || 'default'\r\n const preset = STYLE_PRESETS[styleKey] ?? STYLE_PRESETS.default\r\n return preset?.itemClass\r\n})\r\n\r\nconst handleChange = (value: string) => {\r\n emit('update:modelValue', value)\r\n emit('change', value)\r\n}\r\n</script>\r\n\r\n<template>\r\n <RadioGroup \r\n :model-value=\"String(modelValue)\" \r\n :disabled=\"disabled\"\r\n :required=\"required\"\r\n :name=\"name\"\r\n :id=\"id\"\r\n :class=\"groupClass\" \r\n @update:model-value=\"handleChange\"\r\n >\r\n <div v-for=\"option in options\" :key=\"option.value\" :class=\"styletype === 'vertical' ? 'block' : 'flex items-center space-x-2'\">\r\n <RadioGroupItem \r\n :id=\"String(option.value)\" \r\n :value=\"String(option.value)\" \r\n :disabled=\"option.disabled\"\r\n :class=\"itemClass\"\r\n />\r\n <label\n :for=\"String(option.value)\"\n class=\"text-xs font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70\"\n >\n {{ option.label }}\n </label>\n </div>\r\n </RadioGroup>\r\n</template>\r\n"],"names":["props","__props","emit","__emit","STYLE_PRESETS","groupClass","computed","styleKey","itemClass","handleChange","value","_createBlock","_unref","RadioGroup","_createElementBlock","_Fragment","_renderList","option","_createVNode","RadioGroupItem","_createElementVNode","_toDisplayString","_hoisted_1"],"mappings":"ghBAoBA,MAAMA,EAAQC,EAoBRC,EAAOC,EAQPC,EAA8E,CAClF,QAAS,CACP,WAAY,GACZ,UAAW,EAAA,EAEb,QAAS,CACP,WAAY,GACZ,UAAW,+BAAA,EAEb,QAAS,CACP,WAAY,GACZ,UAAW,iCAAA,EAEb,OAAQ,CACN,WAAY,GACZ,UAAW,qCAAA,EAEb,GAAI,CACF,WAAY,GACZ,UAAW,aAAA,EAEb,GAAI,CACF,WAAY,GACZ,UAAW,SAAA,EAEb,WAAY,CACV,WAAY,sBACZ,UAAW,EAAA,EAEb,SAAU,CACR,WAAY,aACZ,UAAW,EAAA,CACb,EAGIC,EAAaC,EAAAA,SAAS,IAAM,CAChC,MAAMC,EAAWP,EAAM,WAAa,UAEpC,MAAO,EADQI,EAAcG,CAAQ,GAAKH,EAAc,UACxC,WAAYJ,EAAM,KAAK,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,CACnE,CAAC,EAEKQ,EAAYF,EAAAA,SAAS,IAAM,CAC/B,MAAMC,EAAWP,EAAM,WAAa,UAEpC,OADeI,EAAcG,CAAQ,GAAKH,EAAc,UACzC,SACjB,CAAC,EAEKK,EAAgBC,GAAkB,CACtCR,EAAK,oBAAqBQ,CAAK,EAC/BR,EAAK,SAAUQ,CAAK,CACtB,8BAIEC,EAAAA,YAuBaC,EAAAA,MAAAC,EAAAA,OAAA,EAAA,CAtBV,cAAa,OAAOZ,EAAA,UAAU,EAC9B,SAAUA,EAAA,SACV,SAAUA,EAAA,SACV,KAAMA,EAAA,KACN,GAAIA,EAAA,GACJ,uBAAOI,EAAA,KAAU,EACjB,sBAAoBI,CAAA,qBAEhB,IAAyB,kBAA9BK,EAAAA,mBAaMC,EAAAA,SAAA,KAAAC,EAAAA,WAbgBf,EAAA,QAAVgB,kBAAZH,EAAAA,mBAaM,MAAA,CAb0B,IAAKG,EAAO,MAAQ,uBAAOhB,EAAA,YAAS,WAAA,QAAA,6BAAA,CAAA,GAClEiB,cAKEN,EAAAA,MAAAO,EAAAA,OAAA,EAAA,CAJC,GAAI,OAAOF,EAAO,KAAK,EACvB,MAAO,OAAOA,EAAO,KAAK,EAC1B,SAAUA,EAAO,SACjB,uBAAOT,EAAA,KAAS,CAAA,4CAEnBY,EAAAA,mBAKQ,QAAA,CAJL,IAAK,OAAOH,EAAO,KAAK,EACzB,MAAM,4FAAA,EAEHI,EAAAA,gBAAAJ,EAAO,KAAK,EAAA,EAAAK,CAAA,CAAA"}
1
+ {"version":3,"file":"JRadio.vue.cjs","sources":["../../../../src/components/atoms/JRadio.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport { RadioGroup, RadioGroupItem } from '@/components/shadcn'\n\nexport interface Option {\n value: string | number\n label: string\n disabled?: boolean\n}\n\ntype StyleType =\n | 'default' // 기본 스타일\n | 'primary' // 강조 스타일 (파랑)\n | 'success' // 성공 스타일 (초록)\n | 'danger' // 위험 스타일 (빨강)\n | 'sm' // 작은 크기\n | 'lg' // 큰 크기\n | 'horizontal' // 가로 배치\n | 'vertical' // 세로 배치\n\nconst props = withDefaults(\n defineProps<{\n modelValue?: string | number\n options?: Option[]\n disabled?: boolean\n required?: boolean\n name?: string\n id?: string\n class?: string\n /** 스타일 프리셋 */\n styletype?: StyleType\n }>(),\n {\n options: () => [],\n disabled: false,\n required: false,\n styletype: 'default',\n },\n)\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string | number]\n 'change': [value: string | number]\n}>()\n\n/**\n * styletype -> class 매핑\n */\nconst STYLE_PRESETS: Record<StyleType, { groupClass: string; itemClass: string }> = {\n default: { \n groupClass: '',\n itemClass: '',\n },\n primary: { \n groupClass: '',\n itemClass: 'border-blue-500 text-blue-500',\n },\n success: { \n groupClass: '',\n itemClass: 'border-green-500 text-green-600',\n },\n danger: { \n groupClass: '',\n itemClass: 'border-destructive text-destructive',\n },\n sm: { \n groupClass: '',\n itemClass: 'h-3.5 w-3.5',\n },\n lg: { \n groupClass: '',\n itemClass: 'h-5 w-5',\n },\n horizontal: { \n groupClass: 'flex flex-row gap-4',\n itemClass: '',\n },\n vertical: { \n groupClass: 'grid gap-2',\n itemClass: '',\n },\n}\n\nconst groupClass = computed(() => {\n const styleKey = props.styletype || 'default'\n const preset = STYLE_PRESETS[styleKey] ?? STYLE_PRESETS.default\n return [preset?.groupClass, props.class].filter(Boolean).join(' ')\n})\n\nconst itemClass = computed(() => {\n const styleKey = props.styletype || 'default'\n const preset = STYLE_PRESETS[styleKey] ?? STYLE_PRESETS.default\n return preset?.itemClass\n})\n\nconst handleChange = (value: string) => {\n emit('update:modelValue', value)\n emit('change', value)\n}\n</script>\n\n<template>\n <RadioGroup \n :model-value=\"String(modelValue)\" \n :disabled=\"disabled\"\n :required=\"required\"\n :name=\"name\"\n :id=\"id\"\n :class=\"groupClass\" \n @update:model-value=\"handleChange\"\n >\n <div v-for=\"option in options\" :key=\"option.value\" :class=\"styletype === 'vertical' ? 'block' : 'flex items-center space-x-2'\">\n <RadioGroupItem \n :id=\"String(option.value)\" \n :value=\"String(option.value)\" \n :disabled=\"option.disabled\"\n :class=\"itemClass\"\n />\n <label\n :for=\"String(option.value)\"\n class=\"text-xs font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70\"\n >\n {{ option.label }}\n </label>\n </div>\n </RadioGroup>\n</template>\n"],"names":["props","__props","emit","__emit","STYLE_PRESETS","groupClass","computed","styleKey","itemClass","handleChange","value","_createBlock","_unref","RadioGroup","_createElementBlock","_Fragment","_renderList","option","_createVNode","RadioGroupItem","_createElementVNode","_toDisplayString","_hoisted_1"],"mappings":"ghBAoBA,MAAMA,EAAQC,EAoBRC,EAAOC,EAQPC,EAA8E,CAClF,QAAS,CACP,WAAY,GACZ,UAAW,EAAA,EAEb,QAAS,CACP,WAAY,GACZ,UAAW,+BAAA,EAEb,QAAS,CACP,WAAY,GACZ,UAAW,iCAAA,EAEb,OAAQ,CACN,WAAY,GACZ,UAAW,qCAAA,EAEb,GAAI,CACF,WAAY,GACZ,UAAW,aAAA,EAEb,GAAI,CACF,WAAY,GACZ,UAAW,SAAA,EAEb,WAAY,CACV,WAAY,sBACZ,UAAW,EAAA,EAEb,SAAU,CACR,WAAY,aACZ,UAAW,EAAA,CACb,EAGIC,EAAaC,EAAAA,SAAS,IAAM,CAChC,MAAMC,EAAWP,EAAM,WAAa,UAEpC,MAAO,EADQI,EAAcG,CAAQ,GAAKH,EAAc,UACxC,WAAYJ,EAAM,KAAK,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,CACnE,CAAC,EAEKQ,EAAYF,EAAAA,SAAS,IAAM,CAC/B,MAAMC,EAAWP,EAAM,WAAa,UAEpC,OADeI,EAAcG,CAAQ,GAAKH,EAAc,UACzC,SACjB,CAAC,EAEKK,EAAgBC,GAAkB,CACtCR,EAAK,oBAAqBQ,CAAK,EAC/BR,EAAK,SAAUQ,CAAK,CACtB,8BAIEC,EAAAA,YAuBaC,EAAAA,MAAAC,EAAAA,OAAA,EAAA,CAtBV,cAAa,OAAOZ,EAAA,UAAU,EAC9B,SAAUA,EAAA,SACV,SAAUA,EAAA,SACV,KAAMA,EAAA,KACN,GAAIA,EAAA,GACJ,uBAAOI,EAAA,KAAU,EACjB,sBAAoBI,CAAA,qBAEhB,IAAyB,kBAA9BK,EAAAA,mBAaMC,EAAAA,SAAA,KAAAC,EAAAA,WAbgBf,EAAA,QAAVgB,kBAAZH,EAAAA,mBAaM,MAAA,CAb0B,IAAKG,EAAO,MAAQ,uBAAOhB,EAAA,YAAS,WAAA,QAAA,6BAAA,CAAA,GAClEiB,cAKEN,EAAAA,MAAAO,EAAAA,OAAA,EAAA,CAJC,GAAI,OAAOF,EAAO,KAAK,EACvB,MAAO,OAAOA,EAAO,KAAK,EAC1B,SAAUA,EAAO,SACjB,uBAAOT,EAAA,KAAS,CAAA,4CAEnBY,EAAAA,mBAKQ,QAAA,CAJL,IAAK,OAAOH,EAAO,KAAK,EACzB,MAAM,4FAAA,EAEHI,EAAAA,gBAAAJ,EAAO,KAAK,EAAA,EAAAK,CAAA,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"JRadio.vue.js","sources":["../../../../src/components/atoms/JRadio.vue"],"sourcesContent":["<script setup lang=\"ts\">\r\nimport { computed } from 'vue'\r\nimport { RadioGroup, RadioGroupItem } from '@/components/shadcn'\r\n\r\nexport interface Option {\r\n value: string | number\r\n label: string\r\n disabled?: boolean\r\n}\r\n\r\ntype StyleType =\r\n | 'default' // 기본 스타일\r\n | 'primary' // 강조 스타일 (파랑)\r\n | 'success' // 성공 스타일 (초록)\r\n | 'danger' // 위험 스타일 (빨강)\r\n | 'sm' // 작은 크기\r\n | 'lg' // 큰 크기\r\n | 'horizontal' // 가로 배치\r\n | 'vertical' // 세로 배치\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n modelValue?: string | number\r\n options?: Option[]\r\n disabled?: boolean\r\n required?: boolean\r\n name?: string\r\n id?: string\r\n class?: string\r\n /** 스타일 프리셋 */\r\n styletype?: StyleType\r\n }>(),\r\n {\r\n options: () => [],\r\n disabled: false,\r\n required: false,\r\n styletype: 'default',\r\n },\r\n)\r\n\r\nconst emit = defineEmits<{\r\n 'update:modelValue': [value: string | number]\r\n 'change': [value: string | number]\r\n}>()\r\n\r\n/**\r\n * styletype -> class 매핑\r\n */\r\nconst STYLE_PRESETS: Record<StyleType, { groupClass: string; itemClass: string }> = {\r\n default: { \r\n groupClass: '',\r\n itemClass: '',\r\n },\r\n primary: { \r\n groupClass: '',\r\n itemClass: 'border-blue-500 text-blue-500',\r\n },\r\n success: { \r\n groupClass: '',\r\n itemClass: 'border-green-500 text-green-600',\r\n },\r\n danger: { \r\n groupClass: '',\r\n itemClass: 'border-destructive text-destructive',\r\n },\r\n sm: { \r\n groupClass: '',\r\n itemClass: 'h-3.5 w-3.5',\r\n },\r\n lg: { \r\n groupClass: '',\r\n itemClass: 'h-5 w-5',\r\n },\r\n horizontal: { \r\n groupClass: 'flex flex-row gap-4',\r\n itemClass: '',\r\n },\r\n vertical: { \r\n groupClass: 'grid gap-2',\r\n itemClass: '',\r\n },\r\n}\r\n\r\nconst groupClass = computed(() => {\r\n const styleKey = props.styletype || 'default'\r\n const preset = STYLE_PRESETS[styleKey] ?? STYLE_PRESETS.default\r\n return [preset?.groupClass, props.class].filter(Boolean).join(' ')\r\n})\r\n\r\nconst itemClass = computed(() => {\r\n const styleKey = props.styletype || 'default'\r\n const preset = STYLE_PRESETS[styleKey] ?? STYLE_PRESETS.default\r\n return preset?.itemClass\r\n})\r\n\r\nconst handleChange = (value: string) => {\r\n emit('update:modelValue', value)\r\n emit('change', value)\r\n}\r\n</script>\r\n\r\n<template>\r\n <RadioGroup \r\n :model-value=\"String(modelValue)\" \r\n :disabled=\"disabled\"\r\n :required=\"required\"\r\n :name=\"name\"\r\n :id=\"id\"\r\n :class=\"groupClass\" \r\n @update:model-value=\"handleChange\"\r\n >\r\n <div v-for=\"option in options\" :key=\"option.value\" :class=\"styletype === 'vertical' ? 'block' : 'flex items-center space-x-2'\">\r\n <RadioGroupItem \r\n :id=\"String(option.value)\" \r\n :value=\"String(option.value)\" \r\n :disabled=\"option.disabled\"\r\n :class=\"itemClass\"\r\n />\r\n <label\n :for=\"String(option.value)\"\n class=\"text-xs font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70\"\n >\n {{ option.label }}\n </label>\n </div>\r\n </RadioGroup>\r\n</template>\r\n"],"names":["props","__props","emit","__emit","STYLE_PRESETS","groupClass","computed","styleKey","itemClass","handleChange","value","_createBlock","_unref","RadioGroup","_createElementBlock","_Fragment","_renderList","option","_createVNode","RadioGroupItem","_createElementVNode","_toDisplayString","_hoisted_1"],"mappings":";;;;;;;;;;;;;;;;;;AAoBA,UAAMA,IAAQC,GAoBRC,IAAOC,GAQPC,IAA8E;AAAA,MAClF,SAAS;AAAA,QACP,YAAY;AAAA,QACZ,WAAW;AAAA,MAAA;AAAA,MAEb,SAAS;AAAA,QACP,YAAY;AAAA,QACZ,WAAW;AAAA,MAAA;AAAA,MAEb,SAAS;AAAA,QACP,YAAY;AAAA,QACZ,WAAW;AAAA,MAAA;AAAA,MAEb,QAAQ;AAAA,QACN,YAAY;AAAA,QACZ,WAAW;AAAA,MAAA;AAAA,MAEb,IAAI;AAAA,QACF,YAAY;AAAA,QACZ,WAAW;AAAA,MAAA;AAAA,MAEb,IAAI;AAAA,QACF,YAAY;AAAA,QACZ,WAAW;AAAA,MAAA;AAAA,MAEb,YAAY;AAAA,QACV,YAAY;AAAA,QACZ,WAAW;AAAA,MAAA;AAAA,MAEb,UAAU;AAAA,QACR,YAAY;AAAA,QACZ,WAAW;AAAA,MAAA;AAAA,IACb,GAGIC,IAAaC,EAAS,MAAM;AAChC,YAAMC,IAAWP,EAAM,aAAa;AAEpC,aAAO,EADQI,EAAcG,CAAQ,KAAKH,EAAc,UACxC,YAAYJ,EAAM,KAAK,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAAA,IACnE,CAAC,GAEKQ,IAAYF,EAAS,MAAM;AAC/B,YAAMC,IAAWP,EAAM,aAAa;AAEpC,cADeI,EAAcG,CAAQ,KAAKH,EAAc,UACzC;AAAA,IACjB,CAAC,GAEKK,IAAe,CAACC,MAAkB;AACtC,MAAAR,EAAK,qBAAqBQ,CAAK,GAC/BR,EAAK,UAAUQ,CAAK;AAAA,IACtB;2BAIEC,EAuBaC,EAAAC,CAAA,GAAA;AAAA,MAtBV,eAAa,OAAOZ,EAAA,UAAU;AAAA,MAC9B,UAAUA,EAAA;AAAA,MACV,UAAUA,EAAA;AAAA,MACV,MAAMA,EAAA;AAAA,MACN,IAAIA,EAAA;AAAA,MACJ,SAAOI,EAAA,KAAU;AAAA,MACjB,uBAAoBI;AAAA,IAAA;iBAEhB,MAAyB;AAAA,gBAA9BK,EAaMC,GAAA,MAAAC,EAbgBf,EAAA,SAAO,CAAjBgB,YAAZH,EAaM,OAAA;AAAA,UAb0B,KAAKG,EAAO;AAAA,UAAQ,SAAOhB,EAAA,cAAS,aAAA,UAAA,6BAAA;AAAA,QAAA;UAClEiB,EAKEN,EAAAO,CAAA,GAAA;AAAA,YAJC,IAAI,OAAOF,EAAO,KAAK;AAAA,YACvB,OAAO,OAAOA,EAAO,KAAK;AAAA,YAC1B,UAAUA,EAAO;AAAA,YACjB,SAAOT,EAAA,KAAS;AAAA,UAAA;UAEnBY,EAKQ,SAAA;AAAA,YAJL,KAAK,OAAOH,EAAO,KAAK;AAAA,YACzB,OAAM;AAAA,UAAA,GAEHI,EAAAJ,EAAO,KAAK,GAAA,GAAAK,CAAA;AAAA,QAAA;;;;;;"}
1
+ {"version":3,"file":"JRadio.vue.js","sources":["../../../../src/components/atoms/JRadio.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport { RadioGroup, RadioGroupItem } from '@/components/shadcn'\n\nexport interface Option {\n value: string | number\n label: string\n disabled?: boolean\n}\n\ntype StyleType =\n | 'default' // 기본 스타일\n | 'primary' // 강조 스타일 (파랑)\n | 'success' // 성공 스타일 (초록)\n | 'danger' // 위험 스타일 (빨강)\n | 'sm' // 작은 크기\n | 'lg' // 큰 크기\n | 'horizontal' // 가로 배치\n | 'vertical' // 세로 배치\n\nconst props = withDefaults(\n defineProps<{\n modelValue?: string | number\n options?: Option[]\n disabled?: boolean\n required?: boolean\n name?: string\n id?: string\n class?: string\n /** 스타일 프리셋 */\n styletype?: StyleType\n }>(),\n {\n options: () => [],\n disabled: false,\n required: false,\n styletype: 'default',\n },\n)\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string | number]\n 'change': [value: string | number]\n}>()\n\n/**\n * styletype -> class 매핑\n */\nconst STYLE_PRESETS: Record<StyleType, { groupClass: string; itemClass: string }> = {\n default: { \n groupClass: '',\n itemClass: '',\n },\n primary: { \n groupClass: '',\n itemClass: 'border-blue-500 text-blue-500',\n },\n success: { \n groupClass: '',\n itemClass: 'border-green-500 text-green-600',\n },\n danger: { \n groupClass: '',\n itemClass: 'border-destructive text-destructive',\n },\n sm: { \n groupClass: '',\n itemClass: 'h-3.5 w-3.5',\n },\n lg: { \n groupClass: '',\n itemClass: 'h-5 w-5',\n },\n horizontal: { \n groupClass: 'flex flex-row gap-4',\n itemClass: '',\n },\n vertical: { \n groupClass: 'grid gap-2',\n itemClass: '',\n },\n}\n\nconst groupClass = computed(() => {\n const styleKey = props.styletype || 'default'\n const preset = STYLE_PRESETS[styleKey] ?? STYLE_PRESETS.default\n return [preset?.groupClass, props.class].filter(Boolean).join(' ')\n})\n\nconst itemClass = computed(() => {\n const styleKey = props.styletype || 'default'\n const preset = STYLE_PRESETS[styleKey] ?? STYLE_PRESETS.default\n return preset?.itemClass\n})\n\nconst handleChange = (value: string) => {\n emit('update:modelValue', value)\n emit('change', value)\n}\n</script>\n\n<template>\n <RadioGroup \n :model-value=\"String(modelValue)\" \n :disabled=\"disabled\"\n :required=\"required\"\n :name=\"name\"\n :id=\"id\"\n :class=\"groupClass\" \n @update:model-value=\"handleChange\"\n >\n <div v-for=\"option in options\" :key=\"option.value\" :class=\"styletype === 'vertical' ? 'block' : 'flex items-center space-x-2'\">\n <RadioGroupItem \n :id=\"String(option.value)\" \n :value=\"String(option.value)\" \n :disabled=\"option.disabled\"\n :class=\"itemClass\"\n />\n <label\n :for=\"String(option.value)\"\n class=\"text-xs font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70\"\n >\n {{ option.label }}\n </label>\n </div>\n </RadioGroup>\n</template>\n"],"names":["props","__props","emit","__emit","STYLE_PRESETS","groupClass","computed","styleKey","itemClass","handleChange","value","_createBlock","_unref","RadioGroup","_createElementBlock","_Fragment","_renderList","option","_createVNode","RadioGroupItem","_createElementVNode","_toDisplayString","_hoisted_1"],"mappings":";;;;;;;;;;;;;;;;;;AAoBA,UAAMA,IAAQC,GAoBRC,IAAOC,GAQPC,IAA8E;AAAA,MAClF,SAAS;AAAA,QACP,YAAY;AAAA,QACZ,WAAW;AAAA,MAAA;AAAA,MAEb,SAAS;AAAA,QACP,YAAY;AAAA,QACZ,WAAW;AAAA,MAAA;AAAA,MAEb,SAAS;AAAA,QACP,YAAY;AAAA,QACZ,WAAW;AAAA,MAAA;AAAA,MAEb,QAAQ;AAAA,QACN,YAAY;AAAA,QACZ,WAAW;AAAA,MAAA;AAAA,MAEb,IAAI;AAAA,QACF,YAAY;AAAA,QACZ,WAAW;AAAA,MAAA;AAAA,MAEb,IAAI;AAAA,QACF,YAAY;AAAA,QACZ,WAAW;AAAA,MAAA;AAAA,MAEb,YAAY;AAAA,QACV,YAAY;AAAA,QACZ,WAAW;AAAA,MAAA;AAAA,MAEb,UAAU;AAAA,QACR,YAAY;AAAA,QACZ,WAAW;AAAA,MAAA;AAAA,IACb,GAGIC,IAAaC,EAAS,MAAM;AAChC,YAAMC,IAAWP,EAAM,aAAa;AAEpC,aAAO,EADQI,EAAcG,CAAQ,KAAKH,EAAc,UACxC,YAAYJ,EAAM,KAAK,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAAA,IACnE,CAAC,GAEKQ,IAAYF,EAAS,MAAM;AAC/B,YAAMC,IAAWP,EAAM,aAAa;AAEpC,cADeI,EAAcG,CAAQ,KAAKH,EAAc,UACzC;AAAA,IACjB,CAAC,GAEKK,IAAe,CAACC,MAAkB;AACtC,MAAAR,EAAK,qBAAqBQ,CAAK,GAC/BR,EAAK,UAAUQ,CAAK;AAAA,IACtB;2BAIEC,EAuBaC,EAAAC,CAAA,GAAA;AAAA,MAtBV,eAAa,OAAOZ,EAAA,UAAU;AAAA,MAC9B,UAAUA,EAAA;AAAA,MACV,UAAUA,EAAA;AAAA,MACV,MAAMA,EAAA;AAAA,MACN,IAAIA,EAAA;AAAA,MACJ,SAAOI,EAAA,KAAU;AAAA,MACjB,uBAAoBI;AAAA,IAAA;iBAEhB,MAAyB;AAAA,gBAA9BK,EAaMC,GAAA,MAAAC,EAbgBf,EAAA,SAAO,CAAjBgB,YAAZH,EAaM,OAAA;AAAA,UAb0B,KAAKG,EAAO;AAAA,UAAQ,SAAOhB,EAAA,cAAS,aAAA,UAAA,6BAAA;AAAA,QAAA;UAClEiB,EAKEN,EAAAO,CAAA,GAAA;AAAA,YAJC,IAAI,OAAOF,EAAO,KAAK;AAAA,YACvB,OAAO,OAAOA,EAAO,KAAK;AAAA,YAC1B,UAAUA,EAAO;AAAA,YACjB,SAAOT,EAAA,KAAS;AAAA,UAAA;UAEnBY,EAKQ,SAAA;AAAA,YAJL,KAAK,OAAOH,EAAO,KAAK;AAAA,YACzB,OAAM;AAAA,UAAA,GAEHI,EAAAJ,EAAO,KAAK,GAAA,GAAAK,CAAA;AAAA,QAAA;;;;;;"}