@j-solution/components 1.6.1 → 1.8.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 -6
- package/assets/jwms-portal-frontend-BtHTA-UF.css +1 -0
- package/assets/styles/global-utilities.css +34 -0
- package/assets/styles/j-components.css +1 -1
- package/assets/styles/themes.css +128 -21
- 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 +6 -1
- package/components/atoms/JButton.vue.cjs.map +1 -1
- package/components/atoms/JButton.vue.js +10 -85
- package/components/atoms/JButton.vue.js.map +1 -1
- package/components/atoms/JButton.vue2.cjs +1 -1
- package/components/atoms/JButton.vue2.cjs.map +1 -1
- package/components/atoms/JButton.vue2.js +85 -2
- package/components/atoms/JButton.vue2.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 +59 -43
- 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 +26 -22
- 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/JSectionTitle.vue.cjs +7 -0
- package/components/atoms/JSectionTitle.vue.cjs.map +1 -0
- package/components/atoms/JSectionTitle.vue.js +13 -0
- package/components/atoms/JSectionTitle.vue.js.map +1 -0
- package/components/atoms/JSectionTitle.vue2.cjs +2 -0
- package/components/atoms/JSectionTitle.vue2.cjs.map +1 -0
- package/components/atoms/JSectionTitle.vue2.js +67 -0
- package/components/atoms/JSectionTitle.vue2.js.map +1 -0
- 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 +6 -1
- package/components/atoms/JSplitter.vue.cjs.map +1 -1
- package/components/atoms/JSplitter.vue.js +10 -54
- package/components/atoms/JSplitter.vue.js.map +1 -1
- package/components/atoms/JSplitter.vue2.cjs +1 -1
- package/components/atoms/JSplitter.vue2.cjs.map +1 -1
- package/components/atoms/JSplitter.vue2.js +59 -2
- package/components/atoms/JSplitter.vue2.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 +1 -1
- package/components/examples/ExampleCrudPage.vue.cjs.map +1 -1
- package/components/examples/ExampleCrudPage.vue.js +265 -191
- package/components/examples/ExampleCrudPage.vue.js.map +1 -1
- package/components/examples/ExampleTabMappingPage.vue.cjs +1 -1
- package/components/examples/ExampleTabMappingPage.vue.cjs.map +1 -1
- package/components/examples/ExampleTabMappingPage.vue.js +349 -333
- package/components/examples/ExampleTabMappingPage.vue.js.map +1 -1
- package/components/molecules/JAlert.vue.cjs +1 -1
- package/components/molecules/JAlert.vue.cjs.map +1 -1
- package/components/molecules/JAlert.vue.js +18 -16
- package/components/molecules/JAlert.vue.js.map +1 -1
- 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/JCard.vue.cjs +1 -1
- package/components/molecules/JCard.vue.cjs.map +1 -1
- package/components/molecules/JCard.vue.js +55 -39
- package/components/molecules/JCard.vue.js.map +1 -1
- package/components/molecules/JEmptyState.vue.cjs +7 -0
- package/components/molecules/JEmptyState.vue.cjs.map +1 -0
- package/components/molecules/JEmptyState.vue.js +13 -0
- package/components/molecules/JEmptyState.vue.js.map +1 -0
- package/components/molecules/JEmptyState.vue2.cjs +2 -0
- package/components/molecules/JEmptyState.vue2.cjs.map +1 -0
- package/components/molecules/JEmptyState.vue2.js +127 -0
- package/components/molecules/JEmptyState.vue2.js.map +1 -0
- package/components/molecules/JFormField.vue.cjs +6 -1
- package/components/molecules/JFormField.vue.cjs.map +1 -1
- package/components/molecules/JFormField.vue.js +10 -262
- package/components/molecules/JFormField.vue.js.map +1 -1
- package/components/molecules/JFormField.vue2.cjs +2 -0
- package/components/molecules/JFormField.vue2.cjs.map +1 -0
- package/components/molecules/JFormField.vue2.js +271 -0
- package/components/molecules/JFormField.vue2.js.map +1 -0
- 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 +50 -56
- 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 +49 -47
- package/components/molecules/JTitlebar.vue.js.map +1 -1
- package/components/organisms/JDynamicForm.vue2.cjs +1 -1
- package/components/organisms/JDynamicForm.vue2.cjs.map +1 -1
- package/components/organisms/JDynamicForm.vue2.js +35 -32
- package/components/organisms/JDynamicForm.vue2.js.map +1 -1
- package/components/organisms/JDynamicTabs.vue.cjs +1 -1
- package/components/organisms/JDynamicTabs.vue.cjs.map +1 -1
- package/components/organisms/JDynamicTabs.vue.js +47 -52
- package/components/organisms/JDynamicTabs.vue.js.map +1 -1
- package/components/organisms/JFilterBar.vue.cjs +6 -1
- package/components/organisms/JFilterBar.vue.cjs.map +1 -1
- package/components/organisms/JFilterBar.vue.js +10 -137
- package/components/organisms/JFilterBar.vue.js.map +1 -1
- package/components/organisms/JFilterBar.vue2.cjs +1 -1
- package/components/organisms/JFilterBar.vue2.cjs.map +1 -1
- package/components/organisms/JFilterBar.vue2.js +141 -2
- package/components/organisms/JFilterBar.vue2.js.map +1 -1
- package/components/organisms/JFormModal.vue.cjs +1 -1
- package/components/organisms/JFormModal.vue.cjs.map +1 -1
- package/components/organisms/JFormModal.vue.js +54 -49
- package/components/organisms/JFormModal.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 +211 -208
- 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 +31 -26
- package/components/organisms/JModal.vue.js.map +1 -1
- package/components/organisms/JPageContainer.vue.cjs +1 -1
- package/components/organisms/JPageContainer.vue.cjs.map +1 -1
- package/components/organisms/JPageContainer.vue.js +22 -22
- package/components/organisms/JPageContainer.vue.js.map +1 -1
- package/components/organisms/JSearchPanel.vue2.cjs +1 -1
- package/components/organisms/JSearchPanel.vue2.cjs.map +1 -1
- package/components/organisms/JSearchPanel.vue2.js +34 -32
- package/components/organisms/JSearchPanel.vue2.js.map +1 -1
- package/components/organisms/JShuttle.vue.cjs +7 -0
- package/components/organisms/JShuttle.vue.cjs.map +1 -0
- package/components/organisms/JShuttle.vue.js +13 -0
- package/components/organisms/JShuttle.vue.js.map +1 -0
- package/components/organisms/JShuttle.vue2.cjs +2 -0
- package/components/organisms/JShuttle.vue2.cjs.map +1 -0
- package/components/organisms/JShuttle.vue2.js +216 -0
- package/components/organisms/JShuttle.vue2.js.map +1 -0
- 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/Card.vue.cjs +1 -1
- package/components/shadcn/Card.vue.cjs.map +1 -1
- package/components/shadcn/Card.vue.js +1 -1
- package/components/shadcn/Card.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 +4 -4
- 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 +3 -3
- 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/TabsContent.vue.cjs +1 -1
- package/components/shadcn/TabsContent.vue.cjs.map +1 -1
- package/components/shadcn/TabsContent.vue.js +1 -1
- package/components/shadcn/TabsContent.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 +10 -10
- 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 +9 -8
- package/components/shadcn/index.js.map +1 -1
- package/components/templates/JLayout.vue.cjs.map +1 -1
- package/components/templates/JLayout.vue.js.map +1 -1
- package/index.cjs +1 -1
- package/index.js +73 -67
- package/package.json +1 -1
- package/types/index.d.ts +1025 -766
- package/assets/jwms-portal-frontend-DntSIcYt.css +0 -1
- package/components/molecules/JFormField.vue3.cjs +0 -2
- package/components/molecules/JFormField.vue3.cjs.map +0 -1
- package/components/molecules/JFormField.vue3.js +0 -6
- package/components/molecules/JFormField.vue3.js.map +0 -1
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import t from "./JEmptyState.vue2.js";
|
|
2
|
+
/* empty css */
|
|
3
|
+
const o = (o_comp, o_opts) => {
|
|
4
|
+
const o_merged = o_comp.__vccOpts || o_comp;
|
|
5
|
+
for (const [o_key, o_val] of o_opts)
|
|
6
|
+
o_merged[o_key] = o_val;
|
|
7
|
+
return o_merged;
|
|
8
|
+
};
|
|
9
|
+
const a = /* @__PURE__ */ o(t, [["__scopeId", "data-v-b6b7e0cc"]]);
|
|
10
|
+
export {
|
|
11
|
+
a as default
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=JEmptyState.vue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"JEmptyState.vue.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("vue"),u=require("../atoms/JButton.vue.cjs");require("../shadcn/index.cjs");require("lucide-vue-next");const i=require("../../lib/utils.cjs");require("@internationalized/date");require("md-editor-v3");;/* empty css */;/* empty css */require("../shadcn/badge-variants.cjs");require("@vueuse/core");require("reka-ui");;/* empty css */require("../shadcn/avatar-variants.cjs");const l=require("../atoms/JIcon.vue.cjs");require("dompurify");;/* empty css */require("ag-grid-vue3");require("ag-grid-community");require("ag-grid-enterprise");;/* empty css */;/* empty css */;/* empty css */;/* empty css */;/* empty css */;/* empty css */require("vue-sonner");const a={key:1,class:"text-sm text-muted-foreground"},d={key:0,class:"j-empty-icon-wrapper"},m={key:1,class:"text-xl font-semibold text-foreground mb-2 tracking-tight"},f={key:2,class:"text-sm text-muted-foreground mb-6 max-w-sm leading-relaxed"},k=e.defineComponent({__name:"JEmptyState",props:{icon:{default:"inbox"},title:{},description:{},actionText:{},variant:{default:"default"},class:{}},emits:["action"],setup(t,{emit:s}){const o=t,c=s;return(r,n)=>t.variant==="simple"?(e.openBlock(),e.createElementBlock("div",{key:0,class:e.normalizeClass(e.unref(i.cn)("j-empty-state-simple","flex flex-col items-center justify-center p-8 text-center","rounded-sm border-4 border-dashed",o.class))},[t.icon||r.$slots.icon?(e.openBlock(),e.createBlock(e.unref(l.default),{key:0,name:t.icon||"inbox",class:"w-12 h-12 text-muted-foreground mb-3"},{default:e.withCtx(()=>[e.renderSlot(r.$slots,"icon",{},void 0,!0)]),_:3},8,["name"])):e.createCommentVNode("",!0),t.title||r.$slots.title?(e.openBlock(),e.createElementBlock("p",a,[e.renderSlot(r.$slots,"title",{},()=>[e.createTextVNode(e.toDisplayString(t.title),1)],!0)])):e.createCommentVNode("",!0)],2)):(e.openBlock(),e.createElementBlock("div",{key:1,class:e.normalizeClass(e.unref(i.cn)("j-empty-state","flex flex-col items-center justify-center","p-12 text-center","max-w-lg mx-auto","rounded-sm border border-border","bg-card shadow-sm",o.class))},[t.icon||r.$slots.icon?(e.openBlock(),e.createElementBlock("div",d,[e.renderSlot(r.$slots,"icon",{},()=>[t.icon?(e.openBlock(),e.createBlock(e.unref(l.default),{key:0,name:t.icon,class:"w-12 h-12 text-muted-foreground"},null,8,["name"])):e.createCommentVNode("",!0)],!0)])):e.createCommentVNode("",!0),t.title||r.$slots.title?(e.openBlock(),e.createElementBlock("h3",m,[e.renderSlot(r.$slots,"title",{},()=>[e.createTextVNode(e.toDisplayString(t.title),1)],!0)])):e.createCommentVNode("",!0),t.description||r.$slots.description?(e.openBlock(),e.createElementBlock("p",f,[e.renderSlot(r.$slots,"description",{},()=>[e.createTextVNode(e.toDisplayString(t.description),1)],!0)])):e.createCommentVNode("",!0),e.renderSlot(r.$slots,"action",{},()=>[t.actionText?(e.openBlock(),e.createBlock(e.unref(u.default),{key:0,styletype:"primary",size:"sm",onClick:n[0]||(n[0]=q=>c("action"))},{default:e.withCtx(()=>[e.createTextVNode(e.toDisplayString(t.actionText),1)]),_:1})):e.createCommentVNode("",!0)],!0)],2))}});exports.default=k;
|
|
2
|
+
//# sourceMappingURL=JEmptyState.vue2.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"JEmptyState.vue2.cjs","sources":["../../../../src/components/molecules/JEmptyState.vue"],"sourcesContent":["<template>\n <!-- Simple variant: 아이콘 + 텍스트만 -->\n <div \n v-if=\"variant === 'simple'\"\n :class=\"cn(\n 'j-empty-state-simple',\n 'flex flex-col items-center justify-center p-8 text-center',\n 'rounded-sm border-4 border-dashed',\n props.class\n )\"\n >\n <JIcon \n v-if=\"icon || $slots.icon\" \n :name=\"icon || 'inbox'\" \n class=\"w-12 h-12 text-muted-foreground mb-3\"\n >\n <slot name=\"icon\" />\n </JIcon>\n \n <p v-if=\"title || $slots.title\" class=\"text-sm text-muted-foreground\">\n <slot name=\"title\">{{ title }}</slot>\n </p>\n </div>\n\n <!-- Default variant: 풀 스타일 -->\n <div \n v-else\n :class=\"cn(\n 'j-empty-state',\n 'flex flex-col items-center justify-center',\n 'p-12 text-center',\n 'max-w-lg mx-auto',\n 'rounded-sm border border-border',\n 'bg-card shadow-sm',\n props.class\n )\"\n >\n <!-- 아이콘 (원형 배경) -->\n <div v-if=\"icon || $slots.icon\" class=\"j-empty-icon-wrapper\">\n <slot name=\"icon\">\n <JIcon \n v-if=\"icon\" \n :name=\"icon\" \n class=\"w-12 h-12 text-muted-foreground\"\n />\n </slot>\n </div>\n\n <!-- 제목 -->\n <h3 v-if=\"title || $slots.title\" \n class=\"text-xl font-semibold text-foreground mb-2 tracking-tight\">\n <slot name=\"title\">{{ title }}</slot>\n </h3>\n\n <!-- 설명 -->\n <p v-if=\"description || $slots.description\" \n class=\"text-sm text-muted-foreground mb-6 max-w-sm leading-relaxed\">\n <slot name=\"description\">{{ description }}</slot>\n </p>\n\n <!-- 액션 버튼 -->\n <slot name=\"action\">\n <JButton \n v-if=\"actionText\" \n styletype=\"primary\"\n size=\"sm\"\n @click=\"emit('action')\"\n >\n {{ actionText }}\n </JButton>\n </slot>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { JIcon, JButton } from '@/components/atoms'\nimport { cn } from '@/lib/utils'\nimport type { JEmptyStateProps, JEmptyStateEmits } from '@/types/empty-state.types'\n\nconst props = withDefaults(defineProps<JEmptyStateProps>(), {\n icon: 'inbox',\n variant: 'default',\n})\n\nconst emit = defineEmits<JEmptyStateEmits>()\n</script>\n\n<style scoped>\n.j-empty-state {\n transition: all 0.2s ease;\n}\n\n.j-empty-state-simple {\n border-color: hsl(var(--border) / 0.5);\n background: hsl(var(--muted) / 0.1);\n transition: all 0.2s ease;\n}\n\n.j-empty-state-simple:hover {\n border-color: hsl(var(--border) / 0.8);\n background: hsl(var(--muted) / 0.15);\n}\n\n.j-empty-icon-wrapper {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 5rem;\n height: 5rem;\n margin-bottom: 1.5rem;\n border-radius: 9999px;\n background: linear-gradient(135deg, \n hsl(var(--primary) / 0.08) 0%, \n hsl(var(--primary) / 0.02) 100%);\n border: 1px solid hsl(var(--border));\n}\n\n@media (prefers-reduced-motion: no-preference) {\n .j-empty-icon-wrapper {\n animation: pulse 3s ease-in-out infinite;\n }\n}\n\n@keyframes pulse {\n 0%, 100% { \n opacity: 1; \n transform: scale(1);\n }\n 50% { \n opacity: 0.85; \n transform: scale(1.02);\n }\n}\n</style>\n"],"names":["props","__props","emit","__emit","_createElementBlock","_unref","cn","$slots","_createBlock","JIcon","_renderSlot","_ctx","_openBlock","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","JButton"],"mappings":"+uDA+EA,MAAMA,EAAQC,EAKRC,EAAOC,eAjFHF,EAAA,UAAO,wBADfG,EAAAA,mBAoBM,MAAA,OAlBH,uBAAOC,EAAAA,MAAAC,IAAA,yHAAsJN,EAAM,KAAA,KAQ5JC,EAAA,MAAQM,EAAAA,OAAO,oBADvBC,EAAAA,YAMQH,QAAAI,EAAAA,OAAA,EAAA,OAJL,KAAMR,EAAA,MAAI,QACX,MAAM,sCAAA,qBAEN,IAAoB,CAApBS,EAAAA,WAAoBC,EAAA,OAAA,OAAA,CAAA,EAAA,OAAA,EAAA,CAAA,iDAGbV,EAAA,OAASM,EAAAA,OAAO,OAAzBK,EAAAA,YAAAR,EAAAA,mBAEI,IAFJS,EAEI,CADFH,EAAAA,WAAqCC,oBAArC,IAAqC,qCAAfV,EAAA,KAAK,EAAA,CAAA,CAAA,yDAK/BG,EAAAA,mBA8CM,MAAA,OA5CH,uBAAOC,EAAAA,MAAAC,IAAA,0JAA4MN,EAAM,KAAA,KAW/MC,EAAA,MAAQM,EAAAA,OAAO,MAA1BK,EAAAA,YAAAR,EAAAA,mBAQM,MARNU,EAQM,CAPJJ,EAAAA,WAMOC,mBANP,IAMO,CAJGV,EAAA,oBADRO,EAAAA,YAIEH,EAAAA,MAAAI,EAAAA,OAAA,EAAA,OAFC,KAAMR,EAAA,KACP,MAAM,iCAAA,oFAMFA,EAAA,OAASM,EAAAA,OAAO,OAA1BK,EAAAA,YAAAR,EAAAA,mBAGK,KAHLW,EAGK,CADHL,EAAAA,WAAqCC,oBAArC,IAAqC,qCAAfV,EAAA,KAAK,EAAA,CAAA,CAAA,qCAIpBA,EAAA,aAAeM,EAAAA,OAAO,aAA/BK,EAAAA,YAAAR,EAAAA,mBAGI,IAHJY,EAGI,CADFN,EAAAA,WAAiDC,0BAAjD,IAAiD,qCAArBV,EAAA,WAAW,EAAA,CAAA,CAAA,qCAIzCS,EAAAA,WASOC,qBATP,IASO,CAPGV,EAAA,0BADRO,EAAAA,YAOUH,EAAAA,MAAAY,EAAAA,OAAA,EAAA,OALR,UAAU,UACV,KAAK,KACJ,uBAAOf,EAAI,QAAA,EAAA,qBAEZ,IAAgB,qCAAbD,EAAA,UAAU,EAAA,CAAA,CAAA"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { defineComponent as $, createElementBlock as r, openBlock as o, normalizeClass as u, unref as m, createBlock as a, createCommentVNode as i, withCtx as p, renderSlot as s, createTextVNode as n, toDisplayString as l } from "vue";
|
|
2
|
+
import b from "../atoms/JButton.vue.js";
|
|
3
|
+
import "../shadcn/index.js";
|
|
4
|
+
import "lucide-vue-next";
|
|
5
|
+
import { cn as f } from "../../lib/utils.js";
|
|
6
|
+
import "@internationalized/date";
|
|
7
|
+
import "md-editor-v3";
|
|
8
|
+
/* empty css */
|
|
9
|
+
/* empty css */
|
|
10
|
+
import "../shadcn/badge-variants.js";
|
|
11
|
+
import "@vueuse/core";
|
|
12
|
+
import "reka-ui";
|
|
13
|
+
/* empty css */
|
|
14
|
+
import "../shadcn/avatar-variants.js";
|
|
15
|
+
import y from "../atoms/JIcon.vue.js";
|
|
16
|
+
import "dompurify";
|
|
17
|
+
/* empty css */
|
|
18
|
+
import "ag-grid-vue3";
|
|
19
|
+
import "ag-grid-community";
|
|
20
|
+
import "ag-grid-enterprise";
|
|
21
|
+
/* empty css */
|
|
22
|
+
/* empty css */
|
|
23
|
+
/* empty css */
|
|
24
|
+
/* empty css */
|
|
25
|
+
/* empty css */
|
|
26
|
+
/* empty css */
|
|
27
|
+
import "vue-sonner";
|
|
28
|
+
const g = {
|
|
29
|
+
key: 1,
|
|
30
|
+
class: "text-sm text-muted-foreground"
|
|
31
|
+
}, h = {
|
|
32
|
+
key: 0,
|
|
33
|
+
class: "j-empty-icon-wrapper"
|
|
34
|
+
}, v = {
|
|
35
|
+
key: 1,
|
|
36
|
+
class: "text-xl font-semibold text-foreground mb-2 tracking-tight"
|
|
37
|
+
}, w = {
|
|
38
|
+
key: 2,
|
|
39
|
+
class: "text-sm text-muted-foreground mb-6 max-w-sm leading-relaxed"
|
|
40
|
+
}, Z = /* @__PURE__ */ $({
|
|
41
|
+
__name: "JEmptyState",
|
|
42
|
+
props: {
|
|
43
|
+
icon: { default: "inbox" },
|
|
44
|
+
title: {},
|
|
45
|
+
description: {},
|
|
46
|
+
actionText: {},
|
|
47
|
+
variant: { default: "default" },
|
|
48
|
+
class: {}
|
|
49
|
+
},
|
|
50
|
+
emits: ["action"],
|
|
51
|
+
setup(t, { emit: x }) {
|
|
52
|
+
const c = t, k = x;
|
|
53
|
+
return (e, d) => t.variant === "simple" ? (o(), r("div", {
|
|
54
|
+
key: 0,
|
|
55
|
+
class: u(m(f)(
|
|
56
|
+
"j-empty-state-simple",
|
|
57
|
+
"flex flex-col items-center justify-center p-8 text-center",
|
|
58
|
+
"rounded-sm border-4 border-dashed",
|
|
59
|
+
c.class
|
|
60
|
+
))
|
|
61
|
+
}, [
|
|
62
|
+
t.icon || e.$slots.icon ? (o(), a(m(y), {
|
|
63
|
+
key: 0,
|
|
64
|
+
name: t.icon || "inbox",
|
|
65
|
+
class: "w-12 h-12 text-muted-foreground mb-3"
|
|
66
|
+
}, {
|
|
67
|
+
default: p(() => [
|
|
68
|
+
s(e.$slots, "icon", {}, void 0, !0)
|
|
69
|
+
]),
|
|
70
|
+
_: 3
|
|
71
|
+
}, 8, ["name"])) : i("", !0),
|
|
72
|
+
t.title || e.$slots.title ? (o(), r("p", g, [
|
|
73
|
+
s(e.$slots, "title", {}, () => [
|
|
74
|
+
n(l(t.title), 1)
|
|
75
|
+
], !0)
|
|
76
|
+
])) : i("", !0)
|
|
77
|
+
], 2)) : (o(), r("div", {
|
|
78
|
+
key: 1,
|
|
79
|
+
class: u(m(f)(
|
|
80
|
+
"j-empty-state",
|
|
81
|
+
"flex flex-col items-center justify-center",
|
|
82
|
+
"p-12 text-center",
|
|
83
|
+
"max-w-lg mx-auto",
|
|
84
|
+
"rounded-sm border border-border",
|
|
85
|
+
"bg-card shadow-sm",
|
|
86
|
+
c.class
|
|
87
|
+
))
|
|
88
|
+
}, [
|
|
89
|
+
t.icon || e.$slots.icon ? (o(), r("div", h, [
|
|
90
|
+
s(e.$slots, "icon", {}, () => [
|
|
91
|
+
t.icon ? (o(), a(m(y), {
|
|
92
|
+
key: 0,
|
|
93
|
+
name: t.icon,
|
|
94
|
+
class: "w-12 h-12 text-muted-foreground"
|
|
95
|
+
}, null, 8, ["name"])) : i("", !0)
|
|
96
|
+
], !0)
|
|
97
|
+
])) : i("", !0),
|
|
98
|
+
t.title || e.$slots.title ? (o(), r("h3", v, [
|
|
99
|
+
s(e.$slots, "title", {}, () => [
|
|
100
|
+
n(l(t.title), 1)
|
|
101
|
+
], !0)
|
|
102
|
+
])) : i("", !0),
|
|
103
|
+
t.description || e.$slots.description ? (o(), r("p", w, [
|
|
104
|
+
s(e.$slots, "description", {}, () => [
|
|
105
|
+
n(l(t.description), 1)
|
|
106
|
+
], !0)
|
|
107
|
+
])) : i("", !0),
|
|
108
|
+
s(e.$slots, "action", {}, () => [
|
|
109
|
+
t.actionText ? (o(), a(m(b), {
|
|
110
|
+
key: 0,
|
|
111
|
+
styletype: "primary",
|
|
112
|
+
size: "sm",
|
|
113
|
+
onClick: d[0] || (d[0] = (j) => k("action"))
|
|
114
|
+
}, {
|
|
115
|
+
default: p(() => [
|
|
116
|
+
n(l(t.actionText), 1)
|
|
117
|
+
]),
|
|
118
|
+
_: 1
|
|
119
|
+
})) : i("", !0)
|
|
120
|
+
], !0)
|
|
121
|
+
], 2));
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
export {
|
|
125
|
+
Z as default
|
|
126
|
+
};
|
|
127
|
+
//# sourceMappingURL=JEmptyState.vue2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"JEmptyState.vue2.js","sources":["../../../../src/components/molecules/JEmptyState.vue"],"sourcesContent":["<template>\n <!-- Simple variant: 아이콘 + 텍스트만 -->\n <div \n v-if=\"variant === 'simple'\"\n :class=\"cn(\n 'j-empty-state-simple',\n 'flex flex-col items-center justify-center p-8 text-center',\n 'rounded-sm border-4 border-dashed',\n props.class\n )\"\n >\n <JIcon \n v-if=\"icon || $slots.icon\" \n :name=\"icon || 'inbox'\" \n class=\"w-12 h-12 text-muted-foreground mb-3\"\n >\n <slot name=\"icon\" />\n </JIcon>\n \n <p v-if=\"title || $slots.title\" class=\"text-sm text-muted-foreground\">\n <slot name=\"title\">{{ title }}</slot>\n </p>\n </div>\n\n <!-- Default variant: 풀 스타일 -->\n <div \n v-else\n :class=\"cn(\n 'j-empty-state',\n 'flex flex-col items-center justify-center',\n 'p-12 text-center',\n 'max-w-lg mx-auto',\n 'rounded-sm border border-border',\n 'bg-card shadow-sm',\n props.class\n )\"\n >\n <!-- 아이콘 (원형 배경) -->\n <div v-if=\"icon || $slots.icon\" class=\"j-empty-icon-wrapper\">\n <slot name=\"icon\">\n <JIcon \n v-if=\"icon\" \n :name=\"icon\" \n class=\"w-12 h-12 text-muted-foreground\"\n />\n </slot>\n </div>\n\n <!-- 제목 -->\n <h3 v-if=\"title || $slots.title\" \n class=\"text-xl font-semibold text-foreground mb-2 tracking-tight\">\n <slot name=\"title\">{{ title }}</slot>\n </h3>\n\n <!-- 설명 -->\n <p v-if=\"description || $slots.description\" \n class=\"text-sm text-muted-foreground mb-6 max-w-sm leading-relaxed\">\n <slot name=\"description\">{{ description }}</slot>\n </p>\n\n <!-- 액션 버튼 -->\n <slot name=\"action\">\n <JButton \n v-if=\"actionText\" \n styletype=\"primary\"\n size=\"sm\"\n @click=\"emit('action')\"\n >\n {{ actionText }}\n </JButton>\n </slot>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { JIcon, JButton } from '@/components/atoms'\nimport { cn } from '@/lib/utils'\nimport type { JEmptyStateProps, JEmptyStateEmits } from '@/types/empty-state.types'\n\nconst props = withDefaults(defineProps<JEmptyStateProps>(), {\n icon: 'inbox',\n variant: 'default',\n})\n\nconst emit = defineEmits<JEmptyStateEmits>()\n</script>\n\n<style scoped>\n.j-empty-state {\n transition: all 0.2s ease;\n}\n\n.j-empty-state-simple {\n border-color: hsl(var(--border) / 0.5);\n background: hsl(var(--muted) / 0.1);\n transition: all 0.2s ease;\n}\n\n.j-empty-state-simple:hover {\n border-color: hsl(var(--border) / 0.8);\n background: hsl(var(--muted) / 0.15);\n}\n\n.j-empty-icon-wrapper {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 5rem;\n height: 5rem;\n margin-bottom: 1.5rem;\n border-radius: 9999px;\n background: linear-gradient(135deg, \n hsl(var(--primary) / 0.08) 0%, \n hsl(var(--primary) / 0.02) 100%);\n border: 1px solid hsl(var(--border));\n}\n\n@media (prefers-reduced-motion: no-preference) {\n .j-empty-icon-wrapper {\n animation: pulse 3s ease-in-out infinite;\n }\n}\n\n@keyframes pulse {\n 0%, 100% { \n opacity: 1; \n transform: scale(1);\n }\n 50% { \n opacity: 0.85; \n transform: scale(1.02);\n }\n}\n</style>\n"],"names":["props","__props","emit","__emit","_createElementBlock","_unref","cn","$slots","_createBlock","JIcon","_renderSlot","_ctx","_openBlock","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","JButton"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+EA,UAAMA,IAAQC,GAKRC,IAAOC;qBAjFHF,EAAA,YAAO,iBADfG,EAoBM,OAAA;AAAA;MAlBH,SAAOC,EAAAC,CAAA;AAAA;;;QAAsJN,EAAM;AAAA,MAAA;;MAQ5JC,EAAA,QAAQM,EAAAA,OAAO,aADvBC,EAMQH,EAAAI,CAAA,GAAA;AAAA;QAJL,MAAMR,EAAA,QAAI;AAAA,QACX,OAAM;AAAA,MAAA;mBAEN,MAAoB;AAAA,UAApBS,EAAoBC,EAAA,QAAA,QAAA,CAAA,GAAA,QAAA,EAAA;AAAA,QAAA;;;MAGbV,EAAA,SAASM,EAAAA,OAAO,SAAzBK,KAAAR,EAEI,KAFJS,GAEI;AAAA,QADFH,EAAqCC,uBAArC,MAAqC;AAAA,cAAfV,EAAA,KAAK,GAAA,CAAA;AAAA,QAAA;;mBAK/BG,EA8CM,OAAA;AAAA;MA5CH,SAAOC,EAAAC,CAAA;AAAA;;;;;;QAA4MN,EAAM;AAAA,MAAA;;MAW/MC,EAAA,QAAQM,EAAAA,OAAO,QAA1BK,KAAAR,EAQM,OARNU,GAQM;AAAA,QAPJJ,EAMOC,sBANP,MAMO;AAAA,UAJGV,EAAA,aADRO,EAIEH,EAAAI,CAAA,GAAA;AAAA;YAFC,MAAMR,EAAA;AAAA,YACP,OAAM;AAAA,UAAA;;;MAMFA,EAAA,SAASM,EAAAA,OAAO,SAA1BK,KAAAR,EAGK,MAHLW,GAGK;AAAA,QADHL,EAAqCC,uBAArC,MAAqC;AAAA,cAAfV,EAAA,KAAK,GAAA,CAAA;AAAA,QAAA;;MAIpBA,EAAA,eAAeM,EAAAA,OAAO,eAA/BK,KAAAR,EAGI,KAHJY,GAGI;AAAA,QADFN,EAAiDC,6BAAjD,MAAiD;AAAA,cAArBV,EAAA,WAAW,GAAA,CAAA;AAAA,QAAA;;MAIzCS,EASOC,wBATP,MASO;AAAA,QAPGV,EAAA,mBADRO,EAOUH,EAAAY,CAAA,GAAA;AAAA;UALR,WAAU;AAAA,UACV,MAAK;AAAA,UACJ,gCAAOf,EAAI,QAAA;AAAA,QAAA;qBAEZ,MAAgB;AAAA,gBAAbD,EAAA,UAAU,GAAA,CAAA;AAAA,UAAA;;;;;;;"}
|
|
@@ -1,2 +1,7 @@
|
|
|
1
|
-
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("
|
|
1
|
+
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("./JFormField.vue2.cjs");;/* empty css */const t = (t_comp, t_opts) => {
|
|
2
|
+
const t_merged = t_comp.__vccOpts || t_comp;
|
|
3
|
+
for (const [t_key, t_val] of t_opts)
|
|
4
|
+
t_merged[t_key] = t_val;
|
|
5
|
+
return t_merged;
|
|
6
|
+
};,u=t(e.default,[["__scopeId","data-v-9053fa66"]]);exports.default=u;
|
|
2
7
|
//# sourceMappingURL=JFormField.vue.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JFormField.vue.cjs","sources":["../../../../src/components/molecules/JFormField.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, ref } from 'vue'\nimport { Field, FieldContent, FieldLabel, FieldDescription, FieldError, FieldGroup } from '@/components/shadcn'\nimport { JInput, JTextarea, JCheckbox, JSwitch, JCombo, JRadio, JSearchCombo, JDatepicker } from '@/components/atoms'\n\n// 컴포넌트 타입 정의\ntype ComponentType = 'input' | 'textarea' | 'checkbox' | 'switch' | 'combo' | 'radio' | 'searchCombo' | 'datepicker'\n\n// FormField 자체의 props (레이아웃 관련)\nconst FORM_FIELD_PROPS = [\n 'label',\n 'description',\n 'errorMsg',\n 'type',\n 'inlineLabel',\n 'orientation',\n 'labelAlign',\n 'labelWidth',\n 'radioDirection',\n] as const\n\nconst props = withDefaults(\n defineProps<{\n // ============ FormField 자체 props (레이아웃만) ============\n /** 필드 레이블 */\n label?: string\n /** 필드 설명 (레이블 아래 표시) */\n description?: string\n /** 에러 메시지 */\n errorMsg?: string\n /** 컴포넌트 타입 (렌더링할 컴포넌트 지정) */\n type?: ComponentType\n /** 체크박스/스위치 타입일 때만 사용하는 옆 라벨 */\n inlineLabel?: string\n /** 레이블과 컨트롤의 배치 방향 */\n orientation?: 'vertical' | 'horizontal' | 'responsive'\n /** 레이블 텍스트 정렬 */\n labelAlign?: 'left' | 'middle' | 'right'\n /** 레이블 영역 너비 (horizontal orientation일 때만 적용) */\n labelWidth?: string\n\n // ============ 내부 컴포넌트로 전달할 공통 props ============\n /** Input 요소의 id (label for와 연결) */\n id?: string\n /** v-model로 양방향 데이터 바인딩 */\n modelValue?: any\n /** 입력 전 표시되는 안내문 (Input/Textarea/Select/Combobox) */\n placeholder?: string\n /** 비활성화 상태 (전체) */\n disabled?: boolean\n /** 읽기 전용 상태 (Input/Textarea) */\n readonly?: boolean\n /** 필수 입력/선택 여부 (전체) */\n required?: boolean\n /** form 데이터 전송 시 키 이름 (전체) */\n name?: string\n /** 스타일 테마 지정 (J-prefixed 컴포넌트의 styleType) */\n styleType?: string\n\n // ============ Input 전용 props ============\n /** Input 타입 (text, email, password 등) */\n inputType?: string\n\n\n // ============ Select/Combobox/Radio 전용 props ============\n /** 선택 가능한 항목 배열 */\n options?: Array<{ label: string; value: string | number; disabled?: boolean }>\n \n // ============ Select/Combobox 전용 props ============\n /** 다중 선택 허용 여부 */\n multiple?: boolean\n\n\n // ============ Radio 전용 props ============\n /** Radio 옵션 나열 방향 */\n radioDirection?: 'horizontal' | 'vertical'\n }>(),\n {\n type: 'input',\n orientation: 'vertical',\n labelAlign: 'left',\n labelWidth: '8rem',\n radioDirection: 'horizontal',\n }\n)\n\n// 이벤트 정의\nconst emit = defineEmits<{\n 'update:modelValue': [value: any]\n 'change': [value: any]\n 'focus': [event: FocusEvent]\n 'blur': [event: FocusEvent]\n}>()\n\n// 내부 에러 상태 (props.error가 없을 때만 사용)\nconst internalError = ref<string>('')\n\n// 최종 에러 메시지 (외부 errorMsg가 우선)\nconst finalError = computed(() => props.errorMsg || internalError.value)\n\n// FormField 자체 props와 내부 컴포넌트 props 분리\nconst controlProps = computed(() => {\n const result: Record<string, any> = {}\n const propsObj = props as Record<string, any>\n \n for (const key in propsObj) {\n // FormField 자체 props는 제외\n if (!FORM_FIELD_PROPS.includes(key as any)) {\n result[key] = propsObj[key]\n }\n }\n \n // inputType을 type으로 변환 (JInput 컴포넌트에서 사용)\n if (props.inputType && props.type === 'input') {\n result.type = props.inputType\n delete result.inputType // inputType은 제거\n \n // placeholder가 없으면 inputType에 따라 기본값 설정\n if (!props.placeholder) {\n const defaultPlaceholders: Record<string, string> = {\n 'text': '텍스트를 입력하세요',\n 'email': '이메일을 입력하세요',\n 'password': '비밀번호를 입력하세요',\n 'tel': '전화번호를 입력하세요',\n 'url': 'URL을 입력하세요',\n 'number': '숫자를 입력하세요',\n 'search': '검색어를 입력하세요',\n 'date': '날짜를 선택하세요',\n 'time': '시간을 선택하세요',\n 'datetime-local': '날짜와 시간을 선택하세요',\n 'month': '월을 선택하세요',\n 'week': '주를 선택하세요',\n }\n \n result.placeholder = defaultPlaceholders[props.inputType] || '입력하세요'\n }\n }\n \n // radioDirection을 styletype으로 변환 (JRadio 컴포넌트에서 사용)\n if (props.radioDirection && props.type === 'radio') {\n result.styletype = props.radioDirection\n delete result.radioDirection // radioDirection은 제거\n }\n \n return result\n})\n\n // Built-in validation\n const validateField = (currentValue?: any) => {\n if (!props.required) return\n\n internalError.value = ''\n\n // 현재 값 또는 props.modelValue 사용\n const value = currentValue !== undefined ? currentValue : props.modelValue\n\n // Required 체크\n if (props.type === 'checkbox' || props.type === 'switch') {\n if (value !== 'Y') {\n internalError.value = '필수 항목입니다.'\n }\n } else {\n if (value === null || value === undefined || value === '') {\n internalError.value = '필수 입력 항목입니다.'\n }\n }\n }\n\n // 초기 로드 시 validation 실행 (blur 이벤트에서만)\n const shouldValidateOnMount = computed(() => {\n // Storybook에서 초기값이 있는 경우 validation 스킵\n if (props.modelValue !== null && props.modelValue !== undefined && props.modelValue !== '') {\n return false\n }\n return true\n })\n\n// 이벤트 핸들러\nconst handleUpdateModelValue = (value: any) => {\n emit('update:modelValue', value)\n \n // 값이 변경되면 즉시 validation 실행 (현재 값 전달)\n validateField(value)\n}\n\nconst handleChange = (value: any) => {\n emit('change', value)\n \n // change 이벤트에서도 validation 실행 (현재 값 전달)\n validateField(value)\n}\n\nconst handleFocus = (event: FocusEvent) => {\n emit('focus', event)\n}\n\n const handleBlur = (event: FocusEvent) => {\n // blur 시에만 validation 실행 (초기 로드 시에는 실행하지 않음)\n if (shouldValidateOnMount.value) {\n validateField()\n }\n emit('blur', event)\n }\n\n// 레이블 정렬 클래스 (레이블 영역 내에서 레이블의 위치 제어)\nconst labelAlignClass = computed(() => {\n // horizontal일 때는 레이블 영역 내에서 레이블의 위치를 제어\n const mapHorizontal = { \n left: 'justify-start', // 레이블 영역의 왼쪽에 레이블 위치\n middle: 'justify-center', // 레이블 영역의 가운데에 레이블 위치\n right: 'justify-end' // 레이블 영역의 오른쪽에 레이블 위치 (input과 가까이)\n }\n // vertical일 때는 텍스트 정렬만 제어\n const mapVertical = { left: 'text-left', middle: 'text-center', right: 'text-right' }\n return props.orientation === 'horizontal' ? mapHorizontal[props.labelAlign] : mapVertical[props.labelAlign]\n})\n\n/** 행높이 토큰 클래스 매핑 */\nconst densityClass = computed(() => {\n switch (props.styleType) {\n case 'sm': return 'form-density-sm'\n case 'lg': return 'form-density-lg'\n default: return 'form-density-md'\n }\n})\n\n/** 컨트롤 클래스 (datepicker는 최대 너비 제한, radio vertical은 높이 제한 없음) */\nconst controlClass = computed(() => {\n const baseClass = 'h-[var(--ctl-h)] leading-[var(--ctl-h)]'\n \n if (props.type === 'datepicker') {\n return `${baseClass} max-w-xs`\n }\n \n // Radio vertical일 때는 높이 제한 없음\n if (props.type === 'radio' && props.radioDirection === 'vertical') {\n return ''\n }\n \n return baseClass\n})\n\n// 컴포넌트 매핑\nconst componentMap: Record<ComponentType, any> = {\n input: JInput,\n textarea: JTextarea,\n checkbox: JCheckbox,\n switch: JSwitch,\n combo: JCombo,\n radio: JRadio,\n searchCombo: JSearchCombo,\n datepicker: JDatepicker,\n}\n\n// type에 따라 렌더링할 컴포넌트 결정\nconst resolvedComponent = computed(() => {\n return componentMap[props.type!] || JInput\n})\n\n// 외부에서 수동으로 에러 클리어 가능하도록 expose\ndefineExpose({\n clearError: () => { internalError.value = '' }\n})\n</script>\n\n<template>\n <div :class=\"['space-y-2 flex-1 min-w-0', densityClass]\">\n <FieldGroup >\n <Field :class=\"[\n orientation === 'horizontal'\n ? 'grid grid-cols-[var(--label-w,8rem)_1fr] items-start space-y-0 gap-2'\n : 'space-y-1 gap-1'\n ]\"\n :style=\"orientation === 'horizontal' ? `--label-w:${labelWidth};` : ''\"\n >\n <!-- 메인 라벨 (필수표기 포함) -->\n <FieldLabel \n :for=\"id\" \n :class=\"[\n orientation === 'horizontal'\n ? 'flex items-center h-[var(--ctl-h)] w-full'\n : 'flex items-center',\n labelAlignClass\n ]\"\n >\n {{ label }}\n <span v-if=\"required\" class=\"text-destructive ml-1\">*</span>\n </FieldLabel>\n\n <FieldContent \n :class=\"[\n orientation === 'horizontal'\n ? 'min-h-[var(--ctl-h)] flex flex-col justify-start gap-0.5 mt-0'\n : 'space-y-2 gap-0'\n ]\"\n >\n <!-- 체크박스/스위치: 항상 가로 정렬로 컨트롤 + 인라인 라벨 묶기 -->\n <FieldGroup v-if=\"type === 'checkbox' || type === 'switch'\" data-slot=\"checkbox-group\">\n <!-- 부모 orientation과 무관하게 수평 정렬 고정 -->\n <Field orientation=\"horizontal\" class=\"flex gap-2 space-y-0 h-[var(--ctl-h)] leading-[var(--ctl-h)] items-center\">\n <component\n :is=\"resolvedComponent\"\n v-bind=\"controlProps\"\n @update:modelValue=\"handleUpdateModelValue\"\n @change=\"handleChange\"\n @focus=\"handleFocus\"\n @blur=\"handleBlur\"\n />\n <FieldLabel\n v-if=\"inlineLabel\"\n :for=\"id\"\n class=\"font-normal m-0 h-[var(--ctl-h)] leading-[var(--ctl-h)]\"\n >\n {{ inlineLabel }}\n </FieldLabel>\n </Field>\n </FieldGroup>\n\n <!-- Radio 버튼: radioDirection에 따라 분기 처리 -->\n <FieldGroup v-else-if=\"type === 'radio'\">\n <component\n :is=\"resolvedComponent\"\n v-bind=\"controlProps\"\n @update:modelValue=\"handleUpdateModelValue\"\n @change=\"handleChange\"\n @focus=\"handleFocus\"\n @blur=\"handleBlur\"\n :class=\"controlClass\"\n />\n </FieldGroup>\n\n <!-- 그 외 컨트롤: orientation 규칙 그대로 따름 -->\n <FieldGroup v-else>\n <component\n :is=\"resolvedComponent\"\n v-bind=\"controlProps\"\n @update:modelValue=\"handleUpdateModelValue\"\n @change=\"handleChange\"\n @focus=\"handleFocus\"\n @blur=\"handleBlur\"\n :class=\"controlClass\"\n />\n </FieldGroup>\n \n <!-- 설명/에러: 항상 컨트롤 '바로 아래'에 표시 -->\n <FieldContent v-if=\"description || finalError\">\n <FieldDescription v-if=\"description\">\n {{ description }}\n </FieldDescription>\n <FieldError v-if=\"finalError\">\n {{ finalError }}\n </FieldError>\n </FieldContent>\n </FieldContent>\n </Field>\n </FieldGroup>\n </div>\n</template>\n\n\n\n<style>\n/* ⬇⬇ 높이 토큰(밀도) — 프로젝트 전역/레이아웃에 한 번 정의해두고 재사용하세요 */\n.form-density-sm { --ctl-h: 2rem; /* 32px */ }\n.form-density-md { --ctl-h: 2.25rem; /* 36px (shadcn 기본에 근접) */ }\n.form-density-lg { --ctl-h: 2.5rem; /* 40px */ }\n</style>"],"names":["FORM_FIELD_PROPS","props","__props","emit","__emit","internalError","ref","finalError","computed","controlProps","result","propsObj","key","defaultPlaceholders","validateField","currentValue","value","shouldValidateOnMount","handleUpdateModelValue","handleChange","handleFocus","event","handleBlur","labelAlignClass","mapHorizontal","mapVertical","densityClass","controlClass","baseClass","componentMap","JInput","JTextarea","JCheckbox","JSwitch","JCombo","JRadio","JSearchCombo","JDatepicker","resolvedComponent","__expose","_createElementBlock","_createVNode","_unref","FieldGroup","Field","_normalizeClass","_normalizeStyle","FieldLabel","_createTextVNode","_toDisplayString","_hoisted_1","FieldContent","_createBlock","_openBlock","_resolveDynamicComponent","_mergeProps","FieldDescription","FieldError"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"JFormField.vue.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
|
@@ -1,265 +1,13 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
import G from "../atoms/JSwitch.vue.js";
|
|
11
|
-
import K from "../atoms/JDatepicker.vue.js";
|
|
12
|
-
import "md-editor-v3";
|
|
13
|
-
/* empty css */
|
|
14
|
-
/* empty css */
|
|
15
|
-
import "clsx";
|
|
16
|
-
import "tailwind-merge";
|
|
17
|
-
import "../shadcn/badge-variants.js";
|
|
18
|
-
import "@vueuse/core";
|
|
19
|
-
import "reka-ui";
|
|
20
|
-
/* empty css */
|
|
21
|
-
import "../shadcn/avatar-variants.js";
|
|
22
|
-
import "dompurify";
|
|
23
|
-
/* empty css */
|
|
24
|
-
import "ag-grid-vue3";
|
|
25
|
-
import "ag-grid-community";
|
|
26
|
-
import "ag-grid-enterprise";
|
|
27
|
-
/* empty css */
|
|
28
|
-
/* empty css */
|
|
29
|
-
/* empty css */
|
|
30
|
-
/* empty css */
|
|
31
|
-
import "vue-sonner";
|
|
32
|
-
import v from "../shadcn/FieldGroup.vue.js";
|
|
33
|
-
import T from "../shadcn/Field.vue.js";
|
|
34
|
-
import M from "../shadcn/FieldLabel.vue.js";
|
|
35
|
-
import L from "../shadcn/FieldContent.vue.js";
|
|
36
|
-
import Q from "../shadcn/FieldDescription.vue.js";
|
|
37
|
-
import X from "../shadcn/FieldError.vue.js";
|
|
38
|
-
const Z = {
|
|
39
|
-
key: 0,
|
|
40
|
-
class: "text-destructive ml-1"
|
|
41
|
-
}, Pe = /* @__PURE__ */ N({
|
|
42
|
-
__name: "JFormField",
|
|
43
|
-
props: {
|
|
44
|
-
label: {},
|
|
45
|
-
description: {},
|
|
46
|
-
errorMsg: {},
|
|
47
|
-
type: { default: "input" },
|
|
48
|
-
inlineLabel: {},
|
|
49
|
-
orientation: { default: "vertical" },
|
|
50
|
-
labelAlign: { default: "left" },
|
|
51
|
-
labelWidth: { default: "8rem" },
|
|
52
|
-
id: {},
|
|
53
|
-
modelValue: {},
|
|
54
|
-
placeholder: {},
|
|
55
|
-
disabled: { type: Boolean },
|
|
56
|
-
readonly: { type: Boolean },
|
|
57
|
-
required: { type: Boolean },
|
|
58
|
-
name: {},
|
|
59
|
-
styleType: {},
|
|
60
|
-
inputType: {},
|
|
61
|
-
options: {},
|
|
62
|
-
multiple: { type: Boolean },
|
|
63
|
-
radioDirection: { default: "horizontal" }
|
|
64
|
-
},
|
|
65
|
-
emits: ["update:modelValue", "change", "focus", "blur"],
|
|
66
|
-
setup(l, { expose: j, emit: A }) {
|
|
67
|
-
const E = [
|
|
68
|
-
"label",
|
|
69
|
-
"description",
|
|
70
|
-
"errorMsg",
|
|
71
|
-
"type",
|
|
72
|
-
"inlineLabel",
|
|
73
|
-
"orientation",
|
|
74
|
-
"labelAlign",
|
|
75
|
-
"labelWidth",
|
|
76
|
-
"radioDirection"
|
|
77
|
-
], t = l, f = A, s = R(""), g = c(() => t.errorMsg || s.value), b = c(() => {
|
|
78
|
-
const e = {}, r = t;
|
|
79
|
-
for (const m in r)
|
|
80
|
-
E.includes(m) || (e[m] = r[m]);
|
|
81
|
-
if (t.inputType && t.type === "input" && (e.type = t.inputType, delete e.inputType, !t.placeholder)) {
|
|
82
|
-
const m = {
|
|
83
|
-
text: "텍스트를 입력하세요",
|
|
84
|
-
email: "이메일을 입력하세요",
|
|
85
|
-
password: "비밀번호를 입력하세요",
|
|
86
|
-
tel: "전화번호를 입력하세요",
|
|
87
|
-
url: "URL을 입력하세요",
|
|
88
|
-
number: "숫자를 입력하세요",
|
|
89
|
-
search: "검색어를 입력하세요",
|
|
90
|
-
date: "날짜를 선택하세요",
|
|
91
|
-
time: "시간을 선택하세요",
|
|
92
|
-
"datetime-local": "날짜와 시간을 선택하세요",
|
|
93
|
-
month: "월을 선택하세요",
|
|
94
|
-
week: "주를 선택하세요"
|
|
95
|
-
};
|
|
96
|
-
e.placeholder = m[t.inputType] || "입력하세요";
|
|
97
|
-
}
|
|
98
|
-
return t.radioDirection && t.type === "radio" && (e.styletype = t.radioDirection, delete e.radioDirection), e;
|
|
99
|
-
}), x = (e) => {
|
|
100
|
-
if (!t.required) return;
|
|
101
|
-
s.value = "";
|
|
102
|
-
const r = e !== void 0 ? e : t.modelValue;
|
|
103
|
-
t.type === "checkbox" || t.type === "switch" ? r !== "Y" && (s.value = "필수 항목입니다.") : (r == null || r === "") && (s.value = "필수 입력 항목입니다.");
|
|
104
|
-
}, P = c(() => !(t.modelValue !== null && t.modelValue !== void 0 && t.modelValue !== "")), k = (e) => {
|
|
105
|
-
f("update:modelValue", e), x(e);
|
|
106
|
-
}, _ = (e) => {
|
|
107
|
-
f("change", e), x(e);
|
|
108
|
-
}, $ = (e) => {
|
|
109
|
-
f("focus", e);
|
|
110
|
-
}, C = (e) => {
|
|
111
|
-
P.value && x(), f("blur", e);
|
|
112
|
-
}, U = c(() => {
|
|
113
|
-
const e = {
|
|
114
|
-
left: "justify-start",
|
|
115
|
-
// 레이블 영역의 왼쪽에 레이블 위치
|
|
116
|
-
middle: "justify-center",
|
|
117
|
-
// 레이블 영역의 가운데에 레이블 위치
|
|
118
|
-
right: "justify-end"
|
|
119
|
-
// 레이블 영역의 오른쪽에 레이블 위치 (input과 가까이)
|
|
120
|
-
}, r = { left: "text-left", middle: "text-center", right: "text-right" };
|
|
121
|
-
return t.orientation === "horizontal" ? e[t.labelAlign] : r[t.labelAlign];
|
|
122
|
-
}), O = c(() => {
|
|
123
|
-
switch (t.styleType) {
|
|
124
|
-
case "sm":
|
|
125
|
-
return "form-density-sm";
|
|
126
|
-
case "lg":
|
|
127
|
-
return "form-density-lg";
|
|
128
|
-
default:
|
|
129
|
-
return "form-density-md";
|
|
130
|
-
}
|
|
131
|
-
}), z = c(() => {
|
|
132
|
-
const e = "h-[var(--ctl-h)] leading-[var(--ctl-h)]";
|
|
133
|
-
return t.type === "datepicker" ? `${e} max-w-xs` : t.type === "radio" && t.radioDirection === "vertical" ? "" : e;
|
|
134
|
-
}), q = {
|
|
135
|
-
input: F,
|
|
136
|
-
textarea: W,
|
|
137
|
-
checkbox: H,
|
|
138
|
-
switch: G,
|
|
139
|
-
combo: I,
|
|
140
|
-
radio: Y,
|
|
141
|
-
searchCombo: J,
|
|
142
|
-
datepicker: K
|
|
143
|
-
}, V = c(() => q[t.type] || F);
|
|
144
|
-
return j({
|
|
145
|
-
clearError: () => {
|
|
146
|
-
s.value = "";
|
|
147
|
-
}
|
|
148
|
-
}), (e, r) => (o(), D("div", {
|
|
149
|
-
class: p(["space-y-2 flex-1 min-w-0", O.value])
|
|
150
|
-
}, [
|
|
151
|
-
u(a(v), null, {
|
|
152
|
-
default: i(() => [
|
|
153
|
-
u(a(T), {
|
|
154
|
-
class: p([
|
|
155
|
-
l.orientation === "horizontal" ? "grid grid-cols-[var(--label-w,8rem)_1fr] items-start space-y-0 gap-2" : "space-y-1 gap-1"
|
|
156
|
-
]),
|
|
157
|
-
style: S(l.orientation === "horizontal" ? `--label-w:${l.labelWidth};` : "")
|
|
158
|
-
}, {
|
|
159
|
-
default: i(() => [
|
|
160
|
-
u(a(M), {
|
|
161
|
-
for: l.id,
|
|
162
|
-
class: p([
|
|
163
|
-
l.orientation === "horizontal" ? "flex items-center h-[var(--ctl-h)] w-full" : "flex items-center",
|
|
164
|
-
U.value
|
|
165
|
-
])
|
|
166
|
-
}, {
|
|
167
|
-
default: i(() => [
|
|
168
|
-
y(h(l.label) + " ", 1),
|
|
169
|
-
l.required ? (o(), D("span", Z, "*")) : d("", !0)
|
|
170
|
-
]),
|
|
171
|
-
_: 1
|
|
172
|
-
}, 8, ["for", "class"]),
|
|
173
|
-
u(a(L), {
|
|
174
|
-
class: p([
|
|
175
|
-
l.orientation === "horizontal" ? "min-h-[var(--ctl-h)] flex flex-col justify-start gap-0.5 mt-0" : "space-y-2 gap-0"
|
|
176
|
-
])
|
|
177
|
-
}, {
|
|
178
|
-
default: i(() => [
|
|
179
|
-
l.type === "checkbox" || l.type === "switch" ? (o(), n(a(v), {
|
|
180
|
-
key: 0,
|
|
181
|
-
"data-slot": "checkbox-group"
|
|
182
|
-
}, {
|
|
183
|
-
default: i(() => [
|
|
184
|
-
u(a(T), {
|
|
185
|
-
orientation: "horizontal",
|
|
186
|
-
class: "flex gap-2 space-y-0 h-[var(--ctl-h)] leading-[var(--ctl-h)] items-center"
|
|
187
|
-
}, {
|
|
188
|
-
default: i(() => [
|
|
189
|
-
(o(), n(w(V.value), B(b.value, {
|
|
190
|
-
"onUpdate:modelValue": k,
|
|
191
|
-
onChange: _,
|
|
192
|
-
onFocus: $,
|
|
193
|
-
onBlur: C
|
|
194
|
-
}), null, 16)),
|
|
195
|
-
l.inlineLabel ? (o(), n(a(M), {
|
|
196
|
-
key: 0,
|
|
197
|
-
for: l.id,
|
|
198
|
-
class: "font-normal m-0 h-[var(--ctl-h)] leading-[var(--ctl-h)]"
|
|
199
|
-
}, {
|
|
200
|
-
default: i(() => [
|
|
201
|
-
y(h(l.inlineLabel), 1)
|
|
202
|
-
]),
|
|
203
|
-
_: 1
|
|
204
|
-
}, 8, ["for"])) : d("", !0)
|
|
205
|
-
]),
|
|
206
|
-
_: 1
|
|
207
|
-
})
|
|
208
|
-
]),
|
|
209
|
-
_: 1
|
|
210
|
-
})) : l.type === "radio" ? (o(), n(a(v), { key: 1 }, {
|
|
211
|
-
default: i(() => [
|
|
212
|
-
(o(), n(w(V.value), B(b.value, {
|
|
213
|
-
"onUpdate:modelValue": k,
|
|
214
|
-
onChange: _,
|
|
215
|
-
onFocus: $,
|
|
216
|
-
onBlur: C,
|
|
217
|
-
class: z.value
|
|
218
|
-
}), null, 16, ["class"]))
|
|
219
|
-
]),
|
|
220
|
-
_: 1
|
|
221
|
-
})) : (o(), n(a(v), { key: 2 }, {
|
|
222
|
-
default: i(() => [
|
|
223
|
-
(o(), n(w(V.value), B(b.value, {
|
|
224
|
-
"onUpdate:modelValue": k,
|
|
225
|
-
onChange: _,
|
|
226
|
-
onFocus: $,
|
|
227
|
-
onBlur: C,
|
|
228
|
-
class: z.value
|
|
229
|
-
}), null, 16, ["class"]))
|
|
230
|
-
]),
|
|
231
|
-
_: 1
|
|
232
|
-
})),
|
|
233
|
-
l.description || g.value ? (o(), n(a(L), { key: 3 }, {
|
|
234
|
-
default: i(() => [
|
|
235
|
-
l.description ? (o(), n(a(Q), { key: 0 }, {
|
|
236
|
-
default: i(() => [
|
|
237
|
-
y(h(l.description), 1)
|
|
238
|
-
]),
|
|
239
|
-
_: 1
|
|
240
|
-
})) : d("", !0),
|
|
241
|
-
g.value ? (o(), n(a(X), { key: 1 }, {
|
|
242
|
-
default: i(() => [
|
|
243
|
-
y(h(g.value), 1)
|
|
244
|
-
]),
|
|
245
|
-
_: 1
|
|
246
|
-
})) : d("", !0)
|
|
247
|
-
]),
|
|
248
|
-
_: 1
|
|
249
|
-
})) : d("", !0)
|
|
250
|
-
]),
|
|
251
|
-
_: 1
|
|
252
|
-
}, 8, ["class"])
|
|
253
|
-
]),
|
|
254
|
-
_: 1
|
|
255
|
-
}, 8, ["class", "style"])
|
|
256
|
-
]),
|
|
257
|
-
_: 1
|
|
258
|
-
})
|
|
259
|
-
], 2));
|
|
260
|
-
}
|
|
261
|
-
});
|
|
1
|
+
import o from "./JFormField.vue2.js";
|
|
2
|
+
/* empty css */
|
|
3
|
+
const r = (r_comp, r_opts) => {
|
|
4
|
+
const r_merged = r_comp.__vccOpts || r_comp;
|
|
5
|
+
for (const [r_key, r_val] of r_opts)
|
|
6
|
+
r_merged[r_key] = r_val;
|
|
7
|
+
return r_merged;
|
|
8
|
+
};
|
|
9
|
+
const f = /* @__PURE__ */ r(o, [["__scopeId", "data-v-9053fa66"]]);
|
|
262
10
|
export {
|
|
263
|
-
|
|
11
|
+
f as default
|
|
264
12
|
};
|
|
265
13
|
//# sourceMappingURL=JFormField.vue.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JFormField.vue.js","sources":["../../../../src/components/molecules/JFormField.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, ref } from 'vue'\nimport { Field, FieldContent, FieldLabel, FieldDescription, FieldError, FieldGroup } from '@/components/shadcn'\nimport { JInput, JTextarea, JCheckbox, JSwitch, JCombo, JRadio, JSearchCombo, JDatepicker } from '@/components/atoms'\n\n// 컴포넌트 타입 정의\ntype ComponentType = 'input' | 'textarea' | 'checkbox' | 'switch' | 'combo' | 'radio' | 'searchCombo' | 'datepicker'\n\n// FormField 자체의 props (레이아웃 관련)\nconst FORM_FIELD_PROPS = [\n 'label',\n 'description',\n 'errorMsg',\n 'type',\n 'inlineLabel',\n 'orientation',\n 'labelAlign',\n 'labelWidth',\n 'radioDirection',\n] as const\n\nconst props = withDefaults(\n defineProps<{\n // ============ FormField 자체 props (레이아웃만) ============\n /** 필드 레이블 */\n label?: string\n /** 필드 설명 (레이블 아래 표시) */\n description?: string\n /** 에러 메시지 */\n errorMsg?: string\n /** 컴포넌트 타입 (렌더링할 컴포넌트 지정) */\n type?: ComponentType\n /** 체크박스/스위치 타입일 때만 사용하는 옆 라벨 */\n inlineLabel?: string\n /** 레이블과 컨트롤의 배치 방향 */\n orientation?: 'vertical' | 'horizontal' | 'responsive'\n /** 레이블 텍스트 정렬 */\n labelAlign?: 'left' | 'middle' | 'right'\n /** 레이블 영역 너비 (horizontal orientation일 때만 적용) */\n labelWidth?: string\n\n // ============ 내부 컴포넌트로 전달할 공통 props ============\n /** Input 요소의 id (label for와 연결) */\n id?: string\n /** v-model로 양방향 데이터 바인딩 */\n modelValue?: any\n /** 입력 전 표시되는 안내문 (Input/Textarea/Select/Combobox) */\n placeholder?: string\n /** 비활성화 상태 (전체) */\n disabled?: boolean\n /** 읽기 전용 상태 (Input/Textarea) */\n readonly?: boolean\n /** 필수 입력/선택 여부 (전체) */\n required?: boolean\n /** form 데이터 전송 시 키 이름 (전체) */\n name?: string\n /** 스타일 테마 지정 (J-prefixed 컴포넌트의 styleType) */\n styleType?: string\n\n // ============ Input 전용 props ============\n /** Input 타입 (text, email, password 등) */\n inputType?: string\n\n\n // ============ Select/Combobox/Radio 전용 props ============\n /** 선택 가능한 항목 배열 */\n options?: Array<{ label: string; value: string | number; disabled?: boolean }>\n \n // ============ Select/Combobox 전용 props ============\n /** 다중 선택 허용 여부 */\n multiple?: boolean\n\n\n // ============ Radio 전용 props ============\n /** Radio 옵션 나열 방향 */\n radioDirection?: 'horizontal' | 'vertical'\n }>(),\n {\n type: 'input',\n orientation: 'vertical',\n labelAlign: 'left',\n labelWidth: '8rem',\n radioDirection: 'horizontal',\n }\n)\n\n// 이벤트 정의\nconst emit = defineEmits<{\n 'update:modelValue': [value: any]\n 'change': [value: any]\n 'focus': [event: FocusEvent]\n 'blur': [event: FocusEvent]\n}>()\n\n// 내부 에러 상태 (props.error가 없을 때만 사용)\nconst internalError = ref<string>('')\n\n// 최종 에러 메시지 (외부 errorMsg가 우선)\nconst finalError = computed(() => props.errorMsg || internalError.value)\n\n// FormField 자체 props와 내부 컴포넌트 props 분리\nconst controlProps = computed(() => {\n const result: Record<string, any> = {}\n const propsObj = props as Record<string, any>\n \n for (const key in propsObj) {\n // FormField 자체 props는 제외\n if (!FORM_FIELD_PROPS.includes(key as any)) {\n result[key] = propsObj[key]\n }\n }\n \n // inputType을 type으로 변환 (JInput 컴포넌트에서 사용)\n if (props.inputType && props.type === 'input') {\n result.type = props.inputType\n delete result.inputType // inputType은 제거\n \n // placeholder가 없으면 inputType에 따라 기본값 설정\n if (!props.placeholder) {\n const defaultPlaceholders: Record<string, string> = {\n 'text': '텍스트를 입력하세요',\n 'email': '이메일을 입력하세요',\n 'password': '비밀번호를 입력하세요',\n 'tel': '전화번호를 입력하세요',\n 'url': 'URL을 입력하세요',\n 'number': '숫자를 입력하세요',\n 'search': '검색어를 입력하세요',\n 'date': '날짜를 선택하세요',\n 'time': '시간을 선택하세요',\n 'datetime-local': '날짜와 시간을 선택하세요',\n 'month': '월을 선택하세요',\n 'week': '주를 선택하세요',\n }\n \n result.placeholder = defaultPlaceholders[props.inputType] || '입력하세요'\n }\n }\n \n // radioDirection을 styletype으로 변환 (JRadio 컴포넌트에서 사용)\n if (props.radioDirection && props.type === 'radio') {\n result.styletype = props.radioDirection\n delete result.radioDirection // radioDirection은 제거\n }\n \n return result\n})\n\n // Built-in validation\n const validateField = (currentValue?: any) => {\n if (!props.required) return\n\n internalError.value = ''\n\n // 현재 값 또는 props.modelValue 사용\n const value = currentValue !== undefined ? currentValue : props.modelValue\n\n // Required 체크\n if (props.type === 'checkbox' || props.type === 'switch') {\n if (value !== 'Y') {\n internalError.value = '필수 항목입니다.'\n }\n } else {\n if (value === null || value === undefined || value === '') {\n internalError.value = '필수 입력 항목입니다.'\n }\n }\n }\n\n // 초기 로드 시 validation 실행 (blur 이벤트에서만)\n const shouldValidateOnMount = computed(() => {\n // Storybook에서 초기값이 있는 경우 validation 스킵\n if (props.modelValue !== null && props.modelValue !== undefined && props.modelValue !== '') {\n return false\n }\n return true\n })\n\n// 이벤트 핸들러\nconst handleUpdateModelValue = (value: any) => {\n emit('update:modelValue', value)\n \n // 값이 변경되면 즉시 validation 실행 (현재 값 전달)\n validateField(value)\n}\n\nconst handleChange = (value: any) => {\n emit('change', value)\n \n // change 이벤트에서도 validation 실행 (현재 값 전달)\n validateField(value)\n}\n\nconst handleFocus = (event: FocusEvent) => {\n emit('focus', event)\n}\n\n const handleBlur = (event: FocusEvent) => {\n // blur 시에만 validation 실행 (초기 로드 시에는 실행하지 않음)\n if (shouldValidateOnMount.value) {\n validateField()\n }\n emit('blur', event)\n }\n\n// 레이블 정렬 클래스 (레이블 영역 내에서 레이블의 위치 제어)\nconst labelAlignClass = computed(() => {\n // horizontal일 때는 레이블 영역 내에서 레이블의 위치를 제어\n const mapHorizontal = { \n left: 'justify-start', // 레이블 영역의 왼쪽에 레이블 위치\n middle: 'justify-center', // 레이블 영역의 가운데에 레이블 위치\n right: 'justify-end' // 레이블 영역의 오른쪽에 레이블 위치 (input과 가까이)\n }\n // vertical일 때는 텍스트 정렬만 제어\n const mapVertical = { left: 'text-left', middle: 'text-center', right: 'text-right' }\n return props.orientation === 'horizontal' ? mapHorizontal[props.labelAlign] : mapVertical[props.labelAlign]\n})\n\n/** 행높이 토큰 클래스 매핑 */\nconst densityClass = computed(() => {\n switch (props.styleType) {\n case 'sm': return 'form-density-sm'\n case 'lg': return 'form-density-lg'\n default: return 'form-density-md'\n }\n})\n\n/** 컨트롤 클래스 (datepicker는 최대 너비 제한, radio vertical은 높이 제한 없음) */\nconst controlClass = computed(() => {\n const baseClass = 'h-[var(--ctl-h)] leading-[var(--ctl-h)]'\n \n if (props.type === 'datepicker') {\n return `${baseClass} max-w-xs`\n }\n \n // Radio vertical일 때는 높이 제한 없음\n if (props.type === 'radio' && props.radioDirection === 'vertical') {\n return ''\n }\n \n return baseClass\n})\n\n// 컴포넌트 매핑\nconst componentMap: Record<ComponentType, any> = {\n input: JInput,\n textarea: JTextarea,\n checkbox: JCheckbox,\n switch: JSwitch,\n combo: JCombo,\n radio: JRadio,\n searchCombo: JSearchCombo,\n datepicker: JDatepicker,\n}\n\n// type에 따라 렌더링할 컴포넌트 결정\nconst resolvedComponent = computed(() => {\n return componentMap[props.type!] || JInput\n})\n\n// 외부에서 수동으로 에러 클리어 가능하도록 expose\ndefineExpose({\n clearError: () => { internalError.value = '' }\n})\n</script>\n\n<template>\n <div :class=\"['space-y-2 flex-1 min-w-0', densityClass]\">\n <FieldGroup >\n <Field :class=\"[\n orientation === 'horizontal'\n ? 'grid grid-cols-[var(--label-w,8rem)_1fr] items-start space-y-0 gap-2'\n : 'space-y-1 gap-1'\n ]\"\n :style=\"orientation === 'horizontal' ? `--label-w:${labelWidth};` : ''\"\n >\n <!-- 메인 라벨 (필수표기 포함) -->\n <FieldLabel \n :for=\"id\" \n :class=\"[\n orientation === 'horizontal'\n ? 'flex items-center h-[var(--ctl-h)] w-full'\n : 'flex items-center',\n labelAlignClass\n ]\"\n >\n {{ label }}\n <span v-if=\"required\" class=\"text-destructive ml-1\">*</span>\n </FieldLabel>\n\n <FieldContent \n :class=\"[\n orientation === 'horizontal'\n ? 'min-h-[var(--ctl-h)] flex flex-col justify-start gap-0.5 mt-0'\n : 'space-y-2 gap-0'\n ]\"\n >\n <!-- 체크박스/스위치: 항상 가로 정렬로 컨트롤 + 인라인 라벨 묶기 -->\n <FieldGroup v-if=\"type === 'checkbox' || type === 'switch'\" data-slot=\"checkbox-group\">\n <!-- 부모 orientation과 무관하게 수평 정렬 고정 -->\n <Field orientation=\"horizontal\" class=\"flex gap-2 space-y-0 h-[var(--ctl-h)] leading-[var(--ctl-h)] items-center\">\n <component\n :is=\"resolvedComponent\"\n v-bind=\"controlProps\"\n @update:modelValue=\"handleUpdateModelValue\"\n @change=\"handleChange\"\n @focus=\"handleFocus\"\n @blur=\"handleBlur\"\n />\n <FieldLabel\n v-if=\"inlineLabel\"\n :for=\"id\"\n class=\"font-normal m-0 h-[var(--ctl-h)] leading-[var(--ctl-h)]\"\n >\n {{ inlineLabel }}\n </FieldLabel>\n </Field>\n </FieldGroup>\n\n <!-- Radio 버튼: radioDirection에 따라 분기 처리 -->\n <FieldGroup v-else-if=\"type === 'radio'\">\n <component\n :is=\"resolvedComponent\"\n v-bind=\"controlProps\"\n @update:modelValue=\"handleUpdateModelValue\"\n @change=\"handleChange\"\n @focus=\"handleFocus\"\n @blur=\"handleBlur\"\n :class=\"controlClass\"\n />\n </FieldGroup>\n\n <!-- 그 외 컨트롤: orientation 규칙 그대로 따름 -->\n <FieldGroup v-else>\n <component\n :is=\"resolvedComponent\"\n v-bind=\"controlProps\"\n @update:modelValue=\"handleUpdateModelValue\"\n @change=\"handleChange\"\n @focus=\"handleFocus\"\n @blur=\"handleBlur\"\n :class=\"controlClass\"\n />\n </FieldGroup>\n \n <!-- 설명/에러: 항상 컨트롤 '바로 아래'에 표시 -->\n <FieldContent v-if=\"description || finalError\">\n <FieldDescription v-if=\"description\">\n {{ description }}\n </FieldDescription>\n <FieldError v-if=\"finalError\">\n {{ finalError }}\n </FieldError>\n </FieldContent>\n </FieldContent>\n </Field>\n </FieldGroup>\n </div>\n</template>\n\n\n\n<style>\n/* ⬇⬇ 높이 토큰(밀도) — 프로젝트 전역/레이아웃에 한 번 정의해두고 재사용하세요 */\n.form-density-sm { --ctl-h: 2rem; /* 32px */ }\n.form-density-md { --ctl-h: 2.25rem; /* 36px (shadcn 기본에 근접) */ }\n.form-density-lg { --ctl-h: 2.5rem; /* 40px */ }\n</style>"],"names":["FORM_FIELD_PROPS","props","__props","emit","__emit","internalError","ref","finalError","computed","controlProps","result","propsObj","key","defaultPlaceholders","validateField","currentValue","value","shouldValidateOnMount","handleUpdateModelValue","handleChange","handleFocus","event","handleBlur","labelAlignClass","mapHorizontal","mapVertical","densityClass","controlClass","baseClass","componentMap","JInput","JTextarea","JCheckbox","JSwitch","JCombo","JRadio","JSearchCombo","JDatepicker","resolvedComponent","__expose","_createElementBlock","_createVNode","_unref","FieldGroup","Field","_normalizeClass","_normalizeStyle","FieldLabel","_createTextVNode","_toDisplayString","_hoisted_1","FieldContent","_createBlock","_openBlock","_resolveDynamicComponent","_mergeProps","FieldDescription","FieldError"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"JFormField.vue.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("vue");require("../shadcn/index.cjs");require("lucide-vue-next");;/* empty css */const h=require("../atoms/JInput.vue.cjs"),F=require("../atoms/JTextarea.vue.cjs"),N=require("../atoms/JCheckbox.vue.cjs"),z=require("../atoms/JCombo.vue.cjs"),T=require("../atoms/JSearchCombo.vue.cjs"),S=require("../atoms/JRadio.vue.cjs"),J=require("../atoms/JSwitch.vue.cjs"),M=require("../atoms/JDatepicker.vue.cjs");require("md-editor-v3");;/* empty css */;/* empty css */const P=require("../../lib/utils.cjs");require("../shadcn/badge-variants.cjs");require("@vueuse/core");require("reka-ui");;/* empty css */require("../shadcn/avatar-variants.cjs");require("dompurify");;/* empty css */require("ag-grid-vue3");require("ag-grid-community");require("ag-grid-enterprise");;/* empty css */;/* empty css */;/* empty css */;/* empty css */;/* empty css */;/* empty css */require("vue-sonner");const i=require("../shadcn/FieldGroup.vue.cjs"),g=require("../shadcn/Field.vue.cjs"),k=require("../shadcn/FieldLabel.vue.cjs"),q=require("../shadcn/FieldContent.vue.cjs"),E=require("../shadcn/FieldDescription.vue.cjs"),L=require("../shadcn/FieldError.vue.cjs"),j={key:0,class:"text-destructive ml-1"},A=e.defineComponent({__name:"JFormField",props:{class:{},label:{},description:{},errorMsg:{},type:{default:"input"},inlineLabel:{},orientation:{default:"vertical"},labelAlign:{default:"left"},labelWidth:{default:"8rem"},id:{},modelValue:{},placeholder:{},disabled:{type:Boolean},readonly:{type:Boolean},required:{type:Boolean},name:{},styleType:{},inputType:{},options:{},multiple:{type:Boolean},radioDirection:{default:"horizontal"}},emits:["update:modelValue","change","focus","blur"],setup(l,{expose:x,emit:C}){const b=["class","label","description","errorMsg","type","inlineLabel","orientation","labelAlign","labelWidth","radioDirection"],t=l,n=C,o=e.ref(""),c=e.computed(()=>t.errorMsg||o.value),s=e.computed(()=>{const r={},a=t;for(const u in a)b.includes(u)||(r[u]=a[u]);if(t.inputType&&t.type==="input"&&(r.type=t.inputType,delete r.inputType,!t.placeholder)){const u={text:"텍스트를 입력하세요",email:"이메일을 입력하세요",password:"비밀번호를 입력하세요",tel:"전화번호를 입력하세요",url:"URL을 입력하세요",number:"숫자를 입력하세요",search:"검색어를 입력하세요",date:"날짜를 선택하세요",time:"시간을 선택하세요","datetime-local":"날짜와 시간을 선택하세요",month:"월을 선택하세요",week:"주를 선택하세요"};r.placeholder=u[t.inputType]||"입력하세요"}return t.radioDirection&&t.type==="radio"&&(r.styletype=t.radioDirection,delete r.radioDirection),r}),d=r=>{if(!t.required)return;o.value="";const a=r!==void 0?r:t.modelValue;t.type==="checkbox"||t.type==="switch"?a!=="Y"&&(o.value="필수 항목입니다."):(a==null||a==="")&&(o.value="필수 입력 항목입니다.")},B=e.computed(()=>!(t.modelValue!==null&&t.modelValue!==void 0&&t.modelValue!=="")),p=r=>{n("update:modelValue",r),d(r)},f=r=>{n("change",r),d(r)},_=r=>{n("focus",r)},m=r=>{B.value&&d(),n("blur",r)},V=e.computed(()=>{const r={left:"justify-start",middle:"justify-center",right:"justify-end"},a={left:"text-left",middle:"text-center",right:"text-right"};return t.orientation==="horizontal"?r[t.labelAlign]:a[t.labelAlign]}),w=e.computed(()=>{switch(t.styleType){case"md":return"form-density-md";case"lg":return"form-density-lg";default:return"form-density-sm"}}),v=e.computed(()=>{const r="h-[var(--ctl-h)] leading-[var(--ctl-h)]";return t.type==="datepicker"?`${r} max-w-xs`:t.type==="radio"&&t.radioDirection==="vertical"?"":r}),D={input:h.default,textarea:F.default,checkbox:N.default,switch:J.default,combo:z.default,radio:S.default,searchCombo:T.default,datepicker:M.default},y=e.computed(()=>D[t.type]||h.default);return x({clearError:()=>{o.value=""}}),(r,a)=>(e.openBlock(),e.createElementBlock("div",{class:e.normalizeClass(e.unref(P.cn)("space-y-2 flex-1 min-w-0",w.value,t.class))},[e.createVNode(e.unref(i.default),null,{default:e.withCtx(()=>[e.createVNode(e.unref(g.default),{class:e.normalizeClass([l.orientation==="horizontal"?"grid grid-cols-[var(--label-w,8rem)_1fr] items-start space-y-0 gap-2":"space-y-1 gap-1"]),style:e.normalizeStyle(l.orientation==="horizontal"?`--label-w:${l.labelWidth};`:"")},{default:e.withCtx(()=>[e.createVNode(e.unref(k.default),{for:l.id,class:e.normalizeClass(["text-xs",l.orientation==="horizontal"?"flex items-center h-[var(--ctl-h)] w-full":"flex items-center",V.value])},{default:e.withCtx(()=>[e.createTextVNode(e.toDisplayString(l.label)+" ",1),l.required?(e.openBlock(),e.createElementBlock("span",j,"*")):e.createCommentVNode("",!0)]),_:1},8,["for","class"]),e.createVNode(e.unref(q.default),{class:e.normalizeClass([l.orientation==="horizontal"?"min-h-[var(--ctl-h)] flex flex-col justify-start gap-0.5 mt-0":"space-y-2 gap-0"])},{default:e.withCtx(()=>[l.type==="checkbox"||l.type==="switch"?(e.openBlock(),e.createBlock(e.unref(i.default),{key:0,"data-slot":"checkbox-group"},{default:e.withCtx(()=>[e.createVNode(e.unref(g.default),{orientation:"horizontal",class:"flex gap-2 space-y-0 h-[var(--ctl-h)] leading-[var(--ctl-h)] items-center"},{default:e.withCtx(()=>[(e.openBlock(),e.createBlock(e.resolveDynamicComponent(y.value),e.mergeProps(s.value,{"onUpdate:modelValue":p,onChange:f,onFocus:_,onBlur:m}),null,16)),l.inlineLabel?(e.openBlock(),e.createBlock(e.unref(k.default),{key:0,for:l.id,class:"text-xs font-normal m-0 h-[var(--ctl-h)] leading-[var(--ctl-h)]"},{default:e.withCtx(()=>[e.createTextVNode(e.toDisplayString(l.inlineLabel),1)]),_:1},8,["for"])):e.createCommentVNode("",!0)]),_:1})]),_:1})):l.type==="radio"?(e.openBlock(),e.createBlock(e.unref(i.default),{key:1},{default:e.withCtx(()=>[(e.openBlock(),e.createBlock(e.resolveDynamicComponent(y.value),e.mergeProps(s.value,{"onUpdate:modelValue":p,onChange:f,onFocus:_,onBlur:m,class:v.value}),null,16,["class"]))]),_:1})):(e.openBlock(),e.createBlock(e.unref(i.default),{key:2},{default:e.withCtx(()=>[(e.openBlock(),e.createBlock(e.resolveDynamicComponent(y.value),e.mergeProps(s.value,{"onUpdate:modelValue":p,onChange:f,onFocus:_,onBlur:m,class:v.value}),null,16,["class"]))]),_:1})),l.description||c.value?(e.openBlock(),e.createBlock(e.unref(q.default),{key:3},{default:e.withCtx(()=>[l.description?(e.openBlock(),e.createBlock(e.unref(E.default),{key:0},{default:e.withCtx(()=>[e.createTextVNode(e.toDisplayString(l.description),1)]),_:1})):e.createCommentVNode("",!0),c.value?(e.openBlock(),e.createBlock(e.unref(L.default),{key:1},{default:e.withCtx(()=>[e.createTextVNode(e.toDisplayString(c.value),1)]),_:1})):e.createCommentVNode("",!0)]),_:1})):e.createCommentVNode("",!0)]),_:1},8,["class"])]),_:1},8,["class","style"])]),_:1})],2))}});exports.default=A;
|
|
2
|
+
//# sourceMappingURL=JFormField.vue2.cjs.map
|