@j-solution/components 1.6.0 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -7
- package/assets/jwms-portal-frontend-CwxPfHfa.css +1 -0
- package/assets/styles/j-components.css +1 -1
- package/assets/styles/themes.css +107 -0
- package/components/atoms/JAvatar.vue.cjs +1 -1
- package/components/atoms/JAvatar.vue.cjs.map +1 -1
- package/components/atoms/JAvatar.vue.js +10 -7
- package/components/atoms/JAvatar.vue.js.map +1 -1
- package/components/atoms/JBadge.vue.cjs +1 -1
- package/components/atoms/JBadge.vue.cjs.map +1 -1
- package/components/atoms/JBadge.vue.js +7 -6
- package/components/atoms/JBadge.vue.js.map +1 -1
- package/components/atoms/JButton.vue.cjs +1 -1
- package/components/atoms/JButton.vue.cjs.map +1 -1
- package/components/atoms/JButton.vue.js +5 -5
- package/components/atoms/JButton.vue.js.map +1 -1
- package/components/atoms/JDatepicker.vue.cjs +1 -1
- package/components/atoms/JDatepicker.vue.cjs.map +1 -1
- package/components/atoms/JDatepicker.vue.js +10 -10
- package/components/atoms/JDatepicker.vue.js.map +1 -1
- package/components/atoms/JEditor.vue.cjs +1 -1
- package/components/atoms/JEditor.vue.js +1 -1
- package/components/atoms/JEditor.vue2.cjs +1 -1
- package/components/atoms/JEditor.vue2.cjs.map +1 -1
- package/components/atoms/JEditor.vue2.js +31 -17
- package/components/atoms/JEditor.vue2.js.map +1 -1
- package/components/atoms/JGrid.vue.cjs +1 -1
- package/components/atoms/JGrid.vue.js +2 -2
- package/components/atoms/JGrid.vue2.cjs +1 -1
- package/components/atoms/JGrid.vue2.cjs.map +1 -1
- package/components/atoms/JGrid.vue2.js +45 -33
- package/components/atoms/JGrid.vue2.js.map +1 -1
- package/components/atoms/JIcon.vue.cjs +1 -1
- package/components/atoms/JIcon.vue.cjs.map +1 -1
- package/components/atoms/JIcon.vue.js +14 -13
- package/components/atoms/JIcon.vue.js.map +1 -1
- package/components/atoms/JKbd.vue.cjs +1 -1
- package/components/atoms/JKbd.vue.cjs.map +1 -1
- package/components/atoms/JKbd.vue.js +13 -10
- package/components/atoms/JKbd.vue.js.map +1 -1
- package/components/atoms/JLabel.vue.cjs +1 -1
- package/components/atoms/JLabel.vue.cjs.map +1 -1
- package/components/atoms/JLabel.vue.js +4 -4
- package/components/atoms/JLabel.vue.js.map +1 -1
- package/components/atoms/JLink.vue.cjs +1 -1
- package/components/atoms/JLink.vue.cjs.map +1 -1
- package/components/atoms/JLink.vue.js +5 -5
- package/components/atoms/JLink.vue.js.map +1 -1
- package/components/atoms/JPreview.vue.cjs +1 -1
- package/components/atoms/JPreview.vue.js +2 -2
- package/components/atoms/JPreview.vue2.cjs +1 -1
- package/components/atoms/JPreview.vue2.cjs.map +1 -1
- package/components/atoms/JPreview.vue2.js +33 -20
- package/components/atoms/JPreview.vue2.js.map +1 -1
- package/components/atoms/JProgress.vue.cjs +1 -1
- package/components/atoms/JProgress.vue.cjs.map +1 -1
- package/components/atoms/JProgress.vue.js +15 -9
- package/components/atoms/JProgress.vue.js.map +1 -1
- package/components/atoms/JRadio.vue.cjs +1 -1
- package/components/atoms/JRadio.vue.cjs.map +1 -1
- package/components/atoms/JRadio.vue.js +1 -1
- package/components/atoms/JRadio.vue.js.map +1 -1
- package/components/atoms/JSearchCombo.vue.cjs +1 -1
- package/components/atoms/JSearchCombo.vue.cjs.map +1 -1
- package/components/atoms/JSearchCombo.vue.js +38 -37
- package/components/atoms/JSearchCombo.vue.js.map +1 -1
- package/components/atoms/JSpinner.vue.cjs +1 -1
- package/components/atoms/JSpinner.vue.cjs.map +1 -1
- package/components/atoms/JSpinner.vue.js +8 -7
- package/components/atoms/JSpinner.vue.js.map +1 -1
- package/components/atoms/JSplitter.vue.cjs +1 -1
- package/components/atoms/JSplitter.vue.cjs.map +1 -1
- package/components/atoms/JSplitter.vue.js +32 -27
- package/components/atoms/JSplitter.vue.js.map +1 -1
- package/components/atoms/JTooltip.vue.cjs +1 -1
- package/components/atoms/JTooltip.vue.cjs.map +1 -1
- package/components/atoms/JTooltip.vue.js +18 -15
- package/components/atoms/JTooltip.vue.js.map +1 -1
- package/components/examples/ExampleCrudPage.vue.cjs +2 -0
- package/components/examples/ExampleCrudPage.vue.cjs.map +1 -0
- package/components/examples/ExampleCrudPage.vue.js +358 -0
- package/components/examples/ExampleCrudPage.vue.js.map +1 -0
- package/components/examples/ExampleCrudPage.vue2.cjs +2 -0
- package/components/examples/ExampleCrudPage.vue2.cjs.map +1 -0
- package/components/examples/ExampleCrudPage.vue2.js +5 -0
- package/components/examples/ExampleCrudPage.vue2.js.map +1 -0
- package/components/examples/ExampleTabMappingPage.vue.cjs +2 -0
- package/components/examples/ExampleTabMappingPage.vue.cjs.map +1 -0
- package/components/examples/ExampleTabMappingPage.vue.js +522 -0
- package/components/examples/ExampleTabMappingPage.vue.js.map +1 -0
- package/components/examples/ExampleTabMappingPage.vue2.cjs +2 -0
- package/components/examples/ExampleTabMappingPage.vue2.cjs.map +1 -0
- package/components/examples/ExampleTabMappingPage.vue2.js +5 -0
- package/components/examples/ExampleTabMappingPage.vue2.js.map +1 -0
- package/components/molecules/JBreadcrumb.vue.cjs +1 -1
- package/components/molecules/JBreadcrumb.vue.cjs.map +1 -1
- package/components/molecules/JBreadcrumb.vue.js +3 -3
- package/components/molecules/JBreadcrumb.vue.js.map +1 -1
- package/components/molecules/JFormField.vue.cjs +1 -1
- package/components/molecules/JFormField.vue.cjs.map +1 -1
- package/components/molecules/JFormField.vue.js +26 -24
- package/components/molecules/JFormField.vue.js.map +1 -1
- package/components/molecules/JTabs.vue.cjs +1 -1
- package/components/molecules/JTabs.vue.js +1 -1
- package/components/molecules/JTabs.vue2.cjs +1 -1
- package/components/molecules/JTabs.vue2.cjs.map +1 -1
- package/components/molecules/JTabs.vue2.js +7 -7
- package/components/molecules/JTabs.vue2.js.map +1 -1
- package/components/molecules/JTitlebar.vue.cjs +1 -1
- package/components/molecules/JTitlebar.vue.cjs.map +1 -1
- package/components/molecules/JTitlebar.vue.js +35 -36
- package/components/molecules/JTitlebar.vue.js.map +1 -1
- package/components/organisms/JFilterBar.vue.cjs +1 -1
- package/components/organisms/JFilterBar.vue.cjs.map +1 -1
- package/components/organisms/JFilterBar.vue.js +5 -5
- package/components/organisms/JFilterBar.vue.js.map +1 -1
- package/components/organisms/JHeader.vue.cjs +1 -1
- package/components/organisms/JHeader.vue.cjs.map +1 -1
- package/components/organisms/JHeader.vue.js +25 -23
- package/components/organisms/JHeader.vue.js.map +1 -1
- package/components/organisms/JModal.vue.cjs +1 -1
- package/components/organisms/JModal.vue.cjs.map +1 -1
- package/components/organisms/JModal.vue.js +30 -27
- package/components/organisms/JModal.vue.js.map +1 -1
- package/components/organisms/JSidebarAdvanced.vue.cjs +1 -1
- package/components/organisms/JSidebarAdvanced.vue.js +7 -7
- package/components/organisms/JSidebarAdvanced.vue2.cjs +1 -1
- package/components/organisms/JSidebarAdvanced.vue2.cjs.map +1 -1
- package/components/organisms/JSidebarAdvanced.vue2.js +40 -40
- package/components/organisms/JSidebarAdvanced.vue2.js.map +1 -1
- package/components/organisms/JSidebarSimple/JDynamicMenuItem.vue.cjs +1 -1
- package/components/organisms/JSidebarSimple/JDynamicMenuItem.vue.cjs.map +1 -1
- package/components/organisms/JSidebarSimple/JDynamicMenuItem.vue.js +83 -63
- package/components/organisms/JSidebarSimple/JDynamicMenuItem.vue.js.map +1 -1
- package/components/organisms/JSidebarSimple.vue.cjs +1 -1
- package/components/organisms/JSidebarSimple.vue.js +2 -2
- package/components/organisms/JSidebarSimple.vue2.cjs +1 -1
- package/components/organisms/JSidebarSimple.vue2.cjs.map +1 -1
- package/components/organisms/JSidebarSimple.vue2.js +2 -2
- package/components/organisms/JSidebarSimple.vue2.js.map +1 -1
- package/components/shadcn/AccordionTrigger.vue.cjs +1 -1
- package/components/shadcn/AccordionTrigger.vue.cjs.map +1 -1
- package/components/shadcn/AccordionTrigger.vue.js +3 -3
- package/components/shadcn/AccordionTrigger.vue.js.map +1 -1
- package/components/shadcn/CardContent.vue.cjs +1 -1
- package/components/shadcn/CardContent.vue.cjs.map +1 -1
- package/components/shadcn/CardContent.vue.js +1 -1
- package/components/shadcn/CardContent.vue.js.map +1 -1
- package/components/shadcn/CardDescription.vue.cjs +1 -1
- package/components/shadcn/CardDescription.vue.cjs.map +1 -1
- package/components/shadcn/CardDescription.vue.js +1 -1
- package/components/shadcn/CardDescription.vue.js.map +1 -1
- package/components/shadcn/CardFooter.vue.cjs +1 -1
- package/components/shadcn/CardFooter.vue.cjs.map +1 -1
- package/components/shadcn/CardFooter.vue.js +7 -7
- package/components/shadcn/CardFooter.vue.js.map +1 -1
- package/components/shadcn/CardHeader.vue.cjs +1 -1
- package/components/shadcn/CardHeader.vue.cjs.map +1 -1
- package/components/shadcn/CardHeader.vue.js +8 -8
- package/components/shadcn/CardHeader.vue.js.map +1 -1
- package/components/shadcn/CardTitle.vue.cjs +1 -1
- package/components/shadcn/CardTitle.vue.cjs.map +1 -1
- package/components/shadcn/CardTitle.vue.js +5 -5
- package/components/shadcn/CardTitle.vue.js.map +1 -1
- package/components/shadcn/Input.vue.cjs +1 -1
- package/components/shadcn/Input.vue.cjs.map +1 -1
- package/components/shadcn/Input.vue.js +1 -1
- package/components/shadcn/Input.vue.js.map +1 -1
- package/components/shadcn/SelectTrigger.vue.cjs +1 -1
- package/components/shadcn/SelectTrigger.vue.cjs.map +1 -1
- package/components/shadcn/SelectTrigger.vue.js +2 -2
- package/components/shadcn/SelectTrigger.vue.js.map +1 -1
- package/components/shadcn/Switch.vue.cjs +1 -1
- package/components/shadcn/Switch.vue.cjs.map +1 -1
- package/components/shadcn/Switch.vue.js +2 -2
- package/components/shadcn/Switch.vue.js.map +1 -1
- package/components/shadcn/TabsList.vue.cjs +1 -1
- package/components/shadcn/TabsList.vue.cjs.map +1 -1
- package/components/shadcn/TabsList.vue.js +1 -1
- package/components/shadcn/TabsList.vue.js.map +1 -1
- package/components/shadcn/TabsTrigger.vue.cjs +1 -1
- package/components/shadcn/TabsTrigger.vue.cjs.map +1 -1
- package/components/shadcn/TabsTrigger.vue.js +4 -4
- package/components/shadcn/TabsTrigger.vue.js.map +1 -1
- package/components/shadcn/Textarea.vue.cjs +1 -1
- package/components/shadcn/Textarea.vue.cjs.map +1 -1
- package/components/shadcn/Textarea.vue.js +2 -2
- package/components/shadcn/Textarea.vue.js.map +1 -1
- package/components/shadcn/index.cjs +1 -1
- package/components/shadcn/index.cjs.map +1 -1
- package/components/shadcn/index.js +8 -7
- package/components/shadcn/index.js.map +1 -1
- package/index.cjs +1 -1
- package/index.js +76 -72
- package/package.json +1 -1
- package/types/index.d.ts +742 -15
- 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 || '
|
|
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,
|
|
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 || "
|
|
29
|
-
class:
|
|
28
|
+
size: r?.size || "sm",
|
|
29
|
+
class: l,
|
|
30
30
|
disabled: e.disabled
|
|
31
31
|
};
|
|
32
|
-
}),
|
|
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, ...
|
|
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 || '
|
|
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-
|
|
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
|
|
9
|
+
const m = /* @__PURE__ */ r(o, [["__scopeId", "data-v-0ce9f9f8"]]);
|
|
10
10
|
export {
|
|
11
|
-
|
|
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"),
|
|
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\">\
|
|
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
|
|
2
|
-
import { MdPreview as
|
|
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
|
|
5
|
-
const
|
|
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: {
|
|
9
|
+
theme: {},
|
|
10
10
|
class: {}
|
|
11
11
|
},
|
|
12
|
-
setup(
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
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
|
|
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 (
|
|
103
|
-
class:
|
|
115
|
+
return (c, e) => (n(), u("div", {
|
|
116
|
+
class: d(["j-preview-wrapper", t.class])
|
|
104
117
|
}, [
|
|
105
|
-
|
|
118
|
+
m.value === "html" ? (n(), u("div", {
|
|
106
119
|
key: 0,
|
|
107
|
-
class:
|
|
108
|
-
innerHTML:
|
|
109
|
-
}, null, 10,
|
|
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":
|
|
112
|
-
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
|
-
|
|
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\">\
|
|
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},
|
|
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
|
|
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__ */
|
|
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: "
|
|
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-
|
|
70
|
+
class: "h-3"
|
|
68
71
|
},
|
|
69
72
|
lg: {
|
|
70
|
-
class: "h-
|
|
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:
|
|
83
|
+
size: 72
|
|
78
84
|
},
|
|
79
85
|
lg: {
|
|
80
|
-
size:
|
|
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],
|
|
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:
|
|
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-
|
|
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\
|
|
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-
|
|
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
|
]),
|