@j-solution/components 1.7.0 โ 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 -8
- 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 +21 -21
- 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/JGrid.vue.cjs +1 -1
- package/components/atoms/JGrid.vue.js +1 -1
- package/components/atoms/JGrid.vue2.cjs +1 -1
- package/components/atoms/JGrid.vue2.cjs.map +1 -1
- package/components/atoms/JGrid.vue2.js +39 -35
- package/components/atoms/JGrid.vue2.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/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/JSplitter.vue.cjs +6 -1
- package/components/atoms/JSplitter.vue.cjs.map +1 -1
- package/components/atoms/JSplitter.vue.js +10 -59
- 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/examples/ExampleCrudPage.vue.cjs +1 -1
- package/components/examples/ExampleCrudPage.vue.cjs.map +1 -1
- package/components/examples/ExampleCrudPage.vue.js +228 -208
- 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 +341 -368
- 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/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 -264
- 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 +44 -50
- 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 +23 -20
- 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 +191 -190
- 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 +47 -45
- 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/JSidebarSimple/JDynamicMenuItem.vue.cjs +1 -1
- package/components/organisms/JSidebarSimple/JDynamicMenuItem.vue.cjs.map +1 -1
- package/components/organisms/JSidebarSimple/JDynamicMenuItem.vue.js +52 -52
- package/components/organisms/JSidebarSimple/JDynamicMenuItem.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/CardHeader.vue.cjs +1 -1
- package/components/shadcn/CardHeader.vue.cjs.map +1 -1
- package/components/shadcn/CardHeader.vue.js +5 -5
- package/components/shadcn/CardHeader.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 +1 -1
- package/components/shadcn/SelectTrigger.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/Textarea.vue.cjs +1 -1
- package/components/shadcn/Textarea.vue.cjs.map +1 -1
- package/components/shadcn/Textarea.vue.js +1 -1
- 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 +4 -4
- 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 +920 -777
- package/assets/jwms-portal-frontend-CwxPfHfa.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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JTabs.vue2.js","sources":["../../../../src/components/molecules/JTabs.vue"],"sourcesContent":["<script setup lang=\"ts\">\r\nimport { computed, ref, watch, nextTick } from 'vue'\r\nimport { Tabs, TabsList, TabsTrigger, TabsContent } from '@/components/shadcn'\r\nimport type { JTabsProps, JTabsEmits } from '@/types/dynamic-tabs.types'\r\nimport { X } from 'lucide-vue-next'\r\nimport { cn } from '@/lib/utils'\r\nimport JIcon from '@/components/atoms/JIcon.vue'\r\n\r\n/**\r\n * JTabs - ๊ธฐ๋ณธ ํญ UI ์ปดํฌ๋ํธ (molecules)\r\n * Basic Tabs UI Component\r\n * \r\n * @description\r\n * ์ ์ ์ธ ํญ ๋ชฉ๋ก์ ๋ ๋๋งํ๋ ๊ธฐ๋ณธ ํญ ์ปดํฌ๋ํธ์
๋๋ค.\r\n * ๋ซ๊ธฐ ๋ฒํผ, ์์ด์ฝ ๋ฑ์ ์ง์ํฉ๋๋ค.\r\n * \r\n * @example\r\n * ```vue\r\n * <JTabs \r\n * :tabs=\"tabs\"\r\n * :active-tab-id=\"activeId\"\r\n * @tab-change=\"handleChange\"\r\n * @tab-close=\"handleClose\"\r\n * />\r\n * ```\r\n */\r\n\r\ntype StyleType = 'default' | 'minimal'\r\n\r\nconst props = withDefaults(defineProps<JTabsProps>(), {\r\n styletype: 'default',\r\n})\r\n\r\nconst emit = defineEmits<JTabsEmits>()\r\n\r\n/**\r\n * ์์ ํ tabs ๋ฐฐ์ด (undefined/null ์ฒดํฌ)\r\n * Safe tabs array (undefined/null check)\r\n */\r\nconst safeTabs = computed(() => {\r\n return Array.isArray(props.tabs) ? props.tabs : []\r\n})\r\n\r\n/**\r\n * ํ์ฌ ํ์ฑํ๋ ํญ ID (๋ด๋ถ ์ํ)\r\n * Current active tab ID (internal state)\r\n */\r\nconst internalActiveId = ref<string>(\r\n props.activeTabId || (safeTabs.value.length > 0 ? safeTabs.value[0]?.id : '') || ''\r\n)\r\n\r\n/**\r\n * ์ด๋ฒคํธ ์ฒ๋ฆฌ ์ค ํ๋๊ทธ (์ค๋ณต ์ด๋ฒคํธ ๋ฐฉ์ง)\r\n * Flag to prevent duplicate events\r\n */\r\nlet isHandlingEvent = false\r\n\r\n/**\r\n * props.activeTabId๊ฐ ๋ณ๊ฒฝ๋๋ฉด ๋ด๋ถ ์ํ ๋๊ธฐํ\r\n * Sync internal state when props.activeTabId changes\r\n */\r\nwatch(() => props.activeTabId, (newValue) => {\r\n if (newValue !== undefined && newValue !== internalActiveId.value) {\r\n internalActiveId.value = newValue\r\n }\r\n}, { immediate: true })\r\n\r\n/**\r\n * props.tabs๊ฐ ๋ณ๊ฒฝ๋๊ณ activeTabId๊ฐ ์์ผ๋ฉด ์ฒซ ๋ฒ์งธ ํญ ํ์ฑํ\r\n * Activate first tab when tabs change and no activeTabId\r\n */\r\nwatch(safeTabs, (newTabs) => {\r\n if (!props.activeTabId && newTabs.length > 0 && !newTabs.find(t => t.id === internalActiveId.value) && newTabs[0]) {\r\n internalActiveId.value = newTabs[0].id\r\n }\r\n})\r\n\r\n/**\r\n * ํญ ๊ฐ ๋ณ๊ฒฝ ํธ๋ค๋ฌ (reka-ui TabsRoot์์ ์ง์ ํธ์ถ๋จ)\r\n * Tab value change handler (called directly from reka-ui TabsRoot)\r\n */\r\nconst handleTabValueChange = (value: string | number) => {\r\n if (isHandlingEvent) return\r\n \r\n const stringValue = String(value)\r\n if (stringValue !== internalActiveId.value) {\r\n isHandlingEvent = true\r\n internalActiveId.value = stringValue\r\n emit('update:activeTabId', stringValue)\r\n emit('tabChange', stringValue)\r\n // ๋ค์ tick์์ ํ๋๊ทธ ๋ฆฌ์
\r\n nextTick(() => {\r\n isHandlingEvent = false\r\n })\r\n }\r\n}\r\n\r\n/**\r\n * ํญ ํด๋ฆญ ํธ๋ค๋ฌ (๋ฐฑ์
๋ฐฉ์ - reka-ui ์ด๋ฒคํธ๊ฐ ์๋ํ์ง ์์ ๊ฒฝ์ฐ)\r\n * Tab click handler (backup - in case reka-ui events don't work)\r\n */\r\nconst handleTabClick = (tabId: string) => {\r\n // reka-ui ์ด๋ฒคํธ๊ฐ ์๋ํ์ง ์์ ๊ฒฝ์ฐ ์ง์ ์ฒ๋ฆฌ\r\n // handleTabValueChange๊ฐ ์ด๋ฏธ ์ฒ๋ฆฌํ์ผ๋ฉด ์ค๋ณต ๋ฐฉ์ง\r\n if (isHandlingEvent || tabId === internalActiveId.value) return\r\n \r\n isHandlingEvent = true\r\n internalActiveId.value = tabId\r\n emit('update:activeTabId', tabId)\r\n emit('tabChange', tabId)\r\n // ๋ค์ tick์์ ํ๋๊ทธ ๋ฆฌ์
\r\n nextTick(() => {\r\n isHandlingEvent = false\r\n })\r\n}\r\n\r\n/**\r\n * ํญ ๋ซ๊ธฐ ํธ๋ค๋ฌ\r\n * Tab close handler\r\n */\r\nconst handleCloseTab = (e: Event, tabId: string) => {\r\n e.stopPropagation() // ํญ ํด๋ฆญ ์ด๋ฒคํธ ์ ํ ๋ฐฉ์ง\r\n emit('tabClose', tabId)\r\n}\r\n\r\n/**\r\n * ๋ฃจํธ ํด๋์ค\r\n * Root classes\r\n */\r\nconst rootClasses = computed(() => {\r\n const classes = ['flex', 'flex-col', 'w-full', 'h-full']\r\n \r\n if (props.className) {\r\n classes.push(props.className)\r\n }\r\n \r\n return classes.join(' ')\r\n})\r\n\r\n/**\r\n * ์คํ์ผ ํ๋ฆฌ์
\r\n */\r\nconst STYLE_PRESETS: Record<StyleType, {\r\n tabPaddingClass: string\r\n tabTextSizeClass: string\r\n listPaddingClass: string\r\n}> = {\r\n default: {\r\n tabPaddingClass: 'px-2.5 py-1',\r\n tabTextSizeClass: 'text-xs',\r\n listPaddingClass: 'p-0.5',\r\n },\r\n minimal: {\r\n tabPaddingClass: 'px-2 py-0.5',\r\n tabTextSizeClass: 'text-xs',\r\n listPaddingClass: 'p-0.5',\r\n },\r\n}\r\n\r\nconst preset = computed(() => {\r\n return STYLE_PRESETS[props.styletype] ?? STYLE_PRESETS.default\r\n})\r\n\r\n/**\r\n * ํญ ๋ฆฌ์คํธ ํด๋์ค\r\n * Tabs list classes\r\n */\r\nconst listClasses = computed(() => {\r\n const classes = ['w-full', 'justify-start', preset.value.listPaddingClass]\r\n \r\n if (props.listClassName) {\r\n classes.push(props.listClassName)\r\n }\r\n \r\n return classes.join(' ')\r\n})\r\n</script>\r\n\r\n<template>\r\n <Tabs\r\n :model-value=\"internalActiveId\"\r\n @update:model-value=\"handleTabValueChange\"\r\n orientation=\"horizontal\"\r\n :class=\"rootClasses\"\r\n >\r\n <!-- ํญ ํค๋ ์์ญ / Tab Headers -->\r\n <TabsList :class=\"listClasses\">\r\n <TabsTrigger\r\n v-for=\"tab in safeTabs\"\r\n :key=\"tab.id\"\r\n :value=\"tab.id\"\r\n @click=\"handleTabClick(tab.id)\"\r\n :class=\"cn('!flex !items-center !gap-2', preset.tabPaddingClass, preset.tabTextSizeClass)\"\r\n >\r\n <!-- ํญ ์์ด์ฝ (์์ ๊ฒฝ์ฐ) / Tab Icon -->\r\n <JIcon \r\n v-if=\"tab.icon\" \r\n :name=\"tab.icon\" \r\n size=\"sm\"\r\n class=\"flex-shrink-0\"\r\n />\r\n \r\n <!-- ํญ ๋ ์ด๋ธ / Tab Label -->\r\n <span class=\"flex-1 truncate\">{{ tab.label }}</span>\r\n \r\n <!-- ๋ซ๊ธฐ ๋ฒํผ / Close Button (ํญ์ ํ์) -->\r\n <button\r\n v-if=\"tab.closable\"\r\n type=\"button\"\r\n class=\"flex-shrink-0 h-3.5 w-3.5 rounded-sm hover:bg-destructive/10 hover:text-destructive transition-colors focus:outline-none focus:ring-2 focus:ring-ring flex items-center justify-center\"\r\n :aria-label=\"`${tab.label} ํญ ๋ซ๊ธฐ`\"\r\n @click=\"(e) => handleCloseTab(e, tab.id)\"\r\n >\r\n <X class=\"h-2.5 w-2.5\" />\r\n </button>\r\n </TabsTrigger>\r\n </TabsList>\r\n\r\n <!-- ํญ ์ฝํ
์ธ ์์ญ / Tab Contents -->\r\n <div class=\"flex-1 w-full overflow-auto\">\r\n <TabsContent\r\n v-for=\"tab in safeTabs\"\r\n :key=\"`content-${tab.id}`\"\r\n :value=\"tab.id\"\r\n class=\"h-full mt-0 data-[state=active]:flex data-[state=active]:flex-col\"\r\n >\r\n <!-- ์ฌ๋กฏ ์ฐ์ / Slot First -->\r\n <slot :name=\"`content-${tab.id}`\" :tab=\"tab\">\r\n <!-- ๋์ ์ปดํฌ๋ํธ ๋ ๋๋ง / Dynamic Component Rendering -->\r\n <component\r\n v-if=\"tab.component\"\r\n :is=\"tab.component\"\r\n v-bind=\"tab.props || {}\"\r\n />\r\n \r\n <!-- ๊ธฐ๋ณธ ์ฝํ
์ธ / Default Content -->\r\n <div v-else class=\"p-4\">\r\n <p class=\"text-muted-foreground\">{{ tab.label }} ์ฝํ
์ธ </p>\r\n </div>\r\n </slot>\r\n </TabsContent>\r\n </div>\r\n </Tabs>\r\n</template>\r\n\r\n<style scoped>\r\n/**\r\n * ํญ ๋ฆฌ์คํธ ์คํ์ผ - ํ๋จ ๋ณด๋ ์ ๊ฑฐ\r\n * Tab list styles without bottom border\r\n */\r\n:deep([role=\"tablist\"]:not(.ag-side-buttons)) {\r\n overflow-x: auto;\r\n overflow-y: hidden;\r\n scrollbar-width: thin;\r\n scrollbar-color: rgba(0, 0, 0, 0.2) transparent;\r\n background: hsl(var(--background));\r\n padding: 0 0.5rem;\r\n padding-top: 0.25rem;\r\n gap: 0.25rem;\r\n border-bottom: none;\r\n}\r\n\r\n:deep([role=\"tablist\"]:not(.ag-side-buttons)::-webkit-scrollbar) {\r\n height: 6px;\r\n}\r\n\r\n:deep([role=\"tablist\"]:not(.ag-side-buttons)::-webkit-scrollbar-track) {\r\n background: transparent;\r\n}\r\n\r\n:deep([role=\"tablist\"]:not(.ag-side-buttons)::-webkit-scrollbar-thumb) {\r\n background-color: rgba(0, 0, 0, 0.2);\r\n border-radius: 3px;\r\n}\r\n\r\n:deep([role=\"tablist\"]:not(.ag-side-buttons)::-webkit-scrollbar-thumb:hover) {\r\n background-color: rgba(0, 0, 0, 0.3);\r\n}\r\n\r\n/**\r\n * ๋คํฌ๋ชจ๋์์ ์คํฌ๋กค๋ฐ ์คํ์ผ\r\n * Scrollbar styles in dark mode\r\n */\r\n.dark :deep([role=\"tablist\"]:not(.ag-side-buttons)::-webkit-scrollbar-thumb) {\r\n background-color: rgba(255, 255, 255, 0.2);\r\n}\r\n\r\n.dark :deep([role=\"tablist\"]:not(.ag-side-buttons)::-webkit-scrollbar-thumb:hover) {\r\n background-color: rgba(255, 255, 255, 0.3);\r\n}\r\n\r\n.dark :deep([role=\"tablist\"]:not(.ag-side-buttons)) {\r\n scrollbar-color: rgba(255, 255, 255, 0.2) transparent;\r\n}\r\n\r\n/**\r\n * ํญ ๋ฒํผ ์คํ์ผ - ๋ช
ํํ ๊ตฌ๋ถ\r\n * Tab button styles - clear distinction\r\n */\r\n:deep([role=\"tab\"]) {\r\n position: relative;\r\n padding: 0.375rem 0.75rem;\r\n border-radius: 0.375rem 0.375rem 0 0;\r\n transition: all 0.2s ease;\r\n border: 1px solid transparent;\r\n border-bottom: none;\r\n}\r\n\r\n/**\r\n * Minimal ์คํ์ผ ํญ ๋ฒํผ - JSidebarAdvanced์ ๋์ด ๋ง์ถค\r\n */\r\n:deep([role=\"tablist\"][class*=\"p-0.5\"] [role=\"tab\"]) {\r\n padding: 0.25rem 0.5rem;\r\n}\r\n\r\n/**\r\n * ๋นํ์ฑ ํญ - ๋ช
ํํ๊ฒ ๊ตฌ๋ถ\r\n * Inactive tabs - clear distinction\r\n */\r\n:deep([role=\"tab\"][data-state=\"inactive\"]) {\r\n background: hsl(var(--muted) / 0.2);\r\n color: hsl(var(--muted-foreground));\r\n border-top: 1px solid hsl(var(--border) / 0.4);\r\n border-left: 1px solid hsl(var(--border) / 0.4);\r\n border-right: 1px solid hsl(var(--border) / 0.4);\r\n}\r\n\r\n:deep([role=\"tab\"][data-state=\"inactive\"]:hover) {\r\n background: hsl(var(--muted) / 0.4);\r\n color: hsl(var(--foreground));\r\n}\r\n\r\n/**\r\n * ๋คํฌ๋ชจ๋์์ ๋นํ์ฑ ํญ - ๋คํฌ ๋ฐฐ๊ฒฝ์ ์ฌ์ฉ\r\n * Inactive tabs in dark mode - use dark background\r\n */\r\n.dark :deep([role=\"tab\"][data-state=\"inactive\"]) {\r\n background: hsl(var(--secondary));\r\n color: hsl(var(--secondary-foreground));\r\n border-top: 1px solid hsl(var(--border) / 0.5);\r\n border-left: 1px solid hsl(var(--border) / 0.5);\r\n border-right: 1px solid hsl(var(--border) / 0.5);\r\n}\r\n\r\n.dark :deep([role=\"tab\"][data-state=\"inactive\"]:hover) {\r\n background: hsl(var(--muted));\r\n color: hsl(var(--muted-foreground));\r\n}\r\n\r\n/**\r\n * ํ์ฑ ํญ - ๊ฐ์กฐ๋ ์คํ์ผ\r\n * Active tab - emphasized style\r\n */\r\n:deep([role=\"tab\"][data-state=\"active\"]) {\r\n background: hsl(var(--background));\r\n color: hsl(var(--foreground));\r\n font-weight: 500;\r\n border-top: 2px solid hsl(var(--primary));\r\n border-left: 1px solid hsl(var(--border));\r\n border-right: 1px solid hsl(var(--border));\r\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);\r\n z-index: 1;\r\n}\r\n\r\n/**\r\n * ๋คํฌ๋ชจ๋์์ ํ์ฑ ํญ - ๋ฐฐ๊ฒฝ์ ๋ช
ํํ ๊ตฌ๋ถ\r\n * Active tab in dark mode - clear background distinction\r\n */\r\n.dark :deep([role=\"tab\"][data-state=\"active\"]) {\r\n background: hsl(var(--card));\r\n color: hsl(var(--card-foreground));\r\n border-top: 2px solid hsl(var(--primary));\r\n border-left: 1px solid hsl(var(--border));\r\n border-right: 1px solid hsl(var(--border));\r\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);\r\n}\r\n\r\n/**\r\n * ์ฝํ
์ธ ์์ญ์ ์๋จ ๋ณด๋ ์ถ๊ฐ\r\n * Add top border to content area\r\n */\r\n:deep([role=\"tabpanel\"]) {\r\n border-top: 1px solid hsl(var(--border));\r\n}\r\n\r\n/**\r\n * ๋คํฌ๋ชจ๋์์ ์ฝํ
์ธ ์์ญ ๋ณด๋ - ๋ ๋ถ๋๋ฌ์ด ๊ตฌ๋ถ\r\n * Content area border in dark mode - subtler separation\r\n */\r\n.dark :deep([role=\"tabpanel\"]) {\r\n border-top: 1px solid hsl(var(--border) / 0.6);\r\n}\r\n</style>\r\n\r\n"],"names":["props","__props","emit","__emit","safeTabs","computed","internalActiveId","ref","isHandlingEvent","watch","newValue","newTabs","t","handleTabValueChange","value","stringValue","nextTick","handleTabClick","tabId","handleCloseTab","rootClasses","classes","STYLE_PRESETS","preset","listClasses","_createBlock","_unref","Tabs","_createVNode","TabsList","_createElementBlock","_Fragment","_renderList","tab","TabsTrigger","$event","_normalizeClass","JIcon","_createElementVNode","_hoisted_1","_toDisplayString","e","X","_hoisted_3","TabsContent","_renderSlot","_ctx","_openBlock","_resolveDynamicComponent","_mergeProps","_hoisted_4","_hoisted_5"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"JTabs.vue2.js","sources":["../../../../src/components/molecules/JTabs.vue"],"sourcesContent":["<script setup lang=\"ts\">\r\nimport { computed, ref, watch, nextTick } from 'vue'\r\nimport { Tabs, TabsList, TabsTrigger, TabsContent } from '@/components/shadcn'\r\nimport type { JTabsProps, JTabsEmits } from '@/types/dynamic-tabs.types'\r\nimport { X } from 'lucide-vue-next'\r\nimport { cn } from '@/lib/utils'\r\nimport JIcon from '@/components/atoms/JIcon.vue'\r\n\r\n/**\r\n * JTabs - ๊ธฐ๋ณธ ํญ UI ์ปดํฌ๋ํธ (molecules)\r\n * Basic Tabs UI Component\r\n * \r\n * @description\r\n * ์ ์ ์ธ ํญ ๋ชฉ๋ก์ ๋ ๋๋งํ๋ ๊ธฐ๋ณธ ํญ ์ปดํฌ๋ํธ์
๋๋ค.\r\n * ๋ซ๊ธฐ ๋ฒํผ, ์์ด์ฝ ๋ฑ์ ์ง์ํฉ๋๋ค.\r\n * \r\n * @example\r\n * ```vue\r\n * <JTabs \r\n * :tabs=\"tabs\"\r\n * :active-tab-id=\"activeId\"\r\n * @tab-change=\"handleChange\"\r\n * @tab-close=\"handleClose\"\r\n * />\r\n * ```\r\n */\r\n\r\ntype StyleType = 'default' | 'minimal'\r\n\r\nconst props = withDefaults(defineProps<JTabsProps>(), {\r\n styletype: 'default',\r\n})\r\n\r\nconst emit = defineEmits<JTabsEmits>()\r\n\r\n/**\r\n * ์์ ํ tabs ๋ฐฐ์ด (undefined/null ์ฒดํฌ)\r\n * Safe tabs array (undefined/null check)\r\n */\r\nconst safeTabs = computed(() => {\r\n return Array.isArray(props.tabs) ? props.tabs : []\r\n})\r\n\r\n/**\r\n * ํ์ฌ ํ์ฑํ๋ ํญ ID (๋ด๋ถ ์ํ)\r\n * Current active tab ID (internal state)\r\n */\r\nconst internalActiveId = ref<string>(\r\n props.activeTabId || (safeTabs.value.length > 0 ? safeTabs.value[0]?.id : '') || ''\r\n)\r\n\r\n/**\r\n * ์ด๋ฒคํธ ์ฒ๋ฆฌ ์ค ํ๋๊ทธ (์ค๋ณต ์ด๋ฒคํธ ๋ฐฉ์ง)\r\n * Flag to prevent duplicate events\r\n */\r\nlet isHandlingEvent = false\r\n\r\n/**\r\n * props.activeTabId๊ฐ ๋ณ๊ฒฝ๋๋ฉด ๋ด๋ถ ์ํ ๋๊ธฐํ\r\n * Sync internal state when props.activeTabId changes\r\n */\r\nwatch(() => props.activeTabId, (newValue) => {\r\n if (newValue !== undefined && newValue !== internalActiveId.value) {\r\n internalActiveId.value = newValue\r\n }\r\n}, { immediate: true })\r\n\r\n/**\r\n * props.tabs๊ฐ ๋ณ๊ฒฝ๋๊ณ activeTabId๊ฐ ์์ผ๋ฉด ์ฒซ ๋ฒ์งธ ํญ ํ์ฑํ\r\n * Activate first tab when tabs change and no activeTabId\r\n */\r\nwatch(safeTabs, (newTabs) => {\r\n if (!props.activeTabId && newTabs.length > 0 && !newTabs.find(t => t.id === internalActiveId.value) && newTabs[0]) {\r\n internalActiveId.value = newTabs[0].id\r\n }\r\n})\r\n\r\n/**\r\n * ํญ ๊ฐ ๋ณ๊ฒฝ ํธ๋ค๋ฌ (reka-ui TabsRoot์์ ์ง์ ํธ์ถ๋จ)\r\n * Tab value change handler (called directly from reka-ui TabsRoot)\r\n */\r\nconst handleTabValueChange = (value: string | number) => {\r\n if (isHandlingEvent) return\r\n \r\n const stringValue = String(value)\r\n if (stringValue !== internalActiveId.value) {\r\n isHandlingEvent = true\r\n internalActiveId.value = stringValue\r\n emit('update:activeTabId', stringValue)\r\n emit('tabChange', stringValue)\r\n // ๋ค์ tick์์ ํ๋๊ทธ ๋ฆฌ์
\r\n nextTick(() => {\r\n isHandlingEvent = false\r\n })\r\n }\r\n}\r\n\r\n/**\r\n * ํญ ํด๋ฆญ ํธ๋ค๋ฌ (๋ฐฑ์
๋ฐฉ์ - reka-ui ์ด๋ฒคํธ๊ฐ ์๋ํ์ง ์์ ๊ฒฝ์ฐ)\r\n * Tab click handler (backup - in case reka-ui events don't work)\r\n */\r\nconst handleTabClick = (tabId: string) => {\r\n // reka-ui ์ด๋ฒคํธ๊ฐ ์๋ํ์ง ์์ ๊ฒฝ์ฐ ์ง์ ์ฒ๋ฆฌ\r\n // handleTabValueChange๊ฐ ์ด๋ฏธ ์ฒ๋ฆฌํ์ผ๋ฉด ์ค๋ณต ๋ฐฉ์ง\r\n if (isHandlingEvent || tabId === internalActiveId.value) return\r\n \r\n isHandlingEvent = true\r\n internalActiveId.value = tabId\r\n emit('update:activeTabId', tabId)\r\n emit('tabChange', tabId)\r\n // ๋ค์ tick์์ ํ๋๊ทธ ๋ฆฌ์
\r\n nextTick(() => {\r\n isHandlingEvent = false\r\n })\r\n}\r\n\r\n/**\r\n * ํญ ๋ซ๊ธฐ ํธ๋ค๋ฌ\r\n * Tab close handler\r\n */\r\nconst handleCloseTab = (e: Event, tabId: string) => {\r\n e.stopPropagation() // ํญ ํด๋ฆญ ์ด๋ฒคํธ ์ ํ ๋ฐฉ์ง\r\n emit('tabClose', tabId)\r\n}\r\n\r\n/**\r\n * ๋ฃจํธ ํด๋์ค\r\n * Root classes\r\n */\r\nconst rootClasses = computed(() => {\r\n return cn('flex flex-col w-full h-full', props.class)\r\n})\r\n\r\n/**\r\n * ์คํ์ผ ํ๋ฆฌ์
\r\n */\r\nconst STYLE_PRESETS: Record<StyleType, {\r\n tabPaddingClass: string\r\n tabTextSizeClass: string\r\n listPaddingClass: string\r\n}> = {\r\n default: {\r\n tabPaddingClass: 'px-2.5 py-1',\r\n tabTextSizeClass: 'text-xs',\r\n listPaddingClass: 'p-0.5',\r\n },\r\n minimal: {\r\n tabPaddingClass: 'px-2 py-0.5',\r\n tabTextSizeClass: 'text-xs',\r\n listPaddingClass: 'p-0.5',\r\n },\r\n}\r\n\r\nconst preset = computed(() => {\r\n return STYLE_PRESETS[props.styletype] ?? STYLE_PRESETS.default\r\n})\r\n\r\n/**\r\n * ํญ ๋ฆฌ์คํธ ํด๋์ค\r\n * Tabs list classes\r\n */\r\nconst listClasses = computed(() => {\r\n return cn('w-full justify-start', preset.value.listPaddingClass, props.listClass)\r\n})\r\n</script>\r\n\r\n<template>\r\n <Tabs\r\n :model-value=\"internalActiveId\"\r\n @update:model-value=\"handleTabValueChange\"\r\n orientation=\"horizontal\"\r\n :class=\"rootClasses\"\r\n >\r\n <!-- ํญ ํค๋ ์์ญ / Tab Headers -->\r\n <TabsList :class=\"listClasses\">\r\n <TabsTrigger\r\n v-for=\"tab in safeTabs\"\r\n :key=\"tab.id\"\r\n :value=\"tab.id\"\r\n @click=\"handleTabClick(tab.id)\"\r\n :class=\"cn('!flex !items-center !gap-2', preset.tabPaddingClass, preset.tabTextSizeClass)\"\r\n >\r\n <!-- ํญ ์์ด์ฝ (์์ ๊ฒฝ์ฐ) / Tab Icon -->\r\n <JIcon \r\n v-if=\"tab.icon\" \r\n :name=\"tab.icon\" \r\n size=\"sm\"\r\n class=\"flex-shrink-0\"\r\n />\r\n \r\n <!-- ํญ ๋ ์ด๋ธ / Tab Label -->\r\n <span class=\"flex-1 truncate\">{{ tab.label }}</span>\r\n \r\n <!-- ๋ซ๊ธฐ ๋ฒํผ / Close Button (ํญ์ ํ์) -->\r\n <button\r\n v-if=\"tab.closable\"\r\n type=\"button\"\r\n class=\"flex-shrink-0 h-3.5 w-3.5 rounded-sm hover:bg-destructive/10 hover:text-destructive transition-colors focus:outline-none focus:ring-2 focus:ring-ring flex items-center justify-center\"\r\n :aria-label=\"`${tab.label} ํญ ๋ซ๊ธฐ`\"\r\n @click=\"(e) => handleCloseTab(e, tab.id)\"\r\n >\r\n <X class=\"h-2.5 w-2.5\" />\r\n </button>\r\n </TabsTrigger>\r\n </TabsList>\r\n\r\n <!-- ํญ ์ฝํ
์ธ ์์ญ / Tab Contents -->\r\n <div class=\"flex-1 w-full overflow-auto\">\r\n <TabsContent\r\n v-for=\"tab in safeTabs\"\r\n :key=\"`content-${tab.id}`\"\r\n :value=\"tab.id\"\r\n class=\"h-full mt-0 data-[state=active]:flex data-[state=active]:flex-col\"\r\n >\r\n <!-- ์ฌ๋กฏ ์ฐ์ / Slot First -->\r\n <slot :name=\"`content-${tab.id}`\" :tab=\"tab\">\r\n <!-- ๋์ ์ปดํฌ๋ํธ ๋ ๋๋ง / Dynamic Component Rendering -->\r\n <component\r\n v-if=\"tab.component\"\r\n :is=\"tab.component\"\r\n v-bind=\"tab.props || {}\"\r\n />\r\n \r\n <!-- ๊ธฐ๋ณธ ์ฝํ
์ธ / Default Content -->\r\n <div v-else class=\"p-4\">\r\n <p class=\"text-muted-foreground\">{{ tab.label }} ์ฝํ
์ธ </p>\r\n </div>\r\n </slot>\r\n </TabsContent>\r\n </div>\r\n </Tabs>\r\n</template>\r\n\r\n<style scoped>\r\n/**\r\n * ํญ ๋ฆฌ์คํธ ์คํ์ผ - ํ๋จ ๋ณด๋ ์ ๊ฑฐ\r\n * Tab list styles without bottom border\r\n */\r\n:deep([role=\"tablist\"]:not(.ag-side-buttons)) {\r\n overflow-x: auto;\r\n overflow-y: hidden;\r\n scrollbar-width: thin;\r\n scrollbar-color: rgba(0, 0, 0, 0.2) transparent;\r\n background: hsl(var(--background));\r\n padding: 0 0.5rem;\r\n padding-top: 0.25rem;\r\n gap: 0.25rem;\r\n}\r\n\r\n:deep([role=\"tablist\"]:not(.ag-side-buttons)::-webkit-scrollbar) {\r\n height: 6px;\r\n}\r\n\r\n:deep([role=\"tablist\"]:not(.ag-side-buttons)::-webkit-scrollbar-track) {\r\n background: transparent;\r\n}\r\n\r\n:deep([role=\"tablist\"]:not(.ag-side-buttons)::-webkit-scrollbar-thumb) {\r\n background-color: rgba(0, 0, 0, 0.2);\r\n border-radius: 3px;\r\n}\r\n\r\n:deep([role=\"tablist\"]:not(.ag-side-buttons)::-webkit-scrollbar-thumb:hover) {\r\n background-color: rgba(0, 0, 0, 0.3);\r\n}\r\n\r\n/**\r\n * ๋คํฌ๋ชจ๋์์ ์คํฌ๋กค๋ฐ ์คํ์ผ\r\n * Scrollbar styles in dark mode\r\n */\r\n.dark :deep([role=\"tablist\"]:not(.ag-side-buttons)::-webkit-scrollbar-thumb) {\r\n background-color: rgba(255, 255, 255, 0.2);\r\n}\r\n\r\n.dark :deep([role=\"tablist\"]:not(.ag-side-buttons)::-webkit-scrollbar-thumb:hover) {\r\n background-color: rgba(255, 255, 255, 0.3);\r\n}\r\n\r\n.dark :deep([role=\"tablist\"]:not(.ag-side-buttons)) {\r\n scrollbar-color: rgba(255, 255, 255, 0.2) transparent;\r\n}\r\n\r\n/**\r\n * ํญ ๋ฒํผ ์คํ์ผ - ๋ช
ํํ ๊ตฌ๋ถ\r\n * Tab button styles - clear distinction\r\n */\r\n:deep([role=\"tab\"]) {\r\n position: relative;\r\n padding: 0.375rem 0.75rem;\r\n border-radius: 0.375rem 0.375rem 0 0;\r\n transition: all 0.2s ease;\r\n border: 1px solid transparent;\r\n border-bottom: none;\r\n}\r\n\r\n/**\r\n * Minimal ์คํ์ผ ํญ ๋ฒํผ - JSidebarAdvanced์ ๋์ด ๋ง์ถค\r\n */\r\n:deep([role=\"tablist\"][class*=\"p-0.5\"] [role=\"tab\"]) {\r\n padding: 0.25rem 0.5rem;\r\n}\r\n\r\n/**\r\n * ๋นํ์ฑ ํญ - ๋ช
ํํ๊ฒ ๊ตฌ๋ถ\r\n * Inactive tabs - clear distinction\r\n */\r\n:deep([role=\"tab\"][data-state=\"inactive\"]) {\r\n background: hsl(var(--muted) / 0.2);\r\n color: hsl(var(--muted-foreground));\r\n border-top: 1px solid hsl(var(--border) / 0.4);\r\n border-left: 1px solid hsl(var(--border) / 0.4);\r\n border-right: 1px solid hsl(var(--border) / 0.4);\r\n}\r\n\r\n:deep([role=\"tab\"][data-state=\"inactive\"]:hover) {\r\n background: hsl(var(--muted) / 0.4);\r\n color: hsl(var(--foreground));\r\n}\r\n\r\n/**\r\n * ๋คํฌ๋ชจ๋์์ ๋นํ์ฑ ํญ - ๋คํฌ ๋ฐฐ๊ฒฝ์ ์ฌ์ฉ\r\n * Inactive tabs in dark mode - use dark background\r\n */\r\n.dark :deep([role=\"tab\"][data-state=\"inactive\"]) {\r\n background: hsl(var(--secondary));\r\n color: hsl(var(--secondary-foreground));\r\n border-top: 1px solid hsl(var(--border) / 0.5);\r\n border-left: 1px solid hsl(var(--border) / 0.5);\r\n border-right: 1px solid hsl(var(--border) / 0.5);\r\n}\r\n\r\n.dark :deep([role=\"tab\"][data-state=\"inactive\"]:hover) {\r\n background: hsl(var(--muted));\r\n color: hsl(var(--muted-foreground));\r\n}\r\n\r\n/**\r\n * ํ์ฑ ํญ - ๊ฐ์กฐ๋ ์คํ์ผ\r\n * Active tab - emphasized style\r\n */\r\n:deep([role=\"tab\"][data-state=\"active\"]) {\r\n background: hsl(var(--background));\r\n color: hsl(var(--foreground));\r\n font-weight: 500;\r\n border-top: 2px solid hsl(var(--primary));\r\n border-left: 1px solid hsl(var(--border));\r\n border-right: 1px solid hsl(var(--border));\r\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);\r\n z-index: 1;\r\n}\r\n\r\n/**\r\n * ๋คํฌ๋ชจ๋์์ ํ์ฑ ํญ - ๋ฐฐ๊ฒฝ์ ๋ช
ํํ ๊ตฌ๋ถ\r\n * Active tab in dark mode - clear background distinction\r\n */\r\n.dark :deep([role=\"tab\"][data-state=\"active\"]) {\r\n background: hsl(var(--card));\r\n color: hsl(var(--card-foreground));\r\n border-top: 2px solid hsl(var(--primary));\r\n border-left: 1px solid hsl(var(--border));\r\n border-right: 1px solid hsl(var(--border));\r\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);\r\n}\r\n\r\n</style>\r\n\r\n"],"names":["props","__props","emit","__emit","safeTabs","computed","internalActiveId","ref","isHandlingEvent","watch","newValue","newTabs","t","handleTabValueChange","value","stringValue","nextTick","handleTabClick","tabId","handleCloseTab","rootClasses","cn","STYLE_PRESETS","preset","listClasses","_createBlock","_unref","Tabs","_createVNode","TabsList","_createElementBlock","_Fragment","_renderList","tab","TabsTrigger","$event","_normalizeClass","JIcon","_createElementVNode","_hoisted_1","_toDisplayString","e","X","_hoisted_3","TabsContent","_renderSlot","_ctx","_openBlock","_resolveDynamicComponent","_mergeProps","_hoisted_4","_hoisted_5"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AA6BA,UAAMA,IAAQC,GAIRC,IAAOC,GAMPC,IAAWC,EAAS,MACjB,MAAM,QAAQL,EAAM,IAAI,IAAIA,EAAM,OAAO,CAAA,CACjD,GAMKM,IAAmBC;AAAA,MACvBP,EAAM,gBAAgBI,EAAS,MAAM,SAAS,IAAIA,EAAS,MAAM,CAAC,GAAG,KAAK,OAAO;AAAA,IAAA;AAOnF,QAAII,IAAkB;AAMtB,IAAAC,EAAM,MAAMT,EAAM,aAAa,CAACU,MAAa;AAC3C,MAAIA,MAAa,UAAaA,MAAaJ,EAAiB,UAC1DA,EAAiB,QAAQI;AAAA,IAE7B,GAAG,EAAE,WAAW,IAAM,GAMtBD,EAAML,GAAU,CAACO,MAAY;AAC3B,MAAI,CAACX,EAAM,eAAeW,EAAQ,SAAS,KAAK,CAACA,EAAQ,KAAK,CAAAC,MAAKA,EAAE,OAAON,EAAiB,KAAK,KAAKK,EAAQ,CAAC,MAC9GL,EAAiB,QAAQK,EAAQ,CAAC,EAAE;AAAA,IAExC,CAAC;AAMD,UAAME,IAAuB,CAACC,MAA2B;AACvD,UAAIN,EAAiB;AAErB,YAAMO,IAAc,OAAOD,CAAK;AAChC,MAAIC,MAAgBT,EAAiB,UACnCE,IAAkB,IAClBF,EAAiB,QAAQS,GACzBb,EAAK,sBAAsBa,CAAW,GACtCb,EAAK,aAAaa,CAAW,GAE7BC,EAAS,MAAM;AACb,QAAAR,IAAkB;AAAA,MACpB,CAAC;AAAA,IAEL,GAMMS,IAAiB,CAACC,MAAkB;AAGxC,MAAIV,KAAmBU,MAAUZ,EAAiB,UAElDE,IAAkB,IAClBF,EAAiB,QAAQY,GACzBhB,EAAK,sBAAsBgB,CAAK,GAChChB,EAAK,aAAagB,CAAK,GAEvBF,EAAS,MAAM;AACb,QAAAR,IAAkB;AAAA,MACpB,CAAC;AAAA,IACH,GAMMW,IAAiB,CAAC,GAAUD,MAAkB;AAClD,QAAE,gBAAA,GACFhB,EAAK,YAAYgB,CAAK;AAAA,IACxB,GAMME,IAAcf,EAAS,MACpBgB,EAAG,+BAA+BrB,EAAM,KAAK,CACrD,GAKKsB,IAID;AAAA,MACH,SAAS;AAAA,QACP,iBAAiB;AAAA,QACjB,kBAAkB;AAAA,QAClB,kBAAkB;AAAA,MAAA;AAAA,MAEpB,SAAS;AAAA,QACP,iBAAiB;AAAA,QACjB,kBAAkB;AAAA,QAClB,kBAAkB;AAAA,MAAA;AAAA,IACpB,GAGIC,IAASlB,EAAS,MACfiB,EAActB,EAAM,SAAS,KAAKsB,EAAc,OACxD,GAMKE,IAAcnB,EAAS,MACpBgB,EAAG,wBAAwBE,EAAO,MAAM,kBAAkBvB,EAAM,SAAS,CACjF;2BAICyB,EA+DOC,EAAAC,CAAA,GAAA;AAAA,MA9DJ,eAAarB,EAAA;AAAA,MACb,uBAAoBO;AAAA,MACrB,aAAY;AAAA,MACX,SAAOO,EAAA,KAAW;AAAA,IAAA;iBAGnB,MA8BW;AAAA,QA9BXQ,EA8BWF,EAAAG,CAAA,GAAA;AAAA,UA9BA,SAAOL,EAAA,KAAW;AAAA,QAAA;qBAEzB,MAAuB;AAAA,oBADzBM,EA4BcC,GAAA,MAAAC,EA3BE5B,EAAA,OAAQ,CAAf6B,YADTR,EA4BcC,EAAAQ,CAAA,GAAA;AAAA,cA1BX,KAAKD,EAAI;AAAA,cACT,OAAOA,EAAI;AAAA,cACX,SAAK,CAAAE,MAAElB,EAAegB,EAAI,EAAE;AAAA,cAC5B,OAAKG,EAAEV,KAAE,8BAA+BH,EAAA,MAAO,iBAAiBA,EAAA,MAAO,gBAAgB,CAAA;AAAA,YAAA;yBAGxF,MAKE;AAAA,gBAJMU,EAAI,aADZR,EAKEY,GAAA;AAAA;kBAHC,MAAMJ,EAAI;AAAA,kBACX,MAAK;AAAA,kBACL,OAAM;AAAA,gBAAA;gBAIRK,EAAoD,QAApDC,GAAoDC,EAAnBP,EAAI,KAAK,GAAA,CAAA;AAAA,gBAIlCA,EAAI,iBADZH,EAQS,UAAA;AAAA;kBANP,MAAK;AAAA,kBACL,OAAM;AAAA,kBACL,cAAU,GAAKG,EAAI,KAAK;AAAA,kBACxB,SAAK,CAAGQ,MAAMtB,EAAesB,GAAGR,EAAI,EAAE;AAAA,gBAAA;kBAEvCL,EAAyBF,EAAAgB,CAAA,GAAA,EAAtB,OAAM,eAAa;AAAA,gBAAA;;;;;;;QAM5BJ,EAsBM,OAtBNK,GAsBM;AAAA,kBArBJb,EAoBcC,GAAA,MAAAC,EAnBE5B,EAAA,OAAQ,CAAf6B,YADTR,EAoBcC,EAAAkB,CAAA,GAAA;AAAA,YAlBX,KAAG,WAAaX,EAAI,EAAE;AAAA,YACtB,OAAOA,EAAI;AAAA,YACZ,OAAM;AAAA,UAAA;uBAGN,MAYO;AAAA,cAZPY,EAYOC,EAAA,QAAA,WAZiBb,EAAI,EAAE,MAAK,KAAAA,EAAA,GAAnC,MAYO;AAAA,gBATGA,EAAI,aADZc,KAAAtB,EAIEuB,EAFKf,EAAI,SAAS,GAFpBgB,EAIE;AAAA;;mBADQhB,EAAI,SAAK,CAAA,CAAA,GAAA,MAAA,EAAA,MAInBc,EAAA,GAAAjB,EAEM,OAFNoB,GAEM;AAAA,kBADJZ,EAAwD,KAAxDa,GAAwDX,EAApBP,EAAI,KAAK,IAAG,QAAI,CAAA;AAAA,gBAAA;;;;;;;;;;;"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("vue"),x=require("../atoms/JButton.vue.cjs");require("../shadcn/index.cjs");require("lucide-vue-next");const n=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 o=require("../atoms/JIcon.vue.cjs"),
|
|
1
|
+
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("vue"),x=require("../atoms/JButton.vue.cjs");require("../shadcn/index.cjs");require("lucide-vue-next");const n=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 o=require("../atoms/JIcon.vue.cjs"),b=require("../atoms/JLabel.vue.cjs"),p=require("../atoms/JPopover.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 C={class:"flex items-center gap-3 flex-1"},y={class:"flex items-center gap-2"},g={class:"p-2"},k={class:"text-xs text-muted-foreground whitespace-normal break-words"},h={key:0,class:"flex items-center gap-2"},v={key:1},q=e.defineComponent({__name:"JTitlebar",props:{styletype:{default:"default"},icon:{},title:{},description:{},showHelp:{type:Boolean},buttons:{default:()=>[]},class:{}},emits:["buttonClick","help"],setup(r,{emit:d}){const i=r,a={default:{class:"flex items-center justify-between w-full h-8 px-3 border-b border-border bg-background",iconClass:"text-primary",titleClass:"text-foreground text-md",infoIconClass:"text-muted-foreground hover:text-primary"},primary:{class:"flex items-center justify-between w-full h-8 px-3 border-b border-blue-400/30 bg-blue-500",iconClass:"text-white",titleClass:"text-white font-semibold text-md",infoIconClass:"text-white/80 hover:text-white"},accent:{class:"flex items-center justify-between w-full h-8 px-3 border-b border-blue-200 bg-blue-50",iconClass:"text-blue-600",titleClass:"text-blue-700 font-semibold text-md",infoIconClass:"text-blue-600/70 hover:text-blue-700"},neutral:{class:"flex items-center justify-between w-full h-8 px-3 border-b border-gray-300 bg-gray-100",iconClass:"text-gray-600",titleClass:"text-gray-700 text-md",infoIconClass:"text-gray-500 hover:text-gray-700"},elevated:{class:"flex items-center justify-between w-full h-8 px-3 border-b border-border bg-background shadow-md",iconClass:"text-primary",titleClass:"text-foreground font-semibold text-md",infoIconClass:"text-muted-foreground hover:text-primary"}},l=e.computed(()=>a[i.styletype]??a.default),c=d,m=s=>{s.onClick?.(),c("buttonClick",s)};return(s,u)=>(e.openBlock(),e.createElementBlock("div",{class:e.normalizeClass(e.unref(n.cn)(l.value.class,i.class))},[e.createElementVNode("div",C,[r.icon?(e.openBlock(),e.createBlock(e.unref(o.default),{key:0,name:r.icon,class:e.normalizeClass(l.value.iconClass)},null,8,["name","class"])):e.createCommentVNode("",!0),e.createElementVNode("div",y,[e.createVNode(e.unref(b.default),{text:r.title||"",class:e.normalizeClass(e.unref(n.cn)("font-semibold",l.value.titleClass))},null,8,["text","class"]),r.description?(e.openBlock(),e.createBlock(e.unref(p.default),{key:0,position:"bottom",align:"center","side-offset":8},{trigger:e.withCtx(()=>[e.createVNode(e.unref(o.default),{name:"info",size:"sm",class:e.normalizeClass(e.unref(n.cn)("cursor-help transition-colors inline-flex",l.value.infoIconClass))},null,8,["class"])]),default:e.withCtx(()=>[e.createElementVNode("div",g,[e.createElementVNode("p",k,e.toDisplayString(r.description),1)])]),_:1})):e.createCommentVNode("",!0),r.showHelp?(e.openBlock(),e.createBlock(e.unref(o.default),{key:1,name:"circleQuestionMark",size:"sm",class:e.normalizeClass(e.unref(n.cn)("cursor-pointer transition-colors inline-flex",l.value.infoIconClass)),onClick:u[0]||(u[0]=t=>c("help"))},null,8,["class"])):e.createCommentVNode("",!0)])]),r.buttons&&r.buttons.length>0?(e.openBlock(),e.createElementBlock("div",h,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(r.buttons,(t,f)=>(e.openBlock(),e.createBlock(e.unref(x.default),{key:f,variant:t.variant,styletype:t.styletype,disabled:t.disabled,loading:t.loading,size:t.size,onClick:_=>m(t)},{default:e.withCtx(()=>[t.icon?(e.openBlock(),e.createBlock(e.unref(o.default),{key:0,name:t.icon,size:"sm",class:"mr-1.5"},null,8,["name"])):e.createCommentVNode("",!0),t.text?(e.openBlock(),e.createElementBlock("span",v,e.toDisplayString(t.text),1)):e.createCommentVNode("",!0)]),_:2},1032,["variant","styletype","disabled","loading","size","onClick"]))),128))])):e.createCommentVNode("",!0),e.renderSlot(s.$slots,"buttons")],2))}});exports.default=q;
|
|
2
2
|
//# sourceMappingURL=JTitlebar.vue.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JTitlebar.vue.cjs","sources":["../../../../src/components/molecules/JTitlebar.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from \"vue\"\nimport { JIcon, JLabel, JPopover, JButton } from '@/components/atoms'\nimport type { ButtonVariants } from '@/components/shadcn'\nimport { cn } from \"@/lib/utils\"\n\nexport type TitlebarButton = {\n /** ๋ฒํผ ์์ด์ฝ */\n icon?: string\n /** ๋ฒํผ ํ
์คํธ */\n text?: string\n /** ๋ฒํผ ํด๋ฆญ ํธ๋ค๋ฌ */\n onClick?: () => void\n /** ๋ฒํผ variant */\n variant?: ButtonVariants['variant']\n /** ๋ฒํผ ์คํ์ผ ํ์
*/\n styletype?: 'default' | 'primary' | 'secondary' | 'success' | 'warning' | 'danger' | 'outline' | 'ghost' | 'link' | 'sm' | 'lg' | 'icon'\n /** ๋ฒํผ size */\n size?: 'sm' | 'md' | 'lg'\n /** ๋ฒํผ ๋นํ์ฑํ */\n disabled?: boolean\n /** ๋ฒํผ ๋ก๋ฉ ์ํ */\n loading?: boolean\n}\n\ntype StyleType =\n | 'default' // ๊ธฐ๋ณธ ์คํ์ผ: ์ผ๋ฐ ํ์ด์ง์ฉ (ํฐ ๋ฐฐ๊ฒฝ, ์์ ๋ณด๋)\n | 'primary' // ๊ฐ์กฐ ์คํ์ผ: ์ฃผ์ ๊ธฐ๋ฅ์ฉ (๋ฐ์ ํ๋ ๋ฐฐ๊ฒฝ, ํฐ ํ
์คํธ)\n | 'accent' // ์ก์ผํธ ์คํ์ผ: ๋ถ๋๋ฌ์ด ๊ฐ์กฐ์ฉ (์ฐํ ํ๋ ๋ฐฐ๊ฒฝ, ์งํ ํ
์คํธ)\n | 'neutral' // ์ค๋ฆฝ ์คํ์ผ: ์๋ธ ํ์ด์ง์ฉ (ํ์ ๋ฐฐ๊ฒฝ, ํ์ ํ
์คํธ)\n | 'elevated' // ๊ฐ์กฐ ์คํ์ผ: ๊น์ด๊ฐ ์๋ ๊ตฌ๋ถ (ํฐ ๋ฐฐ๊ฒฝ, ๊ทธ๋ฆผ์, ๋ณด๋)\n\nconst props = withDefaults(\n defineProps<{\n /** Titlebar ์คํ์ผ ํ์
*/\n styletype?: StyleType\n /** ํ๋ก๊ทธ๋จ ์์ด์ฝ */\n icon?: string\n /** ํ๋ก๊ทธ๋จ๋ช
*/\n title?: string\n /** ํ๋ก๊ทธ๋จ ์ค๋ช
(Popover์ ํ์) */\n description?: string\n /** ๋์๋ง ์์ด์ฝ(?) ํ์ ์ฌ๋ถ โ ํด๋ฆญ ์ help ์ด๋ฒคํธ emit */\n showHelp?: boolean\n /** ๋ฉ์ธ ๋ฒํผ ๋ชฉ๋ก */\n buttons?: TitlebarButton[]\n }>(),\n {\n styletype: 'default',\n buttons: () => [],\n }\n)\n\n/**\n * styletype -> class ๋งคํ (๋ฐฐ๊ฒฝ, ๋ณด๋, ๊ทธ๋ฆผ์ ๋ฑ)\n */\nconst STYLE_PRESETS: Record<StyleType, { \n class: string\n iconClass: string // ์์ด์ฝ ์์ ํด๋์ค\n titleClass: string // ์ ๋ชฉ ํ
์คํธ ์์ ํด๋์ค\n infoIconClass: string // ์ ๋ณด ์์ด์ฝ ์์ ํด๋์ค\n}> = {\n default: {\n // ๊ธฐ๋ณธ: ํฐ ๋ฐฐ๊ฒฝ + ์์ ๋ณด๋ (๊ฐ์ฅ ์ผ๋ฐ์ )\n class: 'flex items-center justify-between w-full h-8 px-3 border-b border-border bg-background',\n iconClass: 'text-primary',\n titleClass: 'text-foreground text-md',\n infoIconClass: 'text-muted-foreground hover:text-primary',\n },\n primary: {\n // ๊ฐ์กฐ: ๋ฐ์ ํ๋ ๋ฐฐ๊ฒฝ + ํฐ ํ
์คํธ (๋ช
ํํ ๊ฐ์กฐ)\n // text-white๋ฅผ ์ ๊ฑฐํ์ฌ ๋ฒํผ์ด ์์ ์์์ ๋ฐ์ง ์๋๋ก ํจ\n class: 'flex items-center justify-between w-full h-8 px-3 border-b border-blue-400/30 bg-blue-500',\n iconClass: 'text-white',\n titleClass: 'text-white font-semibold text-md',\n infoIconClass: 'text-white/80 hover:text-white',\n },\n accent: {\n // ์ก์ผํธ: ์ฐํ ํ๋ ๋ฐฐ๊ฒฝ + ์งํ ํ๋ ํ
์คํธ (๋ถ๋๋ฌ์ด ๊ฐ์กฐ)\n // text-blue-700์ ์ ๊ฑฐํ์ฌ ๋ฒํผ์ด ์์ ์์์ ๋ฐ์ง ์๋๋ก ํจ\n class: 'flex items-center justify-between w-full h-8 px-3 border-b border-blue-200 bg-blue-50',\n iconClass: 'text-blue-600',\n titleClass: 'text-blue-700 font-semibold text-md',\n infoIconClass: 'text-blue-600/70 hover:text-blue-700',\n },\n neutral: {\n // ์ค๋ฆฝ: ํ์ ๋ฐฐ๊ฒฝ + ํ์ ํ
์คํธ (ํ์คํ ๊ตฌ๋ถ)\n // text-gray-700์ ์ ๊ฑฐํ์ฌ ๋ฒํผ์ด ์์ ์์์ ๋ฐ์ง ์๋๋ก ํจ\n class: 'flex items-center justify-between w-full h-8 px-3 border-b border-gray-300 bg-gray-100',\n iconClass: 'text-gray-600',\n titleClass: 'text-gray-700 text-md',\n infoIconClass: 'text-gray-500 hover:text-gray-700',\n },\n elevated: {\n // ๊ฐ์กฐ: ํฐ ๋ฐฐ๊ฒฝ + ๊ทธ๋ฆผ์ + ๋ณด๋ (๊น์ด๊ฐ ์๋ ๊ตฌ๋ถ)\n class: 'flex items-center justify-between w-full h-8 px-3 border-b border-border bg-background shadow-md',\n iconClass: 'text-primary',\n titleClass: 'text-foreground font-semibold text-md',\n infoIconClass: 'text-muted-foreground hover:text-primary',\n },\n}\n\nconst preset = computed(() => {\n return STYLE_PRESETS[props.styletype] ?? STYLE_PRESETS.default\n})\n\nconst emit = defineEmits<{\n /** ๋ฒํผ ํด๋ฆญ ์ด๋ฒคํธ */\n buttonClick: [button: TitlebarButton]\n /** ๋์๋ง ์์ด์ฝ ํด๋ฆญ ์ด๋ฒคํธ */\n help: []\n}>()\n\nconst handleButtonClick = (button: TitlebarButton) => {\n // ๋ฒํผ ํด๋ฆญ ํธ๋ค๋ฌ ํจํด:\n // 1. button.onClick์ด ์์ผ๋ฉด ์คํ (์ธ๋ผ์ธ ํธ๋ค๋ฌ)\n // 2. ํญ์ emit('buttonClick', button) ์คํ (๋ถ๋ชจ ์ปดํฌ๋ํธ๋ก ์ ๋ฌ)\n // ์ฃผ์: onClick๊ณผ emit์ด ๋ชจ๋ ์คํ๋๋ฏ๋ก ์ค๋ณต ์ฒ๋ฆฌ ๊ฐ๋ฅ์ฑ ์์\n button.onClick?.()\n emit('buttonClick', button)\n}\n</script>\n\n<template>\n <div :class=\"cn(preset.class)\">\n <!-- ์ผ์ชฝ: ์์ด์ฝ + ํ๋ก๊ทธ๋จ๋ช
-->\n <div class=\"flex items-center gap-3 flex-1\">\n <!-- ์์ด์ฝ -->\n <JIcon \n v-if=\"icon\" \n :name=\"icon\" \n :class=\"preset.iconClass\"\n />\n \n <!-- ํ๋ก๊ทธ๋จ๋ช
+ ์ ๋ณด ์์ด์ฝ + Popover -->\n <div class=\"flex items-center gap-2\">\n <!-- ํ๋ก๊ทธ๋จ๋ช
-->\n <JLabel \n :text=\"title || ''\" \n :class=\"cn('font-semibold', preset.titleClass)\"\n />\n \n <!-- ์ ๋ณด ์์ด์ฝ (description์ด ์์ ๋๋ง ํ์) -->\n <JPopover \n v-if=\"description\" \n position=\"bottom\"\n align=\"center\"\n :side-offset=\"8\"\n >\n <template #trigger>\n <JIcon \n name=\"info\" \n size=\"sm\" \n :class=\"cn('cursor-help transition-colors inline-flex', preset.infoIconClass)\"\n />\n </template>\n <div class=\"p-2\">\n <p class=\"text-xs text-muted-foreground whitespace-normal break-words\">{{ description }}</p>\n </div>\n </JPopover>\n\n <!-- ๋์๋ง ์์ด์ฝ (showHelp์ผ ๋ ํ์, ํด๋ฆญ ์ help ์ด๋ฒคํธ) -->\n <JIcon\n v-if=\"showHelp\"\n name=\"circleQuestionMark\"\n size=\"sm\"\n :class=\"cn('cursor-pointer transition-colors inline-flex', preset.infoIconClass)\"\n @click=\"emit('help')\"\n />\n </div>\n </div>\n\n <!-- ์ค๋ฅธ์ชฝ: ๋ฉ์ธ ๋ฒํผ๋ค -->\n <!-- buttons prop์ผ๋ก ์ ์๋ ๋ฒํผ๋ค (v-if๋ก ์กฐ๊ฑด๋ถ ๋ ๋๋ง) -->\n <div v-if=\"buttons && buttons.length > 0\" class=\"flex items-center gap-2\">\n <JButton\n v-for=\"(button, index) in buttons\"\n :key=\"index\"\n :variant=\"button.variant\"\n :styletype=\"button.styletype\"\n :disabled=\"button.disabled\"\n :loading=\"button.loading\"\n :size=\"button.size\"\n @click=\"handleButtonClick(button)\"\n >\n <JIcon v-if=\"button.icon\" :name=\"button.icon\" size=\"sm\" class=\"mr-1.5\" />\n <span v-if=\"button.text\">{{ button.text }}</span>\n </JButton>\n </div>\n\n <!-- ๋ฒํผ ์ฌ๋กฏ ๋ ์ด์์ ์ค๋ช
:\n - buttons prop๊ณผ buttons slot์ด ๋ชจ๋ ์ ๊ณต๋๋ฉด ํจ๊ป ํ์๋จ\n - buttons prop: ๊ตฌ์กฐํ๋ ๋ฒํผ ์ ์ (JButton ์ปดํฌ๋ํธ ์ฌ์ฉ)\n - buttons slot: ์์ ํ ์ปค์คํ
๋ฒํผ ์ ์ด ๊ฐ๋ฅ\n - ๋ ์ด์์: buttons prop์ด ๋จผ์ ๋ ๋๋ง๋๊ณ , ๊ทธ ๋ค์ slot์ด ๋ ๋๋ง๋จ -->\n <slot name=\"buttons\" />\n </div>\n</template>\n\n"],"names":["props","__props","STYLE_PRESETS","preset","computed","emit","__emit","handleButtonClick","button","_createElementBlock","_normalizeClass","_unref","
|
|
1
|
+
{"version":3,"file":"JTitlebar.vue.cjs","sources":["../../../../src/components/molecules/JTitlebar.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from \"vue\"\nimport { JIcon, JLabel, JPopover, JButton } from '@/components/atoms'\nimport type { ButtonVariants } from '@/components/shadcn'\nimport { cn } from \"@/lib/utils\"\n\nexport type TitlebarButton = {\n /** ๋ฒํผ ์์ด์ฝ */\n icon?: string\n /** ๋ฒํผ ํ
์คํธ */\n text?: string\n /** ๋ฒํผ ํด๋ฆญ ํธ๋ค๋ฌ */\n onClick?: () => void\n /** ๋ฒํผ variant */\n variant?: ButtonVariants['variant']\n /** ๋ฒํผ ์คํ์ผ ํ์
*/\n styletype?: 'default' | 'primary' | 'secondary' | 'success' | 'warning' | 'danger' | 'outline' | 'ghost' | 'link' | 'sm' | 'lg' | 'icon'\n /** ๋ฒํผ size */\n size?: 'sm' | 'md' | 'lg'\n /** ๋ฒํผ ๋นํ์ฑํ */\n disabled?: boolean\n /** ๋ฒํผ ๋ก๋ฉ ์ํ */\n loading?: boolean\n}\n\ntype StyleType =\n | 'default' // ๊ธฐ๋ณธ ์คํ์ผ: ์ผ๋ฐ ํ์ด์ง์ฉ (ํฐ ๋ฐฐ๊ฒฝ, ์์ ๋ณด๋)\n | 'primary' // ๊ฐ์กฐ ์คํ์ผ: ์ฃผ์ ๊ธฐ๋ฅ์ฉ (๋ฐ์ ํ๋ ๋ฐฐ๊ฒฝ, ํฐ ํ
์คํธ)\n | 'accent' // ์ก์ผํธ ์คํ์ผ: ๋ถ๋๋ฌ์ด ๊ฐ์กฐ์ฉ (์ฐํ ํ๋ ๋ฐฐ๊ฒฝ, ์งํ ํ
์คํธ)\n | 'neutral' // ์ค๋ฆฝ ์คํ์ผ: ์๋ธ ํ์ด์ง์ฉ (ํ์ ๋ฐฐ๊ฒฝ, ํ์ ํ
์คํธ)\n | 'elevated' // ๊ฐ์กฐ ์คํ์ผ: ๊น์ด๊ฐ ์๋ ๊ตฌ๋ถ (ํฐ ๋ฐฐ๊ฒฝ, ๊ทธ๋ฆผ์, ๋ณด๋)\n\nconst props = withDefaults(\n defineProps<{\n /** Titlebar ์คํ์ผ ํ์
*/\n styletype?: StyleType\n /** ํ๋ก๊ทธ๋จ ์์ด์ฝ */\n icon?: string\n /** ํ๋ก๊ทธ๋จ๋ช
*/\n title?: string\n /** ํ๋ก๊ทธ๋จ ์ค๋ช
(Popover์ ํ์) */\n description?: string\n /** ๋์๋ง ์์ด์ฝ(?) ํ์ ์ฌ๋ถ โ ํด๋ฆญ ์ help ์ด๋ฒคํธ emit */\n showHelp?: boolean\n /** ๋ฉ์ธ ๋ฒํผ ๋ชฉ๋ก */\n buttons?: TitlebarButton[]\n /** ์ถ๊ฐ ํด๋์ค (์ธ๋ถ ์ปค์คํฐ๋ง์ด์ง์ฉ) */\n class?: string\n }>(),\n {\n styletype: 'default',\n buttons: () => [],\n }\n)\n\n/**\n * styletype -> class ๋งคํ (๋ฐฐ๊ฒฝ, ๋ณด๋, ๊ทธ๋ฆผ์ ๋ฑ)\n */\nconst STYLE_PRESETS: Record<StyleType, { \n class: string\n iconClass: string // ์์ด์ฝ ์์ ํด๋์ค\n titleClass: string // ์ ๋ชฉ ํ
์คํธ ์์ ํด๋์ค\n infoIconClass: string // ์ ๋ณด ์์ด์ฝ ์์ ํด๋์ค\n}> = {\n default: {\n // ๊ธฐ๋ณธ: ํฐ ๋ฐฐ๊ฒฝ + ์์ ๋ณด๋ (๊ฐ์ฅ ์ผ๋ฐ์ )\n class: 'flex items-center justify-between w-full h-8 px-3 border-b border-border bg-background',\n iconClass: 'text-primary',\n titleClass: 'text-foreground text-md',\n infoIconClass: 'text-muted-foreground hover:text-primary',\n },\n primary: {\n // ๊ฐ์กฐ: ๋ฐ์ ํ๋ ๋ฐฐ๊ฒฝ + ํฐ ํ
์คํธ (๋ช
ํํ ๊ฐ์กฐ)\n // text-white๋ฅผ ์ ๊ฑฐํ์ฌ ๋ฒํผ์ด ์์ ์์์ ๋ฐ์ง ์๋๋ก ํจ\n class: 'flex items-center justify-between w-full h-8 px-3 border-b border-blue-400/30 bg-blue-500',\n iconClass: 'text-white',\n titleClass: 'text-white font-semibold text-md',\n infoIconClass: 'text-white/80 hover:text-white',\n },\n accent: {\n // ์ก์ผํธ: ์ฐํ ํ๋ ๋ฐฐ๊ฒฝ + ์งํ ํ๋ ํ
์คํธ (๋ถ๋๋ฌ์ด ๊ฐ์กฐ)\n // text-blue-700์ ์ ๊ฑฐํ์ฌ ๋ฒํผ์ด ์์ ์์์ ๋ฐ์ง ์๋๋ก ํจ\n class: 'flex items-center justify-between w-full h-8 px-3 border-b border-blue-200 bg-blue-50',\n iconClass: 'text-blue-600',\n titleClass: 'text-blue-700 font-semibold text-md',\n infoIconClass: 'text-blue-600/70 hover:text-blue-700',\n },\n neutral: {\n // ์ค๋ฆฝ: ํ์ ๋ฐฐ๊ฒฝ + ํ์ ํ
์คํธ (ํ์คํ ๊ตฌ๋ถ)\n // text-gray-700์ ์ ๊ฑฐํ์ฌ ๋ฒํผ์ด ์์ ์์์ ๋ฐ์ง ์๋๋ก ํจ\n class: 'flex items-center justify-between w-full h-8 px-3 border-b border-gray-300 bg-gray-100',\n iconClass: 'text-gray-600',\n titleClass: 'text-gray-700 text-md',\n infoIconClass: 'text-gray-500 hover:text-gray-700',\n },\n elevated: {\n // ๊ฐ์กฐ: ํฐ ๋ฐฐ๊ฒฝ + ๊ทธ๋ฆผ์ + ๋ณด๋ (๊น์ด๊ฐ ์๋ ๊ตฌ๋ถ)\n class: 'flex items-center justify-between w-full h-8 px-3 border-b border-border bg-background shadow-md',\n iconClass: 'text-primary',\n titleClass: 'text-foreground font-semibold text-md',\n infoIconClass: 'text-muted-foreground hover:text-primary',\n },\n}\n\nconst preset = computed(() => {\n return STYLE_PRESETS[props.styletype] ?? STYLE_PRESETS.default\n})\n\nconst emit = defineEmits<{\n /** ๋ฒํผ ํด๋ฆญ ์ด๋ฒคํธ */\n buttonClick: [button: TitlebarButton]\n /** ๋์๋ง ์์ด์ฝ ํด๋ฆญ ์ด๋ฒคํธ */\n help: []\n}>()\n\nconst handleButtonClick = (button: TitlebarButton) => {\n // ๋ฒํผ ํด๋ฆญ ํธ๋ค๋ฌ ํจํด:\n // 1. button.onClick์ด ์์ผ๋ฉด ์คํ (์ธ๋ผ์ธ ํธ๋ค๋ฌ)\n // 2. ํญ์ emit('buttonClick', button) ์คํ (๋ถ๋ชจ ์ปดํฌ๋ํธ๋ก ์ ๋ฌ)\n // ์ฃผ์: onClick๊ณผ emit์ด ๋ชจ๋ ์คํ๋๋ฏ๋ก ์ค๋ณต ์ฒ๋ฆฌ ๊ฐ๋ฅ์ฑ ์์\n button.onClick?.()\n emit('buttonClick', button)\n}\n</script>\n\n<template>\n <div :class=\"cn(preset.class, props.class)\">\n <!-- ์ผ์ชฝ: ์์ด์ฝ + ํ๋ก๊ทธ๋จ๋ช
-->\n <div class=\"flex items-center gap-3 flex-1\">\n <!-- ์์ด์ฝ -->\n <JIcon \n v-if=\"icon\" \n :name=\"icon\" \n :class=\"preset.iconClass\"\n />\n \n <!-- ํ๋ก๊ทธ๋จ๋ช
+ ์ ๋ณด ์์ด์ฝ + Popover -->\n <div class=\"flex items-center gap-2\">\n <!-- ํ๋ก๊ทธ๋จ๋ช
-->\n <JLabel \n :text=\"title || ''\" \n :class=\"cn('font-semibold', preset.titleClass)\"\n />\n \n <!-- ์ ๋ณด ์์ด์ฝ (description์ด ์์ ๋๋ง ํ์) -->\n <JPopover \n v-if=\"description\" \n position=\"bottom\"\n align=\"center\"\n :side-offset=\"8\"\n >\n <template #trigger>\n <JIcon \n name=\"info\" \n size=\"sm\" \n :class=\"cn('cursor-help transition-colors inline-flex', preset.infoIconClass)\"\n />\n </template>\n <div class=\"p-2\">\n <p class=\"text-xs text-muted-foreground whitespace-normal break-words\">{{ description }}</p>\n </div>\n </JPopover>\n\n <!-- ๋์๋ง ์์ด์ฝ (showHelp์ผ ๋ ํ์, ํด๋ฆญ ์ help ์ด๋ฒคํธ) -->\n <JIcon\n v-if=\"showHelp\"\n name=\"circleQuestionMark\"\n size=\"sm\"\n :class=\"cn('cursor-pointer transition-colors inline-flex', preset.infoIconClass)\"\n @click=\"emit('help')\"\n />\n </div>\n </div>\n\n <!-- ์ค๋ฅธ์ชฝ: ๋ฉ์ธ ๋ฒํผ๋ค -->\n <!-- buttons prop์ผ๋ก ์ ์๋ ๋ฒํผ๋ค (v-if๋ก ์กฐ๊ฑด๋ถ ๋ ๋๋ง) -->\n <div v-if=\"buttons && buttons.length > 0\" class=\"flex items-center gap-2\">\n <JButton\n v-for=\"(button, index) in buttons\"\n :key=\"index\"\n :variant=\"button.variant\"\n :styletype=\"button.styletype\"\n :disabled=\"button.disabled\"\n :loading=\"button.loading\"\n :size=\"button.size\"\n @click=\"handleButtonClick(button)\"\n >\n <JIcon v-if=\"button.icon\" :name=\"button.icon\" size=\"sm\" class=\"mr-1.5\" />\n <span v-if=\"button.text\">{{ button.text }}</span>\n </JButton>\n </div>\n\n <!-- ๋ฒํผ ์ฌ๋กฏ ๋ ์ด์์ ์ค๋ช
:\n - buttons prop๊ณผ buttons slot์ด ๋ชจ๋ ์ ๊ณต๋๋ฉด ํจ๊ป ํ์๋จ\n - buttons prop: ๊ตฌ์กฐํ๋ ๋ฒํผ ์ ์ (JButton ์ปดํฌ๋ํธ ์ฌ์ฉ)\n - buttons slot: ์์ ํ ์ปค์คํ
๋ฒํผ ์ ์ด ๊ฐ๋ฅ\n - ๋ ์ด์์: buttons prop์ด ๋จผ์ ๋ ๋๋ง๋๊ณ , ๊ทธ ๋ค์ slot์ด ๋ ๋๋ง๋จ -->\n <slot name=\"buttons\" />\n </div>\n</template>\n\n"],"names":["props","__props","STYLE_PRESETS","preset","computed","emit","__emit","handleButtonClick","button","_createElementBlock","_normalizeClass","_unref","_createElementVNode","_hoisted_1","_createBlock","JIcon","_hoisted_2","_createVNode","JLabel","cn","JPopover","_hoisted_3","_hoisted_4","_toDisplayString","_openBlock","_hoisted_5","_Fragment","_renderList","index","JButton","$event","_hoisted_6","_renderSlot","_ctx"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { defineComponent as w, computed as
|
|
2
|
-
import
|
|
1
|
+
import { defineComponent as w, computed as z, createElementBlock as c, openBlock as o, normalizeClass as r, unref as t, createElementVNode as m, createCommentVNode as l, renderSlot as I, createBlock as n, createVNode as g, withCtx as f, toDisplayString as C, Fragment as B, renderList as _ } from "vue";
|
|
2
|
+
import $ from "../atoms/JButton.vue.js";
|
|
3
3
|
import "../shadcn/index.js";
|
|
4
4
|
import "lucide-vue-next";
|
|
5
5
|
import { cn as d } from "../../lib/utils.js";
|
|
@@ -13,7 +13,7 @@ import "reka-ui";
|
|
|
13
13
|
/* empty css */
|
|
14
14
|
import "../shadcn/avatar-variants.js";
|
|
15
15
|
import u from "../atoms/JIcon.vue.js";
|
|
16
|
-
import
|
|
16
|
+
import j from "../atoms/JLabel.vue.js";
|
|
17
17
|
import E from "../atoms/JPopover.vue.js";
|
|
18
18
|
import "dompurify";
|
|
19
19
|
/* empty css */
|
|
@@ -24,11 +24,13 @@ import "ag-grid-enterprise";
|
|
|
24
24
|
/* empty css */
|
|
25
25
|
/* empty css */
|
|
26
26
|
/* empty css */
|
|
27
|
+
/* empty css */
|
|
28
|
+
/* empty css */
|
|
27
29
|
import "vue-sonner";
|
|
28
30
|
const S = { class: "flex items-center gap-3 flex-1" }, N = { class: "flex items-center gap-2" }, T = { class: "p-2" }, V = { class: "text-xs text-muted-foreground whitespace-normal break-words" }, H = {
|
|
29
31
|
key: 0,
|
|
30
32
|
class: "flex items-center gap-2"
|
|
31
|
-
},
|
|
33
|
+
}, J = { key: 1 }, fe = /* @__PURE__ */ w({
|
|
32
34
|
__name: "JTitlebar",
|
|
33
35
|
props: {
|
|
34
36
|
styletype: { default: "default" },
|
|
@@ -36,11 +38,12 @@ const S = { class: "flex items-center gap-3 flex-1" }, N = { class: "flex items-
|
|
|
36
38
|
title: {},
|
|
37
39
|
description: {},
|
|
38
40
|
showHelp: { type: Boolean },
|
|
39
|
-
buttons: { default: () => [] }
|
|
41
|
+
buttons: { default: () => [] },
|
|
42
|
+
class: {}
|
|
40
43
|
},
|
|
41
44
|
emits: ["buttonClick", "help"],
|
|
42
|
-
setup(s, { emit:
|
|
43
|
-
const
|
|
45
|
+
setup(s, { emit: h }) {
|
|
46
|
+
const p = s, x = {
|
|
44
47
|
default: {
|
|
45
48
|
// ๊ธฐ๋ณธ: ํฐ ๋ฐฐ๊ฒฝ + ์์ ๋ณด๋ (๊ฐ์ฅ ์ผ๋ฐ์ )
|
|
46
49
|
class: "flex items-center justify-between w-full h-8 px-3 border-b border-border bg-background",
|
|
@@ -79,11 +82,11 @@ const S = { class: "flex items-center gap-3 flex-1" }, N = { class: "flex items-
|
|
|
79
82
|
titleClass: "text-foreground font-semibold text-md",
|
|
80
83
|
infoIconClass: "text-muted-foreground hover:text-primary"
|
|
81
84
|
}
|
|
82
|
-
}, i =
|
|
83
|
-
a.onClick?.(),
|
|
85
|
+
}, i = z(() => x[p.styletype] ?? x.default), b = h, k = (a) => {
|
|
86
|
+
a.onClick?.(), b("buttonClick", a);
|
|
84
87
|
};
|
|
85
|
-
return (a,
|
|
86
|
-
class: r(t(d)(i.value.class))
|
|
88
|
+
return (a, y) => (o(), c("div", {
|
|
89
|
+
class: r(t(d)(i.value.class, p.class))
|
|
87
90
|
}, [
|
|
88
91
|
m("div", S, [
|
|
89
92
|
s.icon ? (o(), n(t(u), {
|
|
@@ -92,7 +95,7 @@ const S = { class: "flex items-center gap-3 flex-1" }, N = { class: "flex items-
|
|
|
92
95
|
class: r(i.value.iconClass)
|
|
93
96
|
}, null, 8, ["name", "class"])) : l("", !0),
|
|
94
97
|
m("div", N, [
|
|
95
|
-
|
|
98
|
+
g(t(j), {
|
|
96
99
|
text: s.title || "",
|
|
97
100
|
class: r(t(d)("font-semibold", i.value.titleClass))
|
|
98
101
|
}, null, 8, ["text", "class"]),
|
|
@@ -103,7 +106,7 @@ const S = { class: "flex items-center gap-3 flex-1" }, N = { class: "flex items-
|
|
|
103
106
|
"side-offset": 8
|
|
104
107
|
}, {
|
|
105
108
|
trigger: f(() => [
|
|
106
|
-
|
|
109
|
+
g(t(u), {
|
|
107
110
|
name: "info",
|
|
108
111
|
size: "sm",
|
|
109
112
|
class: r(t(d)("cursor-help transition-colors inline-flex", i.value.infoIconClass))
|
|
@@ -111,7 +114,7 @@ const S = { class: "flex items-center gap-3 flex-1" }, N = { class: "flex items-
|
|
|
111
114
|
]),
|
|
112
115
|
default: f(() => [
|
|
113
116
|
m("div", T, [
|
|
114
|
-
m("p", V,
|
|
117
|
+
m("p", V, C(s.description), 1)
|
|
115
118
|
])
|
|
116
119
|
]),
|
|
117
120
|
_: 1
|
|
@@ -121,19 +124,19 @@ const S = { class: "flex items-center gap-3 flex-1" }, N = { class: "flex items-
|
|
|
121
124
|
name: "circleQuestionMark",
|
|
122
125
|
size: "sm",
|
|
123
126
|
class: r(t(d)("cursor-pointer transition-colors inline-flex", i.value.infoIconClass)),
|
|
124
|
-
onClick:
|
|
127
|
+
onClick: y[0] || (y[0] = (e) => b("help"))
|
|
125
128
|
}, null, 8, ["class"])) : l("", !0)
|
|
126
129
|
])
|
|
127
130
|
]),
|
|
128
131
|
s.buttons && s.buttons.length > 0 ? (o(), c("div", H, [
|
|
129
|
-
(o(!0), c(
|
|
132
|
+
(o(!0), c(B, null, _(s.buttons, (e, v) => (o(), n(t($), {
|
|
130
133
|
key: v,
|
|
131
134
|
variant: e.variant,
|
|
132
135
|
styletype: e.styletype,
|
|
133
136
|
disabled: e.disabled,
|
|
134
137
|
loading: e.loading,
|
|
135
138
|
size: e.size,
|
|
136
|
-
onClick: (
|
|
139
|
+
onClick: (L) => k(e)
|
|
137
140
|
}, {
|
|
138
141
|
default: f(() => [
|
|
139
142
|
e.icon ? (o(), n(t(u), {
|
|
@@ -142,16 +145,16 @@ const S = { class: "flex items-center gap-3 flex-1" }, N = { class: "flex items-
|
|
|
142
145
|
size: "sm",
|
|
143
146
|
class: "mr-1.5"
|
|
144
147
|
}, null, 8, ["name"])) : l("", !0),
|
|
145
|
-
e.text ? (o(), c("span",
|
|
148
|
+
e.text ? (o(), c("span", J, C(e.text), 1)) : l("", !0)
|
|
146
149
|
]),
|
|
147
150
|
_: 2
|
|
148
151
|
}, 1032, ["variant", "styletype", "disabled", "loading", "size", "onClick"]))), 128))
|
|
149
152
|
])) : l("", !0),
|
|
150
|
-
|
|
153
|
+
I(a.$slots, "buttons")
|
|
151
154
|
], 2));
|
|
152
155
|
}
|
|
153
156
|
});
|
|
154
157
|
export {
|
|
155
|
-
|
|
158
|
+
fe as default
|
|
156
159
|
};
|
|
157
160
|
//# sourceMappingURL=JTitlebar.vue.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JTitlebar.vue.js","sources":["../../../../src/components/molecules/JTitlebar.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from \"vue\"\nimport { JIcon, JLabel, JPopover, JButton } from '@/components/atoms'\nimport type { ButtonVariants } from '@/components/shadcn'\nimport { cn } from \"@/lib/utils\"\n\nexport type TitlebarButton = {\n /** ๋ฒํผ ์์ด์ฝ */\n icon?: string\n /** ๋ฒํผ ํ
์คํธ */\n text?: string\n /** ๋ฒํผ ํด๋ฆญ ํธ๋ค๋ฌ */\n onClick?: () => void\n /** ๋ฒํผ variant */\n variant?: ButtonVariants['variant']\n /** ๋ฒํผ ์คํ์ผ ํ์
*/\n styletype?: 'default' | 'primary' | 'secondary' | 'success' | 'warning' | 'danger' | 'outline' | 'ghost' | 'link' | 'sm' | 'lg' | 'icon'\n /** ๋ฒํผ size */\n size?: 'sm' | 'md' | 'lg'\n /** ๋ฒํผ ๋นํ์ฑํ */\n disabled?: boolean\n /** ๋ฒํผ ๋ก๋ฉ ์ํ */\n loading?: boolean\n}\n\ntype StyleType =\n | 'default' // ๊ธฐ๋ณธ ์คํ์ผ: ์ผ๋ฐ ํ์ด์ง์ฉ (ํฐ ๋ฐฐ๊ฒฝ, ์์ ๋ณด๋)\n | 'primary' // ๊ฐ์กฐ ์คํ์ผ: ์ฃผ์ ๊ธฐ๋ฅ์ฉ (๋ฐ์ ํ๋ ๋ฐฐ๊ฒฝ, ํฐ ํ
์คํธ)\n | 'accent' // ์ก์ผํธ ์คํ์ผ: ๋ถ๋๋ฌ์ด ๊ฐ์กฐ์ฉ (์ฐํ ํ๋ ๋ฐฐ๊ฒฝ, ์งํ ํ
์คํธ)\n | 'neutral' // ์ค๋ฆฝ ์คํ์ผ: ์๋ธ ํ์ด์ง์ฉ (ํ์ ๋ฐฐ๊ฒฝ, ํ์ ํ
์คํธ)\n | 'elevated' // ๊ฐ์กฐ ์คํ์ผ: ๊น์ด๊ฐ ์๋ ๊ตฌ๋ถ (ํฐ ๋ฐฐ๊ฒฝ, ๊ทธ๋ฆผ์, ๋ณด๋)\n\nconst props = withDefaults(\n defineProps<{\n /** Titlebar ์คํ์ผ ํ์
*/\n styletype?: StyleType\n /** ํ๋ก๊ทธ๋จ ์์ด์ฝ */\n icon?: string\n /** ํ๋ก๊ทธ๋จ๋ช
*/\n title?: string\n /** ํ๋ก๊ทธ๋จ ์ค๋ช
(Popover์ ํ์) */\n description?: string\n /** ๋์๋ง ์์ด์ฝ(?) ํ์ ์ฌ๋ถ โ ํด๋ฆญ ์ help ์ด๋ฒคํธ emit */\n showHelp?: boolean\n /** ๋ฉ์ธ ๋ฒํผ ๋ชฉ๋ก */\n buttons?: TitlebarButton[]\n }>(),\n {\n styletype: 'default',\n buttons: () => [],\n }\n)\n\n/**\n * styletype -> class ๋งคํ (๋ฐฐ๊ฒฝ, ๋ณด๋, ๊ทธ๋ฆผ์ ๋ฑ)\n */\nconst STYLE_PRESETS: Record<StyleType, { \n class: string\n iconClass: string // ์์ด์ฝ ์์ ํด๋์ค\n titleClass: string // ์ ๋ชฉ ํ
์คํธ ์์ ํด๋์ค\n infoIconClass: string // ์ ๋ณด ์์ด์ฝ ์์ ํด๋์ค\n}> = {\n default: {\n // ๊ธฐ๋ณธ: ํฐ ๋ฐฐ๊ฒฝ + ์์ ๋ณด๋ (๊ฐ์ฅ ์ผ๋ฐ์ )\n class: 'flex items-center justify-between w-full h-8 px-3 border-b border-border bg-background',\n iconClass: 'text-primary',\n titleClass: 'text-foreground text-md',\n infoIconClass: 'text-muted-foreground hover:text-primary',\n },\n primary: {\n // ๊ฐ์กฐ: ๋ฐ์ ํ๋ ๋ฐฐ๊ฒฝ + ํฐ ํ
์คํธ (๋ช
ํํ ๊ฐ์กฐ)\n // text-white๋ฅผ ์ ๊ฑฐํ์ฌ ๋ฒํผ์ด ์์ ์์์ ๋ฐ์ง ์๋๋ก ํจ\n class: 'flex items-center justify-between w-full h-8 px-3 border-b border-blue-400/30 bg-blue-500',\n iconClass: 'text-white',\n titleClass: 'text-white font-semibold text-md',\n infoIconClass: 'text-white/80 hover:text-white',\n },\n accent: {\n // ์ก์ผํธ: ์ฐํ ํ๋ ๋ฐฐ๊ฒฝ + ์งํ ํ๋ ํ
์คํธ (๋ถ๋๋ฌ์ด ๊ฐ์กฐ)\n // text-blue-700์ ์ ๊ฑฐํ์ฌ ๋ฒํผ์ด ์์ ์์์ ๋ฐ์ง ์๋๋ก ํจ\n class: 'flex items-center justify-between w-full h-8 px-3 border-b border-blue-200 bg-blue-50',\n iconClass: 'text-blue-600',\n titleClass: 'text-blue-700 font-semibold text-md',\n infoIconClass: 'text-blue-600/70 hover:text-blue-700',\n },\n neutral: {\n // ์ค๋ฆฝ: ํ์ ๋ฐฐ๊ฒฝ + ํ์ ํ
์คํธ (ํ์คํ ๊ตฌ๋ถ)\n // text-gray-700์ ์ ๊ฑฐํ์ฌ ๋ฒํผ์ด ์์ ์์์ ๋ฐ์ง ์๋๋ก ํจ\n class: 'flex items-center justify-between w-full h-8 px-3 border-b border-gray-300 bg-gray-100',\n iconClass: 'text-gray-600',\n titleClass: 'text-gray-700 text-md',\n infoIconClass: 'text-gray-500 hover:text-gray-700',\n },\n elevated: {\n // ๊ฐ์กฐ: ํฐ ๋ฐฐ๊ฒฝ + ๊ทธ๋ฆผ์ + ๋ณด๋ (๊น์ด๊ฐ ์๋ ๊ตฌ๋ถ)\n class: 'flex items-center justify-between w-full h-8 px-3 border-b border-border bg-background shadow-md',\n iconClass: 'text-primary',\n titleClass: 'text-foreground font-semibold text-md',\n infoIconClass: 'text-muted-foreground hover:text-primary',\n },\n}\n\nconst preset = computed(() => {\n return STYLE_PRESETS[props.styletype] ?? STYLE_PRESETS.default\n})\n\nconst emit = defineEmits<{\n /** ๋ฒํผ ํด๋ฆญ ์ด๋ฒคํธ */\n buttonClick: [button: TitlebarButton]\n /** ๋์๋ง ์์ด์ฝ ํด๋ฆญ ์ด๋ฒคํธ */\n help: []\n}>()\n\nconst handleButtonClick = (button: TitlebarButton) => {\n // ๋ฒํผ ํด๋ฆญ ํธ๋ค๋ฌ ํจํด:\n // 1. button.onClick์ด ์์ผ๋ฉด ์คํ (์ธ๋ผ์ธ ํธ๋ค๋ฌ)\n // 2. ํญ์ emit('buttonClick', button) ์คํ (๋ถ๋ชจ ์ปดํฌ๋ํธ๋ก ์ ๋ฌ)\n // ์ฃผ์: onClick๊ณผ emit์ด ๋ชจ๋ ์คํ๋๋ฏ๋ก ์ค๋ณต ์ฒ๋ฆฌ ๊ฐ๋ฅ์ฑ ์์\n button.onClick?.()\n emit('buttonClick', button)\n}\n</script>\n\n<template>\n <div :class=\"cn(preset.class)\">\n <!-- ์ผ์ชฝ: ์์ด์ฝ + ํ๋ก๊ทธ๋จ๋ช
-->\n <div class=\"flex items-center gap-3 flex-1\">\n <!-- ์์ด์ฝ -->\n <JIcon \n v-if=\"icon\" \n :name=\"icon\" \n :class=\"preset.iconClass\"\n />\n \n <!-- ํ๋ก๊ทธ๋จ๋ช
+ ์ ๋ณด ์์ด์ฝ + Popover -->\n <div class=\"flex items-center gap-2\">\n <!-- ํ๋ก๊ทธ๋จ๋ช
-->\n <JLabel \n :text=\"title || ''\" \n :class=\"cn('font-semibold', preset.titleClass)\"\n />\n \n <!-- ์ ๋ณด ์์ด์ฝ (description์ด ์์ ๋๋ง ํ์) -->\n <JPopover \n v-if=\"description\" \n position=\"bottom\"\n align=\"center\"\n :side-offset=\"8\"\n >\n <template #trigger>\n <JIcon \n name=\"info\" \n size=\"sm\" \n :class=\"cn('cursor-help transition-colors inline-flex', preset.infoIconClass)\"\n />\n </template>\n <div class=\"p-2\">\n <p class=\"text-xs text-muted-foreground whitespace-normal break-words\">{{ description }}</p>\n </div>\n </JPopover>\n\n <!-- ๋์๋ง ์์ด์ฝ (showHelp์ผ ๋ ํ์, ํด๋ฆญ ์ help ์ด๋ฒคํธ) -->\n <JIcon\n v-if=\"showHelp\"\n name=\"circleQuestionMark\"\n size=\"sm\"\n :class=\"cn('cursor-pointer transition-colors inline-flex', preset.infoIconClass)\"\n @click=\"emit('help')\"\n />\n </div>\n </div>\n\n <!-- ์ค๋ฅธ์ชฝ: ๋ฉ์ธ ๋ฒํผ๋ค -->\n <!-- buttons prop์ผ๋ก ์ ์๋ ๋ฒํผ๋ค (v-if๋ก ์กฐ๊ฑด๋ถ ๋ ๋๋ง) -->\n <div v-if=\"buttons && buttons.length > 0\" class=\"flex items-center gap-2\">\n <JButton\n v-for=\"(button, index) in buttons\"\n :key=\"index\"\n :variant=\"button.variant\"\n :styletype=\"button.styletype\"\n :disabled=\"button.disabled\"\n :loading=\"button.loading\"\n :size=\"button.size\"\n @click=\"handleButtonClick(button)\"\n >\n <JIcon v-if=\"button.icon\" :name=\"button.icon\" size=\"sm\" class=\"mr-1.5\" />\n <span v-if=\"button.text\">{{ button.text }}</span>\n </JButton>\n </div>\n\n <!-- ๋ฒํผ ์ฌ๋กฏ ๋ ์ด์์ ์ค๋ช
:\n - buttons prop๊ณผ buttons slot์ด ๋ชจ๋ ์ ๊ณต๋๋ฉด ํจ๊ป ํ์๋จ\n - buttons prop: ๊ตฌ์กฐํ๋ ๋ฒํผ ์ ์ (JButton ์ปดํฌ๋ํธ ์ฌ์ฉ)\n - buttons slot: ์์ ํ ์ปค์คํ
๋ฒํผ ์ ์ด ๊ฐ๋ฅ\n - ๋ ์ด์์: buttons prop์ด ๋จผ์ ๋ ๋๋ง๋๊ณ , ๊ทธ ๋ค์ slot์ด ๋ ๋๋ง๋จ -->\n <slot name=\"buttons\" />\n </div>\n</template>\n\n"],"names":["props","__props","STYLE_PRESETS","preset","computed","emit","__emit","handleButtonClick","button","_createElementBlock","_normalizeClass","_unref","
|
|
1
|
+
{"version":3,"file":"JTitlebar.vue.js","sources":["../../../../src/components/molecules/JTitlebar.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from \"vue\"\nimport { JIcon, JLabel, JPopover, JButton } from '@/components/atoms'\nimport type { ButtonVariants } from '@/components/shadcn'\nimport { cn } from \"@/lib/utils\"\n\nexport type TitlebarButton = {\n /** ๋ฒํผ ์์ด์ฝ */\n icon?: string\n /** ๋ฒํผ ํ
์คํธ */\n text?: string\n /** ๋ฒํผ ํด๋ฆญ ํธ๋ค๋ฌ */\n onClick?: () => void\n /** ๋ฒํผ variant */\n variant?: ButtonVariants['variant']\n /** ๋ฒํผ ์คํ์ผ ํ์
*/\n styletype?: 'default' | 'primary' | 'secondary' | 'success' | 'warning' | 'danger' | 'outline' | 'ghost' | 'link' | 'sm' | 'lg' | 'icon'\n /** ๋ฒํผ size */\n size?: 'sm' | 'md' | 'lg'\n /** ๋ฒํผ ๋นํ์ฑํ */\n disabled?: boolean\n /** ๋ฒํผ ๋ก๋ฉ ์ํ */\n loading?: boolean\n}\n\ntype StyleType =\n | 'default' // ๊ธฐ๋ณธ ์คํ์ผ: ์ผ๋ฐ ํ์ด์ง์ฉ (ํฐ ๋ฐฐ๊ฒฝ, ์์ ๋ณด๋)\n | 'primary' // ๊ฐ์กฐ ์คํ์ผ: ์ฃผ์ ๊ธฐ๋ฅ์ฉ (๋ฐ์ ํ๋ ๋ฐฐ๊ฒฝ, ํฐ ํ
์คํธ)\n | 'accent' // ์ก์ผํธ ์คํ์ผ: ๋ถ๋๋ฌ์ด ๊ฐ์กฐ์ฉ (์ฐํ ํ๋ ๋ฐฐ๊ฒฝ, ์งํ ํ
์คํธ)\n | 'neutral' // ์ค๋ฆฝ ์คํ์ผ: ์๋ธ ํ์ด์ง์ฉ (ํ์ ๋ฐฐ๊ฒฝ, ํ์ ํ
์คํธ)\n | 'elevated' // ๊ฐ์กฐ ์คํ์ผ: ๊น์ด๊ฐ ์๋ ๊ตฌ๋ถ (ํฐ ๋ฐฐ๊ฒฝ, ๊ทธ๋ฆผ์, ๋ณด๋)\n\nconst props = withDefaults(\n defineProps<{\n /** Titlebar ์คํ์ผ ํ์
*/\n styletype?: StyleType\n /** ํ๋ก๊ทธ๋จ ์์ด์ฝ */\n icon?: string\n /** ํ๋ก๊ทธ๋จ๋ช
*/\n title?: string\n /** ํ๋ก๊ทธ๋จ ์ค๋ช
(Popover์ ํ์) */\n description?: string\n /** ๋์๋ง ์์ด์ฝ(?) ํ์ ์ฌ๋ถ โ ํด๋ฆญ ์ help ์ด๋ฒคํธ emit */\n showHelp?: boolean\n /** ๋ฉ์ธ ๋ฒํผ ๋ชฉ๋ก */\n buttons?: TitlebarButton[]\n /** ์ถ๊ฐ ํด๋์ค (์ธ๋ถ ์ปค์คํฐ๋ง์ด์ง์ฉ) */\n class?: string\n }>(),\n {\n styletype: 'default',\n buttons: () => [],\n }\n)\n\n/**\n * styletype -> class ๋งคํ (๋ฐฐ๊ฒฝ, ๋ณด๋, ๊ทธ๋ฆผ์ ๋ฑ)\n */\nconst STYLE_PRESETS: Record<StyleType, { \n class: string\n iconClass: string // ์์ด์ฝ ์์ ํด๋์ค\n titleClass: string // ์ ๋ชฉ ํ
์คํธ ์์ ํด๋์ค\n infoIconClass: string // ์ ๋ณด ์์ด์ฝ ์์ ํด๋์ค\n}> = {\n default: {\n // ๊ธฐ๋ณธ: ํฐ ๋ฐฐ๊ฒฝ + ์์ ๋ณด๋ (๊ฐ์ฅ ์ผ๋ฐ์ )\n class: 'flex items-center justify-between w-full h-8 px-3 border-b border-border bg-background',\n iconClass: 'text-primary',\n titleClass: 'text-foreground text-md',\n infoIconClass: 'text-muted-foreground hover:text-primary',\n },\n primary: {\n // ๊ฐ์กฐ: ๋ฐ์ ํ๋ ๋ฐฐ๊ฒฝ + ํฐ ํ
์คํธ (๋ช
ํํ ๊ฐ์กฐ)\n // text-white๋ฅผ ์ ๊ฑฐํ์ฌ ๋ฒํผ์ด ์์ ์์์ ๋ฐ์ง ์๋๋ก ํจ\n class: 'flex items-center justify-between w-full h-8 px-3 border-b border-blue-400/30 bg-blue-500',\n iconClass: 'text-white',\n titleClass: 'text-white font-semibold text-md',\n infoIconClass: 'text-white/80 hover:text-white',\n },\n accent: {\n // ์ก์ผํธ: ์ฐํ ํ๋ ๋ฐฐ๊ฒฝ + ์งํ ํ๋ ํ
์คํธ (๋ถ๋๋ฌ์ด ๊ฐ์กฐ)\n // text-blue-700์ ์ ๊ฑฐํ์ฌ ๋ฒํผ์ด ์์ ์์์ ๋ฐ์ง ์๋๋ก ํจ\n class: 'flex items-center justify-between w-full h-8 px-3 border-b border-blue-200 bg-blue-50',\n iconClass: 'text-blue-600',\n titleClass: 'text-blue-700 font-semibold text-md',\n infoIconClass: 'text-blue-600/70 hover:text-blue-700',\n },\n neutral: {\n // ์ค๋ฆฝ: ํ์ ๋ฐฐ๊ฒฝ + ํ์ ํ
์คํธ (ํ์คํ ๊ตฌ๋ถ)\n // text-gray-700์ ์ ๊ฑฐํ์ฌ ๋ฒํผ์ด ์์ ์์์ ๋ฐ์ง ์๋๋ก ํจ\n class: 'flex items-center justify-between w-full h-8 px-3 border-b border-gray-300 bg-gray-100',\n iconClass: 'text-gray-600',\n titleClass: 'text-gray-700 text-md',\n infoIconClass: 'text-gray-500 hover:text-gray-700',\n },\n elevated: {\n // ๊ฐ์กฐ: ํฐ ๋ฐฐ๊ฒฝ + ๊ทธ๋ฆผ์ + ๋ณด๋ (๊น์ด๊ฐ ์๋ ๊ตฌ๋ถ)\n class: 'flex items-center justify-between w-full h-8 px-3 border-b border-border bg-background shadow-md',\n iconClass: 'text-primary',\n titleClass: 'text-foreground font-semibold text-md',\n infoIconClass: 'text-muted-foreground hover:text-primary',\n },\n}\n\nconst preset = computed(() => {\n return STYLE_PRESETS[props.styletype] ?? STYLE_PRESETS.default\n})\n\nconst emit = defineEmits<{\n /** ๋ฒํผ ํด๋ฆญ ์ด๋ฒคํธ */\n buttonClick: [button: TitlebarButton]\n /** ๋์๋ง ์์ด์ฝ ํด๋ฆญ ์ด๋ฒคํธ */\n help: []\n}>()\n\nconst handleButtonClick = (button: TitlebarButton) => {\n // ๋ฒํผ ํด๋ฆญ ํธ๋ค๋ฌ ํจํด:\n // 1. button.onClick์ด ์์ผ๋ฉด ์คํ (์ธ๋ผ์ธ ํธ๋ค๋ฌ)\n // 2. ํญ์ emit('buttonClick', button) ์คํ (๋ถ๋ชจ ์ปดํฌ๋ํธ๋ก ์ ๋ฌ)\n // ์ฃผ์: onClick๊ณผ emit์ด ๋ชจ๋ ์คํ๋๋ฏ๋ก ์ค๋ณต ์ฒ๋ฆฌ ๊ฐ๋ฅ์ฑ ์์\n button.onClick?.()\n emit('buttonClick', button)\n}\n</script>\n\n<template>\n <div :class=\"cn(preset.class, props.class)\">\n <!-- ์ผ์ชฝ: ์์ด์ฝ + ํ๋ก๊ทธ๋จ๋ช
-->\n <div class=\"flex items-center gap-3 flex-1\">\n <!-- ์์ด์ฝ -->\n <JIcon \n v-if=\"icon\" \n :name=\"icon\" \n :class=\"preset.iconClass\"\n />\n \n <!-- ํ๋ก๊ทธ๋จ๋ช
+ ์ ๋ณด ์์ด์ฝ + Popover -->\n <div class=\"flex items-center gap-2\">\n <!-- ํ๋ก๊ทธ๋จ๋ช
-->\n <JLabel \n :text=\"title || ''\" \n :class=\"cn('font-semibold', preset.titleClass)\"\n />\n \n <!-- ์ ๋ณด ์์ด์ฝ (description์ด ์์ ๋๋ง ํ์) -->\n <JPopover \n v-if=\"description\" \n position=\"bottom\"\n align=\"center\"\n :side-offset=\"8\"\n >\n <template #trigger>\n <JIcon \n name=\"info\" \n size=\"sm\" \n :class=\"cn('cursor-help transition-colors inline-flex', preset.infoIconClass)\"\n />\n </template>\n <div class=\"p-2\">\n <p class=\"text-xs text-muted-foreground whitespace-normal break-words\">{{ description }}</p>\n </div>\n </JPopover>\n\n <!-- ๋์๋ง ์์ด์ฝ (showHelp์ผ ๋ ํ์, ํด๋ฆญ ์ help ์ด๋ฒคํธ) -->\n <JIcon\n v-if=\"showHelp\"\n name=\"circleQuestionMark\"\n size=\"sm\"\n :class=\"cn('cursor-pointer transition-colors inline-flex', preset.infoIconClass)\"\n @click=\"emit('help')\"\n />\n </div>\n </div>\n\n <!-- ์ค๋ฅธ์ชฝ: ๋ฉ์ธ ๋ฒํผ๋ค -->\n <!-- buttons prop์ผ๋ก ์ ์๋ ๋ฒํผ๋ค (v-if๋ก ์กฐ๊ฑด๋ถ ๋ ๋๋ง) -->\n <div v-if=\"buttons && buttons.length > 0\" class=\"flex items-center gap-2\">\n <JButton\n v-for=\"(button, index) in buttons\"\n :key=\"index\"\n :variant=\"button.variant\"\n :styletype=\"button.styletype\"\n :disabled=\"button.disabled\"\n :loading=\"button.loading\"\n :size=\"button.size\"\n @click=\"handleButtonClick(button)\"\n >\n <JIcon v-if=\"button.icon\" :name=\"button.icon\" size=\"sm\" class=\"mr-1.5\" />\n <span v-if=\"button.text\">{{ button.text }}</span>\n </JButton>\n </div>\n\n <!-- ๋ฒํผ ์ฌ๋กฏ ๋ ์ด์์ ์ค๋ช
:\n - buttons prop๊ณผ buttons slot์ด ๋ชจ๋ ์ ๊ณต๋๋ฉด ํจ๊ป ํ์๋จ\n - buttons prop: ๊ตฌ์กฐํ๋ ๋ฒํผ ์ ์ (JButton ์ปดํฌ๋ํธ ์ฌ์ฉ)\n - buttons slot: ์์ ํ ์ปค์คํ
๋ฒํผ ์ ์ด ๊ฐ๋ฅ\n - ๋ ์ด์์: buttons prop์ด ๋จผ์ ๋ ๋๋ง๋๊ณ , ๊ทธ ๋ค์ slot์ด ๋ ๋๋ง๋จ -->\n <slot name=\"buttons\" />\n </div>\n</template>\n\n"],"names":["props","__props","STYLE_PRESETS","preset","computed","emit","__emit","handleButtonClick","button","_createElementBlock","_normalizeClass","_unref","_createElementVNode","_hoisted_1","_createBlock","JIcon","_hoisted_2","_createVNode","JLabel","cn","JPopover","_hoisted_3","_hoisted_4","_toDisplayString","_openBlock","_hoisted_5","_Fragment","_renderList","index","JButton","$event","_hoisted_6","_renderSlot","_ctx"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const l=require("vue"),A=require("../molecules/JFormField.vue.cjs");;/* empty css */require("../shadcn/index.cjs");require("@vueuse/core");require("reka-ui");require("clsx");require("tailwind-merge");require("lucide-vue-next");;/* empty css */;/* empty css */;/* empty css */const W=require("../molecules/JCard.vue.cjs");require("@internationalized/date");require("md-editor-v3");;/* empty css */;/* empty css */require("../shadcn/badge-variants.cjs");;/* 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 */require("vue-sonner");const M=require("../../lib/styleTypePreset.cjs"),D={key:1,class:"space-y-6"},R={key:2,class:"space-y-4"},Y={class:"font-semibold text-lg"},j={key:0,class:"text-muted-foreground text-sm mb-2"},J=l.defineComponent({__name:"JDynamicForm",props:{schema:{},modelValue:{}},emits:["update:modelValue","submit","change","error"],setup(u,{expose:L,emit:F}){const s=u,p=F,d=["checkbox","switch"],a=l.reactive({});l.watch(()=>s.modelValue,e=>{e&&Object.assign(a,e)},{immediate:!0,deep:!0});function y(e,r){return e.controlId||e.controlName||e.name||e.label||`field-${r}`}function h(e){return e.controlName||e.name||""}function b(e){return e.isRequired!==void 0?e.isRequired:e.required||!1}l.watch(()=>s.schema,e=>{const r=[];e.type==="simple"&&e.fields?r.push(...e.fields):e.type==="sectioned"&&e.sections?e.sections.forEach(t=>{t.fields&&r.push(...t.fields)}):e.type==="wizard"&&e.steps&&e.steps.forEach(t=>{t.fields&&r.push(...t.fields)}),r.forEach(t=>{const o=h(t);if(o&&a[o]===void 0)if(d.includes(t.type))a[o]="N";else if(t.type==="radio")a[o]=t.options?.[0]?.value??"";else if(t.type==="select"||t.type==="searchcombo"){const i=t.addAll!==void 0?t.addAll:t.allowAll||!1;a[o]=i?"ALL":"SELECT"}else a[o]=""})},{immediate:!0}),l.watch(a,e=>p("update:modelValue",e),{deep:!0});function N(){p("submit",{...a}),typeof s.schema.events?.onSubmit=="function"&&s.schema.events.onSubmit({...a})}function T(e,r){p("change",{field:e,value:r}),typeof s.schema.events?.onChange=="function"&&s.schema.events.onChange(e,r)}function $(e){p("error",e),typeof s.schema.events?.onError=="function"&&s.schema.events.onError(e)}function f(e){return e.filter(t=>t.isVisible!==!1).sort((t,o)=>{if(t.sortOrder!==void 0&&o.sortOrder!==void 0&&t.sortOrder!==o.sortOrder)return t.sortOrder-o.sortOrder;const i=t.controlName||t.name||t.label||"",g=o.controlName||o.name||o.label||"";return i.localeCompare(g)})}const w=l.computed(()=>{const e=s.schema.globalStyle?.colCount||(s.schema.layout?.columns?`row-${s.schema.layout.columns}`:"row-1"),r=z(e);let t="";switch(e){case"row-1":t=`flex flex-col ${r}`;break;case"row":case"row-2":t=`flex flex-col md:grid md:grid-flow-row md:items-start ${r} md:grid-cols-2 auto-rows-min`;break;case"row-3":t=`flex flex-col md:grid md:grid-flow-row md:items-start ${r} md:grid-cols-2 lg:grid-cols-3 auto-rows-min`;break;case"row-4":t=`flex flex-col md:grid md:grid-flow-row md:items-start ${r} md:grid-cols-2 lg:grid-cols-4 auto-rows-min`;break;case"row-5":t=`flex flex-col md:grid md:grid-flow-row md:items-start ${r} md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-5 auto-rows-min`;break;case"row-6":t=`flex flex-col md:grid md:grid-flow-row md:items-start ${r} md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-6 auto-rows-min`;break;case"row-7":t=`flex flex-col md:grid md:grid-flow-row md:items-start ${r} md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-7 auto-rows-min`;break;case"row-8":t=`flex flex-col md:grid md:grid-flow-row md:items-start ${r} md:grid-cols-2 lg:grid-cols-4 xl:grid-cols-8 auto-rows-min`;break;default:t=`flex flex-col ${r}`}return t});function k(e){return d.includes(e.type)?"min-w-0 w-auto inline-flex items-center":"min-w-0 w-full"}function C(e){switch(e){case"row":case"row-2":return 2;case"row-3":return 3;case"row-4":return 4;case"row-5":return 5;case"row-6":return 6;case"row-7":return 7;case"row-8":return 8;default:return 1}}function z(e){switch(e){case"row-1":return"gap-6";case"row":case"row-2":return"gap-4";case"row-3":return"gap-4";case"row-4":return"gap-3";case"row-5":return"gap-2";case"row-6":return"gap-2";case"row-7":return"gap-2";case"row-8":return"gap-2";default:return"gap-6"}}function q(){const e=s.schema.globalStyle?.colCount||(s.schema.layout?.columns?`row-${s.schema.layout.columns}`:"row-1"),r=C(e);return r>=6?"6rem":r>=5?"7rem":"8rem"}function v(){return s.schema.globalStyle?.labelPosition||"horizontal"}function x(){return s.schema.globalStyle?.labelAlign||"left"}function E(e){const r=s.schema.globalStyle?.colCount||(s.schema.layout?.columns?`row-${s.schema.layout.columns}`:"row-1"),t=C(r);return{gridColumn:`span ${Math.min(t,Math.max(1,e.colSpan||1))}`}}function B(e){const r=h(e),t=e.isDisabled!==void 0?e.isDisabled:e.disabled||!1,o=e.isReadonly!==void 0?e.isReadonly:e.readonly||!1,i=d.includes(e.type)?"inline-flex items-center gap-2 w-auto":"w-full",g=M.resolveGlobalStyle(s.schema.globalStyle),P=s.schema.globalStyle?.colCount||(s.schema.layout?.columns?`row-${s.schema.layout.columns}`:"row-1"),S=C(P);let c=g.controlSize;S>=6||S>=5?c="sm":S>=4&&g.controlSize==="lg"&&(c="md");const m=(n,V)=>{if(r&&(a[r]=V,T(r,V)),e.events?.[n]){const U=e.events[n];console.log(`Event ${n}: Calling handler "${U}" with value:`,V)}};return d.includes(e.type)?{modelValue:a[r]==="Y"?"Y":"N",disabled:t,styleType:c,class:i,"onUpdate:modelValue":n=>{r&&(a[r]=n),m("onChange",n==="Y")}}:e.type==="radio"?{modelValue:String(a[r]??""),options:e.options??[],multiple:e.multiple,disabled:t,styleType:c,class:i,"onUpdate:modelValue":n=>{m("onChange",n)}}:e.type==="select"||e.type==="combo"?{modelValue:String(a[r]??""),options:_(e),multiple:e.multiple,disabled:t,styleType:c,class:i,"onUpdate:modelValue":n=>{m("onChange",n)}}:e.type==="searchcombo"?{modelValue:String(a[r]??""),options:_(e),disabled:t,styleType:c,class:i,"onUpdate:modelValue":n=>{m("onChange",n)}}:e.type==="textarea"?{modelValue:String(a[r]??""),placeholder:e.placeholder??"",disabled:t,readonly:o,styleType:c,class:i,"onUpdate:modelValue":n=>{m("onChange",n)}}:e.type==="datepicker"?{modelValue:String(a[r]??""),placeholder:e.placeholder??"",disabled:t,readonly:o,styleType:c,class:i,"onUpdate:modelValue":n=>{m("onChange",n)}}:{modelValue:String(a[r]??""),inputType:e.inputType||(e.dataType==="number"?"number":"text"),placeholder:e.placeholder??"",disabled:t,readonly:o,styleType:c,class:i,"onUpdate:modelValue":n=>{m("onChange",n)}}}function _(e){const r=e.addAll!==void 0?e.addAll:e.allowAll||!1;return[{value:r?"ALL":"SELECT",label:r?"์ ์ฒด":"์ ํ"},...e.options||[]]}function O(){Object.keys(a).forEach(r=>{delete a[r]});const e=[];s.schema.type==="simple"&&s.schema.fields?e.push(...s.schema.fields):s.schema.type==="sectioned"&&s.schema.sections?s.schema.sections.forEach(r=>{r.fields&&e.push(...r.fields)}):s.schema.type==="wizard"&&s.schema.steps&&s.schema.steps.forEach(r=>{r.fields&&e.push(...r.fields)}),e.forEach(r=>{const t=h(r);if(t)if(d.includes(r.type))a[t]="N";else if(r.type==="radio")a[t]=r.options?.[0]?.value??"";else if(r.type==="select"||r.type==="searchcombo"){const o=r.addAll!==void 0?r.addAll:r.allowAll||!1;a[t]=o?"ALL":"SELECT"}else a[t]=""})}return L({formState:a,submit:N,reset:O,handleError:$}),(e,r)=>(l.openBlock(),l.createElementBlock("form",{onSubmit:l.withModifiers(N,["prevent"]),class:l.normalizeClass(w.value)},[u.schema.type==="simple"?(l.openBlock(!0),l.createElementBlock(l.Fragment,{key:0},l.renderList(f(u.schema.fields||[]),(t,o)=>(l.openBlock(),l.createElementBlock("div",{key:y(t,o),class:l.normalizeClass(k(t)),style:l.normalizeStyle(E(t))},[l.createVNode(l.unref(A.default),l.mergeProps({label:t.label,required:b(t),orientation:v(),labelAlign:x(),labelWidth:q(),type:t.type==="searchcombo"?"searchCombo":t.type,"input-type":t.inputType,description:t.description,"inline-label":t.inlineLabel},{ref_for:!0},B(t)),null,16,["label","required","orientation","labelAlign","labelWidth","type","input-type","description","inline-label"])],6))),128)):u.schema.type==="sectioned"?(l.openBlock(),l.createElementBlock("div",D,[(l.openBlock(!0),l.createElementBlock(l.Fragment,null,l.renderList(u.schema.sections,t=>(l.openBlock(),l.createBlock(l.unref(W.default),{key:t.id,title:t.title,collapsible:t.collapsible,"default-collapsed":t.defaultCollapsed},{default:l.withCtx(()=>[l.createElementVNode("div",{class:l.normalizeClass(w.value)},[(l.openBlock(!0),l.createElementBlock(l.Fragment,null,l.renderList(f(t.fields||[]),(o,i)=>(l.openBlock(),l.createElementBlock("div",{key:y(o,i),class:l.normalizeClass(k(o)),style:l.normalizeStyle(E(o))},[l.createVNode(l.unref(A.default),l.mergeProps({label:o.label,required:b(o),orientation:v(),labelAlign:x(),labelWidth:q(),type:o.type==="searchcombo"?"searchCombo":o.type,"input-type":o.inputType,description:o.description,"inline-label":o.inlineLabel},{ref_for:!0},B(o)),null,16,["label","required","orientation","labelAlign","labelWidth","type","input-type","description","inline-label"])],6))),128))],2)]),_:2},1032,["title","collapsible","default-collapsed"]))),128))])):u.schema.type==="wizard"?(l.openBlock(),l.createElementBlock("div",R,[(l.openBlock(!0),l.createElementBlock(l.Fragment,null,l.renderList(u.schema.steps,t=>(l.openBlock(),l.createElementBlock("div",{key:t.id,class:"p-4 border rounded-xl"},[l.createElementVNode("h3",Y,l.toDisplayString(t.title),1),t.description?(l.openBlock(),l.createElementBlock("p",j,l.toDisplayString(t.description),1)):l.createCommentVNode("",!0),l.createElementVNode("div",{class:l.normalizeClass(w.value)},[(l.openBlock(!0),l.createElementBlock(l.Fragment,null,l.renderList(f(t.fields||[]),(o,i)=>(l.openBlock(),l.createElementBlock("div",{key:y(o,i),class:l.normalizeClass(k(o)),style:l.normalizeStyle(E(o))},[l.createVNode(l.unref(A.default),l.mergeProps({label:o.label,required:b(o),orientation:v(),labelAlign:x(),labelWidth:q(),type:o.type==="searchcombo"?"searchCombo":o.type,"input-type":o.inputType,description:o.description,"inline-label":o.inlineLabel},{ref_for:!0},B(o)),null,16,["label","required","orientation","labelAlign","labelWidth","type","input-type","description","inline-label"])],6))),128))],2)]))),128))])):l.createCommentVNode("",!0)],34))}});exports.default=J;
|
|
1
|
+
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const r=require("vue"),A=require("../molecules/JFormField.vue.cjs");require("../shadcn/index.cjs");require("@vueuse/core");require("reka-ui");require("clsx");require("tailwind-merge");require("lucide-vue-next");;/* empty css */;/* empty css */;/* empty css */const W=require("../molecules/JCard.vue.cjs");;/* empty css */require("@internationalized/date");require("md-editor-v3");;/* empty css */;/* empty css */require("../shadcn/badge-variants.cjs");;/* 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");;/* empty css */const M=require("../../lib/styleTypePreset.cjs"),D={key:1,class:"space-y-6"},R={key:2,class:"space-y-4"},Y={class:"font-semibold text-lg"},j={key:0,class:"text-muted-foreground text-sm mb-2"},J=r.defineComponent({__name:"JDynamicForm",props:{schema:{},modelValue:{}},emits:["update:modelValue","submit","change","error"],setup(u,{expose:F,emit:T}){const s=u,p=T,d=["checkbox","switch"],a=r.reactive({});r.watch(()=>s.modelValue,e=>{e&&Object.assign(a,e)},{immediate:!0,deep:!0});function y(e,l){return e.controlId||e.controlName||e.name||e.label||`field-${l}`}function h(e){return e.controlName||e.name||""}function b(e){return e.isRequired!==void 0?e.isRequired:e.required||!1}r.watch(()=>s.schema,e=>{const l=[];e.type==="simple"&&e.fields?l.push(...e.fields):e.type==="sectioned"&&e.sections?e.sections.forEach(t=>{t.fields&&l.push(...t.fields)}):e.type==="wizard"&&e.steps&&e.steps.forEach(t=>{t.fields&&l.push(...t.fields)}),l.forEach(t=>{const o=h(t);if(o&&a[o]===void 0)if(d.includes(t.type))a[o]="N";else if(t.type==="radio")a[o]=t.options?.[0]?.value??"";else if(t.type==="select"||t.type==="searchcombo"){const i=t.addAll!==void 0?t.addAll:t.allowAll||!1;a[o]=i?"ALL":"SELECT"}else a[o]=""})},{immediate:!0}),r.watch(a,e=>p("update:modelValue",e),{deep:!0});function N(){p("submit",{...a}),typeof s.schema.events?.onSubmit=="function"&&s.schema.events.onSubmit({...a})}function $(e,l){p("change",{field:e,value:l}),typeof s.schema.events?.onChange=="function"&&s.schema.events.onChange(e,l)}function z(e){p("error",e),typeof s.schema.events?.onError=="function"&&s.schema.events.onError(e)}function f(e){return e.filter(t=>t.isVisible!==!1).sort((t,o)=>{if(t.sortOrder!==void 0&&o.sortOrder!==void 0&&t.sortOrder!==o.sortOrder)return t.sortOrder-o.sortOrder;const i=t.controlName||t.name||t.label||"",g=o.controlName||o.name||o.label||"";return i.localeCompare(g)})}const w=r.computed(()=>{const e=s.schema.globalStyle?.colCount||(s.schema.layout?.columns?`row-${s.schema.layout.columns}`:"row-1"),l=_(e);let t="";switch(e){case"row-1":t=`flex flex-col ${l}`;break;case"row":case"row-2":t=`flex flex-col md:grid md:grid-flow-row md:items-start ${l} md:grid-cols-2 auto-rows-min`;break;case"row-3":t=`flex flex-col md:grid md:grid-flow-row md:items-start ${l} md:grid-cols-2 lg:grid-cols-3 auto-rows-min`;break;case"row-4":t=`flex flex-col md:grid md:grid-flow-row md:items-start ${l} md:grid-cols-2 lg:grid-cols-4 auto-rows-min`;break;case"row-5":t=`flex flex-col md:grid md:grid-flow-row md:items-start ${l} md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-5 auto-rows-min`;break;case"row-6":t=`flex flex-col md:grid md:grid-flow-row md:items-start ${l} md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-6 auto-rows-min`;break;case"row-7":t=`flex flex-col md:grid md:grid-flow-row md:items-start ${l} md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-7 auto-rows-min`;break;case"row-8":t=`flex flex-col md:grid md:grid-flow-row md:items-start ${l} md:grid-cols-2 lg:grid-cols-4 xl:grid-cols-8 auto-rows-min`;break;default:t=`flex flex-col ${l}`}return t});function k(e){return d.includes(e.type)?"min-w-0 w-auto inline-flex items-center":"min-w-0 w-full"}function C(e){switch(e){case"row":case"row-2":return 2;case"row-3":return 3;case"row-4":return 4;case"row-5":return 5;case"row-6":return 6;case"row-7":return 7;case"row-8":return 8;default:return 1}}function _(e){switch(e){case"row-1":return"gap-6";case"row":case"row-2":return"gap-4";case"row-3":return"gap-4";case"row-4":return"gap-3";case"row-5":return"gap-2";case"row-6":return"gap-2";case"row-7":return"gap-2";case"row-8":return"gap-2";default:return"gap-6"}}function q(){const e=s.schema.globalStyle?.colCount||(s.schema.layout?.columns?`row-${s.schema.layout.columns}`:"row-1"),l=C(e);return l>=6?"6rem":l>=5?"7rem":"8rem"}function v(){return s.schema.globalStyle?.labelPosition||"horizontal"}function x(){return s.schema.globalStyle?.labelAlign||"left"}function E(e){const l=s.schema.globalStyle?.colCount||(s.schema.layout?.columns?`row-${s.schema.layout.columns}`:"row-1"),t=C(l);return{gridColumn:`span ${Math.min(t,Math.max(1,e.colSpan||1))}`}}function B(e){const l=h(e),t=e.isDisabled!==void 0?e.isDisabled:e.disabled||!1,o=e.isReadonly!==void 0?e.isReadonly:e.readonly||!1,i=d.includes(e.type)?"inline-flex items-center gap-2 w-auto":"w-full",g=M.resolveGlobalStyle(s.schema.globalStyle),P=s.schema.globalStyle?.colCount||(s.schema.layout?.columns?`row-${s.schema.layout.columns}`:"row-1"),S=C(P);let c=g.controlSize;S>=6||S>=5?c="sm":S>=4&&g.controlSize==="lg"&&(c="md");const m=(n,V)=>{if(l&&(a[l]=V,$(l,V)),e.events?.[n]){const U=e.events[n];console.log(`Event ${n}: Calling handler "${U}" with value:`,V)}};return d.includes(e.type)?{modelValue:a[l]==="Y"?"Y":"N",disabled:t,styleType:c,class:i,"onUpdate:modelValue":n=>{l&&(a[l]=n),m("onChange",n==="Y")}}:e.type==="radio"?{modelValue:String(a[l]??""),options:e.options??[],multiple:e.multiple,disabled:t,styleType:c,class:i,"onUpdate:modelValue":n=>{m("onChange",n)}}:e.type==="select"||e.type==="combo"?{modelValue:String(a[l]??""),options:L(e),multiple:e.multiple,disabled:t,styleType:c,class:i,"onUpdate:modelValue":n=>{m("onChange",n)}}:e.type==="searchcombo"?{modelValue:String(a[l]??""),options:L(e),disabled:t,styleType:c,class:i,"onUpdate:modelValue":n=>{m("onChange",n)}}:e.type==="textarea"?{modelValue:String(a[l]??""),placeholder:e.placeholder??"",disabled:t,readonly:o,styleType:c,class:i,"onUpdate:modelValue":n=>{m("onChange",n)}}:e.type==="datepicker"?{modelValue:String(a[l]??""),placeholder:e.placeholder??"",disabled:t,readonly:o,styleType:c,class:i,"onUpdate:modelValue":n=>{m("onChange",n)}}:{modelValue:String(a[l]??""),inputType:e.inputType||(e.dataType==="number"?"number":"text"),placeholder:e.placeholder??"",disabled:t,readonly:o,styleType:c,class:i,"onUpdate:modelValue":n=>{m("onChange",n)}}}function L(e){const l=e.addAll!==void 0?e.addAll:e.allowAll||!1;return[{value:l?"ALL":"SELECT",label:l?"์ ์ฒด":"์ ํ"},...e.options||[]]}function O(){Object.keys(a).forEach(l=>{delete a[l]});const e=[];s.schema.type==="simple"&&s.schema.fields?e.push(...s.schema.fields):s.schema.type==="sectioned"&&s.schema.sections?s.schema.sections.forEach(l=>{l.fields&&e.push(...l.fields)}):s.schema.type==="wizard"&&s.schema.steps&&s.schema.steps.forEach(l=>{l.fields&&e.push(...l.fields)}),e.forEach(l=>{const t=h(l);if(t)if(d.includes(l.type))a[t]="N";else if(l.type==="radio")a[t]=l.options?.[0]?.value??"";else if(l.type==="select"||l.type==="searchcombo"){const o=l.addAll!==void 0?l.addAll:l.allowAll||!1;a[t]=o?"ALL":"SELECT"}else a[t]=""})}return F({formState:a,submit:N,reset:O,handleError:z}),(e,l)=>(r.openBlock(),r.createElementBlock("form",{onSubmit:r.withModifiers(N,["prevent"]),class:r.normalizeClass(w.value)},[u.schema.type==="simple"?(r.openBlock(!0),r.createElementBlock(r.Fragment,{key:0},r.renderList(f(u.schema.fields||[]),(t,o)=>(r.openBlock(),r.createElementBlock("div",{key:y(t,o),class:r.normalizeClass(k(t)),style:r.normalizeStyle(E(t))},[r.createVNode(r.unref(A.default),r.mergeProps({label:t.label,required:b(t),orientation:v(),labelAlign:x(),labelWidth:q(),type:t.type==="searchcombo"?"searchCombo":t.type,"input-type":t.inputType,description:t.description,"inline-label":t.inlineLabel},{ref_for:!0},B(t)),null,16,["label","required","orientation","labelAlign","labelWidth","type","input-type","description","inline-label"])],6))),128)):u.schema.type==="sectioned"?(r.openBlock(),r.createElementBlock("div",D,[(r.openBlock(!0),r.createElementBlock(r.Fragment,null,r.renderList(u.schema.sections,t=>(r.openBlock(),r.createBlock(r.unref(W.default),{key:t.id,title:t.title,collapsible:t.collapsible,"default-collapsed":t.defaultCollapsed},{default:r.withCtx(()=>[r.createElementVNode("div",{class:r.normalizeClass(w.value)},[(r.openBlock(!0),r.createElementBlock(r.Fragment,null,r.renderList(f(t.fields||[]),(o,i)=>(r.openBlock(),r.createElementBlock("div",{key:y(o,i),class:r.normalizeClass(k(o)),style:r.normalizeStyle(E(o))},[r.createVNode(r.unref(A.default),r.mergeProps({label:o.label,required:b(o),orientation:v(),labelAlign:x(),labelWidth:q(),type:o.type==="searchcombo"?"searchCombo":o.type,"input-type":o.inputType,description:o.description,"inline-label":o.inlineLabel},{ref_for:!0},B(o)),null,16,["label","required","orientation","labelAlign","labelWidth","type","input-type","description","inline-label"])],6))),128))],2)]),_:2},1032,["title","collapsible","default-collapsed"]))),128))])):u.schema.type==="wizard"?(r.openBlock(),r.createElementBlock("div",R,[(r.openBlock(!0),r.createElementBlock(r.Fragment,null,r.renderList(u.schema.steps,t=>(r.openBlock(),r.createElementBlock("div",{key:t.id,class:"p-4 border rounded-xl"},[r.createElementVNode("h3",Y,r.toDisplayString(t.title),1),t.description?(r.openBlock(),r.createElementBlock("p",j,r.toDisplayString(t.description),1)):r.createCommentVNode("",!0),r.createElementVNode("div",{class:r.normalizeClass(w.value)},[(r.openBlock(!0),r.createElementBlock(r.Fragment,null,r.renderList(f(t.fields||[]),(o,i)=>(r.openBlock(),r.createElementBlock("div",{key:y(o,i),class:r.normalizeClass(k(o)),style:r.normalizeStyle(E(o))},[r.createVNode(r.unref(A.default),r.mergeProps({label:o.label,required:b(o),orientation:v(),labelAlign:x(),labelWidth:q(),type:o.type==="searchcombo"?"searchCombo":o.type,"input-type":o.inputType,description:o.description,"inline-label":o.inlineLabel},{ref_for:!0},B(o)),null,16,["label","required","orientation","labelAlign","labelWidth","type","input-type","description","inline-label"])],6))),128))],2)]))),128))])):r.createCommentVNode("",!0)],34))}});exports.default=J;
|
|
2
2
|
//# sourceMappingURL=JDynamicForm.vue2.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JDynamicForm.vue2.cjs","sources":["../../../../src/components/organisms/JDynamicForm.vue"],"sourcesContent":["<template>\n <form @submit.prevent=\"handleSubmit\" :class=\"formClasses\">\n <!-- ๐งฑ ๋จ์ํ ํผ -->\n <template v-if=\"schema.type === 'simple'\">\n <div\n v-for=\"(field, index) in getOrderedFields(schema.fields || [])\"\n :key=\"getFieldKey(field, index)\"\n :class=\"fieldBaseClass(field)\"\n :style=\"getFieldStyle(field)\"\n >\n <JFormField\n :label=\"field.label\"\n :required=\"getFieldRequired(field)\"\n :orientation=\"getLabelPosition()\"\n :labelAlign=\"getLabelAlign()\"\n :labelWidth=\"getLabelWidth()\"\n :type=\"(field.type === 'searchcombo' ? 'searchCombo' : field.type) as any\"\n :input-type=\"field.inputType\"\n :description=\"field.description\"\n :inline-label=\"field.inlineLabel\"\n v-bind=\"getFieldProps(field)\"\n />\n </div>\n </template>\n\n <!-- ๐ฆ ์น์
ํ ํผ -->\n <template v-else-if=\"schema.type === 'sectioned'\">\n <div class=\"space-y-6\">\n <JCard\n v-for=\"section in schema.sections\"\n :key=\"section.id\"\n :title=\"section.title\"\n :collapsible=\"section.collapsible\"\n :default-collapsed=\"section.defaultCollapsed\"\n >\n <div :class=\"formClasses\">\n <div\n v-for=\"(field, index) in getOrderedFields(section.fields || [])\"\n :key=\"getFieldKey(field, index)\"\n :class=\"fieldBaseClass(field)\"\n :style=\"getFieldStyle(field)\"\n >\n <JFormField\n :label=\"field.label\"\n :required=\"getFieldRequired(field)\"\n :orientation=\"getLabelPosition()\"\n :labelAlign=\"getLabelAlign()\"\n :labelWidth=\"getLabelWidth()\"\n :type=\"(field.type === 'searchcombo' ? 'searchCombo' : field.type) as any\"\n :input-type=\"field.inputType\"\n :description=\"field.description\"\n :inline-label=\"field.inlineLabel\"\n v-bind=\"getFieldProps(field)\"\n />\n </div>\n </div>\n </JCard>\n </div>\n </template>\n\n <!-- ๐ช ์คํ
ํ (Wizard) -->\n <template v-else-if=\"schema.type === 'wizard'\">\n <div class=\"space-y-4\">\n <div\n v-for=\"step in schema.steps\"\n :key=\"step.id\"\n class=\"p-4 border rounded-xl\"\n >\n <h3 class=\"font-semibold text-lg\">{{ step.title }}</h3>\n <p v-if=\"step.description\" class=\"text-muted-foreground text-sm mb-2\">\n {{ step.description }}\n </p>\n <div :class=\"formClasses\">\n <div\n v-for=\"(field, index) in getOrderedFields(step.fields || [])\"\n :key=\"getFieldKey(field, index)\"\n :class=\"fieldBaseClass(field)\"\n :style=\"getFieldStyle(field)\"\n >\n <JFormField\n :label=\"field.label\"\n :required=\"getFieldRequired(field)\"\n :orientation=\"getLabelPosition()\"\n :labelAlign=\"getLabelAlign()\"\n :labelWidth=\"getLabelWidth()\"\n :type=\"(field.type === 'searchcombo' ? 'searchCombo' : field.type) as any\"\n :input-type=\"field.inputType\"\n :description=\"field.description\"\n :inline-label=\"field.inlineLabel\"\n v-bind=\"getFieldProps(field)\"\n />\n </div>\n </div>\n </div>\n </div>\n </template>\n\n </form>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, reactive, watch } from 'vue';\nimport { JFormField, JCard } from '@/components/molecules';\nimport type { FormSchema, DynamicFormField } from '@/types/dynamic-form';\nimport { resolveGlobalStyle } from '@/lib/styleTypePreset';\n\n// props\nconst props = defineProps<{\n schema: FormSchema;\n modelValue?: Record<string, any>;\n}>();\n\nconst emit = defineEmits(['update:modelValue', 'submit', 'change', 'error']);\n\nconst BOOLEAN_TYPES: Array<DynamicFormField['type']> = ['checkbox', 'switch'];\n\n// ํผ ์ํ ๊ด๋ฆฌ\nconst formState = reactive<Record<string, any>>({});\n\n// ์ด๊ธฐ๊ฐ ์ค์ \nwatch(\n () => props.modelValue,\n (newValues) => {\n if (newValues) {\n Object.assign(formState, newValues);\n }\n },\n { immediate: true, deep: true }\n);\n\n// ํ๋ ํค ๊ฐ์ ธ์ค๊ธฐ (controlId > controlName > name > label ์์)\nfunction getFieldKey(field: DynamicFormField, index: number): string {\n return field.controlId || field.controlName || (field as any).name || field.label || `field-${index}`;\n}\n\n// ํ๋ ์ด๋ฆ ๊ฐ์ ธ์ค๊ธฐ (controlName > name ์์)\nfunction getFieldName(field: DynamicFormField): string {\n return field.controlName || (field as any).name || '';\n}\n\n// ํ๋ required ๊ฐ์ ธ์ค๊ธฐ (isRequired > required ์์)\nfunction getFieldRequired(field: DynamicFormField): boolean {\n return field.isRequired !== undefined ? field.isRequired : ((field as any).required || false);\n}\n\n// ํ๋ ์ด๊ธฐํ\nwatch(\n () => props.schema,\n (newSchema) => {\n const allFields: DynamicFormField[] = [];\n \n if (newSchema.type === 'simple' && newSchema.fields) {\n allFields.push(...newSchema.fields);\n } else if (newSchema.type === 'sectioned' && newSchema.sections) {\n newSchema.sections.forEach(section => {\n if (section.fields) allFields.push(...section.fields);\n });\n } else if (newSchema.type === 'wizard' && newSchema.steps) {\n newSchema.steps.forEach(step => {\n if (step.fields) allFields.push(...step.fields);\n });\n }\n \n allFields.forEach((field) => {\n const fieldName = getFieldName(field);\n if (fieldName && formState[fieldName] === undefined) {\n if (BOOLEAN_TYPES.includes(field.type)) {\n formState[fieldName] = 'N';\n } else if (field.type === 'radio') {\n formState[fieldName] = field.options?.[0]?.value ?? '';\n } else if (field.type === 'select' || field.type === 'searchcombo') {\n const addAll = field.addAll !== undefined ? field.addAll : ((field as any).allowAll || false);\n formState[fieldName] = addAll ? 'ALL' : 'SELECT';\n } else {\n formState[fieldName] = '';\n }\n }\n });\n },\n { immediate: true }\n);\n\n// ๊ฐ ๋ณ๊ฒฝ ๊ฐ์ง โ ์์ emit\nwatch(formState, (val) => emit('update:modelValue', val), { deep: true });\n\n// ์ด๋ฒคํธ ํธ๋ค๋ฌ\nfunction handleSubmit() {\n emit('submit', { ...formState });\n if (typeof props.schema.events?.onSubmit === 'function') {\n props.schema.events.onSubmit({ ...formState });\n }\n}\n\nfunction handleChange(field: string, value: any) {\n emit('change', { field, value });\n if (typeof props.schema.events?.onChange === 'function') {\n props.schema.events.onChange(field, value);\n }\n}\n\nfunction handleError(errs: any) {\n emit('error', errs);\n if (typeof props.schema.events?.onError === 'function') {\n props.schema.events.onError(errs);\n }\n}\n\n// ์ ๋ ฌ๋ ํ๋ ๊ฐ์ ธ์ค๊ธฐ\nfunction getOrderedFields(fields: DynamicFormField[]): DynamicFormField[] {\n const visibleFields = fields.filter((field) => field.isVisible !== false);\n return visibleFields.sort((a, b) => {\n // sortOrder ๊ธฐ์ค์ผ๋ก ์ ๋ ฌ\n if (a.sortOrder !== undefined && b.sortOrder !== undefined) {\n if (a.sortOrder !== b.sortOrder) {\n return a.sortOrder - b.sortOrder;\n }\n }\n const aName = a.controlName || (a as any).name || a.label || '';\n const bName = b.controlName || (b as any).name || b.label || '';\n return aName.localeCompare(bName);\n });\n}\n\n// ํผ ํด๋์ค ๊ณ์ฐ\nconst formClasses = computed(() => {\n const colCount = props.schema.globalStyle?.colCount || \n (props.schema.layout?.columns ? `row-${props.schema.layout.columns}` : 'row-1');\n const gapClass = getGapClass(colCount);\n \n // ๋ฐ์ํ: ํ๋ฉด ํฌ๊ธฐ์ ๋ฐ๋ผ ์ด ์ ์๋ ์กฐ์ \n let classes = '';\n switch (colCount) {\n case 'row-1':\n classes = `flex flex-col ${gapClass}`;\n break;\n case 'row':\n case 'row-2':\n classes = `flex flex-col md:grid md:grid-flow-row md:items-start ${gapClass} md:grid-cols-2 auto-rows-min`;\n break;\n case 'row-3':\n classes = `flex flex-col md:grid md:grid-flow-row md:items-start ${gapClass} md:grid-cols-2 lg:grid-cols-3 auto-rows-min`;\n break;\n case 'row-4':\n classes = `flex flex-col md:grid md:grid-flow-row md:items-start ${gapClass} md:grid-cols-2 lg:grid-cols-4 auto-rows-min`;\n break;\n case 'row-5':\n classes = `flex flex-col md:grid md:grid-flow-row md:items-start ${gapClass} md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-5 auto-rows-min`;\n break;\n case 'row-6':\n classes = `flex flex-col md:grid md:grid-flow-row md:items-start ${gapClass} md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-6 auto-rows-min`;\n break;\n case 'row-7':\n classes = `flex flex-col md:grid md:grid-flow-row md:items-start ${gapClass} md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-7 auto-rows-min`;\n break;\n case 'row-8':\n classes = `flex flex-col md:grid md:grid-flow-row md:items-start ${gapClass} md:grid-cols-2 lg:grid-cols-4 xl:grid-cols-8 auto-rows-min`;\n break;\n default:\n classes = `flex flex-col ${gapClass}`;\n }\n \n return classes;\n});\n\n// ํ๋ ๊ธฐ๋ณธ ํด๋์ค\nfunction fieldBaseClass(field: DynamicFormField): string {\n return BOOLEAN_TYPES.includes(field.type)\n ? 'min-w-0 w-auto inline-flex items-center'\n : 'min-w-0 w-full';\n}\n\n// ์ต๋ ์ด ์ ๊ณ์ฐ\nfunction getMaxCols(colCount?: string): number {\n switch (colCount) {\n case 'row':\n case 'row-2': return 2;\n case 'row-3': return 3;\n case 'row-4': return 4;\n case 'row-5': return 5;\n case 'row-6': return 6;\n case 'row-7': return 7;\n case 'row-8': return 8;\n default: return 1;\n }\n}\n\n// ์ด ์์ ๋ฐ๋ฅธ gap ๊ณ์ฐ\nfunction getGapClass(colCount: string): string {\n switch (colCount) {\n case 'row-1': return 'gap-6';\n case 'row':\n case 'row-2': return 'gap-4';\n case 'row-3': return 'gap-4';\n case 'row-4': return 'gap-3';\n case 'row-5': return 'gap-2';\n case 'row-6': return 'gap-2';\n case 'row-7': return 'gap-2';\n case 'row-8': return 'gap-2';\n default: return 'gap-6';\n }\n}\n\n// ์ด ์์ ๋ฐ๋ฅธ ๋ผ๋ฒจ ๋๋น ๊ณ์ฐ\nfunction getLabelWidth(): string {\n const colCount = props.schema.globalStyle?.colCount || \n (props.schema.layout?.columns ? `row-${props.schema.layout.columns}` : 'row-1');\n const maxCols = getMaxCols(colCount);\n if (maxCols >= 6) return '6rem';\n if (maxCols >= 5) return '7rem';\n return '8rem';\n}\n\n// ๋ผ๋ฒจ ์์น ๊ฐ์ ธ์ค๊ธฐ\nfunction getLabelPosition(): 'horizontal' | 'vertical' {\n return props.schema.globalStyle?.labelPosition || 'horizontal';\n}\n\n// ๋ผ๋ฒจ ์ ๋ ฌ ๊ฐ์ ธ์ค๊ธฐ\nfunction getLabelAlign(): 'left' | 'middle' | 'right' {\n return props.schema.globalStyle?.labelAlign || 'left';\n}\n\n// ํ๋ ์คํ์ผ ๊ณ์ฐ\nfunction getFieldStyle(field: DynamicFormField): Record<string, string> {\n const colCount = props.schema.globalStyle?.colCount || \n (props.schema.layout?.columns ? `row-${props.schema.layout.columns}` : 'row-1');\n const maxCols = getMaxCols(colCount);\n const span = Math.min(maxCols, Math.max(1, field.colSpan || 1));\n return {\n gridColumn: `span ${span}`\n };\n}\n\n// ํ๋ props ์์ฑ\nfunction getFieldProps(field: DynamicFormField) {\n const fieldName = getFieldName(field);\n const disabled = field.isDisabled !== undefined ? field.isDisabled : ((field as any).disabled || false);\n const readonly = field.isReadonly !== undefined ? field.isReadonly : ((field as any).readonly || false);\n \n // baseClass ์กฐ์ \n const baseClass = BOOLEAN_TYPES.includes(field.type)\n ? 'inline-flex items-center gap-2 w-auto'\n : 'w-full';\n \n // ์ ์ญ ์คํ์ผ ํด๊ฒฐ\n const resolvedStyle = resolveGlobalStyle(props.schema.globalStyle);\n \n // ์ด ์์ ๋ฐ๋ผ ์ปจํธ๋กค ํฌ๊ธฐ ๋์ ์กฐ์ \n const colCount = props.schema.globalStyle?.colCount || \n (props.schema.layout?.columns ? `row-${props.schema.layout.columns}` : 'row-1');\n const maxCols = getMaxCols(colCount);\n let finalSize = resolvedStyle.controlSize;\n \n // 4์ด ์ด์์ผ ๋ ์ปจํธ๋กค ํฌ๊ธฐ๋ฅผ ์๊ฒ ์กฐ์ \n if (maxCols >= 6) {\n finalSize = 'sm';\n } else if (maxCols >= 5) {\n finalSize = 'sm';\n } else if (maxCols >= 4) {\n if (resolvedStyle.controlSize === 'lg') {\n finalSize = 'md';\n }\n }\n\n const createEventHandler = (eventType: string, value: any) => {\n if (fieldName) {\n formState[fieldName] = value;\n handleChange(fieldName, value);\n }\n \n if (field.events?.[eventType as keyof typeof field.events]) {\n const handlerName = field.events[eventType as keyof typeof field.events];\n console.log(`Event ${eventType}: Calling handler \"${handlerName}\" with value:`, value);\n }\n };\n\n if (BOOLEAN_TYPES.includes(field.type)) {\n return {\n modelValue: formState[fieldName] === 'Y' ? 'Y' : 'N',\n disabled,\n styleType: finalSize,\n class: baseClass,\n 'onUpdate:modelValue': (value: string) => {\n if (fieldName) {\n formState[fieldName] = value;\n }\n createEventHandler('onChange', value === 'Y');\n }\n };\n }\n\n if (field.type === 'radio') {\n return {\n modelValue: String(formState[fieldName] ?? ''),\n options: field.options ?? [],\n multiple: field.multiple,\n disabled,\n styleType: finalSize,\n class: baseClass,\n 'onUpdate:modelValue': (value: string) => {\n createEventHandler('onChange', value);\n }\n };\n }\n\n if (field.type === 'select' || field.type === 'combo') {\n return {\n modelValue: String(formState[fieldName] ?? ''),\n options: getSelectOptions(field),\n multiple: field.multiple,\n disabled,\n styleType: finalSize,\n class: baseClass,\n 'onUpdate:modelValue': (value: string) => {\n createEventHandler('onChange', value);\n }\n };\n }\n\n if (field.type === 'searchcombo') {\n return {\n modelValue: String(formState[fieldName] ?? ''),\n options: getSelectOptions(field),\n disabled,\n styleType: finalSize,\n class: baseClass,\n 'onUpdate:modelValue': (value: string) => {\n createEventHandler('onChange', value);\n }\n };\n }\n\n if (field.type === 'textarea') {\n return {\n modelValue: String(formState[fieldName] ?? ''),\n placeholder: field.placeholder ?? '',\n disabled,\n readonly,\n styleType: finalSize,\n class: baseClass,\n 'onUpdate:modelValue': (value: string) => {\n createEventHandler('onChange', value);\n }\n };\n }\n\n if (field.type === 'datepicker') {\n return {\n modelValue: String(formState[fieldName] ?? ''),\n placeholder: field.placeholder ?? '',\n disabled,\n readonly,\n styleType: finalSize,\n class: baseClass,\n 'onUpdate:modelValue': (value: string) => {\n createEventHandler('onChange', value);\n }\n };\n }\n\n // ๊ธฐ๋ณธ input\n return {\n modelValue: String(formState[fieldName] ?? ''),\n inputType: field.inputType || (field.dataType === 'number' ? 'number' : 'text'),\n placeholder: field.placeholder ?? '',\n disabled,\n readonly,\n styleType: finalSize,\n class: baseClass,\n 'onUpdate:modelValue': (value: string | number) => {\n createEventHandler('onChange', value);\n }\n };\n}\n\n// Select ์ต์
์์ฑ\nfunction getSelectOptions(field: DynamicFormField) {\n const addAll = field.addAll !== undefined ? field.addAll : ((field as any).allowAll || false);\n const defaultOption = {\n value: addAll ? 'ALL' : 'SELECT',\n label: addAll ? '์ ์ฒด' : '์ ํ'\n };\n return [defaultOption, ...(field.options || [])];\n}\n\n// ํผ ๋ฆฌ์
\nfunction reset() {\n Object.keys(formState).forEach(key => {\n delete formState[key];\n });\n \n // ๋ชจ๋ ํ๋ ์์ง\n const allFields: DynamicFormField[] = [];\n \n if (props.schema.type === 'simple' && props.schema.fields) {\n allFields.push(...props.schema.fields);\n } else if (props.schema.type === 'sectioned' && props.schema.sections) {\n props.schema.sections.forEach(section => {\n if (section.fields) allFields.push(...section.fields);\n });\n } else if (props.schema.type === 'wizard' && props.schema.steps) {\n props.schema.steps.forEach(step => {\n if (step.fields) allFields.push(...step.fields);\n });\n }\n \n // ์ด๊ธฐ๊ฐ์ผ๋ก ์ฌ์ค์ \n allFields.forEach((field) => {\n const fieldName = getFieldName(field);\n if (fieldName) {\n if (BOOLEAN_TYPES.includes(field.type)) {\n formState[fieldName] = 'N';\n } else if (field.type === 'radio') {\n formState[fieldName] = field.options?.[0]?.value ?? '';\n } else if (field.type === 'select' || field.type === 'searchcombo') {\n const addAll = field.addAll !== undefined ? field.addAll : ((field as any).allowAll || false);\n formState[fieldName] = addAll ? 'ALL' : 'SELECT';\n } else {\n formState[fieldName] = '';\n }\n }\n });\n}\n\n// ํผ ์ํ ๋
ธ์ถ\ndefineExpose({\n formState,\n submit: handleSubmit,\n reset,\n handleError\n});\n</script>\n\n<style scoped>\nform {\n width: 100%;\n}\n</style>\n"],"names":["props","__props","emit","__emit","BOOLEAN_TYPES","formState","reactive","watch","newValues","getFieldKey","field","index","getFieldName","getFieldRequired","newSchema","allFields","section","step","fieldName","addAll","val","handleSubmit","handleChange","value","handleError","errs","getOrderedFields","fields","a","b","aName","bName","formClasses","computed","colCount","gapClass","getGapClass","classes","fieldBaseClass","getMaxCols","getLabelWidth","maxCols","getLabelPosition","getLabelAlign","getFieldStyle","getFieldProps","disabled","readonly","baseClass","resolvedStyle","resolveGlobalStyle","finalSize","createEventHandler","eventType","handlerName","getSelectOptions","reset","key","__expose","_createElementBlock","_Fragment","_renderList","_normalizeClass","_normalizeStyle","_createVNode","_unref","_mergeProps","_openBlock","_hoisted_1","_createBlock","JCard","_createElementVNode","_hoisted_2","_hoisted_3","_toDisplayString","_hoisted_4"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"JDynamicForm.vue2.cjs","sources":["../../../../src/components/organisms/JDynamicForm.vue"],"sourcesContent":["<template>\n <form @submit.prevent=\"handleSubmit\" :class=\"formClasses\">\n <!-- ๐งฑ ๋จ์ํ ํผ -->\n <template v-if=\"schema.type === 'simple'\">\n <div\n v-for=\"(field, index) in getOrderedFields(schema.fields || [])\"\n :key=\"getFieldKey(field, index)\"\n :class=\"fieldBaseClass(field)\"\n :style=\"getFieldStyle(field)\"\n >\n <JFormField\n :label=\"field.label\"\n :required=\"getFieldRequired(field)\"\n :orientation=\"getLabelPosition()\"\n :labelAlign=\"getLabelAlign()\"\n :labelWidth=\"getLabelWidth()\"\n :type=\"(field.type === 'searchcombo' ? 'searchCombo' : field.type) as any\"\n :input-type=\"field.inputType\"\n :description=\"field.description\"\n :inline-label=\"field.inlineLabel\"\n v-bind=\"getFieldProps(field)\"\n />\n </div>\n </template>\n\n <!-- ๐ฆ ์น์
ํ ํผ -->\n <template v-else-if=\"schema.type === 'sectioned'\">\n <div class=\"space-y-6\">\n <JCard\n v-for=\"section in schema.sections\"\n :key=\"section.id\"\n :title=\"section.title\"\n :collapsible=\"section.collapsible\"\n :default-collapsed=\"section.defaultCollapsed\"\n >\n <div :class=\"formClasses\">\n <div\n v-for=\"(field, index) in getOrderedFields(section.fields || [])\"\n :key=\"getFieldKey(field, index)\"\n :class=\"fieldBaseClass(field)\"\n :style=\"getFieldStyle(field)\"\n >\n <JFormField\n :label=\"field.label\"\n :required=\"getFieldRequired(field)\"\n :orientation=\"getLabelPosition()\"\n :labelAlign=\"getLabelAlign()\"\n :labelWidth=\"getLabelWidth()\"\n :type=\"(field.type === 'searchcombo' ? 'searchCombo' : field.type) as any\"\n :input-type=\"field.inputType\"\n :description=\"field.description\"\n :inline-label=\"field.inlineLabel\"\n v-bind=\"getFieldProps(field)\"\n />\n </div>\n </div>\n </JCard>\n </div>\n </template>\n\n <!-- ๐ช ์คํ
ํ (Wizard) -->\n <template v-else-if=\"schema.type === 'wizard'\">\n <div class=\"space-y-4\">\n <div\n v-for=\"step in schema.steps\"\n :key=\"step.id\"\n class=\"p-4 border rounded-xl\"\n >\n <h3 class=\"font-semibold text-lg\">{{ step.title }}</h3>\n <p v-if=\"step.description\" class=\"text-muted-foreground text-sm mb-2\">\n {{ step.description }}\n </p>\n <div :class=\"formClasses\">\n <div\n v-for=\"(field, index) in getOrderedFields(step.fields || [])\"\n :key=\"getFieldKey(field, index)\"\n :class=\"fieldBaseClass(field)\"\n :style=\"getFieldStyle(field)\"\n >\n <JFormField\n :label=\"field.label\"\n :required=\"getFieldRequired(field)\"\n :orientation=\"getLabelPosition()\"\n :labelAlign=\"getLabelAlign()\"\n :labelWidth=\"getLabelWidth()\"\n :type=\"(field.type === 'searchcombo' ? 'searchCombo' : field.type) as any\"\n :input-type=\"field.inputType\"\n :description=\"field.description\"\n :inline-label=\"field.inlineLabel\"\n v-bind=\"getFieldProps(field)\"\n />\n </div>\n </div>\n </div>\n </div>\n </template>\n\n </form>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, reactive, watch } from 'vue';\nimport { JFormField, JCard } from '@/components/molecules';\nimport type { FormSchema, DynamicFormField } from '@/types/dynamic-form';\nimport { resolveGlobalStyle } from '@/lib/styleTypePreset';\n\n// props\nconst props = defineProps<{\n schema: FormSchema;\n modelValue?: Record<string, any>;\n}>();\n\nconst emit = defineEmits(['update:modelValue', 'submit', 'change', 'error']);\n\nconst BOOLEAN_TYPES: Array<DynamicFormField['type']> = ['checkbox', 'switch'];\n\n// ํผ ์ํ ๊ด๋ฆฌ\nconst formState = reactive<Record<string, any>>({});\n\n// ์ด๊ธฐ๊ฐ ์ค์ \nwatch(\n () => props.modelValue,\n (newValues) => {\n if (newValues) {\n Object.assign(formState, newValues);\n }\n },\n { immediate: true, deep: true }\n);\n\n// ํ๋ ํค ๊ฐ์ ธ์ค๊ธฐ (controlId > controlName > name > label ์์)\nfunction getFieldKey(field: DynamicFormField, index: number): string {\n return field.controlId || field.controlName || (field as any).name || field.label || `field-${index}`;\n}\n\n// ํ๋ ์ด๋ฆ ๊ฐ์ ธ์ค๊ธฐ (controlName > name ์์)\nfunction getFieldName(field: DynamicFormField): string {\n return field.controlName || (field as any).name || '';\n}\n\n// ํ๋ required ๊ฐ์ ธ์ค๊ธฐ (isRequired > required ์์)\nfunction getFieldRequired(field: DynamicFormField): boolean {\n return field.isRequired !== undefined ? field.isRequired : ((field as any).required || false);\n}\n\n// ํ๋ ์ด๊ธฐํ\nwatch(\n () => props.schema,\n (newSchema) => {\n const allFields: DynamicFormField[] = [];\n \n if (newSchema.type === 'simple' && newSchema.fields) {\n allFields.push(...newSchema.fields);\n } else if (newSchema.type === 'sectioned' && newSchema.sections) {\n newSchema.sections.forEach(section => {\n if (section.fields) allFields.push(...section.fields);\n });\n } else if (newSchema.type === 'wizard' && newSchema.steps) {\n newSchema.steps.forEach(step => {\n if (step.fields) allFields.push(...step.fields);\n });\n }\n \n allFields.forEach((field) => {\n const fieldName = getFieldName(field);\n if (fieldName && formState[fieldName] === undefined) {\n if (BOOLEAN_TYPES.includes(field.type)) {\n formState[fieldName] = 'N';\n } else if (field.type === 'radio') {\n formState[fieldName] = field.options?.[0]?.value ?? '';\n } else if (field.type === 'select' || field.type === 'searchcombo') {\n const addAll = field.addAll !== undefined ? field.addAll : ((field as any).allowAll || false);\n formState[fieldName] = addAll ? 'ALL' : 'SELECT';\n } else {\n formState[fieldName] = '';\n }\n }\n });\n },\n { immediate: true }\n);\n\n// ๊ฐ ๋ณ๊ฒฝ ๊ฐ์ง โ ์์ emit\nwatch(formState, (val) => emit('update:modelValue', val), { deep: true });\n\n// ์ด๋ฒคํธ ํธ๋ค๋ฌ\nfunction handleSubmit() {\n emit('submit', { ...formState });\n if (typeof props.schema.events?.onSubmit === 'function') {\n props.schema.events.onSubmit({ ...formState });\n }\n}\n\nfunction handleChange(field: string, value: any) {\n emit('change', { field, value });\n if (typeof props.schema.events?.onChange === 'function') {\n props.schema.events.onChange(field, value);\n }\n}\n\nfunction handleError(errs: any) {\n emit('error', errs);\n if (typeof props.schema.events?.onError === 'function') {\n props.schema.events.onError(errs);\n }\n}\n\n// ์ ๋ ฌ๋ ํ๋ ๊ฐ์ ธ์ค๊ธฐ\nfunction getOrderedFields(fields: DynamicFormField[]): DynamicFormField[] {\n const visibleFields = fields.filter((field) => field.isVisible !== false);\n return visibleFields.sort((a, b) => {\n // sortOrder ๊ธฐ์ค์ผ๋ก ์ ๋ ฌ\n if (a.sortOrder !== undefined && b.sortOrder !== undefined) {\n if (a.sortOrder !== b.sortOrder) {\n return a.sortOrder - b.sortOrder;\n }\n }\n const aName = a.controlName || (a as any).name || a.label || '';\n const bName = b.controlName || (b as any).name || b.label || '';\n return aName.localeCompare(bName);\n });\n}\n\n// ํผ ํด๋์ค ๊ณ์ฐ\nconst formClasses = computed(() => {\n const colCount = props.schema.globalStyle?.colCount || \n (props.schema.layout?.columns ? `row-${props.schema.layout.columns}` : 'row-1');\n const gapClass = getGapClass(colCount);\n \n // ๋ฐ์ํ: ํ๋ฉด ํฌ๊ธฐ์ ๋ฐ๋ผ ์ด ์ ์๋ ์กฐ์ \n let classes = '';\n switch (colCount) {\n case 'row-1':\n classes = `flex flex-col ${gapClass}`;\n break;\n case 'row':\n case 'row-2':\n classes = `flex flex-col md:grid md:grid-flow-row md:items-start ${gapClass} md:grid-cols-2 auto-rows-min`;\n break;\n case 'row-3':\n classes = `flex flex-col md:grid md:grid-flow-row md:items-start ${gapClass} md:grid-cols-2 lg:grid-cols-3 auto-rows-min`;\n break;\n case 'row-4':\n classes = `flex flex-col md:grid md:grid-flow-row md:items-start ${gapClass} md:grid-cols-2 lg:grid-cols-4 auto-rows-min`;\n break;\n case 'row-5':\n classes = `flex flex-col md:grid md:grid-flow-row md:items-start ${gapClass} md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-5 auto-rows-min`;\n break;\n case 'row-6':\n classes = `flex flex-col md:grid md:grid-flow-row md:items-start ${gapClass} md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-6 auto-rows-min`;\n break;\n case 'row-7':\n classes = `flex flex-col md:grid md:grid-flow-row md:items-start ${gapClass} md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-7 auto-rows-min`;\n break;\n case 'row-8':\n classes = `flex flex-col md:grid md:grid-flow-row md:items-start ${gapClass} md:grid-cols-2 lg:grid-cols-4 xl:grid-cols-8 auto-rows-min`;\n break;\n default:\n classes = `flex flex-col ${gapClass}`;\n }\n \n return classes;\n});\n\n// ํ๋ ๊ธฐ๋ณธ ํด๋์ค\nfunction fieldBaseClass(field: DynamicFormField): string {\n return BOOLEAN_TYPES.includes(field.type)\n ? 'min-w-0 w-auto inline-flex items-center'\n : 'min-w-0 w-full';\n}\n\n// ์ต๋ ์ด ์ ๊ณ์ฐ\nfunction getMaxCols(colCount?: string): number {\n switch (colCount) {\n case 'row':\n case 'row-2': return 2;\n case 'row-3': return 3;\n case 'row-4': return 4;\n case 'row-5': return 5;\n case 'row-6': return 6;\n case 'row-7': return 7;\n case 'row-8': return 8;\n default: return 1;\n }\n}\n\n// ์ด ์์ ๋ฐ๋ฅธ gap ๊ณ์ฐ\nfunction getGapClass(colCount: string): string {\n switch (colCount) {\n case 'row-1': return 'gap-6';\n case 'row':\n case 'row-2': return 'gap-4';\n case 'row-3': return 'gap-4';\n case 'row-4': return 'gap-3';\n case 'row-5': return 'gap-2';\n case 'row-6': return 'gap-2';\n case 'row-7': return 'gap-2';\n case 'row-8': return 'gap-2';\n default: return 'gap-6';\n }\n}\n\n// ์ด ์์ ๋ฐ๋ฅธ ๋ผ๋ฒจ ๋๋น ๊ณ์ฐ\nfunction getLabelWidth(): string {\n const colCount = props.schema.globalStyle?.colCount || \n (props.schema.layout?.columns ? `row-${props.schema.layout.columns}` : 'row-1');\n const maxCols = getMaxCols(colCount);\n if (maxCols >= 6) return '6rem';\n if (maxCols >= 5) return '7rem';\n return '8rem';\n}\n\n// ๋ผ๋ฒจ ์์น ๊ฐ์ ธ์ค๊ธฐ\nfunction getLabelPosition(): 'horizontal' | 'vertical' {\n return props.schema.globalStyle?.labelPosition || 'horizontal';\n}\n\n// ๋ผ๋ฒจ ์ ๋ ฌ ๊ฐ์ ธ์ค๊ธฐ\nfunction getLabelAlign(): 'left' | 'middle' | 'right' {\n return props.schema.globalStyle?.labelAlign || 'left';\n}\n\n// ํ๋ ์คํ์ผ ๊ณ์ฐ\nfunction getFieldStyle(field: DynamicFormField): Record<string, string> {\n const colCount = props.schema.globalStyle?.colCount || \n (props.schema.layout?.columns ? `row-${props.schema.layout.columns}` : 'row-1');\n const maxCols = getMaxCols(colCount);\n const span = Math.min(maxCols, Math.max(1, field.colSpan || 1));\n return {\n gridColumn: `span ${span}`\n };\n}\n\n// ํ๋ props ์์ฑ\nfunction getFieldProps(field: DynamicFormField) {\n const fieldName = getFieldName(field);\n const disabled = field.isDisabled !== undefined ? field.isDisabled : ((field as any).disabled || false);\n const readonly = field.isReadonly !== undefined ? field.isReadonly : ((field as any).readonly || false);\n \n // baseClass ์กฐ์ \n const baseClass = BOOLEAN_TYPES.includes(field.type)\n ? 'inline-flex items-center gap-2 w-auto'\n : 'w-full';\n \n // ์ ์ญ ์คํ์ผ ํด๊ฒฐ\n const resolvedStyle = resolveGlobalStyle(props.schema.globalStyle);\n \n // ์ด ์์ ๋ฐ๋ผ ์ปจํธ๋กค ํฌ๊ธฐ ๋์ ์กฐ์ \n const colCount = props.schema.globalStyle?.colCount || \n (props.schema.layout?.columns ? `row-${props.schema.layout.columns}` : 'row-1');\n const maxCols = getMaxCols(colCount);\n let finalSize = resolvedStyle.controlSize;\n \n // 4์ด ์ด์์ผ ๋ ์ปจํธ๋กค ํฌ๊ธฐ๋ฅผ ์๊ฒ ์กฐ์ \n if (maxCols >= 6) {\n finalSize = 'sm';\n } else if (maxCols >= 5) {\n finalSize = 'sm';\n } else if (maxCols >= 4) {\n if (resolvedStyle.controlSize === 'lg') {\n finalSize = 'md';\n }\n }\n\n const createEventHandler = (eventType: string, value: any) => {\n if (fieldName) {\n formState[fieldName] = value;\n handleChange(fieldName, value);\n }\n \n if (field.events?.[eventType as keyof typeof field.events]) {\n const handlerName = field.events[eventType as keyof typeof field.events];\n console.log(`Event ${eventType}: Calling handler \"${handlerName}\" with value:`, value);\n }\n };\n\n if (BOOLEAN_TYPES.includes(field.type)) {\n return {\n modelValue: formState[fieldName] === 'Y' ? 'Y' : 'N',\n disabled,\n styleType: finalSize,\n class: baseClass,\n 'onUpdate:modelValue': (value: string) => {\n if (fieldName) {\n formState[fieldName] = value;\n }\n createEventHandler('onChange', value === 'Y');\n }\n };\n }\n\n if (field.type === 'radio') {\n return {\n modelValue: String(formState[fieldName] ?? ''),\n options: field.options ?? [],\n multiple: field.multiple,\n disabled,\n styleType: finalSize,\n class: baseClass,\n 'onUpdate:modelValue': (value: string) => {\n createEventHandler('onChange', value);\n }\n };\n }\n\n if (field.type === 'select' || field.type === 'combo') {\n return {\n modelValue: String(formState[fieldName] ?? ''),\n options: getSelectOptions(field),\n multiple: field.multiple,\n disabled,\n styleType: finalSize,\n class: baseClass,\n 'onUpdate:modelValue': (value: string) => {\n createEventHandler('onChange', value);\n }\n };\n }\n\n if (field.type === 'searchcombo') {\n return {\n modelValue: String(formState[fieldName] ?? ''),\n options: getSelectOptions(field),\n disabled,\n styleType: finalSize,\n class: baseClass,\n 'onUpdate:modelValue': (value: string) => {\n createEventHandler('onChange', value);\n }\n };\n }\n\n if (field.type === 'textarea') {\n return {\n modelValue: String(formState[fieldName] ?? ''),\n placeholder: field.placeholder ?? '',\n disabled,\n readonly,\n styleType: finalSize,\n class: baseClass,\n 'onUpdate:modelValue': (value: string) => {\n createEventHandler('onChange', value);\n }\n };\n }\n\n if (field.type === 'datepicker') {\n return {\n modelValue: String(formState[fieldName] ?? ''),\n placeholder: field.placeholder ?? '',\n disabled,\n readonly,\n styleType: finalSize,\n class: baseClass,\n 'onUpdate:modelValue': (value: string) => {\n createEventHandler('onChange', value);\n }\n };\n }\n\n // ๊ธฐ๋ณธ input\n return {\n modelValue: String(formState[fieldName] ?? ''),\n inputType: field.inputType || (field.dataType === 'number' ? 'number' : 'text'),\n placeholder: field.placeholder ?? '',\n disabled,\n readonly,\n styleType: finalSize,\n class: baseClass,\n 'onUpdate:modelValue': (value: string | number) => {\n createEventHandler('onChange', value);\n }\n };\n}\n\n// Select ์ต์
์์ฑ\nfunction getSelectOptions(field: DynamicFormField) {\n const addAll = field.addAll !== undefined ? field.addAll : ((field as any).allowAll || false);\n const defaultOption = {\n value: addAll ? 'ALL' : 'SELECT',\n label: addAll ? '์ ์ฒด' : '์ ํ'\n };\n return [defaultOption, ...(field.options || [])];\n}\n\n// ํผ ๋ฆฌ์
\nfunction reset() {\n Object.keys(formState).forEach(key => {\n delete formState[key];\n });\n \n // ๋ชจ๋ ํ๋ ์์ง\n const allFields: DynamicFormField[] = [];\n \n if (props.schema.type === 'simple' && props.schema.fields) {\n allFields.push(...props.schema.fields);\n } else if (props.schema.type === 'sectioned' && props.schema.sections) {\n props.schema.sections.forEach(section => {\n if (section.fields) allFields.push(...section.fields);\n });\n } else if (props.schema.type === 'wizard' && props.schema.steps) {\n props.schema.steps.forEach(step => {\n if (step.fields) allFields.push(...step.fields);\n });\n }\n \n // ์ด๊ธฐ๊ฐ์ผ๋ก ์ฌ์ค์ \n allFields.forEach((field) => {\n const fieldName = getFieldName(field);\n if (fieldName) {\n if (BOOLEAN_TYPES.includes(field.type)) {\n formState[fieldName] = 'N';\n } else if (field.type === 'radio') {\n formState[fieldName] = field.options?.[0]?.value ?? '';\n } else if (field.type === 'select' || field.type === 'searchcombo') {\n const addAll = field.addAll !== undefined ? field.addAll : ((field as any).allowAll || false);\n formState[fieldName] = addAll ? 'ALL' : 'SELECT';\n } else {\n formState[fieldName] = '';\n }\n }\n });\n}\n\n// ํผ ์ํ ๋
ธ์ถ\ndefineExpose({\n formState,\n submit: handleSubmit,\n reset,\n handleError\n});\n</script>\n\n<style scoped>\nform {\n width: 100%;\n}\n</style>\n"],"names":["props","__props","emit","__emit","BOOLEAN_TYPES","formState","reactive","watch","newValues","getFieldKey","field","index","getFieldName","getFieldRequired","newSchema","allFields","section","step","fieldName","addAll","val","handleSubmit","handleChange","value","handleError","errs","getOrderedFields","fields","a","b","aName","bName","formClasses","computed","colCount","gapClass","getGapClass","classes","fieldBaseClass","getMaxCols","getLabelWidth","maxCols","getLabelPosition","getLabelAlign","getFieldStyle","getFieldProps","disabled","readonly","baseClass","resolvedStyle","resolveGlobalStyle","finalSize","createEventHandler","eventType","handlerName","getSelectOptions","reset","key","__expose","_createElementBlock","_Fragment","_renderList","_normalizeClass","_normalizeStyle","_createVNode","_unref","_mergeProps","_openBlock","_hoisted_1","_createBlock","JCard","_createElementVNode","_hoisted_2","_hoisted_3","_toDisplayString","_hoisted_4"],"mappings":"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"}
|