@j-solution/components 1.6.1 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (187) hide show
  1. package/README.md +8 -6
  2. package/assets/jwms-portal-frontend-CwxPfHfa.css +1 -0
  3. package/assets/styles/j-components.css +1 -1
  4. package/assets/styles/themes.css +107 -0
  5. package/components/atoms/JAvatar.vue.cjs +1 -1
  6. package/components/atoms/JAvatar.vue.cjs.map +1 -1
  7. package/components/atoms/JAvatar.vue.js +10 -7
  8. package/components/atoms/JAvatar.vue.js.map +1 -1
  9. package/components/atoms/JBadge.vue.cjs +1 -1
  10. package/components/atoms/JBadge.vue.cjs.map +1 -1
  11. package/components/atoms/JBadge.vue.js +7 -6
  12. package/components/atoms/JBadge.vue.js.map +1 -1
  13. package/components/atoms/JButton.vue.cjs +1 -1
  14. package/components/atoms/JButton.vue.cjs.map +1 -1
  15. package/components/atoms/JButton.vue.js +5 -5
  16. package/components/atoms/JButton.vue.js.map +1 -1
  17. package/components/atoms/JDatepicker.vue.cjs +1 -1
  18. package/components/atoms/JDatepicker.vue.cjs.map +1 -1
  19. package/components/atoms/JDatepicker.vue.js +10 -10
  20. package/components/atoms/JDatepicker.vue.js.map +1 -1
  21. package/components/atoms/JEditor.vue.cjs +1 -1
  22. package/components/atoms/JEditor.vue.js +1 -1
  23. package/components/atoms/JEditor.vue2.cjs +1 -1
  24. package/components/atoms/JEditor.vue2.cjs.map +1 -1
  25. package/components/atoms/JEditor.vue2.js +31 -17
  26. package/components/atoms/JEditor.vue2.js.map +1 -1
  27. package/components/atoms/JGrid.vue.cjs +1 -1
  28. package/components/atoms/JGrid.vue.js +2 -2
  29. package/components/atoms/JGrid.vue2.cjs +1 -1
  30. package/components/atoms/JGrid.vue2.cjs.map +1 -1
  31. package/components/atoms/JGrid.vue2.js +45 -33
  32. package/components/atoms/JGrid.vue2.js.map +1 -1
  33. package/components/atoms/JIcon.vue.cjs +1 -1
  34. package/components/atoms/JIcon.vue.cjs.map +1 -1
  35. package/components/atoms/JIcon.vue.js +14 -13
  36. package/components/atoms/JIcon.vue.js.map +1 -1
  37. package/components/atoms/JKbd.vue.cjs +1 -1
  38. package/components/atoms/JKbd.vue.cjs.map +1 -1
  39. package/components/atoms/JKbd.vue.js +13 -10
  40. package/components/atoms/JKbd.vue.js.map +1 -1
  41. package/components/atoms/JLabel.vue.cjs +1 -1
  42. package/components/atoms/JLabel.vue.cjs.map +1 -1
  43. package/components/atoms/JLabel.vue.js +4 -4
  44. package/components/atoms/JLabel.vue.js.map +1 -1
  45. package/components/atoms/JLink.vue.cjs +1 -1
  46. package/components/atoms/JLink.vue.cjs.map +1 -1
  47. package/components/atoms/JLink.vue.js +5 -5
  48. package/components/atoms/JLink.vue.js.map +1 -1
  49. package/components/atoms/JPreview.vue.cjs +1 -1
  50. package/components/atoms/JPreview.vue.js +2 -2
  51. package/components/atoms/JPreview.vue2.cjs +1 -1
  52. package/components/atoms/JPreview.vue2.cjs.map +1 -1
  53. package/components/atoms/JPreview.vue2.js +33 -20
  54. package/components/atoms/JPreview.vue2.js.map +1 -1
  55. package/components/atoms/JProgress.vue.cjs +1 -1
  56. package/components/atoms/JProgress.vue.cjs.map +1 -1
  57. package/components/atoms/JProgress.vue.js +15 -9
  58. package/components/atoms/JProgress.vue.js.map +1 -1
  59. package/components/atoms/JRadio.vue.cjs +1 -1
  60. package/components/atoms/JRadio.vue.cjs.map +1 -1
  61. package/components/atoms/JRadio.vue.js +1 -1
  62. package/components/atoms/JRadio.vue.js.map +1 -1
  63. package/components/atoms/JSearchCombo.vue.cjs +1 -1
  64. package/components/atoms/JSearchCombo.vue.cjs.map +1 -1
  65. package/components/atoms/JSearchCombo.vue.js +38 -37
  66. package/components/atoms/JSearchCombo.vue.js.map +1 -1
  67. package/components/atoms/JSpinner.vue.cjs +1 -1
  68. package/components/atoms/JSpinner.vue.cjs.map +1 -1
  69. package/components/atoms/JSpinner.vue.js +8 -7
  70. package/components/atoms/JSpinner.vue.js.map +1 -1
  71. package/components/atoms/JSplitter.vue.cjs +1 -1
  72. package/components/atoms/JSplitter.vue.cjs.map +1 -1
  73. package/components/atoms/JSplitter.vue.js +32 -27
  74. package/components/atoms/JSplitter.vue.js.map +1 -1
  75. package/components/atoms/JTooltip.vue.cjs +1 -1
  76. package/components/atoms/JTooltip.vue.cjs.map +1 -1
  77. package/components/atoms/JTooltip.vue.js +18 -15
  78. package/components/atoms/JTooltip.vue.js.map +1 -1
  79. package/components/examples/ExampleCrudPage.vue.cjs +1 -1
  80. package/components/examples/ExampleCrudPage.vue.cjs.map +1 -1
  81. package/components/examples/ExampleCrudPage.vue.js +162 -108
  82. package/components/examples/ExampleCrudPage.vue.js.map +1 -1
  83. package/components/examples/ExampleTabMappingPage.vue.cjs +1 -1
  84. package/components/examples/ExampleTabMappingPage.vue.cjs.map +1 -1
  85. package/components/examples/ExampleTabMappingPage.vue.js +162 -119
  86. package/components/examples/ExampleTabMappingPage.vue.js.map +1 -1
  87. package/components/molecules/JBreadcrumb.vue.cjs +1 -1
  88. package/components/molecules/JBreadcrumb.vue.cjs.map +1 -1
  89. package/components/molecules/JBreadcrumb.vue.js +3 -3
  90. package/components/molecules/JBreadcrumb.vue.js.map +1 -1
  91. package/components/molecules/JFormField.vue.cjs +1 -1
  92. package/components/molecules/JFormField.vue.cjs.map +1 -1
  93. package/components/molecules/JFormField.vue.js +26 -24
  94. package/components/molecules/JFormField.vue.js.map +1 -1
  95. package/components/molecules/JTabs.vue.cjs +1 -1
  96. package/components/molecules/JTabs.vue.js +1 -1
  97. package/components/molecules/JTabs.vue2.cjs +1 -1
  98. package/components/molecules/JTabs.vue2.cjs.map +1 -1
  99. package/components/molecules/JTabs.vue2.js +7 -7
  100. package/components/molecules/JTabs.vue2.js.map +1 -1
  101. package/components/molecules/JTitlebar.vue.cjs +1 -1
  102. package/components/molecules/JTitlebar.vue.cjs.map +1 -1
  103. package/components/molecules/JTitlebar.vue.js +35 -36
  104. package/components/molecules/JTitlebar.vue.js.map +1 -1
  105. package/components/organisms/JFilterBar.vue.cjs +1 -1
  106. package/components/organisms/JFilterBar.vue.cjs.map +1 -1
  107. package/components/organisms/JFilterBar.vue.js +5 -5
  108. package/components/organisms/JFilterBar.vue.js.map +1 -1
  109. package/components/organisms/JHeader.vue.cjs +1 -1
  110. package/components/organisms/JHeader.vue.cjs.map +1 -1
  111. package/components/organisms/JHeader.vue.js +25 -23
  112. package/components/organisms/JHeader.vue.js.map +1 -1
  113. package/components/organisms/JModal.vue.cjs +1 -1
  114. package/components/organisms/JModal.vue.cjs.map +1 -1
  115. package/components/organisms/JModal.vue.js +30 -27
  116. package/components/organisms/JModal.vue.js.map +1 -1
  117. package/components/organisms/JSidebarAdvanced.vue.cjs +1 -1
  118. package/components/organisms/JSidebarAdvanced.vue.js +7 -7
  119. package/components/organisms/JSidebarAdvanced.vue2.cjs +1 -1
  120. package/components/organisms/JSidebarAdvanced.vue2.cjs.map +1 -1
  121. package/components/organisms/JSidebarAdvanced.vue2.js +40 -40
  122. package/components/organisms/JSidebarAdvanced.vue2.js.map +1 -1
  123. package/components/organisms/JSidebarSimple/JDynamicMenuItem.vue.cjs +1 -1
  124. package/components/organisms/JSidebarSimple/JDynamicMenuItem.vue.cjs.map +1 -1
  125. package/components/organisms/JSidebarSimple/JDynamicMenuItem.vue.js +83 -63
  126. package/components/organisms/JSidebarSimple/JDynamicMenuItem.vue.js.map +1 -1
  127. package/components/organisms/JSidebarSimple.vue.cjs +1 -1
  128. package/components/organisms/JSidebarSimple.vue.js +2 -2
  129. package/components/organisms/JSidebarSimple.vue2.cjs +1 -1
  130. package/components/organisms/JSidebarSimple.vue2.cjs.map +1 -1
  131. package/components/organisms/JSidebarSimple.vue2.js +2 -2
  132. package/components/organisms/JSidebarSimple.vue2.js.map +1 -1
  133. package/components/shadcn/AccordionTrigger.vue.cjs +1 -1
  134. package/components/shadcn/AccordionTrigger.vue.cjs.map +1 -1
  135. package/components/shadcn/AccordionTrigger.vue.js +3 -3
  136. package/components/shadcn/AccordionTrigger.vue.js.map +1 -1
  137. package/components/shadcn/CardContent.vue.cjs +1 -1
  138. package/components/shadcn/CardContent.vue.cjs.map +1 -1
  139. package/components/shadcn/CardContent.vue.js +1 -1
  140. package/components/shadcn/CardContent.vue.js.map +1 -1
  141. package/components/shadcn/CardDescription.vue.cjs +1 -1
  142. package/components/shadcn/CardDescription.vue.cjs.map +1 -1
  143. package/components/shadcn/CardDescription.vue.js +1 -1
  144. package/components/shadcn/CardDescription.vue.js.map +1 -1
  145. package/components/shadcn/CardFooter.vue.cjs +1 -1
  146. package/components/shadcn/CardFooter.vue.cjs.map +1 -1
  147. package/components/shadcn/CardFooter.vue.js +7 -7
  148. package/components/shadcn/CardFooter.vue.js.map +1 -1
  149. package/components/shadcn/CardHeader.vue.cjs +1 -1
  150. package/components/shadcn/CardHeader.vue.cjs.map +1 -1
  151. package/components/shadcn/CardHeader.vue.js +8 -8
  152. package/components/shadcn/CardHeader.vue.js.map +1 -1
  153. package/components/shadcn/CardTitle.vue.cjs +1 -1
  154. package/components/shadcn/CardTitle.vue.cjs.map +1 -1
  155. package/components/shadcn/CardTitle.vue.js +5 -5
  156. package/components/shadcn/CardTitle.vue.js.map +1 -1
  157. package/components/shadcn/Input.vue.cjs +1 -1
  158. package/components/shadcn/Input.vue.cjs.map +1 -1
  159. package/components/shadcn/Input.vue.js +1 -1
  160. package/components/shadcn/Input.vue.js.map +1 -1
  161. package/components/shadcn/SelectTrigger.vue.cjs +1 -1
  162. package/components/shadcn/SelectTrigger.vue.cjs.map +1 -1
  163. package/components/shadcn/SelectTrigger.vue.js +2 -2
  164. package/components/shadcn/SelectTrigger.vue.js.map +1 -1
  165. package/components/shadcn/Switch.vue.cjs +1 -1
  166. package/components/shadcn/Switch.vue.cjs.map +1 -1
  167. package/components/shadcn/Switch.vue.js +2 -2
  168. package/components/shadcn/Switch.vue.js.map +1 -1
  169. package/components/shadcn/TabsList.vue.cjs +1 -1
  170. package/components/shadcn/TabsList.vue.cjs.map +1 -1
  171. package/components/shadcn/TabsList.vue.js +1 -1
  172. package/components/shadcn/TabsList.vue.js.map +1 -1
  173. package/components/shadcn/TabsTrigger.vue.cjs +1 -1
  174. package/components/shadcn/TabsTrigger.vue.cjs.map +1 -1
  175. package/components/shadcn/TabsTrigger.vue.js +4 -4
  176. package/components/shadcn/TabsTrigger.vue.js.map +1 -1
  177. package/components/shadcn/Textarea.vue.cjs +1 -1
  178. package/components/shadcn/Textarea.vue.cjs.map +1 -1
  179. package/components/shadcn/Textarea.vue.js +2 -2
  180. package/components/shadcn/Textarea.vue.js.map +1 -1
  181. package/components/shadcn/index.cjs +1 -1
  182. package/components/shadcn/index.cjs.map +1 -1
  183. package/components/shadcn/index.js +8 -7
  184. package/components/shadcn/index.js.map +1 -1
  185. package/package.json +1 -1
  186. package/types/index.d.ts +131 -15
  187. package/assets/jwms-portal-frontend-DntSIcYt.css +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"JLink.vue.cjs","sources":["../../../../src/components/atoms/JLink.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport { Button } from '@/components/shadcn'\n\ntype StyleType = 'default' | 'primary' | 'secondary' | 'destructive' | 'outline' | 'ghost' | 'sm' | 'lg'\n\nconst props = withDefaults(\n defineProps<{\n /** 링크 URL */\n href?: string\n /** 링크 텍스트 */\n text?: string\n /** 새 탭에서 열기 */\n target?: '_blank' | '_self' | '_parent' | '_top'\n /** 링크 스타일 테마 */\n styletype?: StyleType\n /** 비활성화 상태 */\n disabled?: boolean\n /** 추가 CSS 클래스 */\n class?: string\n }>(),\n {\n styletype: 'default',\n disabled: false,\n },\n)\n\nconst STYLE_PRESETS: Record<StyleType, { variant?: string; size?: string; class?: string }> = {\n default: { variant: 'link', class: 'text-primary underline-offset-4 hover:underline' },\n primary: { variant: 'link', class: 'text-primary-foreground bg-primary hover:bg-primary/90' },\n secondary: { variant: 'link', class: 'text-secondary-foreground bg-secondary hover:bg-secondary/80' },\n destructive: { variant: 'link', class: 'text-destructive hover:text-destructive/90' },\n outline: { variant: 'outline', class: 'border border-input bg-background hover:bg-accent hover:text-accent-foreground' },\n ghost: { variant: 'ghost', class: 'hover:bg-accent hover:text-accent-foreground' },\n sm: { variant: 'link', size: 'sm', class: 'h-8 px-3 text-xs' },\n lg: { variant: 'link', size: 'lg', class: 'h-12 px-8 text-base' },\n}\n\nconst mapped = computed(() => {\n const styleKey = props.styletype || 'default'\n const preset = STYLE_PRESETS[styleKey] ?? STYLE_PRESETS.default\n const finalClass = [preset?.class, props.class].filter(Boolean).join(' ')\n\n return {\n variant: (preset?.variant || 'link') as 'link' | 'default' | 'destructive' | 'outline' | 'secondary' | 'ghost',\n size: (preset?.size || 'default') as 'default' | 'sm' | 'lg' | 'icon',\n class: finalClass,\n disabled: props.disabled,\n }\n})\n\nconst linkProps = computed(() => {\n const baseProps: Record<string, any> = {\n as: 'a',\n }\n\n if (props.href) {\n baseProps.href = props.href\n }\n\n if (props.target) {\n baseProps.target = props.target\n }\n\n return baseProps\n})\n</script>\n\n<template>\n <Button v-bind=\"{ ...mapped, ...linkProps }\">\n <slot>{{ text }}</slot>\n </Button>\n</template>\n"],"names":["props","__props","STYLE_PRESETS","mapped","computed","styleKey","preset","finalClass","linkProps","baseProps","_createBlock","_unref","Button","_normalizeProps","_guardReactiveProps","_renderSlot","_ctx"],"mappings":"uWAMA,MAAMA,EAAQC,EAqBRC,EAAwF,CAC5F,QAAS,CAAE,QAAS,OAAQ,MAAO,iDAAA,EACnC,QAAS,CAAE,QAAS,OAAQ,MAAO,wDAAA,EACnC,UAAW,CAAE,QAAS,OAAQ,MAAO,8DAAA,EACrC,YAAa,CAAE,QAAS,OAAQ,MAAO,4CAAA,EACvC,QAAS,CAAE,QAAS,UAAW,MAAO,gFAAA,EACtC,MAAO,CAAE,QAAS,QAAS,MAAO,8CAAA,EAClC,GAAI,CAAE,QAAS,OAAQ,KAAM,KAAM,MAAO,kBAAA,EAC1C,GAAI,CAAE,QAAS,OAAQ,KAAM,KAAM,MAAO,qBAAA,CAAsB,EAG5DC,EAASC,EAAAA,SAAS,IAAM,CAC5B,MAAMC,EAAWL,EAAM,WAAa,UAC9BM,EAASJ,EAAcG,CAAQ,GAAKH,EAAc,QAClDK,EAAa,CAACD,GAAQ,MAAON,EAAM,KAAK,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,EAExE,MAAO,CACL,QAAUM,GAAQ,SAAW,OAC7B,KAAOA,GAAQ,MAAQ,UACvB,MAAOC,EACP,SAAUP,EAAM,QAAA,CAEpB,CAAC,EAEKQ,EAAYJ,EAAAA,SAAS,IAAM,CAC/B,MAAMK,EAAiC,CACrC,GAAI,GAAA,EAGN,OAAIT,EAAM,OACRS,EAAU,KAAOT,EAAM,MAGrBA,EAAM,SACRS,EAAU,OAAST,EAAM,QAGpBS,CACT,CAAC,8BAICC,EAAAA,YAESC,EAAAA,MAAAC,EAAAA,OAAA,EAAAC,EAAAA,eAAAC,EAAAA,mBAAA,CAAA,GAFYX,EAAA,MAAM,GAAKK,EAAA,KAAA,CAAS,CAAA,EAAA,mBACvC,IAAuB,CAAvBO,EAAAA,WAAuBC,sBAAvB,IAAuB,qCAAdf,EAAA,IAAI,EAAA,CAAA,CAAA"}
1
+ {"version":3,"file":"JLink.vue.cjs","sources":["../../../../src/components/atoms/JLink.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport { Button } from '@/components/shadcn'\n\ntype StyleType = 'default' | 'primary' | 'secondary' | 'destructive' | 'outline' | 'ghost' | 'sm' | 'lg'\n\nconst props = withDefaults(\n defineProps<{\n /** 링크 URL */\n href?: string\n /** 링크 텍스트 */\n text?: string\n /** 새 탭에서 열기 */\n target?: '_blank' | '_self' | '_parent' | '_top'\n /** 링크 스타일 테마 */\n styletype?: StyleType\n /** 비활성화 상태 */\n disabled?: boolean\n /** 추가 CSS 클래스 */\n class?: string\n }>(),\n {\n styletype: 'default',\n disabled: false,\n },\n)\n\nconst STYLE_PRESETS: Record<StyleType, { variant?: string; size?: string; class?: string }> = {\n default: { variant: 'link', class: 'text-primary underline-offset-4 hover:underline' },\n primary: { variant: 'link', class: 'text-primary-foreground bg-primary hover:bg-primary/90' },\n secondary: { variant: 'link', class: 'text-secondary-foreground bg-secondary hover:bg-secondary/80' },\n destructive: { variant: 'link', class: 'text-destructive hover:text-destructive/90' },\n outline: { variant: 'outline', class: 'border border-input bg-background hover:bg-accent hover:text-accent-foreground' },\n ghost: { variant: 'ghost', class: 'hover:bg-accent hover:text-accent-foreground' },\n sm: { variant: 'link', size: 'sm', class: 'h-8 px-3 text-xs' },\n lg: { variant: 'link', size: 'lg', class: 'h-12 px-8 text-base' },\n}\n\nconst mapped = computed(() => {\n const styleKey = props.styletype || 'default'\n const preset = STYLE_PRESETS[styleKey] ?? STYLE_PRESETS.default\n const finalClass = [preset?.class, props.class].filter(Boolean).join(' ')\n\n return {\n variant: (preset?.variant || 'link') as 'link' | 'default' | 'destructive' | 'outline' | 'secondary' | 'ghost',\n size: (preset?.size || 'sm') as 'xs' | 'sm' | 'md' | 'lg' | 'icon',\n class: finalClass,\n disabled: props.disabled,\n }\n})\n\nconst linkProps = computed(() => {\n const baseProps: Record<string, any> = {\n as: 'a',\n }\n\n if (props.href) {\n baseProps.href = props.href\n }\n\n if (props.target) {\n baseProps.target = props.target\n }\n\n return baseProps\n})\n</script>\n\n<template>\n <Button v-bind=\"{ ...mapped, ...linkProps }\">\n <slot>{{ text }}</slot>\n </Button>\n</template>\n"],"names":["props","__props","STYLE_PRESETS","mapped","computed","styleKey","preset","finalClass","linkProps","baseProps","_createBlock","_unref","Button","_normalizeProps","_guardReactiveProps","_renderSlot","_ctx"],"mappings":"uWAMA,MAAMA,EAAQC,EAqBRC,EAAwF,CAC5F,QAAS,CAAE,QAAS,OAAQ,MAAO,iDAAA,EACnC,QAAS,CAAE,QAAS,OAAQ,MAAO,wDAAA,EACnC,UAAW,CAAE,QAAS,OAAQ,MAAO,8DAAA,EACrC,YAAa,CAAE,QAAS,OAAQ,MAAO,4CAAA,EACvC,QAAS,CAAE,QAAS,UAAW,MAAO,gFAAA,EACtC,MAAO,CAAE,QAAS,QAAS,MAAO,8CAAA,EAClC,GAAI,CAAE,QAAS,OAAQ,KAAM,KAAM,MAAO,kBAAA,EAC1C,GAAI,CAAE,QAAS,OAAQ,KAAM,KAAM,MAAO,qBAAA,CAAsB,EAG5DC,EAASC,EAAAA,SAAS,IAAM,CAC5B,MAAMC,EAAWL,EAAM,WAAa,UAC9BM,EAASJ,EAAcG,CAAQ,GAAKH,EAAc,QAClDK,EAAa,CAACD,GAAQ,MAAON,EAAM,KAAK,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,EAExE,MAAO,CACL,QAAUM,GAAQ,SAAW,OAC7B,KAAOA,GAAQ,MAAQ,KACvB,MAAOC,EACP,SAAUP,EAAM,QAAA,CAEpB,CAAC,EAEKQ,EAAYJ,EAAAA,SAAS,IAAM,CAC/B,MAAMK,EAAiC,CACrC,GAAI,GAAA,EAGN,OAAIT,EAAM,OACRS,EAAU,KAAOT,EAAM,MAGrBA,EAAM,SACRS,EAAU,OAAST,EAAM,QAGpBS,CACT,CAAC,8BAICC,EAAAA,YAESC,EAAAA,MAAAC,EAAAA,OAAA,EAAAC,EAAAA,eAAAC,EAAAA,mBAAA,CAAA,GAFYX,EAAA,MAAM,GAAKK,EAAA,KAAA,CAAS,CAAA,EAAA,mBACvC,IAAuB,CAAvBO,EAAAA,WAAuBC,sBAAvB,IAAuB,qCAAdf,EAAA,IAAI,EAAA,CAAA,CAAA"}
@@ -22,20 +22,20 @@ const z = /* @__PURE__ */ c({
22
22
  sm: { variant: "link", size: "sm", class: "h-8 px-3 text-xs" },
23
23
  lg: { variant: "link", size: "lg", class: "h-12 px-8 text-base" }
24
24
  }, o = n(() => {
25
- const t = e.styletype || "default", r = s[t] ?? s.default, i = [r?.class, e.class].filter(Boolean).join(" ");
25
+ const t = e.styletype || "default", r = s[t] ?? s.default, l = [r?.class, e.class].filter(Boolean).join(" ");
26
26
  return {
27
27
  variant: r?.variant || "link",
28
- size: r?.size || "default",
29
- class: i,
28
+ size: r?.size || "sm",
29
+ class: l,
30
30
  disabled: e.disabled
31
31
  };
32
- }), l = n(() => {
32
+ }), i = n(() => {
33
33
  const t = {
34
34
  as: "a"
35
35
  };
36
36
  return e.href && (t.href = e.href), e.target && (t.target = e.target), t;
37
37
  });
38
- return (t, r) => (u(), d(f(y), p(v({ ...o.value, ...l.value })), {
38
+ return (t, r) => (u(), d(f(y), p(v({ ...o.value, ...i.value })), {
39
39
  default: g(() => [
40
40
  m(t.$slots, "default", {}, () => [
41
41
  h(x(a.text), 1)
@@ -1 +1 @@
1
- {"version":3,"file":"JLink.vue.js","sources":["../../../../src/components/atoms/JLink.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport { Button } from '@/components/shadcn'\n\ntype StyleType = 'default' | 'primary' | 'secondary' | 'destructive' | 'outline' | 'ghost' | 'sm' | 'lg'\n\nconst props = withDefaults(\n defineProps<{\n /** 링크 URL */\n href?: string\n /** 링크 텍스트 */\n text?: string\n /** 새 탭에서 열기 */\n target?: '_blank' | '_self' | '_parent' | '_top'\n /** 링크 스타일 테마 */\n styletype?: StyleType\n /** 비활성화 상태 */\n disabled?: boolean\n /** 추가 CSS 클래스 */\n class?: string\n }>(),\n {\n styletype: 'default',\n disabled: false,\n },\n)\n\nconst STYLE_PRESETS: Record<StyleType, { variant?: string; size?: string; class?: string }> = {\n default: { variant: 'link', class: 'text-primary underline-offset-4 hover:underline' },\n primary: { variant: 'link', class: 'text-primary-foreground bg-primary hover:bg-primary/90' },\n secondary: { variant: 'link', class: 'text-secondary-foreground bg-secondary hover:bg-secondary/80' },\n destructive: { variant: 'link', class: 'text-destructive hover:text-destructive/90' },\n outline: { variant: 'outline', class: 'border border-input bg-background hover:bg-accent hover:text-accent-foreground' },\n ghost: { variant: 'ghost', class: 'hover:bg-accent hover:text-accent-foreground' },\n sm: { variant: 'link', size: 'sm', class: 'h-8 px-3 text-xs' },\n lg: { variant: 'link', size: 'lg', class: 'h-12 px-8 text-base' },\n}\n\nconst mapped = computed(() => {\n const styleKey = props.styletype || 'default'\n const preset = STYLE_PRESETS[styleKey] ?? STYLE_PRESETS.default\n const finalClass = [preset?.class, props.class].filter(Boolean).join(' ')\n\n return {\n variant: (preset?.variant || 'link') as 'link' | 'default' | 'destructive' | 'outline' | 'secondary' | 'ghost',\n size: (preset?.size || 'default') as 'default' | 'sm' | 'lg' | 'icon',\n class: finalClass,\n disabled: props.disabled,\n }\n})\n\nconst linkProps = computed(() => {\n const baseProps: Record<string, any> = {\n as: 'a',\n }\n\n if (props.href) {\n baseProps.href = props.href\n }\n\n if (props.target) {\n baseProps.target = props.target\n }\n\n return baseProps\n})\n</script>\n\n<template>\n <Button v-bind=\"{ ...mapped, ...linkProps }\">\n <slot>{{ text }}</slot>\n </Button>\n</template>\n"],"names":["props","__props","STYLE_PRESETS","mapped","computed","styleKey","preset","finalClass","linkProps","baseProps","_createBlock","_unref","Button","_normalizeProps","_guardReactiveProps","_renderSlot","_ctx"],"mappings":";;;;;;;;;;;;;;AAMA,UAAMA,IAAQC,GAqBRC,IAAwF;AAAA,MAC5F,SAAS,EAAE,SAAS,QAAQ,OAAO,kDAAA;AAAA,MACnC,SAAS,EAAE,SAAS,QAAQ,OAAO,yDAAA;AAAA,MACnC,WAAW,EAAE,SAAS,QAAQ,OAAO,+DAAA;AAAA,MACrC,aAAa,EAAE,SAAS,QAAQ,OAAO,6CAAA;AAAA,MACvC,SAAS,EAAE,SAAS,WAAW,OAAO,iFAAA;AAAA,MACtC,OAAO,EAAE,SAAS,SAAS,OAAO,+CAAA;AAAA,MAClC,IAAI,EAAE,SAAS,QAAQ,MAAM,MAAM,OAAO,mBAAA;AAAA,MAC1C,IAAI,EAAE,SAAS,QAAQ,MAAM,MAAM,OAAO,sBAAA;AAAA,IAAsB,GAG5DC,IAASC,EAAS,MAAM;AAC5B,YAAMC,IAAWL,EAAM,aAAa,WAC9BM,IAASJ,EAAcG,CAAQ,KAAKH,EAAc,SAClDK,IAAa,CAACD,GAAQ,OAAON,EAAM,KAAK,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAExE,aAAO;AAAA,QACL,SAAUM,GAAQ,WAAW;AAAA,QAC7B,MAAOA,GAAQ,QAAQ;AAAA,QACvB,OAAOC;AAAA,QACP,UAAUP,EAAM;AAAA,MAAA;AAAA,IAEpB,CAAC,GAEKQ,IAAYJ,EAAS,MAAM;AAC/B,YAAMK,IAAiC;AAAA,QACrC,IAAI;AAAA,MAAA;AAGN,aAAIT,EAAM,SACRS,EAAU,OAAOT,EAAM,OAGrBA,EAAM,WACRS,EAAU,SAAST,EAAM,SAGpBS;AAAA,IACT,CAAC;2BAICC,EAESC,EAAAC,CAAA,GAAAC,EAAAC,EAAA,EAAA,GAFYX,EAAA,OAAM,GAAKK,EAAA,MAAA,CAAS,CAAA,GAAA;AAAA,iBACvC,MAAuB;AAAA,QAAvBO,EAAuBC,yBAAvB,MAAuB;AAAA,cAAdf,EAAA,IAAI,GAAA,CAAA;AAAA,QAAA;;;;;;"}
1
+ {"version":3,"file":"JLink.vue.js","sources":["../../../../src/components/atoms/JLink.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport { Button } from '@/components/shadcn'\n\ntype StyleType = 'default' | 'primary' | 'secondary' | 'destructive' | 'outline' | 'ghost' | 'sm' | 'lg'\n\nconst props = withDefaults(\n defineProps<{\n /** 링크 URL */\n href?: string\n /** 링크 텍스트 */\n text?: string\n /** 새 탭에서 열기 */\n target?: '_blank' | '_self' | '_parent' | '_top'\n /** 링크 스타일 테마 */\n styletype?: StyleType\n /** 비활성화 상태 */\n disabled?: boolean\n /** 추가 CSS 클래스 */\n class?: string\n }>(),\n {\n styletype: 'default',\n disabled: false,\n },\n)\n\nconst STYLE_PRESETS: Record<StyleType, { variant?: string; size?: string; class?: string }> = {\n default: { variant: 'link', class: 'text-primary underline-offset-4 hover:underline' },\n primary: { variant: 'link', class: 'text-primary-foreground bg-primary hover:bg-primary/90' },\n secondary: { variant: 'link', class: 'text-secondary-foreground bg-secondary hover:bg-secondary/80' },\n destructive: { variant: 'link', class: 'text-destructive hover:text-destructive/90' },\n outline: { variant: 'outline', class: 'border border-input bg-background hover:bg-accent hover:text-accent-foreground' },\n ghost: { variant: 'ghost', class: 'hover:bg-accent hover:text-accent-foreground' },\n sm: { variant: 'link', size: 'sm', class: 'h-8 px-3 text-xs' },\n lg: { variant: 'link', size: 'lg', class: 'h-12 px-8 text-base' },\n}\n\nconst mapped = computed(() => {\n const styleKey = props.styletype || 'default'\n const preset = STYLE_PRESETS[styleKey] ?? STYLE_PRESETS.default\n const finalClass = [preset?.class, props.class].filter(Boolean).join(' ')\n\n return {\n variant: (preset?.variant || 'link') as 'link' | 'default' | 'destructive' | 'outline' | 'secondary' | 'ghost',\n size: (preset?.size || 'sm') as 'xs' | 'sm' | 'md' | 'lg' | 'icon',\n class: finalClass,\n disabled: props.disabled,\n }\n})\n\nconst linkProps = computed(() => {\n const baseProps: Record<string, any> = {\n as: 'a',\n }\n\n if (props.href) {\n baseProps.href = props.href\n }\n\n if (props.target) {\n baseProps.target = props.target\n }\n\n return baseProps\n})\n</script>\n\n<template>\n <Button v-bind=\"{ ...mapped, ...linkProps }\">\n <slot>{{ text }}</slot>\n </Button>\n</template>\n"],"names":["props","__props","STYLE_PRESETS","mapped","computed","styleKey","preset","finalClass","linkProps","baseProps","_createBlock","_unref","Button","_normalizeProps","_guardReactiveProps","_renderSlot","_ctx"],"mappings":";;;;;;;;;;;;;;AAMA,UAAMA,IAAQC,GAqBRC,IAAwF;AAAA,MAC5F,SAAS,EAAE,SAAS,QAAQ,OAAO,kDAAA;AAAA,MACnC,SAAS,EAAE,SAAS,QAAQ,OAAO,yDAAA;AAAA,MACnC,WAAW,EAAE,SAAS,QAAQ,OAAO,+DAAA;AAAA,MACrC,aAAa,EAAE,SAAS,QAAQ,OAAO,6CAAA;AAAA,MACvC,SAAS,EAAE,SAAS,WAAW,OAAO,iFAAA;AAAA,MACtC,OAAO,EAAE,SAAS,SAAS,OAAO,+CAAA;AAAA,MAClC,IAAI,EAAE,SAAS,QAAQ,MAAM,MAAM,OAAO,mBAAA;AAAA,MAC1C,IAAI,EAAE,SAAS,QAAQ,MAAM,MAAM,OAAO,sBAAA;AAAA,IAAsB,GAG5DC,IAASC,EAAS,MAAM;AAC5B,YAAMC,IAAWL,EAAM,aAAa,WAC9BM,IAASJ,EAAcG,CAAQ,KAAKH,EAAc,SAClDK,IAAa,CAACD,GAAQ,OAAON,EAAM,KAAK,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAExE,aAAO;AAAA,QACL,SAAUM,GAAQ,WAAW;AAAA,QAC7B,MAAOA,GAAQ,QAAQ;AAAA,QACvB,OAAOC;AAAA,QACP,UAAUP,EAAM;AAAA,MAAA;AAAA,IAEpB,CAAC,GAEKQ,IAAYJ,EAAS,MAAM;AAC/B,YAAMK,IAAiC;AAAA,QACrC,IAAI;AAAA,MAAA;AAGN,aAAIT,EAAM,SACRS,EAAU,OAAOT,EAAM,OAGrBA,EAAM,WACRS,EAAU,SAAST,EAAM,SAGpBS;AAAA,IACT,CAAC;2BAICC,EAESC,EAAAC,CAAA,GAAAC,EAAAC,EAAA,EAAA,GAFYX,EAAA,OAAM,GAAKK,EAAA,MAAA,CAAS,CAAA,GAAA;AAAA,iBACvC,MAAuB;AAAA,QAAvBO,EAAuBC,yBAAvB,MAAuB;AAAA,cAAdf,EAAA,IAAI,GAAA,CAAA;AAAA,QAAA;;;;;;"}
@@ -3,5 +3,5 @@
3
3
  for (const [t_key, t_val] of t_opts)
4
4
  t_merged[t_key] = t_val;
5
5
  return t_merged;
6
- };,u=t(e.default,[["__scopeId","data-v-b07e3dcb"]]);exports.default=u;
6
+ };,u=t(e.default,[["__scopeId","data-v-0ce9f9f8"]]);exports.default=u;
7
7
  //# sourceMappingURL=JPreview.vue.cjs.map
@@ -6,8 +6,8 @@ const r = (r_comp, r_opts) => {
6
6
  r_merged[r_key] = r_val;
7
7
  return r_merged;
8
8
  };
9
- const p = /* @__PURE__ */ r(o, [["__scopeId", "data-v-b07e3dcb"]]);
9
+ const m = /* @__PURE__ */ r(o, [["__scopeId", "data-v-0ce9f9f8"]]);
10
10
  export {
11
- p as default
11
+ m as default
12
12
  };
13
13
  //# sourceMappingURL=JPreview.vue.js.map
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("vue"),o=require("md-editor-v3");;/* empty css */const m=require("dompurify"),c=["innerHTML"],u=e.defineComponent({__name:"JPreview",props:{modelValue:{default:""},theme:{default:"light"},class:{}},setup(l){const r=l;function n(s){const t=s.trim();return t.startsWith("<!DOCTYPE html")||t.startsWith("<!doctype html")||t.startsWith("<!DOCTYPE HTML")||t.startsWith("<!DOCTYPE Html")||t.startsWith("<html")||t.startsWith("<HTML")||t.startsWith("<Html")?"html":"markdown"}const a=e.computed(()=>n(r.modelValue||"")),i=e.computed(()=>a.value==="html"?m.sanitize(r.modelValue||"",{ALLOWED_TAGS:["p","br","strong","em","u","s","h1","h2","h3","h4","h5","h6","ul","ol","li","blockquote","pre","code","a","img","table","thead","tbody","tr","th","td","div","span","hr","blockquote","del","ins","sub","sup","kbd","mark","abbr","dfn","cite","q","samp","var","time","b","i","small","big","center","font","strike","tt","html","head","body","title","meta","link","style","script","noscript"],ALLOWED_ATTR:["href","src","alt","title","width","height","class","id","style","target","rel","type","charset","name","content","http-equiv","lang"],ALLOW_DATA_ATTR:!1}):"");return(s,t)=>(e.openBlock(),e.createElementBlock("div",{class:e.normalizeClass(["j-preview-wrapper",r.class])},[a.value==="html"?(e.openBlock(),e.createElementBlock("div",{key:0,class:e.normalizeClass(["j-preview-html",l.theme==="dark"?"dark":""]),innerHTML:i.value},null,10,c)):(e.openBlock(),e.createBlock(e.unref(o.MdPreview),{key:1,"model-value":l.modelValue,theme:l.theme,"preview-class-name":"j-preview-markdown",language:"en-US"},null,8,["model-value","theme"]))],2))}});exports.default=u;
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("vue"),d=require("md-editor-v3");;/* empty css */const h=require("dompurify"),p=["innerHTML"],v=e.defineComponent({__name:"JPreview",props:{modelValue:{default:""},theme:{},class:{}},setup(n){const r=n,s=e.ref(!1),a=()=>{s.value=document.documentElement.classList.contains("dark")},o=e.computed(()=>r.theme?r.theme:s.value?"dark":"light");let l=null;e.onMounted(()=>{a(),l=new MutationObserver(()=>{a()}),l.observe(document.documentElement,{attributes:!0,attributeFilter:["class"]})}),e.onUnmounted(()=>{l&&l.disconnect()});function c(u){const t=u.trim();return t.startsWith("<!DOCTYPE html")||t.startsWith("<!doctype html")||t.startsWith("<!DOCTYPE HTML")||t.startsWith("<!DOCTYPE Html")||t.startsWith("<html")||t.startsWith("<HTML")||t.startsWith("<Html")?"html":"markdown"}const i=e.computed(()=>c(r.modelValue||"")),m=e.computed(()=>i.value==="html"?h.sanitize(r.modelValue||"",{ALLOWED_TAGS:["p","br","strong","em","u","s","h1","h2","h3","h4","h5","h6","ul","ol","li","blockquote","pre","code","a","img","table","thead","tbody","tr","th","td","div","span","hr","blockquote","del","ins","sub","sup","kbd","mark","abbr","dfn","cite","q","samp","var","time","b","i","small","big","center","font","strike","tt","html","head","body","title","meta","link","style","script","noscript"],ALLOWED_ATTR:["href","src","alt","title","width","height","class","id","style","target","rel","type","charset","name","content","http-equiv","lang"],ALLOW_DATA_ATTR:!1}):"");return(u,t)=>(e.openBlock(),e.createElementBlock("div",{class:e.normalizeClass(["j-preview-wrapper",r.class])},[i.value==="html"?(e.openBlock(),e.createElementBlock("div",{key:0,class:e.normalizeClass(["j-preview-html",o.value==="dark"?"dark":""]),innerHTML:m.value},null,10,p)):(e.openBlock(),e.createBlock(e.unref(d.MdPreview),{key:1,"model-value":n.modelValue,theme:o.value,"preview-class-name":"j-preview-markdown",language:"en-US"},null,8,["model-value","theme"]))],2))}});exports.default=v;
2
2
  //# sourceMappingURL=JPreview.vue2.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"JPreview.vue2.cjs","sources":["../../../../src/components/atoms/JPreview.vue"],"sourcesContent":["<script setup lang=\"ts\">\r\nimport { computed } from 'vue'\r\nimport { MdPreview } from 'md-editor-v3'\r\nimport 'md-editor-v3/lib/style.css'\r\nimport DOMPurify from 'dompurify'\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n /** 마크다운 또는 HTML 내용 */\r\n modelValue?: string\r\n /** 테마 (light/dark) */\r\n theme?: 'light' | 'dark'\r\n /** 추가 CSS 클래스 */\r\n class?: string\r\n }>(),\r\n {\r\n modelValue: '',\r\n theme: 'light',\r\n },\r\n)\r\n\r\n/**\r\n * 콘텐츠 타입 자동 감지\r\n */\r\nfunction detectContentType(content: string): 'markdown' | 'html' {\r\n const trimmed = content.trim()\r\n \r\n // HTML 문서 시작 태그 확인\r\n if (\r\n trimmed.startsWith('<!DOCTYPE html') ||\r\n trimmed.startsWith('<!doctype html') ||\r\n trimmed.startsWith('<!DOCTYPE HTML') ||\r\n trimmed.startsWith('<!DOCTYPE Html') ||\r\n trimmed.startsWith('<html') ||\r\n trimmed.startsWith('<HTML') ||\r\n trimmed.startsWith('<Html')\r\n ) {\r\n return 'html'\r\n }\r\n \r\n return 'markdown'\r\n}\r\n\r\nconst contentType = computed(() => detectContentType(props.modelValue || ''))\r\n\r\nconst sanitizedHtml = computed(() => {\r\n if (contentType.value === 'html') {\r\n return DOMPurify.sanitize(props.modelValue || '', {\r\n ALLOWED_TAGS: [\r\n 'p', 'br', 'strong', 'em', 'u', 's', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6',\r\n 'ul', 'ol', 'li', 'blockquote', 'pre', 'code', 'a', 'img', 'table', 'thead',\r\n 'tbody', 'tr', 'th', 'td', 'div', 'span', 'hr', 'blockquote', 'del', 'ins',\r\n 'sub', 'sup', 'kbd', 'mark', 'abbr', 'dfn', 'cite', 'q', 'samp', 'var',\r\n 'time', 'b', 'i', 'small', 'big', 'center', 'font', 'strike', 'tt',\r\n 'html', 'head', 'body', 'title', 'meta', 'link', 'style', 'script', 'noscript'\r\n ],\r\n ALLOWED_ATTR: [\r\n 'href', 'src', 'alt', 'title', 'width', 'height', 'class', 'id', 'style',\r\n 'target', 'rel', 'type', 'charset', 'name', 'content', 'http-equiv', 'lang'\r\n ],\r\n ALLOW_DATA_ATTR: false,\r\n })\r\n }\r\n return ''\r\n})\r\n</script>\r\n\r\n<template>\r\n <div :class=\"['j-preview-wrapper', props.class]\">\r\n <!-- HTML 렌더링 -->\r\n <div\r\n v-if=\"contentType === 'html'\"\r\n :class=\"['j-preview-html', theme === 'dark' ? 'dark' : '']\"\r\n v-html=\"sanitizedHtml\"\r\n />\r\n \r\n <!-- 마크다운 렌더링 -->\r\n <MdPreview\r\n v-else\r\n :model-value=\"modelValue\"\r\n :theme=\"theme\"\r\n :preview-class-name=\"'j-preview-markdown'\"\r\n language=\"en-US\"\r\n />\r\n </div>\r\n</template>\r\n\r\n<style scoped>\r\n.j-preview-wrapper {\r\n @apply w-full;\r\n}\r\n\r\n.j-preview-html {\r\n @apply prose prose-slate max-w-none;\r\n}\r\n\r\n.j-preview-html.dark {\r\n @apply prose-invert;\r\n}\r\n\r\n:deep(.j-preview-markdown) {\r\n @apply w-full;\r\n}\r\n</style>\r\n"],"names":["props","__props","detectContentType","content","trimmed","contentType","computed","sanitizedHtml","DOMPurify","_createElementBlock","_normalizeClass","_createBlock","_unref","MdPreview"],"mappings":"2bAMA,MAAMA,EAAQC,EAkBd,SAASC,EAAkBC,EAAsC,CAC/D,MAAMC,EAAUD,EAAQ,KAAA,EAGxB,OACEC,EAAQ,WAAW,gBAAgB,GACnCA,EAAQ,WAAW,gBAAgB,GACnCA,EAAQ,WAAW,gBAAgB,GACnCA,EAAQ,WAAW,gBAAgB,GACnCA,EAAQ,WAAW,OAAO,GAC1BA,EAAQ,WAAW,OAAO,GAC1BA,EAAQ,WAAW,OAAO,EAEnB,OAGF,UACT,CAEA,MAAMC,EAAcC,EAAAA,SAAS,IAAMJ,EAAkBF,EAAM,YAAc,EAAE,CAAC,EAEtEO,EAAgBD,EAAAA,SAAS,IACzBD,EAAY,QAAU,OACjBG,EAAU,SAASR,EAAM,YAAc,GAAI,CAChD,aAAc,CACZ,IAAK,KAAM,SAAU,KAAM,IAAK,IAAK,KAAM,KAAM,KAAM,KAAM,KAAM,KACnE,KAAM,KAAM,KAAM,aAAc,MAAO,OAAQ,IAAK,MAAO,QAAS,QACpE,QAAS,KAAM,KAAM,KAAM,MAAO,OAAQ,KAAM,aAAc,MAAO,MACrE,MAAO,MAAO,MAAO,OAAQ,OAAQ,MAAO,OAAQ,IAAK,OAAQ,MACjE,OAAQ,IAAK,IAAK,QAAS,MAAO,SAAU,OAAQ,SAAU,KAC9D,OAAQ,OAAQ,OAAQ,QAAS,OAAQ,OAAQ,QAAS,SAAU,UAAA,EAEtE,aAAc,CACZ,OAAQ,MAAO,MAAO,QAAS,QAAS,SAAU,QAAS,KAAM,QACjE,SAAU,MAAO,OAAQ,UAAW,OAAQ,UAAW,aAAc,MAAA,EAEvE,gBAAiB,EAAA,CAClB,EAEI,EACR,8BAICS,EAAAA,mBAgBM,MAAA,CAhBA,MAAKC,EAAAA,eAAA,CAAA,oBAAwBV,EAAM,KAAK,CAAA,CAAA,GAGpCK,EAAA,QAAW,sBADnBI,EAAAA,mBAIE,MAAA,OAFC,yCAA0BR,EAAA,QAAK,OAAA,OAAA,EAAA,CAAA,EAChC,UAAQM,EAAA,KAAA,6BAIVI,EAAAA,YAMEC,QAAAC,EAAAA,SAAA,EAAA,OAJC,cAAaZ,EAAA,WACb,MAAOA,EAAA,MACP,qBAAoB,qBACrB,SAAS,OAAA"}
1
+ {"version":3,"file":"JPreview.vue2.cjs","sources":["../../../../src/components/atoms/JPreview.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ref, computed, onMounted, onUnmounted } from 'vue'\nimport { MdPreview } from 'md-editor-v3'\nimport 'md-editor-v3/lib/style.css'\nimport DOMPurify from 'dompurify'\n\nconst props = withDefaults(\n defineProps<{\n /** 마크다운 또는 HTML 내용 */\n modelValue?: string\n /** 테마 (light/dark) - 설정하지 않으면 자동으로 다크모드 감지 */\n theme?: 'light' | 'dark'\n /** 추가 CSS 클래스 */\n class?: string\n }>(),\n {\n modelValue: '',\n },\n)\n\n// 다크모드 상태\nconst isDarkMode = ref(false)\n\n// 다크모드 감지 함수\nconst detectDarkMode = () => {\n isDarkMode.value = document.documentElement.classList.contains('dark')\n}\n\n// 현재 테마 계산 (props.theme이 있으면 그것 사용, 없으면 자동 감지)\nconst currentTheme = computed(() => {\n if (props.theme) {\n return props.theme\n }\n return isDarkMode.value ? 'dark' : 'light'\n})\n\n// MutationObserver로 다크모드 변경 감지\nlet darkModeObserver: MutationObserver | null = null\n\nonMounted(() => {\n // 초기 다크모드 상태 감지\n detectDarkMode()\n \n // MutationObserver로 class 변경 감지\n darkModeObserver = new MutationObserver(() => {\n detectDarkMode()\n })\n \n darkModeObserver.observe(document.documentElement, {\n attributes: true,\n attributeFilter: ['class'],\n })\n})\n\nonUnmounted(() => {\n if (darkModeObserver) {\n darkModeObserver.disconnect()\n }\n})\n\r\n/**\r\n * 콘텐츠 타입 자동 감지\r\n */\r\nfunction detectContentType(content: string): 'markdown' | 'html' {\r\n const trimmed = content.trim()\r\n \r\n // HTML 문서 시작 태그 확인\r\n if (\r\n trimmed.startsWith('<!DOCTYPE html') ||\r\n trimmed.startsWith('<!doctype html') ||\r\n trimmed.startsWith('<!DOCTYPE HTML') ||\r\n trimmed.startsWith('<!DOCTYPE Html') ||\r\n trimmed.startsWith('<html') ||\r\n trimmed.startsWith('<HTML') ||\r\n trimmed.startsWith('<Html')\r\n ) {\r\n return 'html'\r\n }\r\n \r\n return 'markdown'\r\n}\r\n\r\nconst contentType = computed(() => detectContentType(props.modelValue || ''))\r\n\r\nconst sanitizedHtml = computed(() => {\r\n if (contentType.value === 'html') {\r\n return DOMPurify.sanitize(props.modelValue || '', {\r\n ALLOWED_TAGS: [\r\n 'p', 'br', 'strong', 'em', 'u', 's', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6',\r\n 'ul', 'ol', 'li', 'blockquote', 'pre', 'code', 'a', 'img', 'table', 'thead',\r\n 'tbody', 'tr', 'th', 'td', 'div', 'span', 'hr', 'blockquote', 'del', 'ins',\r\n 'sub', 'sup', 'kbd', 'mark', 'abbr', 'dfn', 'cite', 'q', 'samp', 'var',\r\n 'time', 'b', 'i', 'small', 'big', 'center', 'font', 'strike', 'tt',\r\n 'html', 'head', 'body', 'title', 'meta', 'link', 'style', 'script', 'noscript'\r\n ],\r\n ALLOWED_ATTR: [\r\n 'href', 'src', 'alt', 'title', 'width', 'height', 'class', 'id', 'style',\r\n 'target', 'rel', 'type', 'charset', 'name', 'content', 'http-equiv', 'lang'\r\n ],\r\n ALLOW_DATA_ATTR: false,\r\n })\r\n }\r\n return ''\r\n})\r\n</script>\r\n\r\n<template>\n <div :class=\"['j-preview-wrapper', props.class]\">\n <!-- HTML 렌더링 -->\n <div\n v-if=\"contentType === 'html'\"\n :class=\"['j-preview-html', currentTheme === 'dark' ? 'dark' : '']\"\n v-html=\"sanitizedHtml\"\n />\n \n <!-- 마크다운 렌더링 -->\n <MdPreview\n v-else\n :model-value=\"modelValue\"\n :theme=\"currentTheme\"\n :preview-class-name=\"'j-preview-markdown'\"\n language=\"en-US\"\n />\n </div>\n</template>\n\r\n<style scoped>\r\n.j-preview-wrapper {\r\n @apply w-full;\r\n}\r\n\r\n.j-preview-html {\r\n @apply prose prose-slate max-w-none;\r\n}\r\n\r\n.j-preview-html.dark {\r\n @apply prose-invert;\r\n}\r\n\r\n:deep(.j-preview-markdown) {\r\n @apply w-full;\r\n}\r\n</style>\r\n"],"names":["props","__props","isDarkMode","ref","detectDarkMode","currentTheme","computed","darkModeObserver","onMounted","onUnmounted","detectContentType","content","trimmed","contentType","sanitizedHtml","DOMPurify","_createElementBlock","_normalizeClass","_createBlock","_unref","MdPreview"],"mappings":"4aAMA,MAAMA,EAAQC,EAeRC,EAAaC,EAAAA,IAAI,EAAK,EAGtBC,EAAiB,IAAM,CAC3BF,EAAW,MAAQ,SAAS,gBAAgB,UAAU,SAAS,MAAM,CACvE,EAGMG,EAAeC,EAAAA,SAAS,IACxBN,EAAM,MACDA,EAAM,MAERE,EAAW,MAAQ,OAAS,OACpC,EAGD,IAAIK,EAA4C,KAEhDC,EAAAA,UAAU,IAAM,CAEdJ,EAAA,EAGAG,EAAmB,IAAI,iBAAiB,IAAM,CAC5CH,EAAA,CACF,CAAC,EAEDG,EAAiB,QAAQ,SAAS,gBAAiB,CACjD,WAAY,GACZ,gBAAiB,CAAC,OAAO,CAAA,CAC1B,CACH,CAAC,EAEDE,EAAAA,YAAY,IAAM,CACZF,GACFA,EAAiB,WAAA,CAErB,CAAC,EAKD,SAASG,EAAkBC,EAAsC,CAC/D,MAAMC,EAAUD,EAAQ,KAAA,EAGxB,OACEC,EAAQ,WAAW,gBAAgB,GACnCA,EAAQ,WAAW,gBAAgB,GACnCA,EAAQ,WAAW,gBAAgB,GACnCA,EAAQ,WAAW,gBAAgB,GACnCA,EAAQ,WAAW,OAAO,GAC1BA,EAAQ,WAAW,OAAO,GAC1BA,EAAQ,WAAW,OAAO,EAEnB,OAGF,UACT,CAEA,MAAMC,EAAcP,EAAAA,SAAS,IAAMI,EAAkBV,EAAM,YAAc,EAAE,CAAC,EAEtEc,EAAgBR,EAAAA,SAAS,IACzBO,EAAY,QAAU,OACjBE,EAAU,SAASf,EAAM,YAAc,GAAI,CAChD,aAAc,CACZ,IAAK,KAAM,SAAU,KAAM,IAAK,IAAK,KAAM,KAAM,KAAM,KAAM,KAAM,KACnE,KAAM,KAAM,KAAM,aAAc,MAAO,OAAQ,IAAK,MAAO,QAAS,QACpE,QAAS,KAAM,KAAM,KAAM,MAAO,OAAQ,KAAM,aAAc,MAAO,MACrE,MAAO,MAAO,MAAO,OAAQ,OAAQ,MAAO,OAAQ,IAAK,OAAQ,MACjE,OAAQ,IAAK,IAAK,QAAS,MAAO,SAAU,OAAQ,SAAU,KAC9D,OAAQ,OAAQ,OAAQ,QAAS,OAAQ,OAAQ,QAAS,SAAU,UAAA,EAEtE,aAAc,CACZ,OAAQ,MAAO,MAAO,QAAS,QAAS,SAAU,QAAS,KAAM,QACjE,SAAU,MAAO,OAAQ,UAAW,OAAQ,UAAW,aAAc,MAAA,EAEvE,gBAAiB,EAAA,CAClB,EAEI,EACR,8BAICgB,EAAAA,mBAgBM,MAAA,CAhBA,MAAKC,EAAAA,eAAA,CAAA,oBAAwBjB,EAAM,KAAK,CAAA,CAAA,GAGpCa,EAAA,QAAW,sBADnBG,EAAAA,mBAIE,MAAA,OAFC,yCAA0BX,EAAA,QAAY,OAAA,OAAA,EAAA,CAAA,EACvC,UAAQS,EAAA,KAAA,6BAIVI,EAAAA,YAMEC,QAAAC,EAAAA,SAAA,EAAA,OAJC,cAAanB,EAAA,WACb,MAAOI,EAAA,MACP,qBAAoB,qBACrB,SAAS,OAAA"}
@@ -1,21 +1,34 @@
1
- import { defineComponent as c, computed as i, createElementBlock as n, openBlock as r, normalizeClass as m, createBlock as d, unref as u } from "vue";
2
- import { MdPreview as p } from "md-editor-v3";
1
+ import { defineComponent as v, ref as f, computed as l, onMounted as k, onUnmounted as b, createElementBlock as u, openBlock as n, normalizeClass as d, createBlock as T, unref as w } from "vue";
2
+ import { MdPreview as y } from "md-editor-v3";
3
3
  /* empty css */
4
- import f from "dompurify";
5
- const v = ["innerHTML"], w = /* @__PURE__ */ c({
4
+ import L from "dompurify";
5
+ const M = ["innerHTML"], O = /* @__PURE__ */ v({
6
6
  __name: "JPreview",
7
7
  props: {
8
8
  modelValue: { default: "" },
9
- theme: { default: "light" },
9
+ theme: {},
10
10
  class: {}
11
11
  },
12
- setup(e) {
13
- const l = e;
14
- function o(s) {
15
- const t = s.trim();
16
- return t.startsWith("<!DOCTYPE html") || t.startsWith("<!doctype html") || t.startsWith("<!DOCTYPE HTML") || t.startsWith("<!DOCTYPE Html") || t.startsWith("<html") || t.startsWith("<HTML") || t.startsWith("<Html") ? "html" : "markdown";
12
+ setup(a) {
13
+ const t = a, s = f(!1), o = () => {
14
+ s.value = document.documentElement.classList.contains("dark");
15
+ }, i = l(() => t.theme ? t.theme : s.value ? "dark" : "light");
16
+ let r = null;
17
+ k(() => {
18
+ o(), r = new MutationObserver(() => {
19
+ o();
20
+ }), r.observe(document.documentElement, {
21
+ attributes: !0,
22
+ attributeFilter: ["class"]
23
+ });
24
+ }), b(() => {
25
+ r && r.disconnect();
26
+ });
27
+ function h(c) {
28
+ const e = c.trim();
29
+ return e.startsWith("<!DOCTYPE html") || e.startsWith("<!doctype html") || e.startsWith("<!DOCTYPE HTML") || e.startsWith("<!DOCTYPE Html") || e.startsWith("<html") || e.startsWith("<HTML") || e.startsWith("<Html") ? "html" : "markdown";
17
30
  }
18
- const a = i(() => o(l.modelValue || "")), h = i(() => a.value === "html" ? f.sanitize(l.modelValue || "", {
31
+ const m = l(() => h(t.modelValue || "")), p = l(() => m.value === "html" ? L.sanitize(t.modelValue || "", {
19
32
  ALLOWED_TAGS: [
20
33
  "p",
21
34
  "br",
@@ -99,17 +112,17 @@ const v = ["innerHTML"], w = /* @__PURE__ */ c({
99
112
  ],
100
113
  ALLOW_DATA_ATTR: !1
101
114
  }) : "");
102
- return (s, t) => (r(), n("div", {
103
- class: m(["j-preview-wrapper", l.class])
115
+ return (c, e) => (n(), u("div", {
116
+ class: d(["j-preview-wrapper", t.class])
104
117
  }, [
105
- a.value === "html" ? (r(), n("div", {
118
+ m.value === "html" ? (n(), u("div", {
106
119
  key: 0,
107
- class: m(["j-preview-html", e.theme === "dark" ? "dark" : ""]),
108
- innerHTML: h.value
109
- }, null, 10, v)) : (r(), d(u(p), {
120
+ class: d(["j-preview-html", i.value === "dark" ? "dark" : ""]),
121
+ innerHTML: p.value
122
+ }, null, 10, M)) : (n(), T(w(y), {
110
123
  key: 1,
111
- "model-value": e.modelValue,
112
- theme: e.theme,
124
+ "model-value": a.modelValue,
125
+ theme: i.value,
113
126
  "preview-class-name": "j-preview-markdown",
114
127
  language: "en-US"
115
128
  }, null, 8, ["model-value", "theme"]))
@@ -117,6 +130,6 @@ const v = ["innerHTML"], w = /* @__PURE__ */ c({
117
130
  }
118
131
  });
119
132
  export {
120
- w as default
133
+ O as default
121
134
  };
122
135
  //# sourceMappingURL=JPreview.vue2.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"JPreview.vue2.js","sources":["../../../../src/components/atoms/JPreview.vue"],"sourcesContent":["<script setup lang=\"ts\">\r\nimport { computed } from 'vue'\r\nimport { MdPreview } from 'md-editor-v3'\r\nimport 'md-editor-v3/lib/style.css'\r\nimport DOMPurify from 'dompurify'\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n /** 마크다운 또는 HTML 내용 */\r\n modelValue?: string\r\n /** 테마 (light/dark) */\r\n theme?: 'light' | 'dark'\r\n /** 추가 CSS 클래스 */\r\n class?: string\r\n }>(),\r\n {\r\n modelValue: '',\r\n theme: 'light',\r\n },\r\n)\r\n\r\n/**\r\n * 콘텐츠 타입 자동 감지\r\n */\r\nfunction detectContentType(content: string): 'markdown' | 'html' {\r\n const trimmed = content.trim()\r\n \r\n // HTML 문서 시작 태그 확인\r\n if (\r\n trimmed.startsWith('<!DOCTYPE html') ||\r\n trimmed.startsWith('<!doctype html') ||\r\n trimmed.startsWith('<!DOCTYPE HTML') ||\r\n trimmed.startsWith('<!DOCTYPE Html') ||\r\n trimmed.startsWith('<html') ||\r\n trimmed.startsWith('<HTML') ||\r\n trimmed.startsWith('<Html')\r\n ) {\r\n return 'html'\r\n }\r\n \r\n return 'markdown'\r\n}\r\n\r\nconst contentType = computed(() => detectContentType(props.modelValue || ''))\r\n\r\nconst sanitizedHtml = computed(() => {\r\n if (contentType.value === 'html') {\r\n return DOMPurify.sanitize(props.modelValue || '', {\r\n ALLOWED_TAGS: [\r\n 'p', 'br', 'strong', 'em', 'u', 's', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6',\r\n 'ul', 'ol', 'li', 'blockquote', 'pre', 'code', 'a', 'img', 'table', 'thead',\r\n 'tbody', 'tr', 'th', 'td', 'div', 'span', 'hr', 'blockquote', 'del', 'ins',\r\n 'sub', 'sup', 'kbd', 'mark', 'abbr', 'dfn', 'cite', 'q', 'samp', 'var',\r\n 'time', 'b', 'i', 'small', 'big', 'center', 'font', 'strike', 'tt',\r\n 'html', 'head', 'body', 'title', 'meta', 'link', 'style', 'script', 'noscript'\r\n ],\r\n ALLOWED_ATTR: [\r\n 'href', 'src', 'alt', 'title', 'width', 'height', 'class', 'id', 'style',\r\n 'target', 'rel', 'type', 'charset', 'name', 'content', 'http-equiv', 'lang'\r\n ],\r\n ALLOW_DATA_ATTR: false,\r\n })\r\n }\r\n return ''\r\n})\r\n</script>\r\n\r\n<template>\r\n <div :class=\"['j-preview-wrapper', props.class]\">\r\n <!-- HTML 렌더링 -->\r\n <div\r\n v-if=\"contentType === 'html'\"\r\n :class=\"['j-preview-html', theme === 'dark' ? 'dark' : '']\"\r\n v-html=\"sanitizedHtml\"\r\n />\r\n \r\n <!-- 마크다운 렌더링 -->\r\n <MdPreview\r\n v-else\r\n :model-value=\"modelValue\"\r\n :theme=\"theme\"\r\n :preview-class-name=\"'j-preview-markdown'\"\r\n language=\"en-US\"\r\n />\r\n </div>\r\n</template>\r\n\r\n<style scoped>\r\n.j-preview-wrapper {\r\n @apply w-full;\r\n}\r\n\r\n.j-preview-html {\r\n @apply prose prose-slate max-w-none;\r\n}\r\n\r\n.j-preview-html.dark {\r\n @apply prose-invert;\r\n}\r\n\r\n:deep(.j-preview-markdown) {\r\n @apply w-full;\r\n}\r\n</style>\r\n"],"names":["props","__props","detectContentType","content","trimmed","contentType","computed","sanitizedHtml","DOMPurify","_createElementBlock","_normalizeClass","_createBlock","_unref","MdPreview"],"mappings":";;;;;;;;;;;;AAMA,UAAMA,IAAQC;AAkBd,aAASC,EAAkBC,GAAsC;AAC/D,YAAMC,IAAUD,EAAQ,KAAA;AAGxB,aACEC,EAAQ,WAAW,gBAAgB,KACnCA,EAAQ,WAAW,gBAAgB,KACnCA,EAAQ,WAAW,gBAAgB,KACnCA,EAAQ,WAAW,gBAAgB,KACnCA,EAAQ,WAAW,OAAO,KAC1BA,EAAQ,WAAW,OAAO,KAC1BA,EAAQ,WAAW,OAAO,IAEnB,SAGF;AAAA,IACT;AAEA,UAAMC,IAAcC,EAAS,MAAMJ,EAAkBF,EAAM,cAAc,EAAE,CAAC,GAEtEO,IAAgBD,EAAS,MACzBD,EAAY,UAAU,SACjBG,EAAU,SAASR,EAAM,cAAc,IAAI;AAAA,MAChD,cAAc;AAAA,QACZ;AAAA,QAAK;AAAA,QAAM;AAAA,QAAU;AAAA,QAAM;AAAA,QAAK;AAAA,QAAK;AAAA,QAAM;AAAA,QAAM;AAAA,QAAM;AAAA,QAAM;AAAA,QAAM;AAAA,QACnE;AAAA,QAAM;AAAA,QAAM;AAAA,QAAM;AAAA,QAAc;AAAA,QAAO;AAAA,QAAQ;AAAA,QAAK;AAAA,QAAO;AAAA,QAAS;AAAA,QACpE;AAAA,QAAS;AAAA,QAAM;AAAA,QAAM;AAAA,QAAM;AAAA,QAAO;AAAA,QAAQ;AAAA,QAAM;AAAA,QAAc;AAAA,QAAO;AAAA,QACrE;AAAA,QAAO;AAAA,QAAO;AAAA,QAAO;AAAA,QAAQ;AAAA,QAAQ;AAAA,QAAO;AAAA,QAAQ;AAAA,QAAK;AAAA,QAAQ;AAAA,QACjE;AAAA,QAAQ;AAAA,QAAK;AAAA,QAAK;AAAA,QAAS;AAAA,QAAO;AAAA,QAAU;AAAA,QAAQ;AAAA,QAAU;AAAA,QAC9D;AAAA,QAAQ;AAAA,QAAQ;AAAA,QAAQ;AAAA,QAAS;AAAA,QAAQ;AAAA,QAAQ;AAAA,QAAS;AAAA,QAAU;AAAA,MAAA;AAAA,MAEtE,cAAc;AAAA,QACZ;AAAA,QAAQ;AAAA,QAAO;AAAA,QAAO;AAAA,QAAS;AAAA,QAAS;AAAA,QAAU;AAAA,QAAS;AAAA,QAAM;AAAA,QACjE;AAAA,QAAU;AAAA,QAAO;AAAA,QAAQ;AAAA,QAAW;AAAA,QAAQ;AAAA,QAAW;AAAA,QAAc;AAAA,MAAA;AAAA,MAEvE,iBAAiB;AAAA,IAAA,CAClB,IAEI,EACR;2BAICS,EAgBM,OAAA;AAAA,MAhBA,OAAKC,EAAA,CAAA,qBAAwBV,EAAM,KAAK,CAAA;AAAA,IAAA;MAGpCK,EAAA,UAAW,eADnBI,EAIE,OAAA;AAAA;QAFC,4BAA0BR,EAAA,UAAK,SAAA,SAAA,EAAA,CAAA;AAAA,QAChC,WAAQM,EAAA;AAAA,MAAA,yBAIVI,EAMEC,EAAAC,CAAA,GAAA;AAAA;QAJC,eAAaZ,EAAA;AAAA,QACb,OAAOA,EAAA;AAAA,QACP,sBAAoB;AAAA,QACrB,UAAS;AAAA,MAAA;;;;"}
1
+ {"version":3,"file":"JPreview.vue2.js","sources":["../../../../src/components/atoms/JPreview.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ref, computed, onMounted, onUnmounted } from 'vue'\nimport { MdPreview } from 'md-editor-v3'\nimport 'md-editor-v3/lib/style.css'\nimport DOMPurify from 'dompurify'\n\nconst props = withDefaults(\n defineProps<{\n /** 마크다운 또는 HTML 내용 */\n modelValue?: string\n /** 테마 (light/dark) - 설정하지 않으면 자동으로 다크모드 감지 */\n theme?: 'light' | 'dark'\n /** 추가 CSS 클래스 */\n class?: string\n }>(),\n {\n modelValue: '',\n },\n)\n\n// 다크모드 상태\nconst isDarkMode = ref(false)\n\n// 다크모드 감지 함수\nconst detectDarkMode = () => {\n isDarkMode.value = document.documentElement.classList.contains('dark')\n}\n\n// 현재 테마 계산 (props.theme이 있으면 그것 사용, 없으면 자동 감지)\nconst currentTheme = computed(() => {\n if (props.theme) {\n return props.theme\n }\n return isDarkMode.value ? 'dark' : 'light'\n})\n\n// MutationObserver로 다크모드 변경 감지\nlet darkModeObserver: MutationObserver | null = null\n\nonMounted(() => {\n // 초기 다크모드 상태 감지\n detectDarkMode()\n \n // MutationObserver로 class 변경 감지\n darkModeObserver = new MutationObserver(() => {\n detectDarkMode()\n })\n \n darkModeObserver.observe(document.documentElement, {\n attributes: true,\n attributeFilter: ['class'],\n })\n})\n\nonUnmounted(() => {\n if (darkModeObserver) {\n darkModeObserver.disconnect()\n }\n})\n\r\n/**\r\n * 콘텐츠 타입 자동 감지\r\n */\r\nfunction detectContentType(content: string): 'markdown' | 'html' {\r\n const trimmed = content.trim()\r\n \r\n // HTML 문서 시작 태그 확인\r\n if (\r\n trimmed.startsWith('<!DOCTYPE html') ||\r\n trimmed.startsWith('<!doctype html') ||\r\n trimmed.startsWith('<!DOCTYPE HTML') ||\r\n trimmed.startsWith('<!DOCTYPE Html') ||\r\n trimmed.startsWith('<html') ||\r\n trimmed.startsWith('<HTML') ||\r\n trimmed.startsWith('<Html')\r\n ) {\r\n return 'html'\r\n }\r\n \r\n return 'markdown'\r\n}\r\n\r\nconst contentType = computed(() => detectContentType(props.modelValue || ''))\r\n\r\nconst sanitizedHtml = computed(() => {\r\n if (contentType.value === 'html') {\r\n return DOMPurify.sanitize(props.modelValue || '', {\r\n ALLOWED_TAGS: [\r\n 'p', 'br', 'strong', 'em', 'u', 's', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6',\r\n 'ul', 'ol', 'li', 'blockquote', 'pre', 'code', 'a', 'img', 'table', 'thead',\r\n 'tbody', 'tr', 'th', 'td', 'div', 'span', 'hr', 'blockquote', 'del', 'ins',\r\n 'sub', 'sup', 'kbd', 'mark', 'abbr', 'dfn', 'cite', 'q', 'samp', 'var',\r\n 'time', 'b', 'i', 'small', 'big', 'center', 'font', 'strike', 'tt',\r\n 'html', 'head', 'body', 'title', 'meta', 'link', 'style', 'script', 'noscript'\r\n ],\r\n ALLOWED_ATTR: [\r\n 'href', 'src', 'alt', 'title', 'width', 'height', 'class', 'id', 'style',\r\n 'target', 'rel', 'type', 'charset', 'name', 'content', 'http-equiv', 'lang'\r\n ],\r\n ALLOW_DATA_ATTR: false,\r\n })\r\n }\r\n return ''\r\n})\r\n</script>\r\n\r\n<template>\n <div :class=\"['j-preview-wrapper', props.class]\">\n <!-- HTML 렌더링 -->\n <div\n v-if=\"contentType === 'html'\"\n :class=\"['j-preview-html', currentTheme === 'dark' ? 'dark' : '']\"\n v-html=\"sanitizedHtml\"\n />\n \n <!-- 마크다운 렌더링 -->\n <MdPreview\n v-else\n :model-value=\"modelValue\"\n :theme=\"currentTheme\"\n :preview-class-name=\"'j-preview-markdown'\"\n language=\"en-US\"\n />\n </div>\n</template>\n\r\n<style scoped>\r\n.j-preview-wrapper {\r\n @apply w-full;\r\n}\r\n\r\n.j-preview-html {\r\n @apply prose prose-slate max-w-none;\r\n}\r\n\r\n.j-preview-html.dark {\r\n @apply prose-invert;\r\n}\r\n\r\n:deep(.j-preview-markdown) {\r\n @apply w-full;\r\n}\r\n</style>\r\n"],"names":["props","__props","isDarkMode","ref","detectDarkMode","currentTheme","computed","darkModeObserver","onMounted","onUnmounted","detectContentType","content","trimmed","contentType","sanitizedHtml","DOMPurify","_createElementBlock","_normalizeClass","_createBlock","_unref","MdPreview"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("vue"),y=require("../shadcn/Progress.vue.cjs"),f={class:"space-y-2"},k={key:0,class:"flex justify-between items-center"},_={key:0,class:"text-sm font-medium text-gray-700"},v={key:1,class:"text-sm font-medium text-gray-600"},h={key:1,class:"text-center mb-2"},g={class:"text-sm font-medium text-gray-700"},B={key:2},b={key:3,class:"flex justify-center"},E={key:0},x={class:"w-full h-full animate-spin",viewBox:"0 0 100 100"},S=["stroke"],w={key:1},V={class:"w-full h-full transform -rotate-90",viewBox:"0 0 100 100"},z=["stroke","stroke-dashoffset"],N={key:2,class:"absolute inset-0 flex items-center justify-center"},C={class:"text-sm font-medium text-gray-700"},P={key:4,class:"text-center mt-2"},D={class:"text-xs text-gray-500"},L={key:5,class:"text-xs text-gray-500"},T=e.defineComponent({__name:"JProgress",props:{value:{default:0},max:{default:100},class:{},styletype:{default:"default"},size:{default:"md"},label:{default:""},showLabel:{type:Boolean,default:!0},description:{default:""},variant:{default:"linear"},indeterminate:{type:Boolean,default:!1}},setup(i){const t=i,d={default:{class:""},primary:{class:"[&>div]:bg-blue-500"},success:{class:"[&>div]:bg-green-500"},warning:{class:"[&>div]:bg-amber-500"},danger:{class:"[&>div]:bg-red-500"}},a={sm:{class:"h-2"},md:{class:"h-4"},lg:{class:"h-6"}},u={sm:{size:60},md:{size:80},lg:{size:100}},n=e.computed(()=>Math.round(t.value/t.max*100)),m=e.computed(()=>{const s=d[t.styletype],l=a[t.size],p=[s.class,l.class,t.class].filter(Boolean).join(" ");return{modelValue:t.value,max:t.max,class:p}}),o=e.computed(()=>{const s=u[t.size];let l="#000000";return t.styletype==="primary"?l="#3b82f6":t.styletype==="success"?l="#10b981":t.styletype==="warning"?l="#f59e0b":t.styletype==="danger"&&(l="#ef4444"),{size:s.size,color:l}}),r=e.computed(()=>t.indeterminate?"로딩 중...":`${n.value}%`),c=e.computed(()=>{let s="#000000";return t.styletype==="primary"?s="#3b82f6":t.styletype==="success"?s="#10b981":t.styletype==="warning"?s="#f59e0b":t.styletype==="danger"&&(s="#ef4444"),s});return(s,l)=>(e.openBlock(),e.createElementBlock("div",f,[t.variant==="linear"&&(t.label||t.showLabel||t.indeterminate)?(e.openBlock(),e.createElementBlock("div",k,[t.label?(e.openBlock(),e.createElementBlock("p",_,e.toDisplayString(t.label),1)):e.createCommentVNode("",!0),t.showLabel||t.indeterminate?(e.openBlock(),e.createElementBlock("p",v,e.toDisplayString(r.value),1)):e.createCommentVNode("",!0)])):e.createCommentVNode("",!0),t.variant==="circular"&&t.label?(e.openBlock(),e.createElementBlock("div",h,[e.createElementVNode("p",g,e.toDisplayString(t.label),1)])):e.createCommentVNode("",!0),t.variant==="linear"?(e.openBlock(),e.createElementBlock("div",B,[t.indeterminate?(e.openBlock(),e.createElementBlock("div",{key:0,class:e.normalizeClass(["relative overflow-hidden rounded-full bg-gray-200",a[t.size].class])},[e.createElementVNode("div",{class:"absolute h-full w-full animate-pulse",style:e.normalizeStyle({backgroundColor:c.value})},null,4),e.createElementVNode("div",{class:"absolute h-full w-1/3 animate-[indeterminate-linear_2s_infinite]",style:e.normalizeStyle({backgroundColor:c.value})},null,4)],2)):(e.openBlock(),e.createBlock(y.default,e.normalizeProps(e.mergeProps({key:1},m.value)),null,16))])):t.variant==="circular"?(e.openBlock(),e.createElementBlock("div",b,[e.createElementVNode("div",{class:"relative",style:e.normalizeStyle({width:o.value.size+"px",height:o.value.size+"px"})},[t.indeterminate?(e.openBlock(),e.createElementBlock("div",E,[(e.openBlock(),e.createElementBlock("svg",x,[l[0]||(l[0]=e.createElementVNode("circle",{cx:"50",cy:"50",r:"45",stroke:"#e5e7eb","stroke-width":"8",fill:"none"},null,-1)),e.createElementVNode("circle",{cx:"50",cy:"50",r:"45",stroke:o.value.color,"stroke-width":"8",fill:"none","stroke-linecap":"round","stroke-dasharray":"70 213","stroke-dashoffset":"0",class:"animate-[indeterminate-circular_2s_ease-in-out_infinite]"},null,8,S)]))])):(e.openBlock(),e.createElementBlock("div",w,[(e.openBlock(),e.createElementBlock("svg",V,[l[1]||(l[1]=e.createElementVNode("circle",{cx:"50",cy:"50",r:"45",stroke:"#e5e7eb","stroke-width":"8",fill:"none"},null,-1)),e.createElementVNode("circle",{cx:"50",cy:"50",r:"45",stroke:o.value.color,"stroke-width":"8",fill:"none","stroke-linecap":"round","stroke-dasharray":283,"stroke-dashoffset":283-283*n.value/100,class:"transition-all duration-300 ease-in-out"},null,8,z)]))])),t.showLabel||t.indeterminate?(e.openBlock(),e.createElementBlock("div",N,[e.createElementVNode("span",C,e.toDisplayString(r.value),1)])):e.createCommentVNode("",!0)],4)])):e.createCommentVNode("",!0),t.variant==="circular"&&t.description?(e.openBlock(),e.createElementBlock("div",P,[e.createElementVNode("p",D,e.toDisplayString(t.description),1)])):e.createCommentVNode("",!0),t.variant==="linear"&&t.description?(e.openBlock(),e.createElementBlock("p",L,e.toDisplayString(t.description),1)):e.createCommentVNode("",!0)]))}});exports.default=T;
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("vue"),y=require("../shadcn/Progress.vue.cjs"),f={class:"space-y-2"},k={key:0,class:"flex justify-between items-center"},_={key:0,class:"text-sm font-medium text-gray-700"},v={key:1,class:"text-sm font-medium text-gray-600"},h={key:1,class:"text-center mb-2"},g={class:"text-sm font-medium text-gray-700"},B={key:2},x={key:3,class:"flex justify-center"},b={key:0},E={class:"w-full h-full animate-spin",viewBox:"0 0 100 100"},S=["stroke"],w={key:1},z={class:"w-full h-full transform -rotate-90",viewBox:"0 0 100 100"},V=["stroke","stroke-dashoffset"],N={key:2,class:"absolute inset-0 flex items-center justify-center"},C={class:"text-sm font-medium text-gray-700"},P={key:4,class:"text-center mt-2"},D={class:"text-xs text-gray-500"},L={key:5,class:"text-xs text-gray-500"},T=e.defineComponent({__name:"JProgress",props:{value:{default:0},max:{default:100},class:{},styletype:{default:"default"},size:{default:"sm"},label:{default:""},showLabel:{type:Boolean,default:!0},description:{default:""},variant:{default:"linear"},indeterminate:{type:Boolean,default:!1}},setup(i){const t=i,d={default:{class:""},primary:{class:"[&>div]:bg-blue-500"},success:{class:"[&>div]:bg-green-500"},warning:{class:"[&>div]:bg-amber-500"},danger:{class:"[&>div]:bg-red-500"}},a={xs:{class:"h-1"},sm:{class:"h-2"},md:{class:"h-3"},lg:{class:"h-4"}},u={xs:{size:48},sm:{size:60},md:{size:72},lg:{size:88}},n=e.computed(()=>Math.round(t.value/t.max*100)),m=e.computed(()=>{const s=d[t.styletype],l=a[t.size],p=[s.class,l.class,t.class].filter(Boolean).join(" ");return{modelValue:t.value,max:t.max,class:p}}),o=e.computed(()=>{const s=u[t.size];let l="#000000";return t.styletype==="primary"?l="#3b82f6":t.styletype==="success"?l="#10b981":t.styletype==="warning"?l="#f59e0b":t.styletype==="danger"&&(l="#ef4444"),{size:s.size,color:l}}),r=e.computed(()=>t.indeterminate?"로딩 중...":`${n.value}%`),c=e.computed(()=>{let s="#000000";return t.styletype==="primary"?s="#3b82f6":t.styletype==="success"?s="#10b981":t.styletype==="warning"?s="#f59e0b":t.styletype==="danger"&&(s="#ef4444"),s});return(s,l)=>(e.openBlock(),e.createElementBlock("div",f,[t.variant==="linear"&&(t.label||t.showLabel||t.indeterminate)?(e.openBlock(),e.createElementBlock("div",k,[t.label?(e.openBlock(),e.createElementBlock("p",_,e.toDisplayString(t.label),1)):e.createCommentVNode("",!0),t.showLabel||t.indeterminate?(e.openBlock(),e.createElementBlock("p",v,e.toDisplayString(r.value),1)):e.createCommentVNode("",!0)])):e.createCommentVNode("",!0),t.variant==="circular"&&t.label?(e.openBlock(),e.createElementBlock("div",h,[e.createElementVNode("p",g,e.toDisplayString(t.label),1)])):e.createCommentVNode("",!0),t.variant==="linear"?(e.openBlock(),e.createElementBlock("div",B,[t.indeterminate?(e.openBlock(),e.createElementBlock("div",{key:0,class:e.normalizeClass(["relative overflow-hidden rounded-full bg-gray-200",a[t.size].class])},[e.createElementVNode("div",{class:"absolute h-full w-full animate-pulse",style:e.normalizeStyle({backgroundColor:c.value})},null,4),e.createElementVNode("div",{class:"absolute h-full w-1/3 animate-[indeterminate-linear_2s_infinite]",style:e.normalizeStyle({backgroundColor:c.value})},null,4)],2)):(e.openBlock(),e.createBlock(y.default,e.normalizeProps(e.mergeProps({key:1},m.value)),null,16))])):t.variant==="circular"?(e.openBlock(),e.createElementBlock("div",x,[e.createElementVNode("div",{class:"relative",style:e.normalizeStyle({width:o.value.size+"px",height:o.value.size+"px"})},[t.indeterminate?(e.openBlock(),e.createElementBlock("div",b,[(e.openBlock(),e.createElementBlock("svg",E,[l[0]||(l[0]=e.createElementVNode("circle",{cx:"50",cy:"50",r:"45",stroke:"#e5e7eb","stroke-width":"8",fill:"none"},null,-1)),e.createElementVNode("circle",{cx:"50",cy:"50",r:"45",stroke:o.value.color,"stroke-width":"8",fill:"none","stroke-linecap":"round","stroke-dasharray":"70 213","stroke-dashoffset":"0",class:"animate-[indeterminate-circular_2s_ease-in-out_infinite]"},null,8,S)]))])):(e.openBlock(),e.createElementBlock("div",w,[(e.openBlock(),e.createElementBlock("svg",z,[l[1]||(l[1]=e.createElementVNode("circle",{cx:"50",cy:"50",r:"45",stroke:"#e5e7eb","stroke-width":"8",fill:"none"},null,-1)),e.createElementVNode("circle",{cx:"50",cy:"50",r:"45",stroke:o.value.color,"stroke-width":"8",fill:"none","stroke-linecap":"round","stroke-dasharray":283,"stroke-dashoffset":283-283*n.value/100,class:"transition-all duration-300 ease-in-out"},null,8,V)]))])),t.showLabel||t.indeterminate?(e.openBlock(),e.createElementBlock("div",N,[e.createElementVNode("span",C,e.toDisplayString(r.value),1)])):e.createCommentVNode("",!0)],4)])):e.createCommentVNode("",!0),t.variant==="circular"&&t.description?(e.openBlock(),e.createElementBlock("div",P,[e.createElementVNode("p",D,e.toDisplayString(t.description),1)])):e.createCommentVNode("",!0),t.variant==="linear"&&t.description?(e.openBlock(),e.createElementBlock("p",L,e.toDisplayString(t.description),1)):e.createCommentVNode("",!0)]))}});exports.default=T;
2
2
  //# sourceMappingURL=JProgress.vue.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"JProgress.vue.cjs","sources":["../../../../src/components/atoms/JProgress.vue"],"sourcesContent":["<script setup lang=\"ts\">\r\nimport { computed } from 'vue'\r\nimport Progress from '@/components/shadcn/Progress.vue'\r\n\r\ntype StyleType =\r\n | 'default' // 기본 스타일\r\n | 'primary' // 강조 스타일 (파랑)\r\n | 'success' // 성공 스타일 (초록)\r\n | 'warning' // 경고 스타일 (주황)\r\n | 'danger' // 위험 스타일 (빨강)\r\n\r\ntype SizeType = 'sm' | 'md' | 'lg'\r\n\r\ntype VariantType = 'linear' | 'circular'\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n value?: number\r\n max?: number\r\n class?: string\r\n /** 스타일 프리셋 */\r\n styletype?: StyleType\r\n /** 크기 프리셋 */\r\n size?: SizeType\r\n /** 라벨 텍스트 */\r\n label?: string\r\n /** 진행률 퍼센트 표시 여부 */\r\n showLabel?: boolean\r\n /** 설명 텍스트 */\r\n description?: string\r\n /** 프로그레스 바 모양 */\r\n variant?: VariantType\r\n /** 무한 로딩 애니메이션 여부 */\r\n indeterminate?: boolean\r\n }>(),\r\n {\r\n value: 0,\r\n max: 100,\r\n styletype: 'default',\r\n size: 'md',\r\n label: '',\r\n showLabel: true,\r\n description: '',\r\n variant: 'linear',\r\n indeterminate: false,\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: '[&>div]:bg-blue-500',\r\n },\r\n success: { \r\n class: '[&>div]:bg-green-500',\r\n },\r\n warning: { \r\n class: '[&>div]:bg-amber-500',\r\n },\r\n danger: { \r\n class: '[&>div]:bg-red-500',\r\n },\r\n}\r\n\r\n/**\r\n * size -> class 매핑\r\n */\r\nconst SIZE_PRESETS: Record<SizeType, { class: string }> = {\r\n sm: { \r\n class: 'h-2',\r\n },\r\n md: { \r\n class: 'h-4',\r\n },\r\n lg: { \r\n class: 'h-6',\r\n },\r\n}\r\n\r\n/**\r\n * variant -> size 매핑 (circular용)\r\n */\r\nconst CIRCULAR_SIZE_PRESETS: Record<SizeType, { size: number }> = {\r\n sm: { \r\n size: 60,\r\n },\r\n md: { \r\n size: 80,\r\n },\r\n lg: { \r\n size: 100,\r\n },\r\n}\r\n\r\n/** 진행률 퍼센트 계산 */\r\nconst percentage = computed(() => {\r\n return Math.round((props.value! / props.max!) * 100)\r\n})\r\n\r\n/** 최종 바인딩: 직접 넘긴 class가 있으면 styletype과 size 기본값과 병합 */\r\nconst mapped = computed(() => {\r\n const stylePreset = STYLE_PRESETS[props.styletype!]\r\n const sizePreset = SIZE_PRESETS[props.size!]\r\n const finalClass = [stylePreset.class, sizePreset.class, props.class].filter(Boolean).join(' ')\r\n \r\n return {\r\n modelValue: props.value,\r\n max: props.max,\r\n class: finalClass,\r\n }\r\n})\r\n\r\n/** 원형 프로그레스 바 스타일 계산 */\r\nconst circularStyle = computed(() => {\r\n const sizePreset = CIRCULAR_SIZE_PRESETS[props.size!]\r\n \r\n // 색상 추출 - linear와 동일한 색상 사용\r\n let color = '#000000' // default: 검은색 (linear의 기본 색상과 동일)\r\n if (props.styletype === 'primary') color = '#3b82f6' // blue-500\r\n else if (props.styletype === 'success') color = '#10b981' // green-500\r\n else if (props.styletype === 'warning') color = '#f59e0b' // amber-500\r\n else if (props.styletype === 'danger') color = '#ef4444' // red-500\r\n \r\n return {\r\n size: sizePreset.size,\r\n color,\r\n }\r\n})\r\n\r\n/** indeterminate 상태에서 표시할 텍스트 */\r\nconst indeterminateText = computed(() => {\r\n return props.indeterminate ? '로딩 중...' : `${percentage.value}%`\r\n})\r\n\r\n/** Linear indeterminate 색상 계산 */\r\nconst linearIndeterminateColor = computed(() => {\r\n let color = '#000000' // default: 검은색\r\n if (props.styletype === 'primary') color = '#3b82f6' // blue-500\r\n else if (props.styletype === 'success') color = '#10b981' // green-500\r\n else if (props.styletype === 'warning') color = '#f59e0b' // amber-500\r\n else if (props.styletype === 'danger') color = '#ef4444' // red-500\r\n \r\n return color\r\n})\r\n</script>\r\n\r\n<template>\r\n <div class=\"space-y-2\">\r\n <!-- Linear Progress용 상단 라벨 -->\r\n <div v-if=\"props.variant === 'linear' && (props.label || props.showLabel || props.indeterminate)\" class=\"flex justify-between items-center\">\r\n <p v-if=\"props.label\" class=\"text-sm font-medium text-gray-700\">\r\n {{ props.label }}\r\n </p>\r\n <p v-if=\"props.showLabel || props.indeterminate\" class=\"text-sm font-medium text-gray-600\">\r\n {{ indeterminateText }}\r\n </p>\r\n </div>\r\n \r\n <!-- Circular Progress용 상단 라벨 -->\r\n <div v-if=\"props.variant === 'circular' && props.label\" class=\"text-center mb-2\">\r\n <p class=\"text-sm font-medium text-gray-700\">{{ props.label }}</p>\r\n </div>\r\n \r\n <!-- Linear Progress -->\r\n <div v-if=\"props.variant === 'linear'\">\r\n <!-- Indeterminate Linear -->\r\n <div v-if=\"props.indeterminate\" class=\"relative overflow-hidden rounded-full bg-gray-200\" :class=\"SIZE_PRESETS[props.size!].class\">\r\n <div \r\n class=\"absolute h-full w-full animate-pulse\"\r\n :style=\"{ backgroundColor: linearIndeterminateColor }\"\r\n />\r\n <div \r\n class=\"absolute h-full w-1/3 animate-[indeterminate-linear_2s_infinite]\"\r\n :style=\"{ backgroundColor: linearIndeterminateColor }\"\r\n />\r\n </div>\r\n <!-- Determinate Linear -->\r\n <Progress v-else v-bind=\"mapped\" />\r\n </div>\r\n \r\n <!-- Circular Progress -->\r\n <div v-else-if=\"props.variant === 'circular'\" class=\"flex justify-center\">\r\n <div class=\"relative\" :style=\"{ width: circularStyle.size + 'px', height: circularStyle.size + 'px' }\">\r\n <!-- Indeterminate Circular -->\r\n <div v-if=\"props.indeterminate\">\r\n <svg class=\"w-full h-full animate-spin\" viewBox=\"0 0 100 100\">\r\n <circle\r\n cx=\"50\"\r\n cy=\"50\"\r\n r=\"45\"\r\n stroke=\"#e5e7eb\"\r\n stroke-width=\"8\"\r\n fill=\"none\"\r\n />\r\n <circle\r\n cx=\"50\"\r\n cy=\"50\"\r\n r=\"45\"\r\n :stroke=\"circularStyle.color\"\r\n stroke-width=\"8\"\r\n fill=\"none\"\r\n stroke-linecap=\"round\"\r\n stroke-dasharray=\"70 213\"\r\n stroke-dashoffset=\"0\"\r\n class=\"animate-[indeterminate-circular_2s_ease-in-out_infinite]\"\r\n />\r\n </svg>\r\n </div>\r\n <!-- Determinate Circular -->\r\n <div v-else>\r\n <svg class=\"w-full h-full transform -rotate-90\" viewBox=\"0 0 100 100\">\r\n <!-- Background circle -->\r\n <circle\r\n cx=\"50\"\r\n cy=\"50\"\r\n r=\"45\"\r\n stroke=\"#e5e7eb\"\r\n stroke-width=\"8\"\r\n fill=\"none\"\r\n />\r\n <!-- Progress circle -->\r\n <circle\r\n cx=\"50\"\r\n cy=\"50\"\r\n r=\"45\"\r\n :stroke=\"circularStyle.color\"\r\n stroke-width=\"8\"\r\n fill=\"none\"\r\n stroke-linecap=\"round\"\r\n :stroke-dasharray=\"283\"\r\n :stroke-dashoffset=\"283 - (283 * percentage / 100)\"\r\n class=\"transition-all duration-300 ease-in-out\"\r\n />\r\n </svg>\r\n </div>\r\n <!-- Center text -->\r\n <div v-if=\"props.showLabel || props.indeterminate\" class=\"absolute inset-0 flex items-center justify-center\">\r\n <span class=\"text-sm font-medium text-gray-700\">{{ indeterminateText }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n \r\n <!-- Circular Progress용 하단 description -->\r\n <div v-if=\"props.variant === 'circular' && props.description\" class=\"text-center mt-2\">\r\n <p class=\"text-xs text-gray-500\">{{ props.description }}</p>\r\n </div>\r\n \r\n <!-- Linear Progress용 하단 description -->\r\n <p v-if=\"props.variant === 'linear' && props.description\" class=\"text-xs text-gray-500\">\r\n {{ props.description }}\r\n </p>\r\n </div>\r\n</template>\r\n\r\n<style>\r\n@keyframes indeterminate-linear {\r\n 0% {\r\n transform: translateX(-100%);\r\n }\r\n 100% {\r\n transform: translateX(400%);\r\n }\r\n}\r\n\r\n@keyframes indeterminate-circular {\r\n 0% {\r\n stroke-dasharray: 70 213;\r\n stroke-dashoffset: 0;\r\n }\r\n 50% {\r\n stroke-dasharray: 140 143;\r\n stroke-dashoffset: -70;\r\n }\r\n 100% {\r\n stroke-dasharray: 70 213;\r\n stroke-dashoffset: -213;\r\n }\r\n}\r\n</style>\r\n"],"names":["props","__props","STYLE_PRESETS","SIZE_PRESETS","CIRCULAR_SIZE_PRESETS","percentage","computed","mapped","stylePreset","sizePreset","finalClass","circularStyle","color","indeterminateText","linearIndeterminateColor","_openBlock","_createElementBlock","_hoisted_1","_hoisted_2","_hoisted_3","_toDisplayString","_hoisted_4","_hoisted_5","_createElementVNode","_hoisted_6","_hoisted_7","_normalizeClass","_createBlock","Progress","_hoisted_8","_hoisted_9","_hoisted_10","_hoisted_12","_hoisted_13","_hoisted_15","_hoisted_16","_hoisted_17","_hoisted_18","_hoisted_19"],"mappings":"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"}
1
+ {"version":3,"file":"JProgress.vue.cjs","sources":["../../../../src/components/atoms/JProgress.vue"],"sourcesContent":["<script setup lang=\"ts\">\r\nimport { computed } from 'vue'\r\nimport Progress from '@/components/shadcn/Progress.vue'\r\n\r\ntype StyleType =\r\n | 'default' // 기본 스타일\r\n | 'primary' // 강조 스타일 (파랑)\r\n | 'success' // 성공 스타일 (초록)\r\n | 'warning' // 경고 스타일 (주황)\r\n | 'danger' // 위험 스타일 (빨강)\r\n\r\ntype SizeType = 'xs' | 'sm' | 'md' | 'lg'\n\r\ntype VariantType = 'linear' | 'circular'\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n value?: number\r\n max?: number\r\n class?: string\r\n /** 스타일 프리셋 */\r\n styletype?: StyleType\r\n /** 크기 프리셋 */\r\n size?: SizeType\r\n /** 라벨 텍스트 */\r\n label?: string\r\n /** 진행률 퍼센트 표시 여부 */\r\n showLabel?: boolean\r\n /** 설명 텍스트 */\r\n description?: string\r\n /** 프로그레스 바 모양 */\r\n variant?: VariantType\r\n /** 무한 로딩 애니메이션 여부 */\r\n indeterminate?: boolean\r\n }>(),\r\n {\n value: 0,\n max: 100,\n styletype: 'default',\n size: 'sm',\n label: '',\n showLabel: true,\n description: '',\n variant: 'linear',\n indeterminate: false,\n },\r\n)\r\n\r\n/**\r\n * styletype -> class 매핑\r\n */\r\nconst STYLE_PRESETS: Record<StyleType, { class: string }> = {\r\n default: { class: '' },\r\n primary: { \r\n class: '[&>div]:bg-blue-500',\r\n },\r\n success: { \r\n class: '[&>div]:bg-green-500',\r\n },\r\n warning: { \r\n class: '[&>div]:bg-amber-500',\r\n },\r\n danger: { \r\n class: '[&>div]:bg-red-500',\r\n },\r\n}\r\n\r\n/**\r\n * size -> class 매핑\r\n */\r\nconst SIZE_PRESETS: Record<SizeType, { class: string }> = {\n xs: { \n class: 'h-1',\n },\n sm: { \n class: 'h-2',\n },\n md: { \n class: 'h-3',\n },\n lg: { \n class: 'h-4',\n },\n}\n\r\n/**\r\n * variant -> size 매핑 (circular용)\r\n */\r\nconst CIRCULAR_SIZE_PRESETS: Record<SizeType, { size: number }> = {\n xs: { \n size: 48,\n },\n sm: { \n size: 60,\n },\n md: { \n size: 72,\n },\n lg: { \n size: 88,\n },\n}\r\n\r\n/** 진행률 퍼센트 계산 */\r\nconst percentage = computed(() => {\r\n return Math.round((props.value! / props.max!) * 100)\r\n})\r\n\r\n/** 최종 바인딩: 직접 넘긴 class가 있으면 styletype과 size 기본값과 병합 */\r\nconst mapped = computed(() => {\r\n const stylePreset = STYLE_PRESETS[props.styletype!]\r\n const sizePreset = SIZE_PRESETS[props.size!]\r\n const finalClass = [stylePreset.class, sizePreset.class, props.class].filter(Boolean).join(' ')\r\n \r\n return {\r\n modelValue: props.value,\r\n max: props.max,\r\n class: finalClass,\r\n }\r\n})\r\n\r\n/** 원형 프로그레스 바 스타일 계산 */\r\nconst circularStyle = computed(() => {\r\n const sizePreset = CIRCULAR_SIZE_PRESETS[props.size!]\r\n \r\n // 색상 추출 - linear와 동일한 색상 사용\r\n let color = '#000000' // default: 검은색 (linear의 기본 색상과 동일)\r\n if (props.styletype === 'primary') color = '#3b82f6' // blue-500\r\n else if (props.styletype === 'success') color = '#10b981' // green-500\r\n else if (props.styletype === 'warning') color = '#f59e0b' // amber-500\r\n else if (props.styletype === 'danger') color = '#ef4444' // red-500\r\n \r\n return {\r\n size: sizePreset.size,\r\n color,\r\n }\r\n})\r\n\r\n/** indeterminate 상태에서 표시할 텍스트 */\r\nconst indeterminateText = computed(() => {\r\n return props.indeterminate ? '로딩 중...' : `${percentage.value}%`\r\n})\r\n\r\n/** Linear indeterminate 색상 계산 */\r\nconst linearIndeterminateColor = computed(() => {\r\n let color = '#000000' // default: 검은색\r\n if (props.styletype === 'primary') color = '#3b82f6' // blue-500\r\n else if (props.styletype === 'success') color = '#10b981' // green-500\r\n else if (props.styletype === 'warning') color = '#f59e0b' // amber-500\r\n else if (props.styletype === 'danger') color = '#ef4444' // red-500\r\n \r\n return color\r\n})\r\n</script>\r\n\r\n<template>\r\n <div class=\"space-y-2\">\r\n <!-- Linear Progress용 상단 라벨 -->\r\n <div v-if=\"props.variant === 'linear' && (props.label || props.showLabel || props.indeterminate)\" class=\"flex justify-between items-center\">\r\n <p v-if=\"props.label\" class=\"text-sm font-medium text-gray-700\">\r\n {{ props.label }}\r\n </p>\r\n <p v-if=\"props.showLabel || props.indeterminate\" class=\"text-sm font-medium text-gray-600\">\r\n {{ indeterminateText }}\r\n </p>\r\n </div>\r\n \r\n <!-- Circular Progress용 상단 라벨 -->\r\n <div v-if=\"props.variant === 'circular' && props.label\" class=\"text-center mb-2\">\r\n <p class=\"text-sm font-medium text-gray-700\">{{ props.label }}</p>\r\n </div>\r\n \r\n <!-- Linear Progress -->\r\n <div v-if=\"props.variant === 'linear'\">\r\n <!-- Indeterminate Linear -->\r\n <div v-if=\"props.indeterminate\" class=\"relative overflow-hidden rounded-full bg-gray-200\" :class=\"SIZE_PRESETS[props.size!].class\">\r\n <div \r\n class=\"absolute h-full w-full animate-pulse\"\r\n :style=\"{ backgroundColor: linearIndeterminateColor }\"\r\n />\r\n <div \r\n class=\"absolute h-full w-1/3 animate-[indeterminate-linear_2s_infinite]\"\r\n :style=\"{ backgroundColor: linearIndeterminateColor }\"\r\n />\r\n </div>\r\n <!-- Determinate Linear -->\r\n <Progress v-else v-bind=\"mapped\" />\r\n </div>\r\n \r\n <!-- Circular Progress -->\r\n <div v-else-if=\"props.variant === 'circular'\" class=\"flex justify-center\">\r\n <div class=\"relative\" :style=\"{ width: circularStyle.size + 'px', height: circularStyle.size + 'px' }\">\r\n <!-- Indeterminate Circular -->\r\n <div v-if=\"props.indeterminate\">\r\n <svg class=\"w-full h-full animate-spin\" viewBox=\"0 0 100 100\">\r\n <circle\r\n cx=\"50\"\r\n cy=\"50\"\r\n r=\"45\"\r\n stroke=\"#e5e7eb\"\r\n stroke-width=\"8\"\r\n fill=\"none\"\r\n />\r\n <circle\r\n cx=\"50\"\r\n cy=\"50\"\r\n r=\"45\"\r\n :stroke=\"circularStyle.color\"\r\n stroke-width=\"8\"\r\n fill=\"none\"\r\n stroke-linecap=\"round\"\r\n stroke-dasharray=\"70 213\"\r\n stroke-dashoffset=\"0\"\r\n class=\"animate-[indeterminate-circular_2s_ease-in-out_infinite]\"\r\n />\r\n </svg>\r\n </div>\r\n <!-- Determinate Circular -->\r\n <div v-else>\r\n <svg class=\"w-full h-full transform -rotate-90\" viewBox=\"0 0 100 100\">\r\n <!-- Background circle -->\r\n <circle\r\n cx=\"50\"\r\n cy=\"50\"\r\n r=\"45\"\r\n stroke=\"#e5e7eb\"\r\n stroke-width=\"8\"\r\n fill=\"none\"\r\n />\r\n <!-- Progress circle -->\r\n <circle\r\n cx=\"50\"\r\n cy=\"50\"\r\n r=\"45\"\r\n :stroke=\"circularStyle.color\"\r\n stroke-width=\"8\"\r\n fill=\"none\"\r\n stroke-linecap=\"round\"\r\n :stroke-dasharray=\"283\"\r\n :stroke-dashoffset=\"283 - (283 * percentage / 100)\"\r\n class=\"transition-all duration-300 ease-in-out\"\r\n />\r\n </svg>\r\n </div>\r\n <!-- Center text -->\r\n <div v-if=\"props.showLabel || props.indeterminate\" class=\"absolute inset-0 flex items-center justify-center\">\r\n <span class=\"text-sm font-medium text-gray-700\">{{ indeterminateText }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n \r\n <!-- Circular Progress용 하단 description -->\r\n <div v-if=\"props.variant === 'circular' && props.description\" class=\"text-center mt-2\">\r\n <p class=\"text-xs text-gray-500\">{{ props.description }}</p>\r\n </div>\r\n \r\n <!-- Linear Progress용 하단 description -->\r\n <p v-if=\"props.variant === 'linear' && props.description\" class=\"text-xs text-gray-500\">\r\n {{ props.description }}\r\n </p>\r\n </div>\r\n</template>\r\n\r\n<style>\r\n@keyframes indeterminate-linear {\r\n 0% {\r\n transform: translateX(-100%);\r\n }\r\n 100% {\r\n transform: translateX(400%);\r\n }\r\n}\r\n\r\n@keyframes indeterminate-circular {\r\n 0% {\r\n stroke-dasharray: 70 213;\r\n stroke-dashoffset: 0;\r\n }\r\n 50% {\r\n stroke-dasharray: 140 143;\r\n stroke-dashoffset: -70;\r\n }\r\n 100% {\r\n stroke-dasharray: 70 213;\r\n stroke-dashoffset: -213;\r\n }\r\n}\r\n</style>\r\n"],"names":["props","__props","STYLE_PRESETS","SIZE_PRESETS","CIRCULAR_SIZE_PRESETS","percentage","computed","mapped","stylePreset","sizePreset","finalClass","circularStyle","color","indeterminateText","linearIndeterminateColor","_openBlock","_createElementBlock","_hoisted_1","_hoisted_2","_hoisted_3","_toDisplayString","_hoisted_4","_hoisted_5","_createElementVNode","_hoisted_6","_hoisted_7","_normalizeClass","_createBlock","Progress","_hoisted_8","_hoisted_9","_hoisted_10","_hoisted_12","_hoisted_13","_hoisted_15","_hoisted_16","_hoisted_17","_hoisted_18","_hoisted_19"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { defineComponent as x, computed as o, createElementBlock as s, openBlock as t, createCommentVNode as r, toDisplayString as n, createElementVNode as i, createBlock as b, normalizeClass as g, normalizeStyle as d, normalizeProps as w, mergeProps as z } from "vue";
1
+ import { defineComponent as k, computed as o, createElementBlock as s, openBlock as t, createCommentVNode as r, toDisplayString as n, createElementVNode as i, createBlock as b, normalizeClass as g, normalizeStyle as d, normalizeProps as w, mergeProps as z } from "vue";
2
2
  import S from "../shadcn/Progress.vue.js";
3
3
  const E = { class: "space-y-2" }, C = {
4
4
  key: 0,
@@ -30,14 +30,14 @@ const E = { class: "space-y-2" }, C = {
30
30
  }, U = { class: "text-xs text-gray-500" }, Y = {
31
31
  key: 5,
32
32
  class: "text-xs text-gray-500"
33
- }, G = /* @__PURE__ */ x({
33
+ }, G = /* @__PURE__ */ k({
34
34
  __name: "JProgress",
35
35
  props: {
36
36
  value: { default: 0 },
37
37
  max: { default: 100 },
38
38
  class: {},
39
39
  styletype: { default: "default" },
40
- size: { default: "md" },
40
+ size: { default: "sm" },
41
41
  label: { default: "" },
42
42
  showLabel: { type: Boolean, default: !0 },
43
43
  description: { default: "" },
@@ -60,31 +60,37 @@ const E = { class: "space-y-2" }, C = {
60
60
  class: "[&>div]:bg-red-500"
61
61
  }
62
62
  }, u = {
63
+ xs: {
64
+ class: "h-1"
65
+ },
63
66
  sm: {
64
67
  class: "h-2"
65
68
  },
66
69
  md: {
67
- class: "h-4"
70
+ class: "h-3"
68
71
  },
69
72
  lg: {
70
- class: "h-6"
73
+ class: "h-4"
71
74
  }
72
75
  }, v = {
76
+ xs: {
77
+ size: 48
78
+ },
73
79
  sm: {
74
80
  size: 60
75
81
  },
76
82
  md: {
77
- size: 80
83
+ size: 72
78
84
  },
79
85
  lg: {
80
- size: 100
86
+ size: 88
81
87
  }
82
88
  }, f = o(() => Math.round(e.value / e.max * 100)), h = o(() => {
83
- const a = p[e.styletype], l = u[e.size], k = [a.class, l.class, e.class].filter(Boolean).join(" ");
89
+ const a = p[e.styletype], l = u[e.size], x = [a.class, l.class, e.class].filter(Boolean).join(" ");
84
90
  return {
85
91
  modelValue: e.value,
86
92
  max: e.max,
87
- class: k
93
+ class: x
88
94
  };
89
95
  }), c = o(() => {
90
96
  const a = v[e.size];
@@ -1 +1 @@
1
- {"version":3,"file":"JProgress.vue.js","sources":["../../../../src/components/atoms/JProgress.vue"],"sourcesContent":["<script setup lang=\"ts\">\r\nimport { computed } from 'vue'\r\nimport Progress from '@/components/shadcn/Progress.vue'\r\n\r\ntype StyleType =\r\n | 'default' // 기본 스타일\r\n | 'primary' // 강조 스타일 (파랑)\r\n | 'success' // 성공 스타일 (초록)\r\n | 'warning' // 경고 스타일 (주황)\r\n | 'danger' // 위험 스타일 (빨강)\r\n\r\ntype SizeType = 'sm' | 'md' | 'lg'\r\n\r\ntype VariantType = 'linear' | 'circular'\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n value?: number\r\n max?: number\r\n class?: string\r\n /** 스타일 프리셋 */\r\n styletype?: StyleType\r\n /** 크기 프리셋 */\r\n size?: SizeType\r\n /** 라벨 텍스트 */\r\n label?: string\r\n /** 진행률 퍼센트 표시 여부 */\r\n showLabel?: boolean\r\n /** 설명 텍스트 */\r\n description?: string\r\n /** 프로그레스 바 모양 */\r\n variant?: VariantType\r\n /** 무한 로딩 애니메이션 여부 */\r\n indeterminate?: boolean\r\n }>(),\r\n {\r\n value: 0,\r\n max: 100,\r\n styletype: 'default',\r\n size: 'md',\r\n label: '',\r\n showLabel: true,\r\n description: '',\r\n variant: 'linear',\r\n indeterminate: false,\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: '[&>div]:bg-blue-500',\r\n },\r\n success: { \r\n class: '[&>div]:bg-green-500',\r\n },\r\n warning: { \r\n class: '[&>div]:bg-amber-500',\r\n },\r\n danger: { \r\n class: '[&>div]:bg-red-500',\r\n },\r\n}\r\n\r\n/**\r\n * size -> class 매핑\r\n */\r\nconst SIZE_PRESETS: Record<SizeType, { class: string }> = {\r\n sm: { \r\n class: 'h-2',\r\n },\r\n md: { \r\n class: 'h-4',\r\n },\r\n lg: { \r\n class: 'h-6',\r\n },\r\n}\r\n\r\n/**\r\n * variant -> size 매핑 (circular용)\r\n */\r\nconst CIRCULAR_SIZE_PRESETS: Record<SizeType, { size: number }> = {\r\n sm: { \r\n size: 60,\r\n },\r\n md: { \r\n size: 80,\r\n },\r\n lg: { \r\n size: 100,\r\n },\r\n}\r\n\r\n/** 진행률 퍼센트 계산 */\r\nconst percentage = computed(() => {\r\n return Math.round((props.value! / props.max!) * 100)\r\n})\r\n\r\n/** 최종 바인딩: 직접 넘긴 class가 있으면 styletype과 size 기본값과 병합 */\r\nconst mapped = computed(() => {\r\n const stylePreset = STYLE_PRESETS[props.styletype!]\r\n const sizePreset = SIZE_PRESETS[props.size!]\r\n const finalClass = [stylePreset.class, sizePreset.class, props.class].filter(Boolean).join(' ')\r\n \r\n return {\r\n modelValue: props.value,\r\n max: props.max,\r\n class: finalClass,\r\n }\r\n})\r\n\r\n/** 원형 프로그레스 바 스타일 계산 */\r\nconst circularStyle = computed(() => {\r\n const sizePreset = CIRCULAR_SIZE_PRESETS[props.size!]\r\n \r\n // 색상 추출 - linear와 동일한 색상 사용\r\n let color = '#000000' // default: 검은색 (linear의 기본 색상과 동일)\r\n if (props.styletype === 'primary') color = '#3b82f6' // blue-500\r\n else if (props.styletype === 'success') color = '#10b981' // green-500\r\n else if (props.styletype === 'warning') color = '#f59e0b' // amber-500\r\n else if (props.styletype === 'danger') color = '#ef4444' // red-500\r\n \r\n return {\r\n size: sizePreset.size,\r\n color,\r\n }\r\n})\r\n\r\n/** indeterminate 상태에서 표시할 텍스트 */\r\nconst indeterminateText = computed(() => {\r\n return props.indeterminate ? '로딩 중...' : `${percentage.value}%`\r\n})\r\n\r\n/** Linear indeterminate 색상 계산 */\r\nconst linearIndeterminateColor = computed(() => {\r\n let color = '#000000' // default: 검은색\r\n if (props.styletype === 'primary') color = '#3b82f6' // blue-500\r\n else if (props.styletype === 'success') color = '#10b981' // green-500\r\n else if (props.styletype === 'warning') color = '#f59e0b' // amber-500\r\n else if (props.styletype === 'danger') color = '#ef4444' // red-500\r\n \r\n return color\r\n})\r\n</script>\r\n\r\n<template>\r\n <div class=\"space-y-2\">\r\n <!-- Linear Progress용 상단 라벨 -->\r\n <div v-if=\"props.variant === 'linear' && (props.label || props.showLabel || props.indeterminate)\" class=\"flex justify-between items-center\">\r\n <p v-if=\"props.label\" class=\"text-sm font-medium text-gray-700\">\r\n {{ props.label }}\r\n </p>\r\n <p v-if=\"props.showLabel || props.indeterminate\" class=\"text-sm font-medium text-gray-600\">\r\n {{ indeterminateText }}\r\n </p>\r\n </div>\r\n \r\n <!-- Circular Progress용 상단 라벨 -->\r\n <div v-if=\"props.variant === 'circular' && props.label\" class=\"text-center mb-2\">\r\n <p class=\"text-sm font-medium text-gray-700\">{{ props.label }}</p>\r\n </div>\r\n \r\n <!-- Linear Progress -->\r\n <div v-if=\"props.variant === 'linear'\">\r\n <!-- Indeterminate Linear -->\r\n <div v-if=\"props.indeterminate\" class=\"relative overflow-hidden rounded-full bg-gray-200\" :class=\"SIZE_PRESETS[props.size!].class\">\r\n <div \r\n class=\"absolute h-full w-full animate-pulse\"\r\n :style=\"{ backgroundColor: linearIndeterminateColor }\"\r\n />\r\n <div \r\n class=\"absolute h-full w-1/3 animate-[indeterminate-linear_2s_infinite]\"\r\n :style=\"{ backgroundColor: linearIndeterminateColor }\"\r\n />\r\n </div>\r\n <!-- Determinate Linear -->\r\n <Progress v-else v-bind=\"mapped\" />\r\n </div>\r\n \r\n <!-- Circular Progress -->\r\n <div v-else-if=\"props.variant === 'circular'\" class=\"flex justify-center\">\r\n <div class=\"relative\" :style=\"{ width: circularStyle.size + 'px', height: circularStyle.size + 'px' }\">\r\n <!-- Indeterminate Circular -->\r\n <div v-if=\"props.indeterminate\">\r\n <svg class=\"w-full h-full animate-spin\" viewBox=\"0 0 100 100\">\r\n <circle\r\n cx=\"50\"\r\n cy=\"50\"\r\n r=\"45\"\r\n stroke=\"#e5e7eb\"\r\n stroke-width=\"8\"\r\n fill=\"none\"\r\n />\r\n <circle\r\n cx=\"50\"\r\n cy=\"50\"\r\n r=\"45\"\r\n :stroke=\"circularStyle.color\"\r\n stroke-width=\"8\"\r\n fill=\"none\"\r\n stroke-linecap=\"round\"\r\n stroke-dasharray=\"70 213\"\r\n stroke-dashoffset=\"0\"\r\n class=\"animate-[indeterminate-circular_2s_ease-in-out_infinite]\"\r\n />\r\n </svg>\r\n </div>\r\n <!-- Determinate Circular -->\r\n <div v-else>\r\n <svg class=\"w-full h-full transform -rotate-90\" viewBox=\"0 0 100 100\">\r\n <!-- Background circle -->\r\n <circle\r\n cx=\"50\"\r\n cy=\"50\"\r\n r=\"45\"\r\n stroke=\"#e5e7eb\"\r\n stroke-width=\"8\"\r\n fill=\"none\"\r\n />\r\n <!-- Progress circle -->\r\n <circle\r\n cx=\"50\"\r\n cy=\"50\"\r\n r=\"45\"\r\n :stroke=\"circularStyle.color\"\r\n stroke-width=\"8\"\r\n fill=\"none\"\r\n stroke-linecap=\"round\"\r\n :stroke-dasharray=\"283\"\r\n :stroke-dashoffset=\"283 - (283 * percentage / 100)\"\r\n class=\"transition-all duration-300 ease-in-out\"\r\n />\r\n </svg>\r\n </div>\r\n <!-- Center text -->\r\n <div v-if=\"props.showLabel || props.indeterminate\" class=\"absolute inset-0 flex items-center justify-center\">\r\n <span class=\"text-sm font-medium text-gray-700\">{{ indeterminateText }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n \r\n <!-- Circular Progress용 하단 description -->\r\n <div v-if=\"props.variant === 'circular' && props.description\" class=\"text-center mt-2\">\r\n <p class=\"text-xs text-gray-500\">{{ props.description }}</p>\r\n </div>\r\n \r\n <!-- Linear Progress용 하단 description -->\r\n <p v-if=\"props.variant === 'linear' && props.description\" class=\"text-xs text-gray-500\">\r\n {{ props.description }}\r\n </p>\r\n </div>\r\n</template>\r\n\r\n<style>\r\n@keyframes indeterminate-linear {\r\n 0% {\r\n transform: translateX(-100%);\r\n }\r\n 100% {\r\n transform: translateX(400%);\r\n }\r\n}\r\n\r\n@keyframes indeterminate-circular {\r\n 0% {\r\n stroke-dasharray: 70 213;\r\n stroke-dashoffset: 0;\r\n }\r\n 50% {\r\n stroke-dasharray: 140 143;\r\n stroke-dashoffset: -70;\r\n }\r\n 100% {\r\n stroke-dasharray: 70 213;\r\n stroke-dashoffset: -213;\r\n }\r\n}\r\n</style>\r\n"],"names":["props","__props","STYLE_PRESETS","SIZE_PRESETS","CIRCULAR_SIZE_PRESETS","percentage","computed","mapped","stylePreset","sizePreset","finalClass","circularStyle","color","indeterminateText","linearIndeterminateColor","_openBlock","_createElementBlock","_hoisted_1","_hoisted_2","_hoisted_3","_toDisplayString","_hoisted_4","_hoisted_5","_createElementVNode","_hoisted_6","_hoisted_7","_normalizeClass","_createBlock","Progress","_hoisted_8","_hoisted_9","_hoisted_10","_hoisted_12","_hoisted_13","_hoisted_15","_hoisted_16","_hoisted_17","_hoisted_18","_hoisted_19"],"mappings":"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"}
1
+ {"version":3,"file":"JProgress.vue.js","sources":["../../../../src/components/atoms/JProgress.vue"],"sourcesContent":["<script setup lang=\"ts\">\r\nimport { computed } from 'vue'\r\nimport Progress from '@/components/shadcn/Progress.vue'\r\n\r\ntype StyleType =\r\n | 'default' // 기본 스타일\r\n | 'primary' // 강조 스타일 (파랑)\r\n | 'success' // 성공 스타일 (초록)\r\n | 'warning' // 경고 스타일 (주황)\r\n | 'danger' // 위험 스타일 (빨강)\r\n\r\ntype SizeType = 'xs' | 'sm' | 'md' | 'lg'\n\r\ntype VariantType = 'linear' | 'circular'\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n value?: number\r\n max?: number\r\n class?: string\r\n /** 스타일 프리셋 */\r\n styletype?: StyleType\r\n /** 크기 프리셋 */\r\n size?: SizeType\r\n /** 라벨 텍스트 */\r\n label?: string\r\n /** 진행률 퍼센트 표시 여부 */\r\n showLabel?: boolean\r\n /** 설명 텍스트 */\r\n description?: string\r\n /** 프로그레스 바 모양 */\r\n variant?: VariantType\r\n /** 무한 로딩 애니메이션 여부 */\r\n indeterminate?: boolean\r\n }>(),\r\n {\n value: 0,\n max: 100,\n styletype: 'default',\n size: 'sm',\n label: '',\n showLabel: true,\n description: '',\n variant: 'linear',\n indeterminate: false,\n },\r\n)\r\n\r\n/**\r\n * styletype -> class 매핑\r\n */\r\nconst STYLE_PRESETS: Record<StyleType, { class: string }> = {\r\n default: { class: '' },\r\n primary: { \r\n class: '[&>div]:bg-blue-500',\r\n },\r\n success: { \r\n class: '[&>div]:bg-green-500',\r\n },\r\n warning: { \r\n class: '[&>div]:bg-amber-500',\r\n },\r\n danger: { \r\n class: '[&>div]:bg-red-500',\r\n },\r\n}\r\n\r\n/**\r\n * size -> class 매핑\r\n */\r\nconst SIZE_PRESETS: Record<SizeType, { class: string }> = {\n xs: { \n class: 'h-1',\n },\n sm: { \n class: 'h-2',\n },\n md: { \n class: 'h-3',\n },\n lg: { \n class: 'h-4',\n },\n}\n\r\n/**\r\n * variant -> size 매핑 (circular용)\r\n */\r\nconst CIRCULAR_SIZE_PRESETS: Record<SizeType, { size: number }> = {\n xs: { \n size: 48,\n },\n sm: { \n size: 60,\n },\n md: { \n size: 72,\n },\n lg: { \n size: 88,\n },\n}\r\n\r\n/** 진행률 퍼센트 계산 */\r\nconst percentage = computed(() => {\r\n return Math.round((props.value! / props.max!) * 100)\r\n})\r\n\r\n/** 최종 바인딩: 직접 넘긴 class가 있으면 styletype과 size 기본값과 병합 */\r\nconst mapped = computed(() => {\r\n const stylePreset = STYLE_PRESETS[props.styletype!]\r\n const sizePreset = SIZE_PRESETS[props.size!]\r\n const finalClass = [stylePreset.class, sizePreset.class, props.class].filter(Boolean).join(' ')\r\n \r\n return {\r\n modelValue: props.value,\r\n max: props.max,\r\n class: finalClass,\r\n }\r\n})\r\n\r\n/** 원형 프로그레스 바 스타일 계산 */\r\nconst circularStyle = computed(() => {\r\n const sizePreset = CIRCULAR_SIZE_PRESETS[props.size!]\r\n \r\n // 색상 추출 - linear와 동일한 색상 사용\r\n let color = '#000000' // default: 검은색 (linear의 기본 색상과 동일)\r\n if (props.styletype === 'primary') color = '#3b82f6' // blue-500\r\n else if (props.styletype === 'success') color = '#10b981' // green-500\r\n else if (props.styletype === 'warning') color = '#f59e0b' // amber-500\r\n else if (props.styletype === 'danger') color = '#ef4444' // red-500\r\n \r\n return {\r\n size: sizePreset.size,\r\n color,\r\n }\r\n})\r\n\r\n/** indeterminate 상태에서 표시할 텍스트 */\r\nconst indeterminateText = computed(() => {\r\n return props.indeterminate ? '로딩 중...' : `${percentage.value}%`\r\n})\r\n\r\n/** Linear indeterminate 색상 계산 */\r\nconst linearIndeterminateColor = computed(() => {\r\n let color = '#000000' // default: 검은색\r\n if (props.styletype === 'primary') color = '#3b82f6' // blue-500\r\n else if (props.styletype === 'success') color = '#10b981' // green-500\r\n else if (props.styletype === 'warning') color = '#f59e0b' // amber-500\r\n else if (props.styletype === 'danger') color = '#ef4444' // red-500\r\n \r\n return color\r\n})\r\n</script>\r\n\r\n<template>\r\n <div class=\"space-y-2\">\r\n <!-- Linear Progress용 상단 라벨 -->\r\n <div v-if=\"props.variant === 'linear' && (props.label || props.showLabel || props.indeterminate)\" class=\"flex justify-between items-center\">\r\n <p v-if=\"props.label\" class=\"text-sm font-medium text-gray-700\">\r\n {{ props.label }}\r\n </p>\r\n <p v-if=\"props.showLabel || props.indeterminate\" class=\"text-sm font-medium text-gray-600\">\r\n {{ indeterminateText }}\r\n </p>\r\n </div>\r\n \r\n <!-- Circular Progress용 상단 라벨 -->\r\n <div v-if=\"props.variant === 'circular' && props.label\" class=\"text-center mb-2\">\r\n <p class=\"text-sm font-medium text-gray-700\">{{ props.label }}</p>\r\n </div>\r\n \r\n <!-- Linear Progress -->\r\n <div v-if=\"props.variant === 'linear'\">\r\n <!-- Indeterminate Linear -->\r\n <div v-if=\"props.indeterminate\" class=\"relative overflow-hidden rounded-full bg-gray-200\" :class=\"SIZE_PRESETS[props.size!].class\">\r\n <div \r\n class=\"absolute h-full w-full animate-pulse\"\r\n :style=\"{ backgroundColor: linearIndeterminateColor }\"\r\n />\r\n <div \r\n class=\"absolute h-full w-1/3 animate-[indeterminate-linear_2s_infinite]\"\r\n :style=\"{ backgroundColor: linearIndeterminateColor }\"\r\n />\r\n </div>\r\n <!-- Determinate Linear -->\r\n <Progress v-else v-bind=\"mapped\" />\r\n </div>\r\n \r\n <!-- Circular Progress -->\r\n <div v-else-if=\"props.variant === 'circular'\" class=\"flex justify-center\">\r\n <div class=\"relative\" :style=\"{ width: circularStyle.size + 'px', height: circularStyle.size + 'px' }\">\r\n <!-- Indeterminate Circular -->\r\n <div v-if=\"props.indeterminate\">\r\n <svg class=\"w-full h-full animate-spin\" viewBox=\"0 0 100 100\">\r\n <circle\r\n cx=\"50\"\r\n cy=\"50\"\r\n r=\"45\"\r\n stroke=\"#e5e7eb\"\r\n stroke-width=\"8\"\r\n fill=\"none\"\r\n />\r\n <circle\r\n cx=\"50\"\r\n cy=\"50\"\r\n r=\"45\"\r\n :stroke=\"circularStyle.color\"\r\n stroke-width=\"8\"\r\n fill=\"none\"\r\n stroke-linecap=\"round\"\r\n stroke-dasharray=\"70 213\"\r\n stroke-dashoffset=\"0\"\r\n class=\"animate-[indeterminate-circular_2s_ease-in-out_infinite]\"\r\n />\r\n </svg>\r\n </div>\r\n <!-- Determinate Circular -->\r\n <div v-else>\r\n <svg class=\"w-full h-full transform -rotate-90\" viewBox=\"0 0 100 100\">\r\n <!-- Background circle -->\r\n <circle\r\n cx=\"50\"\r\n cy=\"50\"\r\n r=\"45\"\r\n stroke=\"#e5e7eb\"\r\n stroke-width=\"8\"\r\n fill=\"none\"\r\n />\r\n <!-- Progress circle -->\r\n <circle\r\n cx=\"50\"\r\n cy=\"50\"\r\n r=\"45\"\r\n :stroke=\"circularStyle.color\"\r\n stroke-width=\"8\"\r\n fill=\"none\"\r\n stroke-linecap=\"round\"\r\n :stroke-dasharray=\"283\"\r\n :stroke-dashoffset=\"283 - (283 * percentage / 100)\"\r\n class=\"transition-all duration-300 ease-in-out\"\r\n />\r\n </svg>\r\n </div>\r\n <!-- Center text -->\r\n <div v-if=\"props.showLabel || props.indeterminate\" class=\"absolute inset-0 flex items-center justify-center\">\r\n <span class=\"text-sm font-medium text-gray-700\">{{ indeterminateText }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n \r\n <!-- Circular Progress용 하단 description -->\r\n <div v-if=\"props.variant === 'circular' && props.description\" class=\"text-center mt-2\">\r\n <p class=\"text-xs text-gray-500\">{{ props.description }}</p>\r\n </div>\r\n \r\n <!-- Linear Progress용 하단 description -->\r\n <p v-if=\"props.variant === 'linear' && props.description\" class=\"text-xs text-gray-500\">\r\n {{ props.description }}\r\n </p>\r\n </div>\r\n</template>\r\n\r\n<style>\r\n@keyframes indeterminate-linear {\r\n 0% {\r\n transform: translateX(-100%);\r\n }\r\n 100% {\r\n transform: translateX(400%);\r\n }\r\n}\r\n\r\n@keyframes indeterminate-circular {\r\n 0% {\r\n stroke-dasharray: 70 213;\r\n stroke-dashoffset: 0;\r\n }\r\n 50% {\r\n stroke-dasharray: 140 143;\r\n stroke-dashoffset: -70;\r\n }\r\n 100% {\r\n stroke-dasharray: 70 213;\r\n stroke-dashoffset: -213;\r\n }\r\n}\r\n</style>\r\n"],"names":["props","__props","STYLE_PRESETS","SIZE_PRESETS","CIRCULAR_SIZE_PRESETS","percentage","computed","mapped","stylePreset","sizePreset","finalClass","circularStyle","color","indeterminateText","linearIndeterminateColor","_openBlock","_createElementBlock","_hoisted_1","_hoisted_2","_hoisted_3","_toDisplayString","_hoisted_4","_hoisted_5","_createElementVNode","_hoisted_6","_hoisted_7","_normalizeClass","_createBlock","Progress","_hoisted_8","_hoisted_9","_hoisted_10","_hoisted_12","_hoisted_13","_hoisted_15","_hoisted_16","_hoisted_17","_hoisted_18","_hoisted_19"],"mappings":"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"}
@@ -1,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 m=require("../shadcn/RadioGroup.vue.cjs"),p=require("../shadcn/RadioGroupItem.vue.cjs"),g=["for"],f=e.defineComponent({__name:"JRadio",props:{modelValue:{},options:{default:()=>[]},disabled:{type:Boolean,default:!1},required:{type:Boolean,default:!1},name:{},id:{},class:{},styletype:{default:"default"}},emits:["update:modelValue","change"],setup(l,{emit:o}){const r=l,u=o,a={default:{groupClass:"",itemClass:""},primary:{groupClass:"",itemClass:"border-blue-500 text-blue-500"},success:{groupClass:"",itemClass:"border-green-500 text-green-600"},danger:{groupClass:"",itemClass:"border-destructive text-destructive"},sm:{groupClass:"",itemClass:"h-3.5 w-3.5"},lg:{groupClass:"",itemClass:"h-5 w-5"},horizontal:{groupClass:"flex flex-row gap-4",itemClass:""},vertical:{groupClass:"grid gap-2",itemClass:""}},i=e.computed(()=>{const t=r.styletype||"default";return[(a[t]??a.default)?.groupClass,r.class].filter(Boolean).join(" ")}),n=e.computed(()=>{const t=r.styletype||"default";return(a[t]??a.default)?.itemClass}),c=t=>{u("update:modelValue",t),u("change",t)};return(t,d)=>(e.openBlock(),e.createBlock(e.unref(m.default),{"model-value":String(l.modelValue),disabled:l.disabled,required:l.required,name:l.name,id:l.id,class:e.normalizeClass(i.value),"onUpdate:modelValue":c},{default:e.withCtx(()=>[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(l.options,s=>(e.openBlock(),e.createElementBlock("div",{key:s.value,class:e.normalizeClass(l.styletype==="vertical"?"block":"flex items-center space-x-2")},[e.createVNode(e.unref(p.default),{id:String(s.value),value:String(s.value),disabled:s.disabled,class:e.normalizeClass(n.value)},null,8,["id","value","disabled","class"]),e.createElementVNode("label",{for:String(s.value),class:"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"},e.toDisplayString(s.label),9,g)],2))),128))]),_:1},8,["model-value","disabled","required","name","id","class"]))}});exports.default=f;
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("vue");require("../shadcn/index.cjs");const m=require("../shadcn/RadioGroup.vue.cjs"),p=require("../shadcn/RadioGroupItem.vue.cjs"),g=["for"],f=e.defineComponent({__name:"JRadio",props:{modelValue:{},options:{default:()=>[]},disabled:{type:Boolean,default:!1},required:{type:Boolean,default:!1},name:{},id:{},class:{},styletype:{default:"default"}},emits:["update:modelValue","change"],setup(l,{emit:o}){const r=l,u=o,a={default:{groupClass:"",itemClass:""},primary:{groupClass:"",itemClass:"border-blue-500 text-blue-500"},success:{groupClass:"",itemClass:"border-green-500 text-green-600"},danger:{groupClass:"",itemClass:"border-destructive text-destructive"},sm:{groupClass:"",itemClass:"h-3.5 w-3.5"},lg:{groupClass:"",itemClass:"h-5 w-5"},horizontal:{groupClass:"flex flex-row gap-4",itemClass:""},vertical:{groupClass:"grid gap-2",itemClass:""}},i=e.computed(()=>{const t=r.styletype||"default";return[(a[t]??a.default)?.groupClass,r.class].filter(Boolean).join(" ")}),n=e.computed(()=>{const t=r.styletype||"default";return(a[t]??a.default)?.itemClass}),c=t=>{u("update:modelValue",t),u("change",t)};return(t,d)=>(e.openBlock(),e.createBlock(e.unref(m.default),{"model-value":String(l.modelValue),disabled:l.disabled,required:l.required,name:l.name,id:l.id,class:e.normalizeClass(i.value),"onUpdate:modelValue":c},{default:e.withCtx(()=>[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(l.options,s=>(e.openBlock(),e.createElementBlock("div",{key:s.value,class:e.normalizeClass(l.styletype==="vertical"?"block":"flex items-center space-x-2")},[e.createVNode(e.unref(p.default),{id:String(s.value),value:String(s.value),disabled:s.disabled,class:e.normalizeClass(n.value)},null,8,["id","value","disabled","class"]),e.createElementVNode("label",{for:String(s.value),class:"text-xs font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"},e.toDisplayString(s.label),9,g)],2))),128))]),_:1},8,["model-value","disabled","required","name","id","class"]))}});exports.default=f;
2
2
  //# sourceMappingURL=JRadio.vue.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"JRadio.vue.cjs","sources":["../../../../src/components/atoms/JRadio.vue"],"sourcesContent":["<script setup lang=\"ts\">\r\nimport { computed } from 'vue'\r\nimport { RadioGroup, RadioGroupItem } from '@/components/shadcn'\r\n\r\nexport interface Option {\r\n value: string | number\r\n label: string\r\n disabled?: boolean\r\n}\r\n\r\ntype StyleType =\r\n | 'default' // 기본 스타일\r\n | 'primary' // 강조 스타일 (파랑)\r\n | 'success' // 성공 스타일 (초록)\r\n | 'danger' // 위험 스타일 (빨강)\r\n | 'sm' // 작은 크기\r\n | 'lg' // 큰 크기\r\n | 'horizontal' // 가로 배치\r\n | 'vertical' // 세로 배치\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n modelValue?: string | number\r\n options?: Option[]\r\n disabled?: boolean\r\n required?: boolean\r\n name?: string\r\n id?: string\r\n class?: string\r\n /** 스타일 프리셋 */\r\n styletype?: StyleType\r\n }>(),\r\n {\r\n options: () => [],\r\n disabled: false,\r\n required: false,\r\n styletype: 'default',\r\n },\r\n)\r\n\r\nconst emit = defineEmits<{\r\n 'update:modelValue': [value: string | number]\r\n 'change': [value: string | number]\r\n}>()\r\n\r\n/**\r\n * styletype -> class 매핑\r\n */\r\nconst STYLE_PRESETS: Record<StyleType, { groupClass: string; itemClass: string }> = {\r\n default: { \r\n groupClass: '',\r\n itemClass: '',\r\n },\r\n primary: { \r\n groupClass: '',\r\n itemClass: 'border-blue-500 text-blue-500',\r\n },\r\n success: { \r\n groupClass: '',\r\n itemClass: 'border-green-500 text-green-600',\r\n },\r\n danger: { \r\n groupClass: '',\r\n itemClass: 'border-destructive text-destructive',\r\n },\r\n sm: { \r\n groupClass: '',\r\n itemClass: 'h-3.5 w-3.5',\r\n },\r\n lg: { \r\n groupClass: '',\r\n itemClass: 'h-5 w-5',\r\n },\r\n horizontal: { \r\n groupClass: 'flex flex-row gap-4',\r\n itemClass: '',\r\n },\r\n vertical: { \r\n groupClass: 'grid gap-2',\r\n itemClass: '',\r\n },\r\n}\r\n\r\nconst groupClass = computed(() => {\r\n const styleKey = props.styletype || 'default'\r\n const preset = STYLE_PRESETS[styleKey] ?? STYLE_PRESETS.default\r\n return [preset?.groupClass, props.class].filter(Boolean).join(' ')\r\n})\r\n\r\nconst itemClass = computed(() => {\r\n const styleKey = props.styletype || 'default'\r\n const preset = STYLE_PRESETS[styleKey] ?? STYLE_PRESETS.default\r\n return preset?.itemClass\r\n})\r\n\r\nconst handleChange = (value: string) => {\r\n emit('update:modelValue', value)\r\n emit('change', value)\r\n}\r\n</script>\r\n\r\n<template>\r\n <RadioGroup \r\n :model-value=\"String(modelValue)\" \r\n :disabled=\"disabled\"\r\n :required=\"required\"\r\n :name=\"name\"\r\n :id=\"id\"\r\n :class=\"groupClass\" \r\n @update:model-value=\"handleChange\"\r\n >\r\n <div v-for=\"option in options\" :key=\"option.value\" :class=\"styletype === 'vertical' ? 'block' : 'flex items-center space-x-2'\">\r\n <RadioGroupItem \r\n :id=\"String(option.value)\" \r\n :value=\"String(option.value)\" \r\n :disabled=\"option.disabled\"\r\n :class=\"itemClass\"\r\n />\r\n <label\r\n :for=\"String(option.value)\"\r\n class=\"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70\"\r\n >\r\n {{ option.label }}\r\n </label>\r\n </div>\r\n </RadioGroup>\r\n</template>\r\n"],"names":["props","__props","emit","__emit","STYLE_PRESETS","groupClass","computed","styleKey","itemClass","handleChange","value","_createBlock","_unref","RadioGroup","_createElementBlock","_Fragment","_renderList","option","_createVNode","RadioGroupItem","_createElementVNode","_toDisplayString","_hoisted_1"],"mappings":"ghBAoBA,MAAMA,EAAQC,EAoBRC,EAAOC,EAQPC,EAA8E,CAClF,QAAS,CACP,WAAY,GACZ,UAAW,EAAA,EAEb,QAAS,CACP,WAAY,GACZ,UAAW,+BAAA,EAEb,QAAS,CACP,WAAY,GACZ,UAAW,iCAAA,EAEb,OAAQ,CACN,WAAY,GACZ,UAAW,qCAAA,EAEb,GAAI,CACF,WAAY,GACZ,UAAW,aAAA,EAEb,GAAI,CACF,WAAY,GACZ,UAAW,SAAA,EAEb,WAAY,CACV,WAAY,sBACZ,UAAW,EAAA,EAEb,SAAU,CACR,WAAY,aACZ,UAAW,EAAA,CACb,EAGIC,EAAaC,EAAAA,SAAS,IAAM,CAChC,MAAMC,EAAWP,EAAM,WAAa,UAEpC,MAAO,EADQI,EAAcG,CAAQ,GAAKH,EAAc,UACxC,WAAYJ,EAAM,KAAK,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,CACnE,CAAC,EAEKQ,EAAYF,EAAAA,SAAS,IAAM,CAC/B,MAAMC,EAAWP,EAAM,WAAa,UAEpC,OADeI,EAAcG,CAAQ,GAAKH,EAAc,UACzC,SACjB,CAAC,EAEKK,EAAgBC,GAAkB,CACtCR,EAAK,oBAAqBQ,CAAK,EAC/BR,EAAK,SAAUQ,CAAK,CACtB,8BAIEC,EAAAA,YAuBaC,EAAAA,MAAAC,EAAAA,OAAA,EAAA,CAtBV,cAAa,OAAOZ,EAAA,UAAU,EAC9B,SAAUA,EAAA,SACV,SAAUA,EAAA,SACV,KAAMA,EAAA,KACN,GAAIA,EAAA,GACJ,uBAAOI,EAAA,KAAU,EACjB,sBAAoBI,CAAA,qBAEhB,IAAyB,kBAA9BK,EAAAA,mBAaMC,EAAAA,SAAA,KAAAC,EAAAA,WAbgBf,EAAA,QAAVgB,kBAAZH,EAAAA,mBAaM,MAAA,CAb0B,IAAKG,EAAO,MAAQ,uBAAOhB,EAAA,YAAS,WAAA,QAAA,6BAAA,CAAA,GAClEiB,cAKEN,EAAAA,MAAAO,EAAAA,OAAA,EAAA,CAJC,GAAI,OAAOF,EAAO,KAAK,EACvB,MAAO,OAAOA,EAAO,KAAK,EAC1B,SAAUA,EAAO,SACjB,uBAAOT,EAAA,KAAS,CAAA,4CAEnBY,EAAAA,mBAKQ,QAAA,CAJL,IAAK,OAAOH,EAAO,KAAK,EACzB,MAAM,4FAAA,EAEHI,EAAAA,gBAAAJ,EAAO,KAAK,EAAA,EAAAK,CAAA,CAAA"}
1
+ {"version":3,"file":"JRadio.vue.cjs","sources":["../../../../src/components/atoms/JRadio.vue"],"sourcesContent":["<script setup lang=\"ts\">\r\nimport { computed } from 'vue'\r\nimport { RadioGroup, RadioGroupItem } from '@/components/shadcn'\r\n\r\nexport interface Option {\r\n value: string | number\r\n label: string\r\n disabled?: boolean\r\n}\r\n\r\ntype StyleType =\r\n | 'default' // 기본 스타일\r\n | 'primary' // 강조 스타일 (파랑)\r\n | 'success' // 성공 스타일 (초록)\r\n | 'danger' // 위험 스타일 (빨강)\r\n | 'sm' // 작은 크기\r\n | 'lg' // 큰 크기\r\n | 'horizontal' // 가로 배치\r\n | 'vertical' // 세로 배치\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n modelValue?: string | number\r\n options?: Option[]\r\n disabled?: boolean\r\n required?: boolean\r\n name?: string\r\n id?: string\r\n class?: string\r\n /** 스타일 프리셋 */\r\n styletype?: StyleType\r\n }>(),\r\n {\r\n options: () => [],\r\n disabled: false,\r\n required: false,\r\n styletype: 'default',\r\n },\r\n)\r\n\r\nconst emit = defineEmits<{\r\n 'update:modelValue': [value: string | number]\r\n 'change': [value: string | number]\r\n}>()\r\n\r\n/**\r\n * styletype -> class 매핑\r\n */\r\nconst STYLE_PRESETS: Record<StyleType, { groupClass: string; itemClass: string }> = {\r\n default: { \r\n groupClass: '',\r\n itemClass: '',\r\n },\r\n primary: { \r\n groupClass: '',\r\n itemClass: 'border-blue-500 text-blue-500',\r\n },\r\n success: { \r\n groupClass: '',\r\n itemClass: 'border-green-500 text-green-600',\r\n },\r\n danger: { \r\n groupClass: '',\r\n itemClass: 'border-destructive text-destructive',\r\n },\r\n sm: { \r\n groupClass: '',\r\n itemClass: 'h-3.5 w-3.5',\r\n },\r\n lg: { \r\n groupClass: '',\r\n itemClass: 'h-5 w-5',\r\n },\r\n horizontal: { \r\n groupClass: 'flex flex-row gap-4',\r\n itemClass: '',\r\n },\r\n vertical: { \r\n groupClass: 'grid gap-2',\r\n itemClass: '',\r\n },\r\n}\r\n\r\nconst groupClass = computed(() => {\r\n const styleKey = props.styletype || 'default'\r\n const preset = STYLE_PRESETS[styleKey] ?? STYLE_PRESETS.default\r\n return [preset?.groupClass, props.class].filter(Boolean).join(' ')\r\n})\r\n\r\nconst itemClass = computed(() => {\r\n const styleKey = props.styletype || 'default'\r\n const preset = STYLE_PRESETS[styleKey] ?? STYLE_PRESETS.default\r\n return preset?.itemClass\r\n})\r\n\r\nconst handleChange = (value: string) => {\r\n emit('update:modelValue', value)\r\n emit('change', value)\r\n}\r\n</script>\r\n\r\n<template>\r\n <RadioGroup \r\n :model-value=\"String(modelValue)\" \r\n :disabled=\"disabled\"\r\n :required=\"required\"\r\n :name=\"name\"\r\n :id=\"id\"\r\n :class=\"groupClass\" \r\n @update:model-value=\"handleChange\"\r\n >\r\n <div v-for=\"option in options\" :key=\"option.value\" :class=\"styletype === 'vertical' ? 'block' : 'flex items-center space-x-2'\">\r\n <RadioGroupItem \r\n :id=\"String(option.value)\" \r\n :value=\"String(option.value)\" \r\n :disabled=\"option.disabled\"\r\n :class=\"itemClass\"\r\n />\r\n <label\n :for=\"String(option.value)\"\n class=\"text-xs font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70\"\n >\n {{ option.label }}\n </label>\n </div>\r\n </RadioGroup>\r\n</template>\r\n"],"names":["props","__props","emit","__emit","STYLE_PRESETS","groupClass","computed","styleKey","itemClass","handleChange","value","_createBlock","_unref","RadioGroup","_createElementBlock","_Fragment","_renderList","option","_createVNode","RadioGroupItem","_createElementVNode","_toDisplayString","_hoisted_1"],"mappings":"ghBAoBA,MAAMA,EAAQC,EAoBRC,EAAOC,EAQPC,EAA8E,CAClF,QAAS,CACP,WAAY,GACZ,UAAW,EAAA,EAEb,QAAS,CACP,WAAY,GACZ,UAAW,+BAAA,EAEb,QAAS,CACP,WAAY,GACZ,UAAW,iCAAA,EAEb,OAAQ,CACN,WAAY,GACZ,UAAW,qCAAA,EAEb,GAAI,CACF,WAAY,GACZ,UAAW,aAAA,EAEb,GAAI,CACF,WAAY,GACZ,UAAW,SAAA,EAEb,WAAY,CACV,WAAY,sBACZ,UAAW,EAAA,EAEb,SAAU,CACR,WAAY,aACZ,UAAW,EAAA,CACb,EAGIC,EAAaC,EAAAA,SAAS,IAAM,CAChC,MAAMC,EAAWP,EAAM,WAAa,UAEpC,MAAO,EADQI,EAAcG,CAAQ,GAAKH,EAAc,UACxC,WAAYJ,EAAM,KAAK,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,CACnE,CAAC,EAEKQ,EAAYF,EAAAA,SAAS,IAAM,CAC/B,MAAMC,EAAWP,EAAM,WAAa,UAEpC,OADeI,EAAcG,CAAQ,GAAKH,EAAc,UACzC,SACjB,CAAC,EAEKK,EAAgBC,GAAkB,CACtCR,EAAK,oBAAqBQ,CAAK,EAC/BR,EAAK,SAAUQ,CAAK,CACtB,8BAIEC,EAAAA,YAuBaC,EAAAA,MAAAC,EAAAA,OAAA,EAAA,CAtBV,cAAa,OAAOZ,EAAA,UAAU,EAC9B,SAAUA,EAAA,SACV,SAAUA,EAAA,SACV,KAAMA,EAAA,KACN,GAAIA,EAAA,GACJ,uBAAOI,EAAA,KAAU,EACjB,sBAAoBI,CAAA,qBAEhB,IAAyB,kBAA9BK,EAAAA,mBAaMC,EAAAA,SAAA,KAAAC,EAAAA,WAbgBf,EAAA,QAAVgB,kBAAZH,EAAAA,mBAaM,MAAA,CAb0B,IAAKG,EAAO,MAAQ,uBAAOhB,EAAA,YAAS,WAAA,QAAA,6BAAA,CAAA,GAClEiB,cAKEN,EAAAA,MAAAO,EAAAA,OAAA,EAAA,CAJC,GAAI,OAAOF,EAAO,KAAK,EACvB,MAAO,OAAOA,EAAO,KAAK,EAC1B,SAAUA,EAAO,SACjB,uBAAOT,EAAA,KAAS,CAAA,4CAEnBY,EAAAA,mBAKQ,QAAA,CAJL,IAAK,OAAOH,EAAO,KAAK,EACzB,MAAM,4FAAA,EAEHI,EAAAA,gBAAAJ,EAAO,KAAK,EAAA,EAAAK,CAAA,CAAA"}
@@ -80,7 +80,7 @@ const w = ["for"], L = /* @__PURE__ */ C({
80
80
  }, null, 8, ["id", "value", "disabled", "class"]),
81
81
  S("label", {
82
82
  for: String(a.value),
83
- class: "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
83
+ class: "text-xs font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
84
84
  }, V(a.label), 9, w)
85
85
  ], 2))), 128))
86
86
  ]),