@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":"JSearchCombo.vue.cjs","sources":["../../../../src/components/atoms/JSearchCombo.vue"],"sourcesContent":["<script setup lang=\"ts\">\r\nimport { computed } from 'vue'\r\nimport { Check, ChevronsUpDown, Search } from 'lucide-vue-next'\r\nimport { cn } from '@/lib/utils'\r\nimport {\r\n Button,\r\n Combobox,\r\n ComboboxAnchor,\r\n ComboboxEmpty,\r\n ComboboxGroup,\r\n ComboboxInput,\r\n ComboboxItem,\r\n ComboboxList,\r\n ComboboxTrigger,\r\n} from '@/components/shadcn'\r\n\r\nexport interface ComboboxOption {\r\n value: string | number\r\n label: string\r\n}\r\n\r\ntype StyleType =\r\n | 'default' // 기본 스타일\r\n | 'error' // 에러 상태\r\n | 'success' // 성공 상태\r\n | 'warning' // 경고 상태\r\n | 'sm' // 작은 크기\r\n | 'lg' // 큰 크기\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n modelValue?: ComboboxOption\r\n options?: ComboboxOption[]\r\n placeholder?: string\r\n searchPlaceholder?: string\r\n emptyText?: string\r\n disabled?: boolean\r\n required?: boolean\r\n name?: string\r\n id?: string\r\n multiple?: boolean\r\n class?: string\r\n /** 스타일 프리셋 */\r\n styletype?: StyleType\r\n }>(),\r\n {\r\n options: () => [],\r\n placeholder: '선택해주세요.',\r\n searchPlaceholder: '',\r\n emptyText: '검색 결과가 없습니다.',\r\n disabled: false,\r\n required: false,\r\n multiple: false,\r\n styletype: 'default',\r\n },\r\n)\r\n\r\nconst emit = defineEmits<{\r\n 'update:modelValue': [value: ComboboxOption | undefined]\r\n 'change': [value: ComboboxOption | undefined]\r\n 'focus': [event: FocusEvent]\r\n 'blur': [event: FocusEvent]\r\n}>()\r\n\r\n/**\r\n * styletype -> variant/class 매핑\r\n */\r\nconst STYLE_PRESETS: Record<StyleType, { variant: 'default' | 'outline' | 'destructive' | 'secondary' | 'ghost' | 'link', buttonClass?: string, inputClass?: string }> = {\n default: { \n variant: 'outline',\n buttonClass: 'h-8 text-xs px-2.5',\n },\n error: { \n variant: 'outline',\n buttonClass: 'h-8 text-xs px-2.5 border-destructive text-destructive',\n inputClass: 'border-destructive focus:ring-destructive',\n },\n success: { \n variant: 'outline',\n buttonClass: 'h-8 text-xs px-2.5 border-green-500 text-green-700',\n inputClass: 'border-green-500 focus:ring-green-500',\n },\n warning: { \n variant: 'outline',\n buttonClass: 'h-8 text-xs px-2.5 border-amber-500 text-amber-700',\n inputClass: 'border-amber-500 focus:ring-amber-500',\n },\n sm: { \n variant: 'outline',\n buttonClass: 'h-7 text-[11px] px-2',\n inputClass: 'h-7 text-[11px] px-2 py-1',\n },\n lg: { \n variant: 'outline',\n buttonClass: 'h-10 text-sm px-3',\n inputClass: 'h-10 text-sm px-3 py-2',\n },\n}\n\r\nconst preset = computed(() => {\r\n const styleKey = props.styletype || 'default'\r\n return STYLE_PRESETS[styleKey] ?? STYLE_PRESETS.default\r\n})\r\n\r\nconst buttonClass = computed(() => {\r\n return cn('justify-between', preset.value?.buttonClass, props.class)\r\n})\r\n\r\nconst inputClass = computed(() => {\n return cn('pl-8 pr-2 py-1.5 focus-visible:ring-0 border-0 border-b rounded-none h-8 text-xs', preset.value?.inputClass)\n})\n\r\nconst handleChange = (value: ComboboxOption | undefined) => {\r\n emit('update:modelValue', value)\r\n emit('change', value)\r\n}\r\n</script>\r\n\r\n<template>\r\n <Combobox \r\n :model-value=\"modelValue\" \r\n by=\"label\" \r\n :disabled=\"disabled\"\r\n :required=\"required\"\r\n :name=\"name\"\r\n @update:model-value=\"(value) => handleChange(value as ComboboxOption | undefined)\"\r\n >\r\n <ComboboxAnchor as-child>\r\n <ComboboxTrigger as-child>\r\n <Button \r\n :id=\"id\"\r\n :variant=\"preset.variant\" \r\n :class=\"buttonClass\"\r\n :disabled=\"disabled\"\r\n @focus=\"emit('focus', $event as FocusEvent)\"\r\n @blur=\"emit('blur', $event as FocusEvent)\"\r\n >\n {{ modelValue?.label ?? placeholder }}\n <ChevronsUpDown class=\"ml-2 h-3.5 w-3.5 shrink-0 opacity-50\" />\n </Button>\n </ComboboxTrigger>\r\n </ComboboxAnchor>\r\n\r\n <ComboboxList>\r\n <div class=\"relative w-full max-w-sm items-center\">\n <ComboboxInput :class=\"inputClass\" :placeholder=\"searchPlaceholder\" />\n <span class=\"absolute start-0 inset-y-0 flex items-center justify-center px-2.5\">\n <Search class=\"size-3.5 text-muted-foreground\" />\n </span>\n </div>\n\r\n <ComboboxEmpty>\r\n {{ emptyText }}\r\n </ComboboxEmpty>\r\n\r\n <ComboboxGroup>\r\n <ComboboxItem\r\n v-for=\"option in options\"\r\n :key=\"option.value\"\r\n :value=\"option\"\r\n >\r\n {{ option.label }}\n\n <Check v-if=\"modelValue?.value === option.value\" :class=\"cn('ml-auto h-3.5 w-3.5')\" />\n </ComboboxItem>\r\n </ComboboxGroup>\r\n </ComboboxList>\r\n </Combobox>\r\n</template>\r\n"],"names":["props","__props","emit","__emit","STYLE_PRESETS","preset","computed","styleKey","buttonClass","cn","inputClass","handleChange","value","_createBlock","_unref","Combobox","_cache","_createVNode","ComboboxAnchor","ComboboxTrigger","Button","$event","_createTextVNode","_toDisplayString","ChevronsUpDown","ComboboxList","_createElementVNode","_hoisted_1","ComboboxInput","_hoisted_2","Search","ComboboxEmpty","ComboboxGroup","_createElementBlock","_Fragment","_renderList","option","ComboboxItem","Check"],"mappings":"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"}
1
+ {"version":3,"file":"JSearchCombo.vue.cjs","sources":["../../../../src/components/atoms/JSearchCombo.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport { Check, ChevronsUpDown, Search } from 'lucide-vue-next'\nimport { cn } from '@/lib/utils'\nimport {\n Button,\n Combobox,\n ComboboxAnchor,\n ComboboxEmpty,\n ComboboxGroup,\n ComboboxInput,\n ComboboxItem,\n ComboboxList,\n ComboboxTrigger,\n} from '@/components/shadcn'\n\nexport interface ComboboxOption {\n value: string | number\n label: string\n}\n\ntype StyleType =\n | 'default' // 기본 스타일\n | 'error' // 에러 상태\n | 'success' // 성공 상태\n | 'warning' // 경고 상태\n | 'sm' // 작은 크기\n | 'lg' // 큰 크기\n\nconst props = withDefaults(\n defineProps<{\n modelValue?: ComboboxOption\n options?: ComboboxOption[]\n placeholder?: string\n searchPlaceholder?: string\n emptyText?: string\n disabled?: boolean\n required?: boolean\n name?: string\n id?: string\n multiple?: boolean\n class?: string\n /** 스타일 프리셋 */\n styletype?: StyleType\n }>(),\n {\n options: () => [],\n placeholder: '선택해주세요.',\n searchPlaceholder: '',\n emptyText: '검색 결과가 없습니다.',\n disabled: false,\n required: false,\n multiple: false,\n styletype: 'default',\n },\n)\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: ComboboxOption | undefined]\n 'change': [value: ComboboxOption | undefined]\n 'focus': [event: FocusEvent]\n 'blur': [event: FocusEvent]\n}>()\n\n/**\n * styletype -> variant/class 매핑\n */\nconst STYLE_PRESETS: Record<StyleType, { variant: 'default' | 'outline' | 'destructive' | 'secondary' | 'ghost' | 'link', buttonClass?: string, inputClass?: string }> = {\n default: { \n variant: 'outline',\n buttonClass: 'h-8 text-xs px-2.5',\n },\n error: { \n variant: 'outline',\n buttonClass: 'h-8 text-xs px-2.5 border-destructive text-destructive',\n inputClass: 'border-destructive focus:ring-destructive',\n },\n success: { \n variant: 'outline',\n buttonClass: 'h-8 text-xs px-2.5 border-green-500 text-green-700',\n inputClass: 'border-green-500 focus:ring-green-500',\n },\n warning: { \n variant: 'outline',\n buttonClass: 'h-8 text-xs px-2.5 border-amber-500 text-amber-700',\n inputClass: 'border-amber-500 focus:ring-amber-500',\n },\n sm: { \n variant: 'outline',\n buttonClass: 'h-7 text-[11px] px-2',\n inputClass: 'h-7 text-[11px] px-2 py-1',\n },\n lg: { \n variant: 'outline',\n buttonClass: 'h-10 text-sm px-3',\n inputClass: 'h-10 text-sm px-3 py-2',\n },\n}\n\nconst preset = computed(() => {\n const styleKey = props.styletype || 'default'\n return STYLE_PRESETS[styleKey] ?? STYLE_PRESETS.default\n})\n\nconst buttonClass = computed(() => {\n return cn('justify-between', preset.value?.buttonClass, props.class)\n})\n\nconst inputClass = computed(() => {\n return cn('pl-8 pr-2 py-1.5 focus-visible:ring-0 border-0 border-b rounded-none h-8 text-xs', preset.value?.inputClass)\n})\n\nconst handleChange = (value: ComboboxOption | undefined) => {\n emit('update:modelValue', value)\n emit('change', value)\n}\n</script>\n\n<template>\n <Combobox \n :model-value=\"modelValue\" \n by=\"label\" \n :disabled=\"disabled\"\n :required=\"required\"\n :name=\"name\"\n @update:model-value=\"(value) => handleChange(value as ComboboxOption | undefined)\"\n >\n <ComboboxAnchor as-child>\n <ComboboxTrigger as-child>\n <Button \n :id=\"id\"\n :variant=\"preset.variant\" \n :class=\"buttonClass\"\n :disabled=\"disabled\"\n @focus=\"emit('focus', $event as FocusEvent)\"\n @blur=\"emit('blur', $event as FocusEvent)\"\n >\n {{ modelValue?.label ?? placeholder }}\n <ChevronsUpDown class=\"ml-2 h-3.5 w-3.5 shrink-0 opacity-50\" />\n </Button>\n </ComboboxTrigger>\n </ComboboxAnchor>\n\n <ComboboxList>\n <div class=\"relative w-full max-w-sm items-center\">\n <ComboboxInput :class=\"inputClass\" :placeholder=\"searchPlaceholder\" />\n <span class=\"absolute start-0 inset-y-0 flex items-center justify-center px-2.5\">\n <Search class=\"size-3.5 text-muted-foreground\" />\n </span>\n </div>\n\n <ComboboxEmpty>\n {{ emptyText }}\n </ComboboxEmpty>\n\n <ComboboxGroup>\n <ComboboxItem\n v-for=\"option in options\"\n :key=\"option.value\"\n :value=\"option\"\n >\n {{ option.label }}\n\n <Check v-if=\"modelValue?.value === option.value\" :class=\"cn('ml-auto h-3.5 w-3.5')\" />\n </ComboboxItem>\n </ComboboxGroup>\n </ComboboxList>\n </Combobox>\n</template>\n"],"names":["props","__props","emit","__emit","STYLE_PRESETS","preset","computed","styleKey","buttonClass","cn","inputClass","handleChange","value","_createBlock","_unref","Combobox","_cache","_createVNode","ComboboxAnchor","ComboboxTrigger","Button","$event","_createTextVNode","_toDisplayString","ChevronsUpDown","ComboboxList","_createElementVNode","_hoisted_1","ComboboxInput","_hoisted_2","Search","ComboboxEmpty","ComboboxGroup","_createElementBlock","_Fragment","_renderList","option","ComboboxItem","Check"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"JSearchCombo.vue.js","sources":["../../../../src/components/atoms/JSearchCombo.vue"],"sourcesContent":["<script setup lang=\"ts\">\r\nimport { computed } from 'vue'\r\nimport { Check, ChevronsUpDown, Search } from 'lucide-vue-next'\r\nimport { cn } from '@/lib/utils'\r\nimport {\r\n Button,\r\n Combobox,\r\n ComboboxAnchor,\r\n ComboboxEmpty,\r\n ComboboxGroup,\r\n ComboboxInput,\r\n ComboboxItem,\r\n ComboboxList,\r\n ComboboxTrigger,\r\n} from '@/components/shadcn'\r\n\r\nexport interface ComboboxOption {\r\n value: string | number\r\n label: string\r\n}\r\n\r\ntype StyleType =\r\n | 'default' // 기본 스타일\r\n | 'error' // 에러 상태\r\n | 'success' // 성공 상태\r\n | 'warning' // 경고 상태\r\n | 'sm' // 작은 크기\r\n | 'lg' // 큰 크기\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n modelValue?: ComboboxOption\r\n options?: ComboboxOption[]\r\n placeholder?: string\r\n searchPlaceholder?: string\r\n emptyText?: string\r\n disabled?: boolean\r\n required?: boolean\r\n name?: string\r\n id?: string\r\n multiple?: boolean\r\n class?: string\r\n /** 스타일 프리셋 */\r\n styletype?: StyleType\r\n }>(),\r\n {\r\n options: () => [],\r\n placeholder: '선택해주세요.',\r\n searchPlaceholder: '',\r\n emptyText: '검색 결과가 없습니다.',\r\n disabled: false,\r\n required: false,\r\n multiple: false,\r\n styletype: 'default',\r\n },\r\n)\r\n\r\nconst emit = defineEmits<{\r\n 'update:modelValue': [value: ComboboxOption | undefined]\r\n 'change': [value: ComboboxOption | undefined]\r\n 'focus': [event: FocusEvent]\r\n 'blur': [event: FocusEvent]\r\n}>()\r\n\r\n/**\r\n * styletype -> variant/class 매핑\r\n */\r\nconst STYLE_PRESETS: Record<StyleType, { variant: 'default' | 'outline' | 'destructive' | 'secondary' | 'ghost' | 'link', buttonClass?: string, inputClass?: string }> = {\n default: { \n variant: 'outline',\n buttonClass: 'h-8 text-xs px-2.5',\n },\n error: { \n variant: 'outline',\n buttonClass: 'h-8 text-xs px-2.5 border-destructive text-destructive',\n inputClass: 'border-destructive focus:ring-destructive',\n },\n success: { \n variant: 'outline',\n buttonClass: 'h-8 text-xs px-2.5 border-green-500 text-green-700',\n inputClass: 'border-green-500 focus:ring-green-500',\n },\n warning: { \n variant: 'outline',\n buttonClass: 'h-8 text-xs px-2.5 border-amber-500 text-amber-700',\n inputClass: 'border-amber-500 focus:ring-amber-500',\n },\n sm: { \n variant: 'outline',\n buttonClass: 'h-7 text-[11px] px-2',\n inputClass: 'h-7 text-[11px] px-2 py-1',\n },\n lg: { \n variant: 'outline',\n buttonClass: 'h-10 text-sm px-3',\n inputClass: 'h-10 text-sm px-3 py-2',\n },\n}\n\r\nconst preset = computed(() => {\r\n const styleKey = props.styletype || 'default'\r\n return STYLE_PRESETS[styleKey] ?? STYLE_PRESETS.default\r\n})\r\n\r\nconst buttonClass = computed(() => {\r\n return cn('justify-between', preset.value?.buttonClass, props.class)\r\n})\r\n\r\nconst inputClass = computed(() => {\n return cn('pl-8 pr-2 py-1.5 focus-visible:ring-0 border-0 border-b rounded-none h-8 text-xs', preset.value?.inputClass)\n})\n\r\nconst handleChange = (value: ComboboxOption | undefined) => {\r\n emit('update:modelValue', value)\r\n emit('change', value)\r\n}\r\n</script>\r\n\r\n<template>\r\n <Combobox \r\n :model-value=\"modelValue\" \r\n by=\"label\" \r\n :disabled=\"disabled\"\r\n :required=\"required\"\r\n :name=\"name\"\r\n @update:model-value=\"(value) => handleChange(value as ComboboxOption | undefined)\"\r\n >\r\n <ComboboxAnchor as-child>\r\n <ComboboxTrigger as-child>\r\n <Button \r\n :id=\"id\"\r\n :variant=\"preset.variant\" \r\n :class=\"buttonClass\"\r\n :disabled=\"disabled\"\r\n @focus=\"emit('focus', $event as FocusEvent)\"\r\n @blur=\"emit('blur', $event as FocusEvent)\"\r\n >\n {{ modelValue?.label ?? placeholder }}\n <ChevronsUpDown class=\"ml-2 h-3.5 w-3.5 shrink-0 opacity-50\" />\n </Button>\n </ComboboxTrigger>\r\n </ComboboxAnchor>\r\n\r\n <ComboboxList>\r\n <div class=\"relative w-full max-w-sm items-center\">\n <ComboboxInput :class=\"inputClass\" :placeholder=\"searchPlaceholder\" />\n <span class=\"absolute start-0 inset-y-0 flex items-center justify-center px-2.5\">\n <Search class=\"size-3.5 text-muted-foreground\" />\n </span>\n </div>\n\r\n <ComboboxEmpty>\r\n {{ emptyText }}\r\n </ComboboxEmpty>\r\n\r\n <ComboboxGroup>\r\n <ComboboxItem\r\n v-for=\"option in options\"\r\n :key=\"option.value\"\r\n :value=\"option\"\r\n >\r\n {{ option.label }}\n\n <Check v-if=\"modelValue?.value === option.value\" :class=\"cn('ml-auto h-3.5 w-3.5')\" />\n </ComboboxItem>\r\n </ComboboxGroup>\r\n </ComboboxList>\r\n </Combobox>\r\n</template>\r\n"],"names":["props","__props","emit","__emit","STYLE_PRESETS","preset","computed","styleKey","buttonClass","cn","inputClass","handleChange","value","_createBlock","_unref","Combobox","_cache","_createVNode","ComboboxAnchor","ComboboxTrigger","Button","$event","_createTextVNode","_toDisplayString","ChevronsUpDown","ComboboxList","_createElementVNode","_hoisted_1","ComboboxInput","_hoisted_2","Search","ComboboxEmpty","ComboboxGroup","_createElementBlock","_Fragment","_renderList","option","ComboboxItem","Check"],"mappings":"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"}
1
+ {"version":3,"file":"JSearchCombo.vue.js","sources":["../../../../src/components/atoms/JSearchCombo.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport { Check, ChevronsUpDown, Search } from 'lucide-vue-next'\nimport { cn } from '@/lib/utils'\nimport {\n Button,\n Combobox,\n ComboboxAnchor,\n ComboboxEmpty,\n ComboboxGroup,\n ComboboxInput,\n ComboboxItem,\n ComboboxList,\n ComboboxTrigger,\n} from '@/components/shadcn'\n\nexport interface ComboboxOption {\n value: string | number\n label: string\n}\n\ntype StyleType =\n | 'default' // 기본 스타일\n | 'error' // 에러 상태\n | 'success' // 성공 상태\n | 'warning' // 경고 상태\n | 'sm' // 작은 크기\n | 'lg' // 큰 크기\n\nconst props = withDefaults(\n defineProps<{\n modelValue?: ComboboxOption\n options?: ComboboxOption[]\n placeholder?: string\n searchPlaceholder?: string\n emptyText?: string\n disabled?: boolean\n required?: boolean\n name?: string\n id?: string\n multiple?: boolean\n class?: string\n /** 스타일 프리셋 */\n styletype?: StyleType\n }>(),\n {\n options: () => [],\n placeholder: '선택해주세요.',\n searchPlaceholder: '',\n emptyText: '검색 결과가 없습니다.',\n disabled: false,\n required: false,\n multiple: false,\n styletype: 'default',\n },\n)\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: ComboboxOption | undefined]\n 'change': [value: ComboboxOption | undefined]\n 'focus': [event: FocusEvent]\n 'blur': [event: FocusEvent]\n}>()\n\n/**\n * styletype -> variant/class 매핑\n */\nconst STYLE_PRESETS: Record<StyleType, { variant: 'default' | 'outline' | 'destructive' | 'secondary' | 'ghost' | 'link', buttonClass?: string, inputClass?: string }> = {\n default: { \n variant: 'outline',\n buttonClass: 'h-8 text-xs px-2.5',\n },\n error: { \n variant: 'outline',\n buttonClass: 'h-8 text-xs px-2.5 border-destructive text-destructive',\n inputClass: 'border-destructive focus:ring-destructive',\n },\n success: { \n variant: 'outline',\n buttonClass: 'h-8 text-xs px-2.5 border-green-500 text-green-700',\n inputClass: 'border-green-500 focus:ring-green-500',\n },\n warning: { \n variant: 'outline',\n buttonClass: 'h-8 text-xs px-2.5 border-amber-500 text-amber-700',\n inputClass: 'border-amber-500 focus:ring-amber-500',\n },\n sm: { \n variant: 'outline',\n buttonClass: 'h-7 text-[11px] px-2',\n inputClass: 'h-7 text-[11px] px-2 py-1',\n },\n lg: { \n variant: 'outline',\n buttonClass: 'h-10 text-sm px-3',\n inputClass: 'h-10 text-sm px-3 py-2',\n },\n}\n\nconst preset = computed(() => {\n const styleKey = props.styletype || 'default'\n return STYLE_PRESETS[styleKey] ?? STYLE_PRESETS.default\n})\n\nconst buttonClass = computed(() => {\n return cn('justify-between', preset.value?.buttonClass, props.class)\n})\n\nconst inputClass = computed(() => {\n return cn('pl-8 pr-2 py-1.5 focus-visible:ring-0 border-0 border-b rounded-none h-8 text-xs', preset.value?.inputClass)\n})\n\nconst handleChange = (value: ComboboxOption | undefined) => {\n emit('update:modelValue', value)\n emit('change', value)\n}\n</script>\n\n<template>\n <Combobox \n :model-value=\"modelValue\" \n by=\"label\" \n :disabled=\"disabled\"\n :required=\"required\"\n :name=\"name\"\n @update:model-value=\"(value) => handleChange(value as ComboboxOption | undefined)\"\n >\n <ComboboxAnchor as-child>\n <ComboboxTrigger as-child>\n <Button \n :id=\"id\"\n :variant=\"preset.variant\" \n :class=\"buttonClass\"\n :disabled=\"disabled\"\n @focus=\"emit('focus', $event as FocusEvent)\"\n @blur=\"emit('blur', $event as FocusEvent)\"\n >\n {{ modelValue?.label ?? placeholder }}\n <ChevronsUpDown class=\"ml-2 h-3.5 w-3.5 shrink-0 opacity-50\" />\n </Button>\n </ComboboxTrigger>\n </ComboboxAnchor>\n\n <ComboboxList>\n <div class=\"relative w-full max-w-sm items-center\">\n <ComboboxInput :class=\"inputClass\" :placeholder=\"searchPlaceholder\" />\n <span class=\"absolute start-0 inset-y-0 flex items-center justify-center px-2.5\">\n <Search class=\"size-3.5 text-muted-foreground\" />\n </span>\n </div>\n\n <ComboboxEmpty>\n {{ emptyText }}\n </ComboboxEmpty>\n\n <ComboboxGroup>\n <ComboboxItem\n v-for=\"option in options\"\n :key=\"option.value\"\n :value=\"option\"\n >\n {{ option.label }}\n\n <Check v-if=\"modelValue?.value === option.value\" :class=\"cn('ml-auto h-3.5 w-3.5')\" />\n </ComboboxItem>\n </ComboboxGroup>\n </ComboboxList>\n </Combobox>\n</template>\n"],"names":["props","__props","emit","__emit","STYLE_PRESETS","preset","computed","styleKey","buttonClass","cn","inputClass","handleChange","value","_createBlock","_unref","Combobox","_cache","_createVNode","ComboboxAnchor","ComboboxTrigger","Button","$event","_createTextVNode","_toDisplayString","ChevronsUpDown","ComboboxList","_createElementVNode","_hoisted_1","ComboboxInput","_hoisted_2","Search","ComboboxEmpty","ComboboxGroup","_createElementBlock","_Fragment","_renderList","option","ComboboxItem","Check"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("vue"),c=require("../../lib/utils.cjs");require("lucide-vue-next");require("../shadcn/index.cjs");;/* empty css */require("@internationalized/date");require("md-editor-v3");;/* empty css */;/* empty css */require("../shadcn/badge-variants.cjs");require("@vueuse/core");require("reka-ui");;/* empty css */require("../shadcn/avatar-variants.cjs");const o=require("./JIcon.vue.cjs");require("dompurify");;/* empty css */require("ag-grid-vue3");require("ag-grid-community");require("ag-grid-enterprise");;/* empty css */;/* empty css */;/* empty css */;/* empty css */;/* empty css */;/* empty css */require("vue-sonner");const u={class:"j-section-title-content"},l={class:"j-section-title-text-wrapper"},s={class:"j-section-title-text"},a={key:0,class:"j-section-subtitle-text"},d=e.defineComponent({__name:"JSectionTitle",props:{title:{},subtitle:{},variant:{default:"default"},icon:{},class:{}},setup(t){const r=t,i={default:"border-l-border text-foreground dark:border-l-border",primary:"border-l-primary text-primary",secondary:"border-l-secondary text-secondary",accent:"border-l-accent text-accent"},n=e.computed(()=>i[r.variant]||i.default);return(q,m)=>(e.openBlock(),e.createElementBlock("div",{class:e.normalizeClass(e.unref(c.cn)("j-section-title",n.value,r.class))},[e.createElementVNode("div",u,[t.icon?(e.openBlock(),e.createBlock(e.unref(o.default),{key:0,name:t.icon,class:"j-section-title-icon"},null,8,["name"])):e.createCommentVNode("",!0),e.createElementVNode("div",l,[e.createElementVNode("h3",s,e.toDisplayString(t.title),1),t.subtitle?(e.openBlock(),e.createElementBlock("p",a,e.toDisplayString(t.subtitle),1)):e.createCommentVNode("",!0)])])],2))}});exports.default=d;
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("vue"),c=require("../../lib/utils.cjs");require("lucide-vue-next");require("../shadcn/index.cjs");;/* empty css */require("@internationalized/date");require("md-editor-v3");;/* empty css */;/* empty css */require("../shadcn/badge-variants.cjs");require("@vueuse/core");require("reka-ui");;/* empty css */require("../shadcn/avatar-variants.cjs");const o=require("./JIcon.vue.cjs");require("dompurify");;/* empty css */require("ag-grid-vue3");require("ag-grid-community");require("ag-grid-enterprise");;/* empty css */;/* empty css */;/* empty css */require("vue-sonner");const u={class:"j-section-title-content"},l={class:"j-section-title-text-wrapper"},s={class:"j-section-title-text"},a={key:0,class:"j-section-subtitle-text"},d=e.defineComponent({__name:"JSectionTitle",props:{title:{},subtitle:{},variant:{default:"default"},icon:{},class:{}},setup(t){const r=t,i={default:"border-l-border text-foreground dark:border-l-border",primary:"border-l-primary text-primary",secondary:"border-l-secondary text-secondary",accent:"border-l-accent text-accent"},n=e.computed(()=>i[r.variant]||i.default);return(q,m)=>(e.openBlock(),e.createElementBlock("div",{class:e.normalizeClass(e.unref(c.cn)("j-section-title",n.value,r.class))},[e.createElementVNode("div",u,[t.icon?(e.openBlock(),e.createBlock(e.unref(o.default),{key:0,name:t.icon,class:"j-section-title-icon"},null,8,["name"])):e.createCommentVNode("",!0),e.createElementVNode("div",l,[e.createElementVNode("h3",s,e.toDisplayString(t.title),1),t.subtitle?(e.openBlock(),e.createElementBlock("p",a,e.toDisplayString(t.subtitle),1)):e.createCommentVNode("",!0)])])],2))}});exports.default=d;
2
2
  //# sourceMappingURL=JSectionTitle.vue2.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"JSectionTitle.vue2.cjs","sources":["../../../../src/components/atoms/JSectionTitle.vue"],"sourcesContent":["<template>\n <div :class=\"cn('j-section-title', variantClasses, props.class)\">\n <div class=\"j-section-title-content\">\n <JIcon v-if=\"icon\" :name=\"icon\" class=\"j-section-title-icon\" />\n <div class=\"j-section-title-text-wrapper\">\n <h3 class=\"j-section-title-text\">{{ title }}</h3>\n <p v-if=\"subtitle\" class=\"j-section-subtitle-text\">{{ subtitle }}</p>\n </div>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport { cn } from '@/lib/utils'\nimport { JIcon } from '@/components/atoms'\nimport type { JSectionTitleProps, SectionTitleVariant } from '@/types/section-title.types'\n\nconst props = withDefaults(defineProps<JSectionTitleProps>(), {\n variant: 'default',\n})\n\nconst VARIANT_STYLES: Record<SectionTitleVariant, string> = {\n default: 'border-l-border text-foreground dark:border-l-border',\n primary: 'border-l-primary text-primary',\n secondary: 'border-l-secondary text-secondary',\n accent: 'border-l-accent text-accent',\n}\n\nconst variantClasses = computed(() => {\n return VARIANT_STYLES[props.variant] || VARIANT_STYLES.default\n})\n</script>\n\n<style scoped>\n.j-section-title {\n position: relative;\n display: flex;\n flex-direction: column;\n gap: 0.375rem;\n padding: 0.75rem 1rem;\n border-left: 3px solid;\n border-radius: 0.375rem;\n background: hsl(var(--card));\n box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);\n transition: all 0.2s ease;\n overflow: hidden;\n}\n\n.j-section-title::before {\n content: '';\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n height: 2px;\n background: currentColor;\n opacity: 0.15;\n}\n\n.j-section-title:hover {\n box-shadow: 0 2px 4px 0 rgb(0 0 0 / 0.08);\n transform: translateY(-1px);\n}\n\n.j-section-title-content {\n display: flex;\n align-items: flex-start;\n gap: 0.625rem;\n}\n\n.j-section-title-icon {\n width: 1.125rem;\n height: 1.125rem;\n flex-shrink: 0;\n margin-top: 0.125rem;\n color: currentColor;\n}\n\n.j-section-title-text-wrapper {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 0.25rem;\n}\n\n.j-section-title-text {\n font-size: 0.9375rem;\n font-weight: 600;\n color: hsl(var(--foreground));\n line-height: 1.3;\n letter-spacing: -0.01em;\n}\n\n.j-section-title-subtitle-text {\n font-size: 0.8125rem;\n color: hsl(var(--muted-foreground));\n line-height: 1.4;\n}\n</style>\n"],"names":["props","__props","VARIANT_STYLES","variantClasses","computed","_createElementBlock","_unref","cn","_createElementVNode","_hoisted_1","_createBlock","JIcon","_hoisted_2","_hoisted_3","_toDisplayString","_hoisted_4"],"mappings":"+hDAkBA,MAAMA,EAAQC,EAIRC,EAAsD,CAC1D,QAAS,uDACT,QAAS,gCACT,UAAW,oCACX,OAAQ,6BAAA,EAGJC,EAAiBC,EAAAA,SAAS,IACvBF,EAAeF,EAAM,OAAO,GAAKE,EAAe,OACxD,8BA9BCG,EAAAA,mBAQM,MAAA,CARA,uBAAOC,EAAAA,MAAAC,IAAA,EAAE,kBAAoBJ,QAAgBH,EAAM,KAAK,CAAA,CAAA,GAC5DQ,EAAAA,mBAMM,MANNC,EAMM,CALSR,EAAA,oBAAbS,EAAAA,YAA+DJ,EAAAA,MAAAK,EAAAA,OAAA,EAAA,OAA3C,KAAMV,EAAA,KAAM,MAAM,sBAAA,gDACtCO,EAAAA,mBAGM,MAHNI,EAGM,CAFJJ,EAAAA,mBAAiD,KAAjDK,EAAiDC,EAAAA,gBAAbb,EAAA,KAAK,EAAA,CAAA,EAChCA,EAAA,wBAATI,EAAAA,mBAAqE,IAArEU,EAAqED,EAAAA,gBAAfb,EAAA,QAAQ,EAAA,CAAA"}
1
+ {"version":3,"file":"JSectionTitle.vue2.cjs","sources":["../../../../src/components/atoms/JSectionTitle.vue"],"sourcesContent":["<template>\n <div :class=\"cn('j-section-title', variantClasses, props.class)\">\n <div class=\"j-section-title-content\">\n <JIcon v-if=\"icon\" :name=\"icon\" class=\"j-section-title-icon\" />\n <div class=\"j-section-title-text-wrapper\">\n <h3 class=\"j-section-title-text\">{{ title }}</h3>\n <p v-if=\"subtitle\" class=\"j-section-subtitle-text\">{{ subtitle }}</p>\n </div>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport { cn } from '@/lib/utils'\nimport { JIcon } from '@/components/atoms'\nimport type { JSectionTitleProps, SectionTitleVariant } from '@/types/section-title.types'\n\nconst props = withDefaults(defineProps<JSectionTitleProps>(), {\n variant: 'default',\n})\n\nconst VARIANT_STYLES: Record<SectionTitleVariant, string> = {\n default: 'border-l-border text-foreground dark:border-l-border',\n primary: 'border-l-primary text-primary',\n secondary: 'border-l-secondary text-secondary',\n accent: 'border-l-accent text-accent',\n}\n\nconst variantClasses = computed(() => {\n return VARIANT_STYLES[props.variant] || VARIANT_STYLES.default\n})\n</script>\n\n<style scoped>\n.j-section-title {\n position: relative;\n display: flex;\n flex-direction: column;\n gap: 0.375rem;\n padding: 0.75rem 1rem;\n border-left: 3px solid;\n border-radius: 0.375rem;\n background: hsl(var(--card));\n box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);\n transition: all 0.2s ease;\n overflow: hidden;\n}\n\n.j-section-title::before {\n content: '';\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n height: 2px;\n background: currentColor;\n opacity: 0.15;\n}\n\n.j-section-title:hover {\n box-shadow: 0 2px 4px 0 rgb(0 0 0 / 0.08);\n transform: translateY(-1px);\n}\n\n.j-section-title-content {\n display: flex;\n align-items: flex-start;\n gap: 0.625rem;\n}\n\n.j-section-title-icon {\n width: 1.125rem;\n height: 1.125rem;\n flex-shrink: 0;\n margin-top: 0.125rem;\n color: currentColor;\n}\n\n.j-section-title-text-wrapper {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 0.25rem;\n}\n\n.j-section-title-text {\n font-size: 0.9375rem;\n font-weight: 600;\n color: hsl(var(--foreground));\n line-height: 1.3;\n letter-spacing: -0.01em;\n}\n\n.j-section-title-subtitle-text {\n font-size: 0.8125rem;\n color: hsl(var(--muted-foreground));\n line-height: 1.4;\n}\n</style>\n"],"names":["props","__props","VARIANT_STYLES","variantClasses","computed","_createElementBlock","_unref","cn","_createElementVNode","_hoisted_1","_createBlock","JIcon","_hoisted_2","_hoisted_3","_toDisplayString","_hoisted_4"],"mappings":"8qCAkBA,MAAMA,EAAQC,EAIRC,EAAsD,CAC1D,QAAS,uDACT,QAAS,gCACT,UAAW,oCACX,OAAQ,6BAAA,EAGJC,EAAiBC,EAAAA,SAAS,IACvBF,EAAeF,EAAM,OAAO,GAAKE,EAAe,OACxD,8BA9BCG,EAAAA,mBAQM,MAAA,CARA,uBAAOC,EAAAA,MAAAC,IAAA,EAAE,kBAAoBJ,QAAgBH,EAAM,KAAK,CAAA,CAAA,GAC5DQ,EAAAA,mBAMM,MANNC,EAMM,CALSR,EAAA,oBAAbS,EAAAA,YAA+DJ,EAAAA,MAAAK,EAAAA,OAAA,EAAA,OAA3C,KAAMV,EAAA,KAAM,MAAM,sBAAA,gDACtCO,EAAAA,mBAGM,MAHNI,EAGM,CAFJJ,EAAAA,mBAAiD,KAAjDK,EAAiDC,EAAAA,gBAAbb,EAAA,KAAK,EAAA,CAAA,EAChCA,EAAA,wBAATI,EAAAA,mBAAqE,IAArEU,EAAqED,EAAAA,gBAAfb,EAAA,QAAQ,EAAA,CAAA"}
@@ -1,4 +1,4 @@
1
- import { defineComponent as l, computed as p, createElementBlock as c, openBlock as e, normalizeClass as d, unref as n, createElementVNode as o, createBlock as u, createCommentVNode as s, toDisplayString as a } from "vue";
1
+ import { defineComponent as m, computed as p, createElementBlock as c, openBlock as e, normalizeClass as d, unref as n, createElementVNode as o, createBlock as u, createCommentVNode as s, toDisplayString as a } from "vue";
2
2
  import { cn as f } from "../../lib/utils.js";
3
3
  import "lucide-vue-next";
4
4
  import "../shadcn/index.js";
@@ -18,9 +18,6 @@ import "dompurify";
18
18
  import "ag-grid-vue3";
19
19
  import "ag-grid-community";
20
20
  import "ag-grid-enterprise";
21
- /* empty css */
22
- /* empty css */
23
- /* empty css */
24
21
  /* empty css */
25
22
  /* empty css */
26
23
  /* empty css */
@@ -28,7 +25,7 @@ import "vue-sonner";
28
25
  const x = { class: "j-section-title-content" }, y = { class: "j-section-title-text-wrapper" }, v = { class: "j-section-title-text" }, _ = {
29
26
  key: 0,
30
27
  class: "j-section-subtitle-text"
31
- }, Q = /* @__PURE__ */ l({
28
+ }, M = /* @__PURE__ */ m({
32
29
  __name: "JSectionTitle",
33
30
  props: {
34
31
  title: {},
@@ -43,9 +40,9 @@ const x = { class: "j-section-title-content" }, y = { class: "j-section-title-te
43
40
  primary: "border-l-primary text-primary",
44
41
  secondary: "border-l-secondary text-secondary",
45
42
  accent: "border-l-accent text-accent"
46
- }, m = p(() => i[r.variant] || i.default);
43
+ }, l = p(() => i[r.variant] || i.default);
47
44
  return (h, j) => (e(), c("div", {
48
- class: d(n(f)("j-section-title", m.value, r.class))
45
+ class: d(n(f)("j-section-title", l.value, r.class))
49
46
  }, [
50
47
  o("div", x, [
51
48
  t.icon ? (e(), u(n(b), {
@@ -62,6 +59,6 @@ const x = { class: "j-section-title-content" }, y = { class: "j-section-title-te
62
59
  }
63
60
  });
64
61
  export {
65
- Q as default
62
+ M as default
66
63
  };
67
64
  //# sourceMappingURL=JSectionTitle.vue2.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"JSectionTitle.vue2.js","sources":["../../../../src/components/atoms/JSectionTitle.vue"],"sourcesContent":["<template>\n <div :class=\"cn('j-section-title', variantClasses, props.class)\">\n <div class=\"j-section-title-content\">\n <JIcon v-if=\"icon\" :name=\"icon\" class=\"j-section-title-icon\" />\n <div class=\"j-section-title-text-wrapper\">\n <h3 class=\"j-section-title-text\">{{ title }}</h3>\n <p v-if=\"subtitle\" class=\"j-section-subtitle-text\">{{ subtitle }}</p>\n </div>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport { cn } from '@/lib/utils'\nimport { JIcon } from '@/components/atoms'\nimport type { JSectionTitleProps, SectionTitleVariant } from '@/types/section-title.types'\n\nconst props = withDefaults(defineProps<JSectionTitleProps>(), {\n variant: 'default',\n})\n\nconst VARIANT_STYLES: Record<SectionTitleVariant, string> = {\n default: 'border-l-border text-foreground dark:border-l-border',\n primary: 'border-l-primary text-primary',\n secondary: 'border-l-secondary text-secondary',\n accent: 'border-l-accent text-accent',\n}\n\nconst variantClasses = computed(() => {\n return VARIANT_STYLES[props.variant] || VARIANT_STYLES.default\n})\n</script>\n\n<style scoped>\n.j-section-title {\n position: relative;\n display: flex;\n flex-direction: column;\n gap: 0.375rem;\n padding: 0.75rem 1rem;\n border-left: 3px solid;\n border-radius: 0.375rem;\n background: hsl(var(--card));\n box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);\n transition: all 0.2s ease;\n overflow: hidden;\n}\n\n.j-section-title::before {\n content: '';\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n height: 2px;\n background: currentColor;\n opacity: 0.15;\n}\n\n.j-section-title:hover {\n box-shadow: 0 2px 4px 0 rgb(0 0 0 / 0.08);\n transform: translateY(-1px);\n}\n\n.j-section-title-content {\n display: flex;\n align-items: flex-start;\n gap: 0.625rem;\n}\n\n.j-section-title-icon {\n width: 1.125rem;\n height: 1.125rem;\n flex-shrink: 0;\n margin-top: 0.125rem;\n color: currentColor;\n}\n\n.j-section-title-text-wrapper {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 0.25rem;\n}\n\n.j-section-title-text {\n font-size: 0.9375rem;\n font-weight: 600;\n color: hsl(var(--foreground));\n line-height: 1.3;\n letter-spacing: -0.01em;\n}\n\n.j-section-title-subtitle-text {\n font-size: 0.8125rem;\n color: hsl(var(--muted-foreground));\n line-height: 1.4;\n}\n</style>\n"],"names":["props","__props","VARIANT_STYLES","variantClasses","computed","_createElementBlock","_unref","cn","_createElementVNode","_hoisted_1","_createBlock","JIcon","_hoisted_2","_hoisted_3","_toDisplayString","_hoisted_4"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkBA,UAAMA,IAAQC,GAIRC,IAAsD;AAAA,MAC1D,SAAS;AAAA,MACT,SAAS;AAAA,MACT,WAAW;AAAA,MACX,QAAQ;AAAA,IAAA,GAGJC,IAAiBC,EAAS,MACvBF,EAAeF,EAAM,OAAO,KAAKE,EAAe,OACxD;2BA9BCG,EAQM,OAAA;AAAA,MARA,SAAOC,EAAAC,CAAA,EAAE,mBAAoBJ,SAAgBH,EAAM,KAAK,CAAA;AAAA,IAAA;MAC5DQ,EAMM,OANNC,GAMM;AAAA,QALSR,EAAA,aAAbS,EAA+DJ,EAAAK,CAAA,GAAA;AAAA;UAA3C,MAAMV,EAAA;AAAA,UAAM,OAAM;AAAA,QAAA;QACtCO,EAGM,OAHNI,GAGM;AAAA,UAFJJ,EAAiD,MAAjDK,GAAiDC,EAAbb,EAAA,KAAK,GAAA,CAAA;AAAA,UAChCA,EAAA,iBAATI,EAAqE,KAArEU,GAAqED,EAAfb,EAAA,QAAQ,GAAA,CAAA;;;;;;"}
1
+ {"version":3,"file":"JSectionTitle.vue2.js","sources":["../../../../src/components/atoms/JSectionTitle.vue"],"sourcesContent":["<template>\n <div :class=\"cn('j-section-title', variantClasses, props.class)\">\n <div class=\"j-section-title-content\">\n <JIcon v-if=\"icon\" :name=\"icon\" class=\"j-section-title-icon\" />\n <div class=\"j-section-title-text-wrapper\">\n <h3 class=\"j-section-title-text\">{{ title }}</h3>\n <p v-if=\"subtitle\" class=\"j-section-subtitle-text\">{{ subtitle }}</p>\n </div>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport { cn } from '@/lib/utils'\nimport { JIcon } from '@/components/atoms'\nimport type { JSectionTitleProps, SectionTitleVariant } from '@/types/section-title.types'\n\nconst props = withDefaults(defineProps<JSectionTitleProps>(), {\n variant: 'default',\n})\n\nconst VARIANT_STYLES: Record<SectionTitleVariant, string> = {\n default: 'border-l-border text-foreground dark:border-l-border',\n primary: 'border-l-primary text-primary',\n secondary: 'border-l-secondary text-secondary',\n accent: 'border-l-accent text-accent',\n}\n\nconst variantClasses = computed(() => {\n return VARIANT_STYLES[props.variant] || VARIANT_STYLES.default\n})\n</script>\n\n<style scoped>\n.j-section-title {\n position: relative;\n display: flex;\n flex-direction: column;\n gap: 0.375rem;\n padding: 0.75rem 1rem;\n border-left: 3px solid;\n border-radius: 0.375rem;\n background: hsl(var(--card));\n box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);\n transition: all 0.2s ease;\n overflow: hidden;\n}\n\n.j-section-title::before {\n content: '';\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n height: 2px;\n background: currentColor;\n opacity: 0.15;\n}\n\n.j-section-title:hover {\n box-shadow: 0 2px 4px 0 rgb(0 0 0 / 0.08);\n transform: translateY(-1px);\n}\n\n.j-section-title-content {\n display: flex;\n align-items: flex-start;\n gap: 0.625rem;\n}\n\n.j-section-title-icon {\n width: 1.125rem;\n height: 1.125rem;\n flex-shrink: 0;\n margin-top: 0.125rem;\n color: currentColor;\n}\n\n.j-section-title-text-wrapper {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 0.25rem;\n}\n\n.j-section-title-text {\n font-size: 0.9375rem;\n font-weight: 600;\n color: hsl(var(--foreground));\n line-height: 1.3;\n letter-spacing: -0.01em;\n}\n\n.j-section-title-subtitle-text {\n font-size: 0.8125rem;\n color: hsl(var(--muted-foreground));\n line-height: 1.4;\n}\n</style>\n"],"names":["props","__props","VARIANT_STYLES","variantClasses","computed","_createElementBlock","_unref","cn","_createElementVNode","_hoisted_1","_createBlock","JIcon","_hoisted_2","_hoisted_3","_toDisplayString","_hoisted_4"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkBA,UAAMA,IAAQC,GAIRC,IAAsD;AAAA,MAC1D,SAAS;AAAA,MACT,SAAS;AAAA,MACT,WAAW;AAAA,MACX,QAAQ;AAAA,IAAA,GAGJC,IAAiBC,EAAS,MACvBF,EAAeF,EAAM,OAAO,KAAKE,EAAe,OACxD;2BA9BCG,EAQM,OAAA;AAAA,MARA,SAAOC,EAAAC,CAAA,EAAE,mBAAoBJ,SAAgBH,EAAM,KAAK,CAAA;AAAA,IAAA;MAC5DQ,EAMM,OANNC,GAMM;AAAA,QALSR,EAAA,aAAbS,EAA+DJ,EAAAK,CAAA,GAAA;AAAA;UAA3C,MAAMV,EAAA;AAAA,UAAM,OAAM;AAAA,QAAA;QACtCO,EAGM,OAHNI,GAGM;AAAA,UAFJJ,EAAiD,MAAjDK,GAAiDC,EAAbb,EAAA,KAAK,GAAA,CAAA;AAAA,UAChCA,EAAA,iBAATI,EAAqE,KAArEU,GAAqED,EAAfb,EAAA,QAAQ,GAAA,CAAA;;;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"JSpinner.vue.cjs","sources":["../../../../src/components/atoms/JSpinner.vue"],"sourcesContent":["<script setup lang=\"ts\">\r\nimport { computed } from 'vue'\r\nimport { Loader2Icon } from 'lucide-vue-next'\r\nimport { cn } from '@/lib/utils'\r\n\r\ntype StyleType =\r\n | 'default' // 기본 스타일\r\n | 'primary' // 강조 스타일 (파랑)\r\n | 'success' // 성공 스타일 (초록)\r\n | 'warning' // 경고 스타일 (주황)\r\n | 'danger' // 위험 스타일 (빨강)\r\n\r\ntype LabelPosition =\r\n | 'right' // 오른쪽 (기본)\r\n | 'left' // 왼쪽\r\n | 'top' // 위쪽\r\n | 'bottom' // 아래쪽\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n size?: 'xs' | 'sm' | 'md' | 'lg'\n class?: string\r\n /** 스타일 프리셋 */\r\n styletype?: StyleType\r\n /** 스피너 원의 테두리 두께 */\r\n thickness?: number\r\n /** 스피너 옆에 표시될 텍스트 */\r\n label?: string\r\n /** 라벨 위치 */\r\n labelPosition?: LabelPosition\r\n }>(),\r\n {\n size: 'sm',\n styletype: 'default',\n thickness: 2,\n label: '',\r\n labelPosition: 'right',\r\n },\r\n)\r\n\r\n/**\r\n * 크기별 클래스 매핑\r\n */\r\nconst SIZE_CLASSES = {\n xs: 'size-2.5',\n sm: 'size-3',\n md: 'size-4', \n lg: 'size-5',\n}\n\r\n/**\r\n * 라벨 위치별 레이아웃 클래스 매핑\r\n */\r\nconst LABEL_POSITION_CLASSES = {\r\n right: 'flex-row items-center gap-2',\r\n left: 'flex-row-reverse items-center gap-2',\r\n top: 'flex-col items-center gap-2',\r\n bottom: 'flex-col-reverse items-center gap-2',\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: 'text-blue-500',\r\n },\r\n success: { \r\n class: 'text-green-500',\r\n },\r\n warning: { \r\n class: 'text-amber-500',\r\n },\r\n danger: { \r\n class: 'text-red-500',\r\n },\r\n}\r\n\r\n/** 최종 바인딩: 직접 넘긴 props가 있으면 styletype 기본값과 병합 */\r\nconst spinnerProps = computed(() => {\r\n const preset = STYLE_PRESETS[props.styletype!]\r\n const finalSize = props.size || 'md'\r\n const sizeClass = SIZE_CLASSES[finalSize as keyof typeof SIZE_CLASSES]\r\n const finalClass = cn('animate-spin', sizeClass, preset.class, props.class)\r\n \r\n return {\r\n class: finalClass,\r\n style: {\r\n strokeWidth: props.thickness,\r\n },\r\n 'aria-label': '처리 중',\r\n }\r\n})\r\n\r\n/** 컨테이너 레이아웃 클래스 */\r\nconst containerClass = computed(() => {\r\n const position = props.labelPosition || 'right'\r\n return cn('inline-flex', LABEL_POSITION_CLASSES[position as keyof typeof LABEL_POSITION_CLASSES])\r\n})\r\n</script>\r\n\r\n<template>\r\n <div :class=\"containerClass\">\r\n <Loader2Icon\r\n role=\"status\"\r\n v-bind=\"spinnerProps\"\r\n />\r\n <span v-if=\"props.label\" class=\"text-sm\">{{ props.label }}</span>\r\n </div>\r\n</template>\r\n"],"names":["props","__props","SIZE_CLASSES","LABEL_POSITION_CLASSES","STYLE_PRESETS","spinnerProps","computed","preset","finalSize","sizeClass","cn","containerClass","position","_createElementBlock","_createVNode","_unref","_mergeProps","_openBlock","_hoisted_1","_toDisplayString"],"mappings":"uZAkBA,MAAMA,EAAQC,EAyBRC,EAAe,CACnB,GAAI,WACJ,GAAI,SACJ,GAAI,SACJ,GAAI,QAAA,EAMAC,EAAyB,CAC7B,MAAO,8BACP,KAAM,sCACN,IAAK,8BACL,OAAQ,qCAAA,EAMJC,EAAsD,CAC1D,QAAS,CAAE,MAAO,EAAA,EAClB,QAAS,CACP,MAAO,eAAA,EAET,QAAS,CACP,MAAO,gBAAA,EAET,QAAS,CACP,MAAO,gBAAA,EAET,OAAQ,CACN,MAAO,cAAA,CACT,EAIIC,EAAeC,EAAAA,SAAS,IAAM,CAClC,MAAMC,EAASH,EAAcJ,EAAM,SAAU,EACvCQ,EAAYR,EAAM,MAAQ,KAC1BS,EAAYP,EAAaM,CAAsC,EAGrE,MAAO,CACL,MAHiBE,EAAAA,GAAG,eAAgBD,EAAWF,EAAO,MAAOP,EAAM,KAAK,EAIxE,MAAO,CACL,YAAaA,EAAM,SAAA,EAErB,aAAc,MAAA,CAElB,CAAC,EAGKW,EAAiBL,EAAAA,SAAS,IAAM,CACpC,MAAMM,EAAWZ,EAAM,eAAiB,QACxC,OAAOU,KAAG,cAAeP,EAAuBS,CAA+C,CAAC,CAClG,CAAC,8BAICC,EAAAA,mBAMM,MAAA,CANA,uBAAOF,EAAA,KAAc,CAAA,GACzBG,EAAAA,YAGEC,EAAAA,qBAHFC,EAAAA,WAGE,CAFA,KAAK,QAAA,EACGX,EAAA,KAAY,EAAA,KAAA,EAAA,EAEVL,EAAM,OAAlBiB,EAAAA,UAAA,EAAAJ,EAAAA,mBAAiE,OAAjEK,EAAiEC,EAAAA,gBAArBnB,EAAM,KAAK,EAAA,CAAA"}
1
+ {"version":3,"file":"JSpinner.vue.cjs","sources":["../../../../src/components/atoms/JSpinner.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport { Loader2Icon } from 'lucide-vue-next'\nimport { cn } from '@/lib/utils'\n\ntype StyleType =\n | 'default' // 기본 스타일\n | 'primary' // 강조 스타일 (파랑)\n | 'success' // 성공 스타일 (초록)\n | 'warning' // 경고 스타일 (주황)\n | 'danger' // 위험 스타일 (빨강)\n\ntype LabelPosition =\n | 'right' // 오른쪽 (기본)\n | 'left' // 왼쪽\n | 'top' // 위쪽\n | 'bottom' // 아래쪽\n\nconst props = withDefaults(\n defineProps<{\n size?: 'xs' | 'sm' | 'md' | 'lg'\n class?: string\n /** 스타일 프리셋 */\n styletype?: StyleType\n /** 스피너 원의 테두리 두께 */\n thickness?: number\n /** 스피너 옆에 표시될 텍스트 */\n label?: string\n /** 라벨 위치 */\n labelPosition?: LabelPosition\n }>(),\n {\n size: 'sm',\n styletype: 'default',\n thickness: 2,\n label: '',\n labelPosition: 'right',\n },\n)\n\n/**\n * 크기별 클래스 매핑\n */\nconst SIZE_CLASSES = {\n xs: 'size-2.5',\n sm: 'size-3',\n md: 'size-4', \n lg: 'size-5',\n}\n\n/**\n * 라벨 위치별 레이아웃 클래스 매핑\n */\nconst LABEL_POSITION_CLASSES = {\n right: 'flex-row items-center gap-2',\n left: 'flex-row-reverse items-center gap-2',\n top: 'flex-col items-center gap-2',\n bottom: 'flex-col-reverse items-center gap-2',\n}\n\n/**\n * styletype -> class 매핑\n */\nconst STYLE_PRESETS: Record<StyleType, { class: string }> = {\n default: { class: '' },\n primary: { \n class: 'text-blue-500',\n },\n success: { \n class: 'text-green-500',\n },\n warning: { \n class: 'text-amber-500',\n },\n danger: { \n class: 'text-red-500',\n },\n}\n\n/** 최종 바인딩: 직접 넘긴 props가 있으면 styletype 기본값과 병합 */\nconst spinnerProps = computed(() => {\n const preset = STYLE_PRESETS[props.styletype!]\n const finalSize = props.size || 'md'\n const sizeClass = SIZE_CLASSES[finalSize as keyof typeof SIZE_CLASSES]\n const finalClass = cn('animate-spin', sizeClass, preset.class, props.class)\n \n return {\n class: finalClass,\n style: {\n strokeWidth: props.thickness,\n },\n 'aria-label': '처리 중',\n }\n})\n\n/** 컨테이너 레이아웃 클래스 */\nconst containerClass = computed(() => {\n const position = props.labelPosition || 'right'\n return cn('inline-flex', LABEL_POSITION_CLASSES[position as keyof typeof LABEL_POSITION_CLASSES])\n})\n</script>\n\n<template>\n <div :class=\"containerClass\">\n <Loader2Icon\n role=\"status\"\n v-bind=\"spinnerProps\"\n />\n <span v-if=\"props.label\" class=\"text-sm\">{{ props.label }}</span>\n </div>\n</template>\n"],"names":["props","__props","SIZE_CLASSES","LABEL_POSITION_CLASSES","STYLE_PRESETS","spinnerProps","computed","preset","finalSize","sizeClass","cn","containerClass","position","_createElementBlock","_createVNode","_unref","_mergeProps","_openBlock","_hoisted_1","_toDisplayString"],"mappings":"uZAkBA,MAAMA,EAAQC,EAyBRC,EAAe,CACnB,GAAI,WACJ,GAAI,SACJ,GAAI,SACJ,GAAI,QAAA,EAMAC,EAAyB,CAC7B,MAAO,8BACP,KAAM,sCACN,IAAK,8BACL,OAAQ,qCAAA,EAMJC,EAAsD,CAC1D,QAAS,CAAE,MAAO,EAAA,EAClB,QAAS,CACP,MAAO,eAAA,EAET,QAAS,CACP,MAAO,gBAAA,EAET,QAAS,CACP,MAAO,gBAAA,EAET,OAAQ,CACN,MAAO,cAAA,CACT,EAIIC,EAAeC,EAAAA,SAAS,IAAM,CAClC,MAAMC,EAASH,EAAcJ,EAAM,SAAU,EACvCQ,EAAYR,EAAM,MAAQ,KAC1BS,EAAYP,EAAaM,CAAsC,EAGrE,MAAO,CACL,MAHiBE,EAAAA,GAAG,eAAgBD,EAAWF,EAAO,MAAOP,EAAM,KAAK,EAIxE,MAAO,CACL,YAAaA,EAAM,SAAA,EAErB,aAAc,MAAA,CAElB,CAAC,EAGKW,EAAiBL,EAAAA,SAAS,IAAM,CACpC,MAAMM,EAAWZ,EAAM,eAAiB,QACxC,OAAOU,KAAG,cAAeP,EAAuBS,CAA+C,CAAC,CAClG,CAAC,8BAICC,EAAAA,mBAMM,MAAA,CANA,uBAAOF,EAAA,KAAc,CAAA,GACzBG,EAAAA,YAGEC,EAAAA,qBAHFC,EAAAA,WAGE,CAFA,KAAK,QAAA,EACGX,EAAA,KAAY,EAAA,KAAA,EAAA,EAEVL,EAAM,OAAlBiB,EAAAA,UAAA,EAAAJ,EAAAA,mBAAiE,OAAjEK,EAAiEC,EAAAA,gBAArBnB,EAAM,KAAK,EAAA,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"JSpinner.vue.js","sources":["../../../../src/components/atoms/JSpinner.vue"],"sourcesContent":["<script setup lang=\"ts\">\r\nimport { computed } from 'vue'\r\nimport { Loader2Icon } from 'lucide-vue-next'\r\nimport { cn } from '@/lib/utils'\r\n\r\ntype StyleType =\r\n | 'default' // 기본 스타일\r\n | 'primary' // 강조 스타일 (파랑)\r\n | 'success' // 성공 스타일 (초록)\r\n | 'warning' // 경고 스타일 (주황)\r\n | 'danger' // 위험 스타일 (빨강)\r\n\r\ntype LabelPosition =\r\n | 'right' // 오른쪽 (기본)\r\n | 'left' // 왼쪽\r\n | 'top' // 위쪽\r\n | 'bottom' // 아래쪽\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n size?: 'xs' | 'sm' | 'md' | 'lg'\n class?: string\r\n /** 스타일 프리셋 */\r\n styletype?: StyleType\r\n /** 스피너 원의 테두리 두께 */\r\n thickness?: number\r\n /** 스피너 옆에 표시될 텍스트 */\r\n label?: string\r\n /** 라벨 위치 */\r\n labelPosition?: LabelPosition\r\n }>(),\r\n {\n size: 'sm',\n styletype: 'default',\n thickness: 2,\n label: '',\r\n labelPosition: 'right',\r\n },\r\n)\r\n\r\n/**\r\n * 크기별 클래스 매핑\r\n */\r\nconst SIZE_CLASSES = {\n xs: 'size-2.5',\n sm: 'size-3',\n md: 'size-4', \n lg: 'size-5',\n}\n\r\n/**\r\n * 라벨 위치별 레이아웃 클래스 매핑\r\n */\r\nconst LABEL_POSITION_CLASSES = {\r\n right: 'flex-row items-center gap-2',\r\n left: 'flex-row-reverse items-center gap-2',\r\n top: 'flex-col items-center gap-2',\r\n bottom: 'flex-col-reverse items-center gap-2',\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: 'text-blue-500',\r\n },\r\n success: { \r\n class: 'text-green-500',\r\n },\r\n warning: { \r\n class: 'text-amber-500',\r\n },\r\n danger: { \r\n class: 'text-red-500',\r\n },\r\n}\r\n\r\n/** 최종 바인딩: 직접 넘긴 props가 있으면 styletype 기본값과 병합 */\r\nconst spinnerProps = computed(() => {\r\n const preset = STYLE_PRESETS[props.styletype!]\r\n const finalSize = props.size || 'md'\r\n const sizeClass = SIZE_CLASSES[finalSize as keyof typeof SIZE_CLASSES]\r\n const finalClass = cn('animate-spin', sizeClass, preset.class, props.class)\r\n \r\n return {\r\n class: finalClass,\r\n style: {\r\n strokeWidth: props.thickness,\r\n },\r\n 'aria-label': '처리 중',\r\n }\r\n})\r\n\r\n/** 컨테이너 레이아웃 클래스 */\r\nconst containerClass = computed(() => {\r\n const position = props.labelPosition || 'right'\r\n return cn('inline-flex', LABEL_POSITION_CLASSES[position as keyof typeof LABEL_POSITION_CLASSES])\r\n})\r\n</script>\r\n\r\n<template>\r\n <div :class=\"containerClass\">\r\n <Loader2Icon\r\n role=\"status\"\r\n v-bind=\"spinnerProps\"\r\n />\r\n <span v-if=\"props.label\" class=\"text-sm\">{{ props.label }}</span>\r\n </div>\r\n</template>\r\n"],"names":["props","__props","SIZE_CLASSES","LABEL_POSITION_CLASSES","STYLE_PRESETS","spinnerProps","computed","preset","finalSize","sizeClass","cn","containerClass","position","_createElementBlock","_createVNode","_unref","_mergeProps","_openBlock","_hoisted_1","_toDisplayString"],"mappings":";;;;;;;;;;;;;;;;;AAkBA,UAAMA,IAAQC,GAyBRC,IAAe;AAAA,MACnB,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,IAAI;AAAA,IAAA,GAMAC,IAAyB;AAAA,MAC7B,OAAO;AAAA,MACP,MAAM;AAAA,MACN,KAAK;AAAA,MACL,QAAQ;AAAA,IAAA,GAMJC,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,GAIIC,IAAeC,EAAS,MAAM;AAClC,YAAMC,IAASH,EAAcJ,EAAM,SAAU,GACvCQ,IAAYR,EAAM,QAAQ,MAC1BS,IAAYP,EAAaM,CAAsC;AAGrE,aAAO;AAAA,QACL,OAHiBE,EAAG,gBAAgBD,GAAWF,EAAO,OAAOP,EAAM,KAAK;AAAA,QAIxE,OAAO;AAAA,UACL,aAAaA,EAAM;AAAA,QAAA;AAAA,QAErB,cAAc;AAAA,MAAA;AAAA,IAElB,CAAC,GAGKW,IAAiBL,EAAS,MAAM;AACpC,YAAMM,IAAWZ,EAAM,iBAAiB;AACxC,aAAOU,EAAG,eAAeP,EAAuBS,CAA+C,CAAC;AAAA,IAClG,CAAC;2BAICC,EAMM,OAAA;AAAA,MANA,SAAOF,EAAA,KAAc;AAAA,IAAA;MACzBG,EAGEC,MAHFC,EAGE,EAFA,MAAK,SAAA,GACGX,EAAA,KAAY,GAAA,MAAA,EAAA;AAAA,MAEVL,EAAM,SAAlBiB,EAAA,GAAAJ,EAAiE,QAAjEK,GAAiEC,EAArBnB,EAAM,KAAK,GAAA,CAAA;;;;"}
1
+ {"version":3,"file":"JSpinner.vue.js","sources":["../../../../src/components/atoms/JSpinner.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport { Loader2Icon } from 'lucide-vue-next'\nimport { cn } from '@/lib/utils'\n\ntype StyleType =\n | 'default' // 기본 스타일\n | 'primary' // 강조 스타일 (파랑)\n | 'success' // 성공 스타일 (초록)\n | 'warning' // 경고 스타일 (주황)\n | 'danger' // 위험 스타일 (빨강)\n\ntype LabelPosition =\n | 'right' // 오른쪽 (기본)\n | 'left' // 왼쪽\n | 'top' // 위쪽\n | 'bottom' // 아래쪽\n\nconst props = withDefaults(\n defineProps<{\n size?: 'xs' | 'sm' | 'md' | 'lg'\n class?: string\n /** 스타일 프리셋 */\n styletype?: StyleType\n /** 스피너 원의 테두리 두께 */\n thickness?: number\n /** 스피너 옆에 표시될 텍스트 */\n label?: string\n /** 라벨 위치 */\n labelPosition?: LabelPosition\n }>(),\n {\n size: 'sm',\n styletype: 'default',\n thickness: 2,\n label: '',\n labelPosition: 'right',\n },\n)\n\n/**\n * 크기별 클래스 매핑\n */\nconst SIZE_CLASSES = {\n xs: 'size-2.5',\n sm: 'size-3',\n md: 'size-4', \n lg: 'size-5',\n}\n\n/**\n * 라벨 위치별 레이아웃 클래스 매핑\n */\nconst LABEL_POSITION_CLASSES = {\n right: 'flex-row items-center gap-2',\n left: 'flex-row-reverse items-center gap-2',\n top: 'flex-col items-center gap-2',\n bottom: 'flex-col-reverse items-center gap-2',\n}\n\n/**\n * styletype -> class 매핑\n */\nconst STYLE_PRESETS: Record<StyleType, { class: string }> = {\n default: { class: '' },\n primary: { \n class: 'text-blue-500',\n },\n success: { \n class: 'text-green-500',\n },\n warning: { \n class: 'text-amber-500',\n },\n danger: { \n class: 'text-red-500',\n },\n}\n\n/** 최종 바인딩: 직접 넘긴 props가 있으면 styletype 기본값과 병합 */\nconst spinnerProps = computed(() => {\n const preset = STYLE_PRESETS[props.styletype!]\n const finalSize = props.size || 'md'\n const sizeClass = SIZE_CLASSES[finalSize as keyof typeof SIZE_CLASSES]\n const finalClass = cn('animate-spin', sizeClass, preset.class, props.class)\n \n return {\n class: finalClass,\n style: {\n strokeWidth: props.thickness,\n },\n 'aria-label': '처리 중',\n }\n})\n\n/** 컨테이너 레이아웃 클래스 */\nconst containerClass = computed(() => {\n const position = props.labelPosition || 'right'\n return cn('inline-flex', LABEL_POSITION_CLASSES[position as keyof typeof LABEL_POSITION_CLASSES])\n})\n</script>\n\n<template>\n <div :class=\"containerClass\">\n <Loader2Icon\n role=\"status\"\n v-bind=\"spinnerProps\"\n />\n <span v-if=\"props.label\" class=\"text-sm\">{{ props.label }}</span>\n </div>\n</template>\n"],"names":["props","__props","SIZE_CLASSES","LABEL_POSITION_CLASSES","STYLE_PRESETS","spinnerProps","computed","preset","finalSize","sizeClass","cn","containerClass","position","_createElementBlock","_createVNode","_unref","_mergeProps","_openBlock","_hoisted_1","_toDisplayString"],"mappings":";;;;;;;;;;;;;;;;;AAkBA,UAAMA,IAAQC,GAyBRC,IAAe;AAAA,MACnB,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,IAAI;AAAA,IAAA,GAMAC,IAAyB;AAAA,MAC7B,OAAO;AAAA,MACP,MAAM;AAAA,MACN,KAAK;AAAA,MACL,QAAQ;AAAA,IAAA,GAMJC,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,GAIIC,IAAeC,EAAS,MAAM;AAClC,YAAMC,IAASH,EAAcJ,EAAM,SAAU,GACvCQ,IAAYR,EAAM,QAAQ,MAC1BS,IAAYP,EAAaM,CAAsC;AAGrE,aAAO;AAAA,QACL,OAHiBE,EAAG,gBAAgBD,GAAWF,EAAO,OAAOP,EAAM,KAAK;AAAA,QAIxE,OAAO;AAAA,UACL,aAAaA,EAAM;AAAA,QAAA;AAAA,QAErB,cAAc;AAAA,MAAA;AAAA,IAElB,CAAC,GAGKW,IAAiBL,EAAS,MAAM;AACpC,YAAMM,IAAWZ,EAAM,iBAAiB;AACxC,aAAOU,EAAG,eAAeP,EAAuBS,CAA+C,CAAC;AAAA,IAClG,CAAC;2BAICC,EAMM,OAAA;AAAA,MANA,SAAOF,EAAA,KAAc;AAAA,IAAA;MACzBG,EAGEC,MAHFC,EAGE,EAFA,MAAK,SAAA,GACGX,EAAA,KAAY,GAAA,MAAA,EAAA;AAAA,MAEVL,EAAM,SAAlBiB,EAAA,GAAAJ,EAAiE,QAAjEK,GAAiEC,EAArBnB,EAAM,KAAK,GAAA,CAAA;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"JToast.vue.cjs","sources":["../../../../src/components/atoms/JToast.vue"],"sourcesContent":["<script setup lang=\"ts\">\r\nimport { Toaster } from '@/components/shadcn'\r\nimport type { ToasterProps } from 'vue-sonner'\r\n\r\nconst props = withDefaults(\r\n defineProps<ToasterProps>(),\r\n {\r\n position: 'top-center',\r\n expand: true,\r\n richColors: true,\r\n closeButton: false,\r\n },\r\n)\r\n</script>\r\n\r\n<template>\r\n <Toaster v-bind=\"props\" />\r\n</template>\r\n\r\n"],"names":["props","__props","_openBlock","_createBlock","_unref"],"mappings":"gnBAIA,MAAMA,EAAQC,gBAYZC,YAAA,EAAAC,cAA0BC,EAAAA,uDAATJ,CAAK,CAAA,EAAA,KAAA,EAAA"}
1
+ {"version":3,"file":"JToast.vue.cjs","sources":["../../../../src/components/atoms/JToast.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { Toaster } from '@/components/shadcn'\nimport type { ToasterProps } from 'vue-sonner'\n\nconst props = withDefaults(\n defineProps<ToasterProps>(),\n {\n position: 'top-center',\n expand: true,\n richColors: true,\n closeButton: false,\n },\n)\n</script>\n\n<template>\n <Toaster v-bind=\"props\" />\n</template>\n\n"],"names":["props","__props","_openBlock","_createBlock","_unref"],"mappings":"gnBAIA,MAAMA,EAAQC,gBAYZC,YAAA,EAAAC,cAA0BC,EAAAA,uDAATJ,CAAK,CAAA,EAAA,KAAA,EAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"JToast.vue.js","sources":["../../../../src/components/atoms/JToast.vue"],"sourcesContent":["<script setup lang=\"ts\">\r\nimport { Toaster } from '@/components/shadcn'\r\nimport type { ToasterProps } from 'vue-sonner'\r\n\r\nconst props = withDefaults(\r\n defineProps<ToasterProps>(),\r\n {\r\n position: 'top-center',\r\n expand: true,\r\n richColors: true,\r\n closeButton: false,\r\n },\r\n)\r\n</script>\r\n\r\n<template>\r\n <Toaster v-bind=\"props\" />\r\n</template>\r\n\r\n"],"names":["props","__props","_openBlock","_createBlock","_unref"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAIA,UAAMA,IAAQC;sBAYZC,EAAA,GAAAC,EAA0BC,UAATJ,CAAK,CAAA,GAAA,MAAA,EAAA;AAAA;;"}
1
+ {"version":3,"file":"JToast.vue.js","sources":["../../../../src/components/atoms/JToast.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { Toaster } from '@/components/shadcn'\nimport type { ToasterProps } from 'vue-sonner'\n\nconst props = withDefaults(\n defineProps<ToasterProps>(),\n {\n position: 'top-center',\n expand: true,\n richColors: true,\n closeButton: false,\n },\n)\n</script>\n\n<template>\n <Toaster v-bind=\"props\" />\n</template>\n\n"],"names":["props","__props","_openBlock","_createBlock","_unref"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAIA,UAAMA,IAAQC;sBAYZC,EAAA,GAAAC,EAA0BC,UAATJ,CAAK,CAAA,GAAA,MAAA,EAAA;AAAA;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"JTooltip.vue.cjs","sources":["../../../../src/components/atoms/JTooltip.vue"],"sourcesContent":["<script setup lang=\"ts\">\r\nimport { computed, ref, onMounted, onUnmounted } from 'vue'\r\nimport Tooltip from '@/components/shadcn/Tooltip.vue'\r\nimport TooltipContent from '@/components/shadcn/TooltipContent.vue'\r\nimport TooltipProvider from '@/components/shadcn/TooltipProvider.vue'\r\nimport TooltipTrigger from '@/components/shadcn/TooltipTrigger.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 Size = 'xs' | 'sm' | 'md' | 'lg'\n\r\ntype Trigger = 'hover' | 'focus' | 'click' | 'manual'\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n content?: string\r\n side?: 'top' | 'right' | 'bottom' | 'left'\r\n align?: 'start' | 'center' | 'end'\r\n class?: string\r\n /** 스타일 프리셋 */\r\n styletype?: StyleType\r\n /** 툴팁 크기 */\r\n size?: Size\r\n /** 툴팁 비활성화 */\r\n disabled?: boolean\r\n /** 표시 지연 시간 (ms) */\r\n delay?: number\r\n /** 툴팁 최대 너비 */\r\n maxWidth?: string | number\r\n /** 툴팁 트리거 타입 */\r\n trigger?: Trigger\r\n }>(),\r\n {\n side: 'top',\n align: 'center',\n styletype: 'default',\n size: 'sm',\n disabled: false,\n delay: 200,\n maxWidth: '200px',\n trigger: 'hover',\r\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: 'bg-blue-500 text-white border-blue-600',\r\n },\r\n success: { \r\n class: 'bg-green-500 text-white border-green-600',\r\n },\r\n warning: { \r\n class: 'bg-amber-500 text-white border-amber-600',\r\n },\r\n danger: { \r\n class: 'bg-red-500 text-white border-red-600',\r\n },\r\n}\r\n\r\n/**\r\n * size -> class 매핑\r\n */\r\nconst SIZE_PRESETS: Record<Size, { class: string }> = {\n xs: { \n class: 'text-[10px] px-1.5 py-0.5 max-w-40',\n },\n sm: { \n class: 'text-xs px-2 py-1 max-w-48',\n },\n md: { \n class: 'text-xs px-2.5 py-1 max-w-56',\n },\n lg: { \n class: 'text-sm px-3 py-1.5 max-w-64',\n },\n}\n\r\n// click과 manual 트리거를 위한 상태 관리\r\nconst isOpen = ref(false)\r\n\r\n// 각 트리거 타입별 핸들러\r\nconst handleClick = (event: MouseEvent) => {\r\n console.log('Click handler called, trigger:', props.trigger)\r\n if (props.trigger === 'click') {\r\n console.log('Toggling tooltip, current state:', isOpen.value)\r\n isOpen.value = !isOpen.value\r\n console.log('New state:', isOpen.value)\r\n } else if (props.trigger === 'focus') {\r\n // focus 트리거에서는 클릭 이벤트 무시\r\n event.preventDefault()\r\n event.stopPropagation()\r\n }\r\n}\r\n\r\n// delay를 위한 타이머 관리\r\nlet hoverTimer: number | null = null\r\n\r\nconst handleMouseEnter = () => {\r\n if (props.trigger === 'hover') {\r\n // 기존 타이머가 있으면 취소\r\n if (hoverTimer) {\r\n clearTimeout(hoverTimer)\r\n }\r\n // delay 적용\r\n hoverTimer = setTimeout(() => {\r\n isOpen.value = true\r\n }, props.delay)\r\n }\r\n}\r\n\r\nconst handleMouseLeave = () => {\r\n if (props.trigger === 'hover') {\r\n // 타이머 취소\r\n if (hoverTimer) {\r\n clearTimeout(hoverTimer)\r\n hoverTimer = null\r\n }\r\n isOpen.value = false\r\n }\r\n}\r\n\r\nconst handleFocus = () => {\r\n if (props.trigger === 'focus') {\r\n isOpen.value = true\r\n }\r\n}\r\n\r\nconst handleBlur = () => {\r\n if (props.trigger === 'focus') {\r\n isOpen.value = false\r\n }\r\n}\r\n\r\n// 트리거 타입에 따른 Tooltip 설정 계산\r\nconst tooltipConfig = computed(() => {\r\n const config: any = {\r\n disabled: props.disabled,\r\n }\r\n \r\n // 모든 트리거 타입에 대해 수동 제어\r\n config.open = isOpen.value\r\n \r\n return config\r\n})\r\n\r\n// 외부 클릭 감지를 위한 핸들러\r\nconst handleOutsideClick = (event: Event) => {\r\n if (props.trigger === 'hover' && isOpen.value) {\r\n const target = event.target as HTMLElement\r\n const tooltipElement = document.querySelector('[data-tooltip-trigger]')\r\n if (tooltipElement && !tooltipElement.contains(target)) {\r\n isOpen.value = false\r\n }\r\n }\r\n}\r\n\r\n// manual 트리거를 위한 메서드들\r\nconst showTooltip = () => {\r\n if (props.trigger === 'manual') {\r\n isOpen.value = true\r\n }\r\n}\r\n\r\nconst hideTooltip = () => {\r\n if (props.trigger === 'manual') {\r\n isOpen.value = false\r\n }\r\n}\r\n\r\n// 외부에서 사용할 수 있도록 expose\r\ndefineExpose({\r\n showTooltip,\r\n hideTooltip,\r\n})\r\n\r\n// 외부 클릭 감지를 위한 이벤트 리스너 등록/해제\r\nonMounted(() => {\r\n if (props.trigger === 'hover') {\r\n document.addEventListener('click', handleOutsideClick)\r\n }\r\n})\r\n\r\nonUnmounted(() => {\r\n if (props.trigger === 'hover') {\r\n document.removeEventListener('click', handleOutsideClick)\r\n }\r\n \r\n // 타이머 정리\r\n if (hoverTimer) {\r\n clearTimeout(hoverTimer)\r\n }\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 // maxWidth 스타일 처리\r\n const maxWidthStyle = typeof props.maxWidth === 'number' \r\n ? `${props.maxWidth}px` \r\n : props.maxWidth\r\n \r\n return {\r\n side: props.side,\r\n align: props.align,\r\n class: finalClass,\r\n style: {\r\n maxWidth: maxWidthStyle,\r\n },\r\n }\r\n})\r\n</script>\r\n\r\n<template>\r\n <TooltipProvider :delayDuration=\"props.delay\">\r\n <Tooltip v-bind=\"tooltipConfig\">\r\n <TooltipTrigger \r\n as-child\r\n :data-tooltip-trigger=\"true\"\r\n @click=\"handleClick\"\r\n @mouseenter=\"handleMouseEnter\"\r\n @mouseleave=\"handleMouseLeave\"\r\n @focus=\"handleFocus\"\r\n @blur=\"handleBlur\"\r\n >\r\n <slot name=\"trigger\" />\r\n </TooltipTrigger>\r\n <TooltipContent v-bind=\"mapped\">\r\n {{ props.content }}\r\n </TooltipContent>\r\n </Tooltip>\r\n </TooltipProvider>\r\n</template>\r\n"],"names":["props","__props","STYLE_PRESETS","SIZE_PRESETS","isOpen","ref","handleClick","event","hoverTimer","handleMouseEnter","handleMouseLeave","handleFocus","handleBlur","tooltipConfig","computed","config","handleOutsideClick","target","tooltipElement","__expose","onMounted","onUnmounted","mapped","stylePreset","sizePreset","finalClass","maxWidthStyle","_createBlock","TooltipProvider","_createVNode","Tooltip","TooltipTrigger","_renderSlot","_ctx","TooltipContent","_createTextVNode","_toDisplayString"],"mappings":"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"}
1
+ {"version":3,"file":"JTooltip.vue.cjs","sources":["../../../../src/components/atoms/JTooltip.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, ref, onMounted, onUnmounted } from 'vue'\nimport Tooltip from '@/components/shadcn/Tooltip.vue'\nimport TooltipContent from '@/components/shadcn/TooltipContent.vue'\nimport TooltipProvider from '@/components/shadcn/TooltipProvider.vue'\nimport TooltipTrigger from '@/components/shadcn/TooltipTrigger.vue'\n\ntype StyleType =\n | 'default' // 기본 스타일\n | 'primary' // 강조 스타일 (파랑)\n | 'success' // 성공 스타일 (초록)\n | 'warning' // 경고 스타일 (주황)\n | 'danger' // 위험 스타일 (빨강)\n\ntype Size = 'xs' | 'sm' | 'md' | 'lg'\n\ntype Trigger = 'hover' | 'focus' | 'click' | 'manual'\n\nconst props = withDefaults(\n defineProps<{\n content?: string\n side?: 'top' | 'right' | 'bottom' | 'left'\n align?: 'start' | 'center' | 'end'\n class?: string\n /** 스타일 프리셋 */\n styletype?: StyleType\n /** 툴팁 크기 */\n size?: Size\n /** 툴팁 비활성화 */\n disabled?: boolean\n /** 표시 지연 시간 (ms) */\n delay?: number\n /** 툴팁 최대 너비 */\n maxWidth?: string | number\n /** 툴팁 트리거 타입 */\n trigger?: Trigger\n }>(),\n {\n side: 'top',\n align: 'center',\n styletype: 'default',\n size: 'sm',\n disabled: false,\n delay: 200,\n maxWidth: '200px',\n trigger: 'hover',\n },\n)\n\n/**\n * styletype -> class 매핑\n */\nconst STYLE_PRESETS: Record<StyleType, { class: string }> = {\n default: { class: '' },\n primary: { \n class: 'bg-blue-500 text-white border-blue-600',\n },\n success: { \n class: 'bg-green-500 text-white border-green-600',\n },\n warning: { \n class: 'bg-amber-500 text-white border-amber-600',\n },\n danger: { \n class: 'bg-red-500 text-white border-red-600',\n },\n}\n\n/**\n * size -> class 매핑\n */\nconst SIZE_PRESETS: Record<Size, { class: string }> = {\n xs: { \n class: 'text-[10px] px-1.5 py-0.5 max-w-40',\n },\n sm: { \n class: 'text-xs px-2 py-1 max-w-48',\n },\n md: { \n class: 'text-xs px-2.5 py-1 max-w-56',\n },\n lg: { \n class: 'text-sm px-3 py-1.5 max-w-64',\n },\n}\n\n// click과 manual 트리거를 위한 상태 관리\nconst isOpen = ref(false)\n\n// 각 트리거 타입별 핸들러\nconst handleClick = (event: MouseEvent) => {\n console.log('Click handler called, trigger:', props.trigger)\n if (props.trigger === 'click') {\n console.log('Toggling tooltip, current state:', isOpen.value)\n isOpen.value = !isOpen.value\n console.log('New state:', isOpen.value)\n } else if (props.trigger === 'focus') {\n // focus 트리거에서는 클릭 이벤트 무시\n event.preventDefault()\n event.stopPropagation()\n }\n}\n\n// delay를 위한 타이머 관리\nlet hoverTimer: number | null = null\n\nconst handleMouseEnter = () => {\n if (props.trigger === 'hover') {\n // 기존 타이머가 있으면 취소\n if (hoverTimer) {\n clearTimeout(hoverTimer)\n }\n // delay 적용\n hoverTimer = setTimeout(() => {\n isOpen.value = true\n }, props.delay)\n }\n}\n\nconst handleMouseLeave = () => {\n if (props.trigger === 'hover') {\n // 타이머 취소\n if (hoverTimer) {\n clearTimeout(hoverTimer)\n hoverTimer = null\n }\n isOpen.value = false\n }\n}\n\nconst handleFocus = () => {\n if (props.trigger === 'focus') {\n isOpen.value = true\n }\n}\n\nconst handleBlur = () => {\n if (props.trigger === 'focus') {\n isOpen.value = false\n }\n}\n\n// 트리거 타입에 따른 Tooltip 설정 계산\nconst tooltipConfig = computed(() => {\n const config: any = {\n disabled: props.disabled,\n }\n \n // 모든 트리거 타입에 대해 수동 제어\n config.open = isOpen.value\n \n return config\n})\n\n// 외부 클릭 감지를 위한 핸들러\nconst handleOutsideClick = (event: Event) => {\n if (props.trigger === 'hover' && isOpen.value) {\n const target = event.target as HTMLElement\n const tooltipElement = document.querySelector('[data-tooltip-trigger]')\n if (tooltipElement && !tooltipElement.contains(target)) {\n isOpen.value = false\n }\n }\n}\n\n// manual 트리거를 위한 메서드들\nconst showTooltip = () => {\n if (props.trigger === 'manual') {\n isOpen.value = true\n }\n}\n\nconst hideTooltip = () => {\n if (props.trigger === 'manual') {\n isOpen.value = false\n }\n}\n\n// 외부에서 사용할 수 있도록 expose\ndefineExpose({\n showTooltip,\n hideTooltip,\n})\n\n// 외부 클릭 감지를 위한 이벤트 리스너 등록/해제\nonMounted(() => {\n if (props.trigger === 'hover') {\n document.addEventListener('click', handleOutsideClick)\n }\n})\n\nonUnmounted(() => {\n if (props.trigger === 'hover') {\n document.removeEventListener('click', handleOutsideClick)\n }\n \n // 타이머 정리\n if (hoverTimer) {\n clearTimeout(hoverTimer)\n }\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 // maxWidth 스타일 처리\n const maxWidthStyle = typeof props.maxWidth === 'number' \n ? `${props.maxWidth}px` \n : props.maxWidth\n \n return {\n side: props.side,\n align: props.align,\n class: finalClass,\n style: {\n maxWidth: maxWidthStyle,\n },\n }\n})\n</script>\n\n<template>\n <TooltipProvider :delayDuration=\"props.delay\">\n <Tooltip v-bind=\"tooltipConfig\">\n <TooltipTrigger \n as-child\n :data-tooltip-trigger=\"true\"\n @click=\"handleClick\"\n @mouseenter=\"handleMouseEnter\"\n @mouseleave=\"handleMouseLeave\"\n @focus=\"handleFocus\"\n @blur=\"handleBlur\"\n >\n <slot name=\"trigger\" />\n </TooltipTrigger>\n <TooltipContent v-bind=\"mapped\">\n {{ props.content }}\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n</template>\n"],"names":["props","__props","STYLE_PRESETS","SIZE_PRESETS","isOpen","ref","handleClick","event","hoverTimer","handleMouseEnter","handleMouseLeave","handleFocus","handleBlur","tooltipConfig","computed","config","handleOutsideClick","target","tooltipElement","__expose","onMounted","onUnmounted","mapped","stylePreset","sizePreset","finalClass","maxWidthStyle","_createBlock","TooltipProvider","_createVNode","Tooltip","TooltipTrigger","_renderSlot","_ctx","TooltipContent","_createTextVNode","_toDisplayString"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"JTooltip.vue.js","sources":["../../../../src/components/atoms/JTooltip.vue"],"sourcesContent":["<script setup lang=\"ts\">\r\nimport { computed, ref, onMounted, onUnmounted } from 'vue'\r\nimport Tooltip from '@/components/shadcn/Tooltip.vue'\r\nimport TooltipContent from '@/components/shadcn/TooltipContent.vue'\r\nimport TooltipProvider from '@/components/shadcn/TooltipProvider.vue'\r\nimport TooltipTrigger from '@/components/shadcn/TooltipTrigger.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 Size = 'xs' | 'sm' | 'md' | 'lg'\n\r\ntype Trigger = 'hover' | 'focus' | 'click' | 'manual'\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n content?: string\r\n side?: 'top' | 'right' | 'bottom' | 'left'\r\n align?: 'start' | 'center' | 'end'\r\n class?: string\r\n /** 스타일 프리셋 */\r\n styletype?: StyleType\r\n /** 툴팁 크기 */\r\n size?: Size\r\n /** 툴팁 비활성화 */\r\n disabled?: boolean\r\n /** 표시 지연 시간 (ms) */\r\n delay?: number\r\n /** 툴팁 최대 너비 */\r\n maxWidth?: string | number\r\n /** 툴팁 트리거 타입 */\r\n trigger?: Trigger\r\n }>(),\r\n {\n side: 'top',\n align: 'center',\n styletype: 'default',\n size: 'sm',\n disabled: false,\n delay: 200,\n maxWidth: '200px',\n trigger: 'hover',\r\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: 'bg-blue-500 text-white border-blue-600',\r\n },\r\n success: { \r\n class: 'bg-green-500 text-white border-green-600',\r\n },\r\n warning: { \r\n class: 'bg-amber-500 text-white border-amber-600',\r\n },\r\n danger: { \r\n class: 'bg-red-500 text-white border-red-600',\r\n },\r\n}\r\n\r\n/**\r\n * size -> class 매핑\r\n */\r\nconst SIZE_PRESETS: Record<Size, { class: string }> = {\n xs: { \n class: 'text-[10px] px-1.5 py-0.5 max-w-40',\n },\n sm: { \n class: 'text-xs px-2 py-1 max-w-48',\n },\n md: { \n class: 'text-xs px-2.5 py-1 max-w-56',\n },\n lg: { \n class: 'text-sm px-3 py-1.5 max-w-64',\n },\n}\n\r\n// click과 manual 트리거를 위한 상태 관리\r\nconst isOpen = ref(false)\r\n\r\n// 각 트리거 타입별 핸들러\r\nconst handleClick = (event: MouseEvent) => {\r\n console.log('Click handler called, trigger:', props.trigger)\r\n if (props.trigger === 'click') {\r\n console.log('Toggling tooltip, current state:', isOpen.value)\r\n isOpen.value = !isOpen.value\r\n console.log('New state:', isOpen.value)\r\n } else if (props.trigger === 'focus') {\r\n // focus 트리거에서는 클릭 이벤트 무시\r\n event.preventDefault()\r\n event.stopPropagation()\r\n }\r\n}\r\n\r\n// delay를 위한 타이머 관리\r\nlet hoverTimer: number | null = null\r\n\r\nconst handleMouseEnter = () => {\r\n if (props.trigger === 'hover') {\r\n // 기존 타이머가 있으면 취소\r\n if (hoverTimer) {\r\n clearTimeout(hoverTimer)\r\n }\r\n // delay 적용\r\n hoverTimer = setTimeout(() => {\r\n isOpen.value = true\r\n }, props.delay)\r\n }\r\n}\r\n\r\nconst handleMouseLeave = () => {\r\n if (props.trigger === 'hover') {\r\n // 타이머 취소\r\n if (hoverTimer) {\r\n clearTimeout(hoverTimer)\r\n hoverTimer = null\r\n }\r\n isOpen.value = false\r\n }\r\n}\r\n\r\nconst handleFocus = () => {\r\n if (props.trigger === 'focus') {\r\n isOpen.value = true\r\n }\r\n}\r\n\r\nconst handleBlur = () => {\r\n if (props.trigger === 'focus') {\r\n isOpen.value = false\r\n }\r\n}\r\n\r\n// 트리거 타입에 따른 Tooltip 설정 계산\r\nconst tooltipConfig = computed(() => {\r\n const config: any = {\r\n disabled: props.disabled,\r\n }\r\n \r\n // 모든 트리거 타입에 대해 수동 제어\r\n config.open = isOpen.value\r\n \r\n return config\r\n})\r\n\r\n// 외부 클릭 감지를 위한 핸들러\r\nconst handleOutsideClick = (event: Event) => {\r\n if (props.trigger === 'hover' && isOpen.value) {\r\n const target = event.target as HTMLElement\r\n const tooltipElement = document.querySelector('[data-tooltip-trigger]')\r\n if (tooltipElement && !tooltipElement.contains(target)) {\r\n isOpen.value = false\r\n }\r\n }\r\n}\r\n\r\n// manual 트리거를 위한 메서드들\r\nconst showTooltip = () => {\r\n if (props.trigger === 'manual') {\r\n isOpen.value = true\r\n }\r\n}\r\n\r\nconst hideTooltip = () => {\r\n if (props.trigger === 'manual') {\r\n isOpen.value = false\r\n }\r\n}\r\n\r\n// 외부에서 사용할 수 있도록 expose\r\ndefineExpose({\r\n showTooltip,\r\n hideTooltip,\r\n})\r\n\r\n// 외부 클릭 감지를 위한 이벤트 리스너 등록/해제\r\nonMounted(() => {\r\n if (props.trigger === 'hover') {\r\n document.addEventListener('click', handleOutsideClick)\r\n }\r\n})\r\n\r\nonUnmounted(() => {\r\n if (props.trigger === 'hover') {\r\n document.removeEventListener('click', handleOutsideClick)\r\n }\r\n \r\n // 타이머 정리\r\n if (hoverTimer) {\r\n clearTimeout(hoverTimer)\r\n }\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 // maxWidth 스타일 처리\r\n const maxWidthStyle = typeof props.maxWidth === 'number' \r\n ? `${props.maxWidth}px` \r\n : props.maxWidth\r\n \r\n return {\r\n side: props.side,\r\n align: props.align,\r\n class: finalClass,\r\n style: {\r\n maxWidth: maxWidthStyle,\r\n },\r\n }\r\n})\r\n</script>\r\n\r\n<template>\r\n <TooltipProvider :delayDuration=\"props.delay\">\r\n <Tooltip v-bind=\"tooltipConfig\">\r\n <TooltipTrigger \r\n as-child\r\n :data-tooltip-trigger=\"true\"\r\n @click=\"handleClick\"\r\n @mouseenter=\"handleMouseEnter\"\r\n @mouseleave=\"handleMouseLeave\"\r\n @focus=\"handleFocus\"\r\n @blur=\"handleBlur\"\r\n >\r\n <slot name=\"trigger\" />\r\n </TooltipTrigger>\r\n <TooltipContent v-bind=\"mapped\">\r\n {{ props.content }}\r\n </TooltipContent>\r\n </Tooltip>\r\n </TooltipProvider>\r\n</template>\r\n"],"names":["props","__props","STYLE_PRESETS","SIZE_PRESETS","isOpen","ref","handleClick","event","hoverTimer","handleMouseEnter","handleMouseLeave","handleFocus","handleBlur","tooltipConfig","computed","config","handleOutsideClick","target","tooltipElement","__expose","onMounted","onUnmounted","mapped","stylePreset","sizePreset","finalClass","maxWidthStyle","_createBlock","TooltipProvider","_createVNode","Tooltip","TooltipTrigger","_renderSlot","_ctx","TooltipContent","_createTextVNode","_toDisplayString"],"mappings":"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"}
1
+ {"version":3,"file":"JTooltip.vue.js","sources":["../../../../src/components/atoms/JTooltip.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, ref, onMounted, onUnmounted } from 'vue'\nimport Tooltip from '@/components/shadcn/Tooltip.vue'\nimport TooltipContent from '@/components/shadcn/TooltipContent.vue'\nimport TooltipProvider from '@/components/shadcn/TooltipProvider.vue'\nimport TooltipTrigger from '@/components/shadcn/TooltipTrigger.vue'\n\ntype StyleType =\n | 'default' // 기본 스타일\n | 'primary' // 강조 스타일 (파랑)\n | 'success' // 성공 스타일 (초록)\n | 'warning' // 경고 스타일 (주황)\n | 'danger' // 위험 스타일 (빨강)\n\ntype Size = 'xs' | 'sm' | 'md' | 'lg'\n\ntype Trigger = 'hover' | 'focus' | 'click' | 'manual'\n\nconst props = withDefaults(\n defineProps<{\n content?: string\n side?: 'top' | 'right' | 'bottom' | 'left'\n align?: 'start' | 'center' | 'end'\n class?: string\n /** 스타일 프리셋 */\n styletype?: StyleType\n /** 툴팁 크기 */\n size?: Size\n /** 툴팁 비활성화 */\n disabled?: boolean\n /** 표시 지연 시간 (ms) */\n delay?: number\n /** 툴팁 최대 너비 */\n maxWidth?: string | number\n /** 툴팁 트리거 타입 */\n trigger?: Trigger\n }>(),\n {\n side: 'top',\n align: 'center',\n styletype: 'default',\n size: 'sm',\n disabled: false,\n delay: 200,\n maxWidth: '200px',\n trigger: 'hover',\n },\n)\n\n/**\n * styletype -> class 매핑\n */\nconst STYLE_PRESETS: Record<StyleType, { class: string }> = {\n default: { class: '' },\n primary: { \n class: 'bg-blue-500 text-white border-blue-600',\n },\n success: { \n class: 'bg-green-500 text-white border-green-600',\n },\n warning: { \n class: 'bg-amber-500 text-white border-amber-600',\n },\n danger: { \n class: 'bg-red-500 text-white border-red-600',\n },\n}\n\n/**\n * size -> class 매핑\n */\nconst SIZE_PRESETS: Record<Size, { class: string }> = {\n xs: { \n class: 'text-[10px] px-1.5 py-0.5 max-w-40',\n },\n sm: { \n class: 'text-xs px-2 py-1 max-w-48',\n },\n md: { \n class: 'text-xs px-2.5 py-1 max-w-56',\n },\n lg: { \n class: 'text-sm px-3 py-1.5 max-w-64',\n },\n}\n\n// click과 manual 트리거를 위한 상태 관리\nconst isOpen = ref(false)\n\n// 각 트리거 타입별 핸들러\nconst handleClick = (event: MouseEvent) => {\n console.log('Click handler called, trigger:', props.trigger)\n if (props.trigger === 'click') {\n console.log('Toggling tooltip, current state:', isOpen.value)\n isOpen.value = !isOpen.value\n console.log('New state:', isOpen.value)\n } else if (props.trigger === 'focus') {\n // focus 트리거에서는 클릭 이벤트 무시\n event.preventDefault()\n event.stopPropagation()\n }\n}\n\n// delay를 위한 타이머 관리\nlet hoverTimer: number | null = null\n\nconst handleMouseEnter = () => {\n if (props.trigger === 'hover') {\n // 기존 타이머가 있으면 취소\n if (hoverTimer) {\n clearTimeout(hoverTimer)\n }\n // delay 적용\n hoverTimer = setTimeout(() => {\n isOpen.value = true\n }, props.delay)\n }\n}\n\nconst handleMouseLeave = () => {\n if (props.trigger === 'hover') {\n // 타이머 취소\n if (hoverTimer) {\n clearTimeout(hoverTimer)\n hoverTimer = null\n }\n isOpen.value = false\n }\n}\n\nconst handleFocus = () => {\n if (props.trigger === 'focus') {\n isOpen.value = true\n }\n}\n\nconst handleBlur = () => {\n if (props.trigger === 'focus') {\n isOpen.value = false\n }\n}\n\n// 트리거 타입에 따른 Tooltip 설정 계산\nconst tooltipConfig = computed(() => {\n const config: any = {\n disabled: props.disabled,\n }\n \n // 모든 트리거 타입에 대해 수동 제어\n config.open = isOpen.value\n \n return config\n})\n\n// 외부 클릭 감지를 위한 핸들러\nconst handleOutsideClick = (event: Event) => {\n if (props.trigger === 'hover' && isOpen.value) {\n const target = event.target as HTMLElement\n const tooltipElement = document.querySelector('[data-tooltip-trigger]')\n if (tooltipElement && !tooltipElement.contains(target)) {\n isOpen.value = false\n }\n }\n}\n\n// manual 트리거를 위한 메서드들\nconst showTooltip = () => {\n if (props.trigger === 'manual') {\n isOpen.value = true\n }\n}\n\nconst hideTooltip = () => {\n if (props.trigger === 'manual') {\n isOpen.value = false\n }\n}\n\n// 외부에서 사용할 수 있도록 expose\ndefineExpose({\n showTooltip,\n hideTooltip,\n})\n\n// 외부 클릭 감지를 위한 이벤트 리스너 등록/해제\nonMounted(() => {\n if (props.trigger === 'hover') {\n document.addEventListener('click', handleOutsideClick)\n }\n})\n\nonUnmounted(() => {\n if (props.trigger === 'hover') {\n document.removeEventListener('click', handleOutsideClick)\n }\n \n // 타이머 정리\n if (hoverTimer) {\n clearTimeout(hoverTimer)\n }\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 // maxWidth 스타일 처리\n const maxWidthStyle = typeof props.maxWidth === 'number' \n ? `${props.maxWidth}px` \n : props.maxWidth\n \n return {\n side: props.side,\n align: props.align,\n class: finalClass,\n style: {\n maxWidth: maxWidthStyle,\n },\n }\n})\n</script>\n\n<template>\n <TooltipProvider :delayDuration=\"props.delay\">\n <Tooltip v-bind=\"tooltipConfig\">\n <TooltipTrigger \n as-child\n :data-tooltip-trigger=\"true\"\n @click=\"handleClick\"\n @mouseenter=\"handleMouseEnter\"\n @mouseleave=\"handleMouseLeave\"\n @focus=\"handleFocus\"\n @blur=\"handleBlur\"\n >\n <slot name=\"trigger\" />\n </TooltipTrigger>\n <TooltipContent v-bind=\"mapped\">\n {{ props.content }}\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n</template>\n"],"names":["props","__props","STYLE_PRESETS","SIZE_PRESETS","isOpen","ref","handleClick","event","hoverTimer","handleMouseEnter","handleMouseLeave","handleFocus","handleBlur","tooltipConfig","computed","config","handleOutsideClick","target","tooltipElement","__expose","onMounted","onUnmounted","mapped","stylePreset","sizePreset","finalClass","maxWidthStyle","_createBlock","TooltipProvider","_createVNode","Tooltip","TooltipTrigger","_renderSlot","_ctx","TooltipContent","_createTextVNode","_toDisplayString"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("vue");require("../shadcn/index.cjs");const a=require("../atoms/JButton.vue.cjs");require("lucide-vue-next");const l=require("../../lib/utils.cjs");require("@internationalized/date");require("md-editor-v3");;/* empty css */;/* empty css */require("../shadcn/badge-variants.cjs");require("@vueuse/core");require("reka-ui");;/* empty css */require("../shadcn/avatar-variants.cjs");require("dompurify");;/* empty css */require("ag-grid-vue3");require("ag-grid-community");require("ag-grid-enterprise");;/* empty css */;/* empty css */;/* empty css */;/* empty css */;/* empty css */;/* empty css */require("vue-sonner");const s=require("../shadcn/Alert.vue.cjs"),c=require("../shadcn/AlertTitle.vue.cjs"),d=require("../shadcn/AlertDescription.vue.cjs"),f={key:1,class:"mt-4 flex justify-end gap-2"},q=e.defineComponent({__name:"JAlert",props:{class:{},variant:{default:"default"},title:{},description:{},buttonText:{default:"확인"},onConfirm:{},showFooter:{type:Boolean,default:!0}},emits:["confirm"],setup(t,{emit:u}){const r=t,n=u,o=()=>{r.onConfirm?.(),n("confirm")};return(i,m)=>(e.openBlock(),e.createBlock(e.unref(s.default),{variant:r.variant,class:e.normalizeClass(e.unref(l.cn)(r.class))},{default:e.withCtx(()=>[t.title?(e.openBlock(),e.createBlock(e.unref(c.default),{key:0},{default:e.withCtx(()=>[e.renderSlot(i.$slots,"header",{},()=>[e.createTextVNode(e.toDisplayString(t.title),1)])]),_:3})):e.createCommentVNode("",!0),e.createVNode(e.unref(d.default),null,{default:e.withCtx(()=>[e.renderSlot(i.$slots,"default",{},()=>[e.createTextVNode(e.toDisplayString(t.description),1)])]),_:3}),t.showFooter?(e.openBlock(),e.createElementBlock("div",f,[e.renderSlot(i.$slots,"footer",{},()=>[e.createVNode(e.unref(a.default),{variant:t.variant==="destructive"?"secondary":"default",size:"sm",onClick:o},{default:e.withCtx(()=>[e.createTextVNode(e.toDisplayString(t.buttonText),1)]),_:1},8,["variant"])])])):e.createCommentVNode("",!0)]),_:3},8,["variant","class"]))}});exports.default=q;
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("vue");require("../shadcn/index.cjs");const a=require("../atoms/JButton.vue.cjs");require("lucide-vue-next");const l=require("../../lib/utils.cjs");require("@internationalized/date");require("md-editor-v3");;/* empty css */;/* empty css */require("../shadcn/badge-variants.cjs");require("@vueuse/core");require("reka-ui");;/* empty css */require("../shadcn/avatar-variants.cjs");require("dompurify");;/* empty css */require("ag-grid-vue3");require("ag-grid-community");require("ag-grid-enterprise");;/* empty css */;/* empty css */;/* empty css */require("vue-sonner");const s=require("../shadcn/Alert.vue.cjs"),c=require("../shadcn/AlertTitle.vue.cjs"),d=require("../shadcn/AlertDescription.vue.cjs"),f={key:1,class:"mt-4 flex justify-end gap-2"},q=e.defineComponent({__name:"JAlert",props:{class:{},variant:{default:"default"},title:{},description:{},buttonText:{default:"확인"},onConfirm:{},showFooter:{type:Boolean,default:!0}},emits:["confirm"],setup(t,{emit:u}){const r=t,n=u,o=()=>{r.onConfirm?.(),n("confirm")};return(i,m)=>(e.openBlock(),e.createBlock(e.unref(s.default),{variant:r.variant,class:e.normalizeClass(e.unref(l.cn)(r.class))},{default:e.withCtx(()=>[t.title?(e.openBlock(),e.createBlock(e.unref(c.default),{key:0},{default:e.withCtx(()=>[e.renderSlot(i.$slots,"header",{},()=>[e.createTextVNode(e.toDisplayString(t.title),1)])]),_:3})):e.createCommentVNode("",!0),e.createVNode(e.unref(d.default),null,{default:e.withCtx(()=>[e.renderSlot(i.$slots,"default",{},()=>[e.createTextVNode(e.toDisplayString(t.description),1)])]),_:3}),t.showFooter?(e.openBlock(),e.createElementBlock("div",f,[e.renderSlot(i.$slots,"footer",{},()=>[e.createVNode(e.unref(a.default),{variant:t.variant==="destructive"?"secondary":"default",size:"sm",onClick:o},{default:e.withCtx(()=>[e.createTextVNode(e.toDisplayString(t.buttonText),1)]),_:1},8,["variant"])])])):e.createCommentVNode("",!0)]),_:3},8,["variant","class"]))}});exports.default=q;
2
2
  //# sourceMappingURL=JAlert.vue.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"JAlert.vue.cjs","sources":["../../../../src/components/molecules/JAlert.vue"],"sourcesContent":["<script setup lang=\"ts\">\r\nimport type { HTMLAttributes } from \"vue\"\r\nimport { Alert, AlertTitle, AlertDescription } from '@/components/shadcn'\r\nimport { JButton } from '@/components/atoms'\r\nimport { cn } from \"@/lib/utils\"\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n /** Alert 자체의 클래스 */\r\n class?: HTMLAttributes[\"class\"]\r\n /** Alert variant 스타일 */\r\n variant?: \"default\" | \"destructive\"\r\n /** Alert 제목 (Header) */\r\n title?: string\r\n /** Alert 설명/내용 (Body) */\r\n description?: string\r\n /** Footer에 표시할 버튼 텍스트 */\r\n buttonText?: string\r\n /** Footer 버튼 클릭 핸들러 */\r\n onConfirm?: () => void\r\n /** Footer 표시 여부 */\r\n showFooter?: boolean\r\n }>(),\r\n {\r\n variant: \"default\",\r\n showFooter: true,\r\n buttonText: \"확인\"\r\n }\r\n)\r\n\r\nconst emit = defineEmits<{\r\n confirm: []\r\n}>()\r\n\r\nconst handleConfirm = () => {\r\n props.onConfirm?.()\r\n emit('confirm')\r\n}\r\n</script>\r\n\r\n<template>\r\n <Alert :variant=\"props.variant\" :class=\"cn(props.class)\">\r\n <!-- Header -->\r\n <AlertTitle v-if=\"title\">\r\n <slot name=\"header\">{{ title }}</slot>\r\n </AlertTitle>\r\n \r\n <!-- Body -->\r\n <AlertDescription>\r\n <slot>{{ description }}</slot>\r\n </AlertDescription>\r\n \r\n <!-- Footer -->\r\n <div v-if=\"showFooter\" class=\"mt-4 flex justify-end gap-2\">\r\n <slot name=\"footer\">\r\n <JButton \r\n :variant=\"variant === 'destructive' ? 'secondary' : 'default'\"\r\n size=\"sm\"\r\n @click=\"handleConfirm\"\r\n >\r\n {{ buttonText }}\r\n </JButton>\r\n </slot>\r\n </div>\r\n </Alert>\r\n</template>\r\n"],"names":["props","__props","emit","__emit","handleConfirm","_createBlock","_unref","Alert","_normalizeClass","cn","AlertTitle","_renderSlot","_ctx","_createVNode","AlertDescription","_openBlock","_createElementBlock","_hoisted_1","JButton"],"mappings":"0qDAMA,MAAMA,EAAQC,EAwBRC,EAAOC,EAIPC,EAAgB,IAAM,CAC1BJ,EAAM,YAAA,EACNE,EAAK,SAAS,CAChB,8BAIEG,EAAAA,YAuBQC,EAAAA,MAAAC,EAAAA,OAAA,EAAA,CAvBA,QAASP,EAAM,QAAU,MAAKQ,EAAAA,eAAEF,EAAAA,MAAAG,EAAAA,EAAA,EAAGT,EAAM,KAAK,CAAA,CAAA,qBAEpD,IAEa,CAFKC,EAAA,qBAAlBI,EAAAA,YAEaC,QAAAI,EAAAA,OAAA,EAAA,CAAA,IAAA,GAAA,mBADX,IAAsC,CAAtCC,EAAAA,WAAsCC,qBAAtC,IAAsC,qCAAfX,EAAA,KAAK,EAAA,CAAA,CAAA,wCAI9BY,EAAAA,YAEmBP,EAAAA,MAAAQ,SAAA,EAAA,KAAA,mBADjB,IAA8B,CAA9BH,EAAAA,WAA8BC,sBAA9B,IAA8B,qCAArBX,EAAA,WAAW,EAAA,CAAA,CAAA,WAIXA,EAAA,YAAXc,EAAAA,UAAA,EAAAC,EAAAA,mBAUM,MAVNC,EAUM,CATJN,EAAAA,WAQOC,qBARP,IAQO,CAPLC,cAMUP,EAAAA,MAAAY,EAAAA,OAAA,EAAA,CALP,QAASjB,EAAA,UAAO,cAAA,YAAA,UACjB,KAAK,KACJ,QAAOG,CAAA,qBAER,IAAgB,qCAAbH,EAAA,UAAU,EAAA,CAAA,CAAA"}
1
+ {"version":3,"file":"JAlert.vue.cjs","sources":["../../../../src/components/molecules/JAlert.vue"],"sourcesContent":["<script setup lang=\"ts\">\r\nimport type { HTMLAttributes } from \"vue\"\r\nimport { Alert, AlertTitle, AlertDescription } from '@/components/shadcn'\r\nimport { JButton } from '@/components/atoms'\r\nimport { cn } from \"@/lib/utils\"\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n /** Alert 자체의 클래스 */\r\n class?: HTMLAttributes[\"class\"]\r\n /** Alert variant 스타일 */\r\n variant?: \"default\" | \"destructive\"\r\n /** Alert 제목 (Header) */\r\n title?: string\r\n /** Alert 설명/내용 (Body) */\r\n description?: string\r\n /** Footer에 표시할 버튼 텍스트 */\r\n buttonText?: string\r\n /** Footer 버튼 클릭 핸들러 */\r\n onConfirm?: () => void\r\n /** Footer 표시 여부 */\r\n showFooter?: boolean\r\n }>(),\r\n {\r\n variant: \"default\",\r\n showFooter: true,\r\n buttonText: \"확인\"\r\n }\r\n)\r\n\r\nconst emit = defineEmits<{\r\n confirm: []\r\n}>()\r\n\r\nconst handleConfirm = () => {\r\n props.onConfirm?.()\r\n emit('confirm')\r\n}\r\n</script>\r\n\r\n<template>\r\n <Alert :variant=\"props.variant\" :class=\"cn(props.class)\">\r\n <!-- Header -->\r\n <AlertTitle v-if=\"title\">\r\n <slot name=\"header\">{{ title }}</slot>\r\n </AlertTitle>\r\n \r\n <!-- Body -->\r\n <AlertDescription>\r\n <slot>{{ description }}</slot>\r\n </AlertDescription>\r\n \r\n <!-- Footer -->\r\n <div v-if=\"showFooter\" class=\"mt-4 flex justify-end gap-2\">\r\n <slot name=\"footer\">\r\n <JButton \r\n :variant=\"variant === 'destructive' ? 'secondary' : 'default'\"\r\n size=\"sm\"\r\n @click=\"handleConfirm\"\r\n >\r\n {{ buttonText }}\r\n </JButton>\r\n </slot>\r\n </div>\r\n </Alert>\r\n</template>\r\n"],"names":["props","__props","emit","__emit","handleConfirm","_createBlock","_unref","Alert","_normalizeClass","cn","AlertTitle","_renderSlot","_ctx","_createVNode","AlertDescription","_openBlock","_createElementBlock","_hoisted_1","JButton"],"mappings":"yzCAMA,MAAMA,EAAQC,EAwBRC,EAAOC,EAIPC,EAAgB,IAAM,CAC1BJ,EAAM,YAAA,EACNE,EAAK,SAAS,CAChB,8BAIEG,EAAAA,YAuBQC,EAAAA,MAAAC,EAAAA,OAAA,EAAA,CAvBA,QAASP,EAAM,QAAU,MAAKQ,EAAAA,eAAEF,EAAAA,MAAAG,EAAAA,EAAA,EAAGT,EAAM,KAAK,CAAA,CAAA,qBAEpD,IAEa,CAFKC,EAAA,qBAAlBI,EAAAA,YAEaC,QAAAI,EAAAA,OAAA,EAAA,CAAA,IAAA,GAAA,mBADX,IAAsC,CAAtCC,EAAAA,WAAsCC,qBAAtC,IAAsC,qCAAfX,EAAA,KAAK,EAAA,CAAA,CAAA,wCAI9BY,EAAAA,YAEmBP,EAAAA,MAAAQ,SAAA,EAAA,KAAA,mBADjB,IAA8B,CAA9BH,EAAAA,WAA8BC,sBAA9B,IAA8B,qCAArBX,EAAA,WAAW,EAAA,CAAA,CAAA,WAIXA,EAAA,YAAXc,EAAAA,UAAA,EAAAC,EAAAA,mBAUM,MAVNC,EAUM,CATJN,EAAAA,WAQOC,qBARP,IAQO,CAPLC,cAMUP,EAAAA,MAAAY,EAAAA,OAAA,EAAA,CALP,QAASjB,EAAA,UAAO,cAAA,YAAA,UACjB,KAAK,KACJ,QAAOG,CAAA,qBAER,IAAgB,qCAAbH,EAAA,UAAU,EAAA,CAAA,CAAA"}
@@ -17,9 +17,6 @@ import "dompurify";
17
17
  import "ag-grid-vue3";
18
18
  import "ag-grid-community";
19
19
  import "ag-grid-enterprise";
20
- /* empty css */
21
- /* empty css */
22
- /* empty css */
23
20
  /* empty css */
24
21
  /* empty css */
25
22
  /* empty css */
@@ -30,7 +27,7 @@ import x from "../shadcn/AlertDescription.vue.js";
30
27
  const w = {
31
28
  key: 1,
32
29
  class: "mt-4 flex justify-end gap-2"
33
- }, tt = /* @__PURE__ */ v({
30
+ }, X = /* @__PURE__ */ v({
34
31
  __name: "JAlert",
35
32
  props: {
36
33
  class: {},
@@ -87,6 +84,6 @@ const w = {
87
84
  }
88
85
  });
89
86
  export {
90
- tt as default
87
+ X as default
91
88
  };
92
89
  //# sourceMappingURL=JAlert.vue.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"JAlert.vue.js","sources":["../../../../src/components/molecules/JAlert.vue"],"sourcesContent":["<script setup lang=\"ts\">\r\nimport type { HTMLAttributes } from \"vue\"\r\nimport { Alert, AlertTitle, AlertDescription } from '@/components/shadcn'\r\nimport { JButton } from '@/components/atoms'\r\nimport { cn } from \"@/lib/utils\"\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n /** Alert 자체의 클래스 */\r\n class?: HTMLAttributes[\"class\"]\r\n /** Alert variant 스타일 */\r\n variant?: \"default\" | \"destructive\"\r\n /** Alert 제목 (Header) */\r\n title?: string\r\n /** Alert 설명/내용 (Body) */\r\n description?: string\r\n /** Footer에 표시할 버튼 텍스트 */\r\n buttonText?: string\r\n /** Footer 버튼 클릭 핸들러 */\r\n onConfirm?: () => void\r\n /** Footer 표시 여부 */\r\n showFooter?: boolean\r\n }>(),\r\n {\r\n variant: \"default\",\r\n showFooter: true,\r\n buttonText: \"확인\"\r\n }\r\n)\r\n\r\nconst emit = defineEmits<{\r\n confirm: []\r\n}>()\r\n\r\nconst handleConfirm = () => {\r\n props.onConfirm?.()\r\n emit('confirm')\r\n}\r\n</script>\r\n\r\n<template>\r\n <Alert :variant=\"props.variant\" :class=\"cn(props.class)\">\r\n <!-- Header -->\r\n <AlertTitle v-if=\"title\">\r\n <slot name=\"header\">{{ title }}</slot>\r\n </AlertTitle>\r\n \r\n <!-- Body -->\r\n <AlertDescription>\r\n <slot>{{ description }}</slot>\r\n </AlertDescription>\r\n \r\n <!-- Footer -->\r\n <div v-if=\"showFooter\" class=\"mt-4 flex justify-end gap-2\">\r\n <slot name=\"footer\">\r\n <JButton \r\n :variant=\"variant === 'destructive' ? 'secondary' : 'default'\"\r\n size=\"sm\"\r\n @click=\"handleConfirm\"\r\n >\r\n {{ buttonText }}\r\n </JButton>\r\n </slot>\r\n </div>\r\n </Alert>\r\n</template>\r\n"],"names":["props","__props","emit","__emit","handleConfirm","_createBlock","_unref","Alert","_normalizeClass","cn","AlertTitle","_renderSlot","_ctx","_createVNode","AlertDescription","_openBlock","_createElementBlock","_hoisted_1","JButton"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAMA,UAAMA,IAAQC,GAwBRC,IAAOC,GAIPC,IAAgB,MAAM;AAC1B,MAAAJ,EAAM,YAAA,GACNE,EAAK,SAAS;AAAA,IAChB;2BAIEG,EAuBQC,EAAAC,CAAA,GAAA;AAAA,MAvBA,SAASP,EAAM;AAAA,MAAU,OAAKQ,EAAEF,EAAAG,CAAA,EAAGT,EAAM,KAAK,CAAA;AAAA,IAAA;iBAEpD,MAEa;AAAA,QAFKC,EAAA,cAAlBI,EAEaC,EAAAI,CAAA,GAAA,EAAA,KAAA,KAAA;AAAA,qBADX,MAAsC;AAAA,YAAtCC,EAAsCC,wBAAtC,MAAsC;AAAA,kBAAfX,EAAA,KAAK,GAAA,CAAA;AAAA,YAAA;;;;QAI9BY,EAEmBP,EAAAQ,CAAA,GAAA,MAAA;AAAA,qBADjB,MAA8B;AAAA,YAA9BH,EAA8BC,yBAA9B,MAA8B;AAAA,kBAArBX,EAAA,WAAW,GAAA,CAAA;AAAA,YAAA;;;;QAIXA,EAAA,cAAXc,EAAA,GAAAC,EAUM,OAVNC,GAUM;AAAA,UATJN,EAQOC,wBARP,MAQO;AAAA,YAPLC,EAMUP,EAAAY,CAAA,GAAA;AAAA,cALP,SAASjB,EAAA,YAAO,gBAAA,cAAA;AAAA,cACjB,MAAK;AAAA,cACJ,SAAOG;AAAA,YAAA;yBAER,MAAgB;AAAA,oBAAbH,EAAA,UAAU,GAAA,CAAA;AAAA,cAAA;;;;;;;;;;"}
1
+ {"version":3,"file":"JAlert.vue.js","sources":["../../../../src/components/molecules/JAlert.vue"],"sourcesContent":["<script setup lang=\"ts\">\r\nimport type { HTMLAttributes } from \"vue\"\r\nimport { Alert, AlertTitle, AlertDescription } from '@/components/shadcn'\r\nimport { JButton } from '@/components/atoms'\r\nimport { cn } from \"@/lib/utils\"\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n /** Alert 자체의 클래스 */\r\n class?: HTMLAttributes[\"class\"]\r\n /** Alert variant 스타일 */\r\n variant?: \"default\" | \"destructive\"\r\n /** Alert 제목 (Header) */\r\n title?: string\r\n /** Alert 설명/내용 (Body) */\r\n description?: string\r\n /** Footer에 표시할 버튼 텍스트 */\r\n buttonText?: string\r\n /** Footer 버튼 클릭 핸들러 */\r\n onConfirm?: () => void\r\n /** Footer 표시 여부 */\r\n showFooter?: boolean\r\n }>(),\r\n {\r\n variant: \"default\",\r\n showFooter: true,\r\n buttonText: \"확인\"\r\n }\r\n)\r\n\r\nconst emit = defineEmits<{\r\n confirm: []\r\n}>()\r\n\r\nconst handleConfirm = () => {\r\n props.onConfirm?.()\r\n emit('confirm')\r\n}\r\n</script>\r\n\r\n<template>\r\n <Alert :variant=\"props.variant\" :class=\"cn(props.class)\">\r\n <!-- Header -->\r\n <AlertTitle v-if=\"title\">\r\n <slot name=\"header\">{{ title }}</slot>\r\n </AlertTitle>\r\n \r\n <!-- Body -->\r\n <AlertDescription>\r\n <slot>{{ description }}</slot>\r\n </AlertDescription>\r\n \r\n <!-- Footer -->\r\n <div v-if=\"showFooter\" class=\"mt-4 flex justify-end gap-2\">\r\n <slot name=\"footer\">\r\n <JButton \r\n :variant=\"variant === 'destructive' ? 'secondary' : 'default'\"\r\n size=\"sm\"\r\n @click=\"handleConfirm\"\r\n >\r\n {{ buttonText }}\r\n </JButton>\r\n </slot>\r\n </div>\r\n </Alert>\r\n</template>\r\n"],"names":["props","__props","emit","__emit","handleConfirm","_createBlock","_unref","Alert","_normalizeClass","cn","AlertTitle","_renderSlot","_ctx","_createVNode","AlertDescription","_openBlock","_createElementBlock","_hoisted_1","JButton"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAMA,UAAMA,IAAQC,GAwBRC,IAAOC,GAIPC,IAAgB,MAAM;AAC1B,MAAAJ,EAAM,YAAA,GACNE,EAAK,SAAS;AAAA,IAChB;2BAIEG,EAuBQC,EAAAC,CAAA,GAAA;AAAA,MAvBA,SAASP,EAAM;AAAA,MAAU,OAAKQ,EAAEF,EAAAG,CAAA,EAAGT,EAAM,KAAK,CAAA;AAAA,IAAA;iBAEpD,MAEa;AAAA,QAFKC,EAAA,cAAlBI,EAEaC,EAAAI,CAAA,GAAA,EAAA,KAAA,KAAA;AAAA,qBADX,MAAsC;AAAA,YAAtCC,EAAsCC,wBAAtC,MAAsC;AAAA,kBAAfX,EAAA,KAAK,GAAA,CAAA;AAAA,YAAA;;;;QAI9BY,EAEmBP,EAAAQ,CAAA,GAAA,MAAA;AAAA,qBADjB,MAA8B;AAAA,YAA9BH,EAA8BC,yBAA9B,MAA8B;AAAA,kBAArBX,EAAA,WAAW,GAAA,CAAA;AAAA,YAAA;;;;QAIXA,EAAA,cAAXc,EAAA,GAAAC,EAUM,OAVNC,GAUM;AAAA,UATJN,EAQOC,wBARP,MAQO;AAAA,YAPLC,EAMUP,EAAAY,CAAA,GAAA;AAAA,cALP,SAASjB,EAAA,YAAO,gBAAA,cAAA;AAAA,cACjB,MAAK;AAAA,cACJ,SAAOG;AAAA,YAAA;yBAER,MAAgB;AAAA,oBAAbH,EAAA,UAAU,GAAA,CAAA;AAAA,cAAA;;;;;;;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"JBreadcrumb.vue.cjs","sources":["../../../../src/components/molecules/JBreadcrumb.vue"],"sourcesContent":["<script setup lang=\"ts\">\r\nimport { computed } from 'vue'\r\nimport JIcon from '@/components/atoms/JIcon.vue'\r\nimport JLink from '@/components/atoms/JLink.vue'\r\nimport { cn } from '@/lib/utils'\r\n\r\n/**\r\n * JBreadcrumb - 브레드크럼 네비게이션 컴포넌트 (molecules)\r\n * Breadcrumb Navigation Component\r\n * \r\n * @description\r\n * 페이지의 네비게이션 경로를 표시하는 브레드크럼 컴포넌트입니다.\r\n * \r\n * Features:\r\n * - 경로 아이템 표시\r\n * - 클릭 가능한 링크 지원\r\n * - 아이콘 지원\r\n * - 커스터마이징 가능한 구분자\r\n * \r\n * @example\r\n * ```vue\r\n * <JBreadcrumb \r\n * :items=\"[\r\n * { label: '홈', href: '/' },\r\n * { label: '제품', href: '/products' },\r\n * { label: '상세' }\r\n * ]\"\r\n * />\r\n * ```\r\n */\r\n\r\nexport type BreadcrumbItem = {\r\n /** 라벨 텍스트 */\r\n label: string\r\n /** 링크 URL (없으면 텍스트만 표시) */\r\n href?: string\r\n /** 아이콘 이름 */\r\n icon?: string\r\n /** 클릭 핸들러 */\r\n onClick?: () => void\r\n}\r\n\r\ntype StyleType =\r\n | 'default' // 기본 스타일\r\n | 'minimal' // 최소 스타일 (작은 크기, 얇은 구분자)\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n /** 브레드크럼 아이템 목록 */\r\n items: BreadcrumbItem[]\r\n /** 구분자 (기본값: /) */\r\n separator?: string\r\n /** 스타일 타입 */\r\n styletype?: StyleType\r\n /** 추가 CSS 클래스 */\r\n class?: string\r\n }>(),\r\n {\r\n separator: '/',\r\n styletype: 'default',\r\n }\r\n)\r\n\r\nconst emit = defineEmits<{\r\n /** 아이템 클릭 이벤트 */\r\n itemClick: [item: BreadcrumbItem, index: number]\r\n}>()\r\n\r\n/**\r\n * 스타일 프리셋\r\n */\r\nconst STYLE_PRESETS: Record<StyleType, {\r\n containerClass: string\r\n itemClass: string\r\n separatorClass: string\r\n lastItemClass: string\r\n}> = {\r\n default: {\n containerClass: 'flex items-center gap-2 px-4 py-1.5',\n itemClass: 'text-xs text-muted-foreground hover:text-foreground transition-colors',\n separatorClass: 'text-muted-foreground/50 text-xs',\n lastItemClass: 'text-foreground font-medium',\n },\n minimal: {\r\n containerClass: 'flex items-center gap-1.5 px-2 py-1',\r\n itemClass: 'text-xs text-muted-foreground hover:text-foreground transition-colors',\r\n separatorClass: 'text-muted-foreground/40 text-xs',\r\n lastItemClass: 'text-foreground font-medium',\r\n },\r\n}\r\n\r\nconst preset = computed(() => {\r\n return STYLE_PRESETS[props.styletype] ?? STYLE_PRESETS.default\r\n})\r\n\r\n/**\r\n * 아이템 클릭 핸들러\r\n */\r\nconst handleItemClick = (item: BreadcrumbItem, index: number) => {\r\n item.onClick?.()\r\n emit('itemClick', item, index)\r\n}\r\n\r\n/**\r\n * 마지막 아이템인지 확인\r\n */\r\nconst isLastItem = (index: number) => {\r\n return index === props.items.length - 1\r\n}\r\n</script>\r\n\r\n<template>\r\n <nav \r\n :class=\"cn(preset.containerClass, props.class)\"\r\n aria-label=\"브레드크럼 네비게이션\"\r\n >\r\n <ol class=\"flex items-center gap-2 list-none p-0 m-0\">\r\n <li\r\n v-for=\"(item, index) in items\"\r\n :key=\"index\"\r\n class=\"flex items-center gap-2\"\r\n >\r\n <!-- 아이템 -->\r\n <span\r\n v-if=\"isLastItem(index) || (!item.href && !item.onClick)\"\r\n :class=\"cn(preset.itemClass, preset.lastItemClass, isLastItem(index) && 'cursor-default')\"\r\n >\r\n <!-- 아이콘 -->\r\n <JIcon\r\n v-if=\"item.icon\"\r\n :name=\"item.icon\"\r\n size=\"sm\"\r\n class=\"mr-1\"\r\n />\r\n {{ item.label }}\r\n </span>\r\n \r\n <JLink\r\n v-else\r\n :href=\"item.href\"\r\n :class=\"cn(preset.itemClass)\"\r\n @click=\"handleItemClick(item, index)\"\r\n >\r\n <!-- 아이콘 -->\r\n <JIcon\r\n v-if=\"item.icon\"\r\n :name=\"item.icon\"\r\n size=\"sm\"\r\n class=\"mr-1\"\r\n />\r\n {{ item.label }}\r\n </JLink>\r\n\r\n <!-- 구분자 (마지막 아이템이 아니면 표시) -->\r\n <span\r\n v-if=\"!isLastItem(index)\"\r\n :class=\"preset.separatorClass\"\r\n aria-hidden=\"true\"\r\n >\r\n <JIcon\r\n v-if=\"separator === 'chevron'\"\r\n name=\"chevronRight\"\r\n size=\"sm\"\r\n />\r\n <span v-else>{{ separator }}</span>\r\n </span>\r\n </li>\r\n </ol>\r\n </nav>\r\n</template>\r\n"],"names":["props","__props","emit","__emit","STYLE_PRESETS","preset","computed","handleItemClick","item","index","isLastItem","_createElementBlock","_normalizeClass","_unref","_createElementVNode","_hoisted_1","_openBlock","_Fragment","_renderList","cn","_createBlock","JIcon","_toDisplayString","JLink","$event"],"mappings":"4cA8CA,MAAMA,EAAQC,EAiBRC,EAAOC,EAQPC,EAKD,CACH,QAAS,CACP,eAAgB,sCAChB,UAAW,wEACX,eAAgB,mCAChB,cAAe,6BAAA,EAEjB,QAAS,CACP,eAAgB,sCAChB,UAAW,wEACX,eAAgB,mCAChB,cAAe,6BAAA,CACjB,EAGIC,EAASC,EAAAA,SAAS,IACfF,EAAcJ,EAAM,SAAS,GAAKI,EAAc,OACxD,EAKKG,EAAkB,CAACC,EAAsBC,IAAkB,CAC/DD,EAAK,UAAA,EACLN,EAAK,YAAaM,EAAMC,CAAK,CAC/B,EAKMC,EAAcD,GACXA,IAAUT,EAAM,MAAM,OAAS,8BAKtCW,EAAAA,mBAwDM,MAAA,CAvDH,MAAKC,EAAAA,eAAEC,EAAAA,YAAGR,EAAA,MAAO,eAAgBL,EAAM,KAAK,CAAA,EAC7C,aAAW,aAAA,GAEXc,EAAAA,mBAmDK,KAnDLC,EAmDK,EAlDHC,EAAAA,UAAA,EAAA,EAAAL,EAAAA,mBAiDKM,WAAA,KAAAC,EAAAA,WAhDqBjB,EAAA,MAAK,CAArBO,EAAMC,mBADhBE,EAAAA,mBAiDK,KAAA,CA/CF,IAAKF,EACN,MAAM,yBAAA,GAIEC,EAAWD,CAAK,GAAA,CAAOD,EAAK,MAAI,CAAKA,EAAK,uBADlDG,EAAAA,mBAYO,OAAA,OAVJ,MAAKC,EAAAA,eAAEC,EAAAA,MAAAM,EAAAA,EAAA,EAAGd,EAAA,MAAO,UAAWA,EAAA,MAAO,cAAeK,EAAWD,CAAK,GAAA,gBAAA,CAAA,CAAA,GAI3DD,EAAK,oBADbY,EAAAA,YAKEC,EAAAA,QAAA,OAHC,KAAMb,EAAK,KACZ,KAAK,KACL,MAAM,MAAA,kEACN,IACFc,EAAAA,gBAAGd,EAAK,KAAK,EAAA,CAAA,CAAA,qBAGfY,EAAAA,YAcQG,EAAAA,QAAA,OAZL,KAAMf,EAAK,KACX,MAAKI,EAAAA,eAAEC,QAAAM,EAAAA,EAAA,EAAGd,EAAA,MAAO,SAAS,CAAA,EAC1B,QAAKmB,GAAEjB,EAAgBC,EAAMC,CAAK,CAAA,qBAGnC,IAKE,CAJMD,EAAK,oBADbY,EAAAA,YAKEC,EAAAA,QAAA,OAHC,KAAMb,EAAK,KACZ,KAAK,KACL,MAAM,MAAA,kEACN,IACFc,EAAAA,gBAAGd,EAAK,KAAK,EAAA,CAAA,CAAA,0CAKNE,EAAWD,CAAK,6CADzBE,EAAAA,mBAWO,OAAA,OATJ,MAAKC,EAAAA,eAAEP,EAAA,MAAO,cAAc,EAC7B,cAAY,MAAA,GAGJJ,EAAA,YAAS,yBADjBmB,EAAAA,YAIEC,EAAAA,QAAA,OAFA,KAAK,eACL,KAAK,IAAA,KAEPL,EAAAA,YAAAL,EAAAA,mBAAmC,2BAAnBV,EAAA,SAAS,EAAA,CAAA,EAAA"}
1
+ {"version":3,"file":"JBreadcrumb.vue.cjs","sources":["../../../../src/components/molecules/JBreadcrumb.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport JIcon from '@/components/atoms/JIcon.vue'\nimport JLink from '@/components/atoms/JLink.vue'\nimport { cn } from '@/lib/utils'\n\n/**\n * JBreadcrumb - 브레드크럼 네비게이션 컴포넌트 (molecules)\n * Breadcrumb Navigation Component\n * \n * @description\n * 페이지의 네비게이션 경로를 표시하는 브레드크럼 컴포넌트입니다.\n * \n * Features:\n * - 경로 아이템 표시\n * - 클릭 가능한 링크 지원\n * - 아이콘 지원\n * - 커스터마이징 가능한 구분자\n * \n * @example\n * ```vue\n * <JBreadcrumb \n * :items=\"[\n * { label: '홈', href: '/' },\n * { label: '제품', href: '/products' },\n * { label: '상세' }\n * ]\"\n * />\n * ```\n */\n\nexport type BreadcrumbItem = {\n /** 라벨 텍스트 */\n label: string\n /** 링크 URL (없으면 텍스트만 표시) */\n href?: string\n /** 아이콘 이름 */\n icon?: string\n /** 클릭 핸들러 */\n onClick?: () => void\n}\n\ntype StyleType =\n | 'default' // 기본 스타일\n | 'minimal' // 최소 스타일 (작은 크기, 얇은 구분자)\n\nconst props = withDefaults(\n defineProps<{\n /** 브레드크럼 아이템 목록 */\n items: BreadcrumbItem[]\n /** 구분자 (기본값: /) */\n separator?: string\n /** 스타일 타입 */\n styletype?: StyleType\n /** 추가 CSS 클래스 */\n class?: string\n }>(),\n {\n separator: '/',\n styletype: 'default',\n }\n)\n\nconst emit = defineEmits<{\n /** 아이템 클릭 이벤트 */\n itemClick: [item: BreadcrumbItem, index: number]\n}>()\n\n/**\n * 스타일 프리셋\n */\nconst STYLE_PRESETS: Record<StyleType, {\n containerClass: string\n itemClass: string\n separatorClass: string\n lastItemClass: string\n}> = {\n default: {\n containerClass: 'flex items-center gap-2 px-4 py-1.5',\n itemClass: 'text-xs text-muted-foreground hover:text-foreground transition-colors',\n separatorClass: 'text-muted-foreground/50 text-xs',\n lastItemClass: 'text-foreground font-medium',\n },\n minimal: {\n containerClass: 'flex items-center gap-1.5 px-2 py-1',\n itemClass: 'text-xs text-muted-foreground hover:text-foreground transition-colors',\n separatorClass: 'text-muted-foreground/40 text-xs',\n lastItemClass: 'text-foreground font-medium',\n },\n}\n\nconst preset = computed(() => {\n return STYLE_PRESETS[props.styletype] ?? STYLE_PRESETS.default\n})\n\n/**\n * 아이템 클릭 핸들러\n */\nconst handleItemClick = (item: BreadcrumbItem, index: number) => {\n item.onClick?.()\n emit('itemClick', item, index)\n}\n\n/**\n * 마지막 아이템인지 확인\n */\nconst isLastItem = (index: number) => {\n return index === props.items.length - 1\n}\n</script>\n\n<template>\n <nav \n :class=\"cn(preset.containerClass, props.class)\"\n aria-label=\"브레드크럼 네비게이션\"\n >\n <ol class=\"flex items-center gap-2 list-none p-0 m-0\">\n <li\n v-for=\"(item, index) in items\"\n :key=\"index\"\n class=\"flex items-center gap-2\"\n >\n <!-- 아이템 -->\n <span\n v-if=\"isLastItem(index) || (!item.href && !item.onClick)\"\n :class=\"cn(preset.itemClass, preset.lastItemClass, isLastItem(index) && 'cursor-default')\"\n >\n <!-- 아이콘 -->\n <JIcon\n v-if=\"item.icon\"\n :name=\"item.icon\"\n size=\"sm\"\n class=\"mr-1\"\n />\n {{ item.label }}\n </span>\n \n <JLink\n v-else\n :href=\"item.href\"\n :class=\"cn(preset.itemClass)\"\n @click=\"handleItemClick(item, index)\"\n >\n <!-- 아이콘 -->\n <JIcon\n v-if=\"item.icon\"\n :name=\"item.icon\"\n size=\"sm\"\n class=\"mr-1\"\n />\n {{ item.label }}\n </JLink>\n\n <!-- 구분자 (마지막 아이템이 아니면 표시) -->\n <span\n v-if=\"!isLastItem(index)\"\n :class=\"preset.separatorClass\"\n aria-hidden=\"true\"\n >\n <JIcon\n v-if=\"separator === 'chevron'\"\n name=\"chevronRight\"\n size=\"sm\"\n />\n <span v-else>{{ separator }}</span>\n </span>\n </li>\n </ol>\n </nav>\n</template>\n"],"names":["props","__props","emit","__emit","STYLE_PRESETS","preset","computed","handleItemClick","item","index","isLastItem","_createElementBlock","_normalizeClass","_unref","_createElementVNode","_hoisted_1","_openBlock","_Fragment","_renderList","cn","_createBlock","JIcon","_toDisplayString","JLink","$event"],"mappings":"4cA8CA,MAAMA,EAAQC,EAiBRC,EAAOC,EAQPC,EAKD,CACH,QAAS,CACP,eAAgB,sCAChB,UAAW,wEACX,eAAgB,mCAChB,cAAe,6BAAA,EAEjB,QAAS,CACP,eAAgB,sCAChB,UAAW,wEACX,eAAgB,mCAChB,cAAe,6BAAA,CACjB,EAGIC,EAASC,EAAAA,SAAS,IACfF,EAAcJ,EAAM,SAAS,GAAKI,EAAc,OACxD,EAKKG,EAAkB,CAACC,EAAsBC,IAAkB,CAC/DD,EAAK,UAAA,EACLN,EAAK,YAAaM,EAAMC,CAAK,CAC/B,EAKMC,EAAcD,GACXA,IAAUT,EAAM,MAAM,OAAS,8BAKtCW,EAAAA,mBAwDM,MAAA,CAvDH,MAAKC,EAAAA,eAAEC,EAAAA,YAAGR,EAAA,MAAO,eAAgBL,EAAM,KAAK,CAAA,EAC7C,aAAW,aAAA,GAEXc,EAAAA,mBAmDK,KAnDLC,EAmDK,EAlDHC,EAAAA,UAAA,EAAA,EAAAL,EAAAA,mBAiDKM,WAAA,KAAAC,EAAAA,WAhDqBjB,EAAA,MAAK,CAArBO,EAAMC,mBADhBE,EAAAA,mBAiDK,KAAA,CA/CF,IAAKF,EACN,MAAM,yBAAA,GAIEC,EAAWD,CAAK,GAAA,CAAOD,EAAK,MAAI,CAAKA,EAAK,uBADlDG,EAAAA,mBAYO,OAAA,OAVJ,MAAKC,EAAAA,eAAEC,EAAAA,MAAAM,EAAAA,EAAA,EAAGd,EAAA,MAAO,UAAWA,EAAA,MAAO,cAAeK,EAAWD,CAAK,GAAA,gBAAA,CAAA,CAAA,GAI3DD,EAAK,oBADbY,EAAAA,YAKEC,EAAAA,QAAA,OAHC,KAAMb,EAAK,KACZ,KAAK,KACL,MAAM,MAAA,kEACN,IACFc,EAAAA,gBAAGd,EAAK,KAAK,EAAA,CAAA,CAAA,qBAGfY,EAAAA,YAcQG,EAAAA,QAAA,OAZL,KAAMf,EAAK,KACX,MAAKI,EAAAA,eAAEC,QAAAM,EAAAA,EAAA,EAAGd,EAAA,MAAO,SAAS,CAAA,EAC1B,QAAKmB,GAAEjB,EAAgBC,EAAMC,CAAK,CAAA,qBAGnC,IAKE,CAJMD,EAAK,oBADbY,EAAAA,YAKEC,EAAAA,QAAA,OAHC,KAAMb,EAAK,KACZ,KAAK,KACL,MAAM,MAAA,kEACN,IACFc,EAAAA,gBAAGd,EAAK,KAAK,EAAA,CAAA,CAAA,0CAKNE,EAAWD,CAAK,6CADzBE,EAAAA,mBAWO,OAAA,OATJ,MAAKC,EAAAA,eAAEP,EAAA,MAAO,cAAc,EAC7B,cAAY,MAAA,GAGJJ,EAAA,YAAS,yBADjBmB,EAAAA,YAIEC,EAAAA,QAAA,OAFA,KAAK,eACL,KAAK,IAAA,KAEPL,EAAAA,YAAAL,EAAAA,mBAAmC,2BAAnBV,EAAA,SAAS,EAAA,CAAA,EAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"JBreadcrumb.vue.js","sources":["../../../../src/components/molecules/JBreadcrumb.vue"],"sourcesContent":["<script setup lang=\"ts\">\r\nimport { computed } from 'vue'\r\nimport JIcon from '@/components/atoms/JIcon.vue'\r\nimport JLink from '@/components/atoms/JLink.vue'\r\nimport { cn } from '@/lib/utils'\r\n\r\n/**\r\n * JBreadcrumb - 브레드크럼 네비게이션 컴포넌트 (molecules)\r\n * Breadcrumb Navigation Component\r\n * \r\n * @description\r\n * 페이지의 네비게이션 경로를 표시하는 브레드크럼 컴포넌트입니다.\r\n * \r\n * Features:\r\n * - 경로 아이템 표시\r\n * - 클릭 가능한 링크 지원\r\n * - 아이콘 지원\r\n * - 커스터마이징 가능한 구분자\r\n * \r\n * @example\r\n * ```vue\r\n * <JBreadcrumb \r\n * :items=\"[\r\n * { label: '홈', href: '/' },\r\n * { label: '제품', href: '/products' },\r\n * { label: '상세' }\r\n * ]\"\r\n * />\r\n * ```\r\n */\r\n\r\nexport type BreadcrumbItem = {\r\n /** 라벨 텍스트 */\r\n label: string\r\n /** 링크 URL (없으면 텍스트만 표시) */\r\n href?: string\r\n /** 아이콘 이름 */\r\n icon?: string\r\n /** 클릭 핸들러 */\r\n onClick?: () => void\r\n}\r\n\r\ntype StyleType =\r\n | 'default' // 기본 스타일\r\n | 'minimal' // 최소 스타일 (작은 크기, 얇은 구분자)\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n /** 브레드크럼 아이템 목록 */\r\n items: BreadcrumbItem[]\r\n /** 구분자 (기본값: /) */\r\n separator?: string\r\n /** 스타일 타입 */\r\n styletype?: StyleType\r\n /** 추가 CSS 클래스 */\r\n class?: string\r\n }>(),\r\n {\r\n separator: '/',\r\n styletype: 'default',\r\n }\r\n)\r\n\r\nconst emit = defineEmits<{\r\n /** 아이템 클릭 이벤트 */\r\n itemClick: [item: BreadcrumbItem, index: number]\r\n}>()\r\n\r\n/**\r\n * 스타일 프리셋\r\n */\r\nconst STYLE_PRESETS: Record<StyleType, {\r\n containerClass: string\r\n itemClass: string\r\n separatorClass: string\r\n lastItemClass: string\r\n}> = {\r\n default: {\n containerClass: 'flex items-center gap-2 px-4 py-1.5',\n itemClass: 'text-xs text-muted-foreground hover:text-foreground transition-colors',\n separatorClass: 'text-muted-foreground/50 text-xs',\n lastItemClass: 'text-foreground font-medium',\n },\n minimal: {\r\n containerClass: 'flex items-center gap-1.5 px-2 py-1',\r\n itemClass: 'text-xs text-muted-foreground hover:text-foreground transition-colors',\r\n separatorClass: 'text-muted-foreground/40 text-xs',\r\n lastItemClass: 'text-foreground font-medium',\r\n },\r\n}\r\n\r\nconst preset = computed(() => {\r\n return STYLE_PRESETS[props.styletype] ?? STYLE_PRESETS.default\r\n})\r\n\r\n/**\r\n * 아이템 클릭 핸들러\r\n */\r\nconst handleItemClick = (item: BreadcrumbItem, index: number) => {\r\n item.onClick?.()\r\n emit('itemClick', item, index)\r\n}\r\n\r\n/**\r\n * 마지막 아이템인지 확인\r\n */\r\nconst isLastItem = (index: number) => {\r\n return index === props.items.length - 1\r\n}\r\n</script>\r\n\r\n<template>\r\n <nav \r\n :class=\"cn(preset.containerClass, props.class)\"\r\n aria-label=\"브레드크럼 네비게이션\"\r\n >\r\n <ol class=\"flex items-center gap-2 list-none p-0 m-0\">\r\n <li\r\n v-for=\"(item, index) in items\"\r\n :key=\"index\"\r\n class=\"flex items-center gap-2\"\r\n >\r\n <!-- 아이템 -->\r\n <span\r\n v-if=\"isLastItem(index) || (!item.href && !item.onClick)\"\r\n :class=\"cn(preset.itemClass, preset.lastItemClass, isLastItem(index) && 'cursor-default')\"\r\n >\r\n <!-- 아이콘 -->\r\n <JIcon\r\n v-if=\"item.icon\"\r\n :name=\"item.icon\"\r\n size=\"sm\"\r\n class=\"mr-1\"\r\n />\r\n {{ item.label }}\r\n </span>\r\n \r\n <JLink\r\n v-else\r\n :href=\"item.href\"\r\n :class=\"cn(preset.itemClass)\"\r\n @click=\"handleItemClick(item, index)\"\r\n >\r\n <!-- 아이콘 -->\r\n <JIcon\r\n v-if=\"item.icon\"\r\n :name=\"item.icon\"\r\n size=\"sm\"\r\n class=\"mr-1\"\r\n />\r\n {{ item.label }}\r\n </JLink>\r\n\r\n <!-- 구분자 (마지막 아이템이 아니면 표시) -->\r\n <span\r\n v-if=\"!isLastItem(index)\"\r\n :class=\"preset.separatorClass\"\r\n aria-hidden=\"true\"\r\n >\r\n <JIcon\r\n v-if=\"separator === 'chevron'\"\r\n name=\"chevronRight\"\r\n size=\"sm\"\r\n />\r\n <span v-else>{{ separator }}</span>\r\n </span>\r\n </li>\r\n </ol>\r\n </nav>\r\n</template>\r\n"],"names":["props","__props","emit","__emit","STYLE_PRESETS","preset","computed","handleItemClick","item","index","isLastItem","_createElementBlock","_normalizeClass","_unref","_createElementVNode","_hoisted_1","_openBlock","_Fragment","_renderList","cn","_createBlock","JIcon","_toDisplayString","JLink","$event"],"mappings":";;;;;;;;;;;;;;AA8CA,UAAMA,IAAQC,GAiBRC,IAAOC,GAQPC,IAKD;AAAA,MACH,SAAS;AAAA,QACP,gBAAgB;AAAA,QAChB,WAAW;AAAA,QACX,gBAAgB;AAAA,QAChB,eAAe;AAAA,MAAA;AAAA,MAEjB,SAAS;AAAA,QACP,gBAAgB;AAAA,QAChB,WAAW;AAAA,QACX,gBAAgB;AAAA,QAChB,eAAe;AAAA,MAAA;AAAA,IACjB,GAGIC,IAASC,EAAS,MACfF,EAAcJ,EAAM,SAAS,KAAKI,EAAc,OACxD,GAKKG,IAAkB,CAACC,GAAsBC,MAAkB;AAC/D,MAAAD,EAAK,UAAA,GACLN,EAAK,aAAaM,GAAMC,CAAK;AAAA,IAC/B,GAKMC,IAAa,CAACD,MACXA,MAAUT,EAAM,MAAM,SAAS;2BAKtCW,EAwDM,OAAA;AAAA,MAvDH,OAAKC,EAAEC,KAAGR,EAAA,MAAO,gBAAgBL,EAAM,KAAK,CAAA;AAAA,MAC7C,cAAW;AAAA,IAAA;MAEXc,EAmDK,MAnDLC,GAmDK;AAAA,SAlDHC,EAAA,EAAA,GAAAL,EAiDKM,GAAA,MAAAC,EAhDqBjB,EAAA,OAAK,CAArBO,GAAMC,YADhBE,EAiDK,MAAA;AAAA,UA/CF,KAAKF;AAAA,UACN,OAAM;AAAA,QAAA;UAIEC,EAAWD,CAAK,KAAA,CAAOD,EAAK,QAAI,CAAKA,EAAK,gBADlDG,EAYO,QAAA;AAAA;YAVJ,OAAKC,EAAEC,EAAAM,CAAA,EAAGd,EAAA,MAAO,WAAWA,EAAA,MAAO,eAAeK,EAAWD,CAAK,KAAA,gBAAA,CAAA;AAAA,UAAA;YAI3DD,EAAK,aADbY,EAKEC,GAAA;AAAA;cAHC,MAAMb,EAAK;AAAA,cACZ,MAAK;AAAA,cACL,OAAM;AAAA,YAAA;cACN,MACFc,EAAGd,EAAK,KAAK,GAAA,CAAA;AAAA,UAAA,eAGfY,EAcQG,GAAA;AAAA;YAZL,MAAMf,EAAK;AAAA,YACX,OAAKI,EAAEC,EAAAM,CAAA,EAAGd,EAAA,MAAO,SAAS,CAAA;AAAA,YAC1B,SAAK,CAAAmB,MAAEjB,EAAgBC,GAAMC,CAAK;AAAA,UAAA;uBAGnC,MAKE;AAAA,cAJMD,EAAK,aADbY,EAKEC,GAAA;AAAA;gBAHC,MAAMb,EAAK;AAAA,gBACZ,MAAK;AAAA,gBACL,OAAM;AAAA,cAAA;gBACN,MACFc,EAAGd,EAAK,KAAK,GAAA,CAAA;AAAA,YAAA;;;UAKNE,EAAWD,CAAK,sBADzBE,EAWO,QAAA;AAAA;YATJ,OAAKC,EAAEP,EAAA,MAAO,cAAc;AAAA,YAC7B,eAAY;AAAA,UAAA;YAGJJ,EAAA,cAAS,kBADjBmB,EAIEC,GAAA;AAAA;cAFA,MAAK;AAAA,cACL,MAAK;AAAA,YAAA,OAEPL,KAAAL,EAAmC,aAAnBV,EAAA,SAAS,GAAA,CAAA;AAAA,UAAA;;;;;;"}
1
+ {"version":3,"file":"JBreadcrumb.vue.js","sources":["../../../../src/components/molecules/JBreadcrumb.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport JIcon from '@/components/atoms/JIcon.vue'\nimport JLink from '@/components/atoms/JLink.vue'\nimport { cn } from '@/lib/utils'\n\n/**\n * JBreadcrumb - 브레드크럼 네비게이션 컴포넌트 (molecules)\n * Breadcrumb Navigation Component\n * \n * @description\n * 페이지의 네비게이션 경로를 표시하는 브레드크럼 컴포넌트입니다.\n * \n * Features:\n * - 경로 아이템 표시\n * - 클릭 가능한 링크 지원\n * - 아이콘 지원\n * - 커스터마이징 가능한 구분자\n * \n * @example\n * ```vue\n * <JBreadcrumb \n * :items=\"[\n * { label: '홈', href: '/' },\n * { label: '제품', href: '/products' },\n * { label: '상세' }\n * ]\"\n * />\n * ```\n */\n\nexport type BreadcrumbItem = {\n /** 라벨 텍스트 */\n label: string\n /** 링크 URL (없으면 텍스트만 표시) */\n href?: string\n /** 아이콘 이름 */\n icon?: string\n /** 클릭 핸들러 */\n onClick?: () => void\n}\n\ntype StyleType =\n | 'default' // 기본 스타일\n | 'minimal' // 최소 스타일 (작은 크기, 얇은 구분자)\n\nconst props = withDefaults(\n defineProps<{\n /** 브레드크럼 아이템 목록 */\n items: BreadcrumbItem[]\n /** 구분자 (기본값: /) */\n separator?: string\n /** 스타일 타입 */\n styletype?: StyleType\n /** 추가 CSS 클래스 */\n class?: string\n }>(),\n {\n separator: '/',\n styletype: 'default',\n }\n)\n\nconst emit = defineEmits<{\n /** 아이템 클릭 이벤트 */\n itemClick: [item: BreadcrumbItem, index: number]\n}>()\n\n/**\n * 스타일 프리셋\n */\nconst STYLE_PRESETS: Record<StyleType, {\n containerClass: string\n itemClass: string\n separatorClass: string\n lastItemClass: string\n}> = {\n default: {\n containerClass: 'flex items-center gap-2 px-4 py-1.5',\n itemClass: 'text-xs text-muted-foreground hover:text-foreground transition-colors',\n separatorClass: 'text-muted-foreground/50 text-xs',\n lastItemClass: 'text-foreground font-medium',\n },\n minimal: {\n containerClass: 'flex items-center gap-1.5 px-2 py-1',\n itemClass: 'text-xs text-muted-foreground hover:text-foreground transition-colors',\n separatorClass: 'text-muted-foreground/40 text-xs',\n lastItemClass: 'text-foreground font-medium',\n },\n}\n\nconst preset = computed(() => {\n return STYLE_PRESETS[props.styletype] ?? STYLE_PRESETS.default\n})\n\n/**\n * 아이템 클릭 핸들러\n */\nconst handleItemClick = (item: BreadcrumbItem, index: number) => {\n item.onClick?.()\n emit('itemClick', item, index)\n}\n\n/**\n * 마지막 아이템인지 확인\n */\nconst isLastItem = (index: number) => {\n return index === props.items.length - 1\n}\n</script>\n\n<template>\n <nav \n :class=\"cn(preset.containerClass, props.class)\"\n aria-label=\"브레드크럼 네비게이션\"\n >\n <ol class=\"flex items-center gap-2 list-none p-0 m-0\">\n <li\n v-for=\"(item, index) in items\"\n :key=\"index\"\n class=\"flex items-center gap-2\"\n >\n <!-- 아이템 -->\n <span\n v-if=\"isLastItem(index) || (!item.href && !item.onClick)\"\n :class=\"cn(preset.itemClass, preset.lastItemClass, isLastItem(index) && 'cursor-default')\"\n >\n <!-- 아이콘 -->\n <JIcon\n v-if=\"item.icon\"\n :name=\"item.icon\"\n size=\"sm\"\n class=\"mr-1\"\n />\n {{ item.label }}\n </span>\n \n <JLink\n v-else\n :href=\"item.href\"\n :class=\"cn(preset.itemClass)\"\n @click=\"handleItemClick(item, index)\"\n >\n <!-- 아이콘 -->\n <JIcon\n v-if=\"item.icon\"\n :name=\"item.icon\"\n size=\"sm\"\n class=\"mr-1\"\n />\n {{ item.label }}\n </JLink>\n\n <!-- 구분자 (마지막 아이템이 아니면 표시) -->\n <span\n v-if=\"!isLastItem(index)\"\n :class=\"preset.separatorClass\"\n aria-hidden=\"true\"\n >\n <JIcon\n v-if=\"separator === 'chevron'\"\n name=\"chevronRight\"\n size=\"sm\"\n />\n <span v-else>{{ separator }}</span>\n </span>\n </li>\n </ol>\n </nav>\n</template>\n"],"names":["props","__props","emit","__emit","STYLE_PRESETS","preset","computed","handleItemClick","item","index","isLastItem","_createElementBlock","_normalizeClass","_unref","_createElementVNode","_hoisted_1","_openBlock","_Fragment","_renderList","cn","_createBlock","JIcon","_toDisplayString","JLink","$event"],"mappings":";;;;;;;;;;;;;;AA8CA,UAAMA,IAAQC,GAiBRC,IAAOC,GAQPC,IAKD;AAAA,MACH,SAAS;AAAA,QACP,gBAAgB;AAAA,QAChB,WAAW;AAAA,QACX,gBAAgB;AAAA,QAChB,eAAe;AAAA,MAAA;AAAA,MAEjB,SAAS;AAAA,QACP,gBAAgB;AAAA,QAChB,WAAW;AAAA,QACX,gBAAgB;AAAA,QAChB,eAAe;AAAA,MAAA;AAAA,IACjB,GAGIC,IAASC,EAAS,MACfF,EAAcJ,EAAM,SAAS,KAAKI,EAAc,OACxD,GAKKG,IAAkB,CAACC,GAAsBC,MAAkB;AAC/D,MAAAD,EAAK,UAAA,GACLN,EAAK,aAAaM,GAAMC,CAAK;AAAA,IAC/B,GAKMC,IAAa,CAACD,MACXA,MAAUT,EAAM,MAAM,SAAS;2BAKtCW,EAwDM,OAAA;AAAA,MAvDH,OAAKC,EAAEC,KAAGR,EAAA,MAAO,gBAAgBL,EAAM,KAAK,CAAA;AAAA,MAC7C,cAAW;AAAA,IAAA;MAEXc,EAmDK,MAnDLC,GAmDK;AAAA,SAlDHC,EAAA,EAAA,GAAAL,EAiDKM,GAAA,MAAAC,EAhDqBjB,EAAA,OAAK,CAArBO,GAAMC,YADhBE,EAiDK,MAAA;AAAA,UA/CF,KAAKF;AAAA,UACN,OAAM;AAAA,QAAA;UAIEC,EAAWD,CAAK,KAAA,CAAOD,EAAK,QAAI,CAAKA,EAAK,gBADlDG,EAYO,QAAA;AAAA;YAVJ,OAAKC,EAAEC,EAAAM,CAAA,EAAGd,EAAA,MAAO,WAAWA,EAAA,MAAO,eAAeK,EAAWD,CAAK,KAAA,gBAAA,CAAA;AAAA,UAAA;YAI3DD,EAAK,aADbY,EAKEC,GAAA;AAAA;cAHC,MAAMb,EAAK;AAAA,cACZ,MAAK;AAAA,cACL,OAAM;AAAA,YAAA;cACN,MACFc,EAAGd,EAAK,KAAK,GAAA,CAAA;AAAA,UAAA,eAGfY,EAcQG,GAAA;AAAA;YAZL,MAAMf,EAAK;AAAA,YACX,OAAKI,EAAEC,EAAAM,CAAA,EAAGd,EAAA,MAAO,SAAS,CAAA;AAAA,YAC1B,SAAK,CAAAmB,MAAEjB,EAAgBC,GAAMC,CAAK;AAAA,UAAA;uBAGnC,MAKE;AAAA,cAJMD,EAAK,aADbY,EAKEC,GAAA;AAAA;gBAHC,MAAMb,EAAK;AAAA,gBACZ,MAAK;AAAA,gBACL,OAAM;AAAA,cAAA;gBACN,MACFc,EAAGd,EAAK,KAAK,GAAA,CAAA;AAAA,YAAA;;;UAKNE,EAAWD,CAAK,sBADzBE,EAWO,QAAA;AAAA;YATJ,OAAKC,EAAEP,EAAA,MAAO,cAAc;AAAA,YAC7B,eAAY;AAAA,UAAA;YAGJJ,EAAA,cAAS,kBADjBmB,EAIEC,GAAA;AAAA;cAFA,MAAK;AAAA,cACL,MAAK;AAAA,YAAA,OAEPL,KAAAL,EAAmC,aAAnBV,EAAA,SAAS,GAAA,CAAA;AAAA,UAAA;;;;;;"}