polarvo-layout 1.0.63 → 1.0.65

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "polarvo-layout",
3
- "version": "1.0.63",
3
+ "version": "1.0.65",
4
4
  "type": "module",
5
5
  "author": "unigence <unigencelab@gmail.com>",
6
6
  "repository": {
@@ -43,8 +43,9 @@
43
43
  :rootId="item.id"
44
44
  :ref="setRef"
45
45
  v-bind="item"
46
+ :isHovable="isHovable"
46
47
  class="hover:opacity-80"
47
- :class="activeEditMode ? `pointer-events-auto ` : `pointer-events-none`"
48
+ :class="activeEditMode || isHovable ? `pointer-events-auto ` : `pointer-events-none`"
48
49
  @set:defaultStyle="setDefaultStyle"
49
50
  />
50
51
  </div>
@@ -59,6 +60,7 @@ const props = defineProps({
59
60
  item: { type: Object, required: true },
60
61
  polarvo: { type: Object, required: true },
61
62
  sectionKey: { type: String, required: true },
63
+ isHovable: { type: Boolean, required: true },
62
64
  });
63
65
 
64
66
  const { activeId, handles, activeElement } = toRefs(props.polarvo.freeDrop.state);
@@ -6,6 +6,7 @@
6
6
  :item="item"
7
7
  :polarvo="props.polarvo"
8
8
  :sectionKey="props.sectionKey"
9
+ :isHovable="isHovable(item)"
9
10
  ></FreeItem>
10
11
 
11
12
  <!-- 오버레이 -->
@@ -68,6 +69,11 @@ const filteredElements = computed(() => {
68
69
  const selectedElement = inject('selectedElement');
69
70
  const activeEditMode = inject('activeEditMode');
70
71
 
72
+ const isHovable = (item) => {
73
+ if (!item || props.preview) return true;
74
+ return activeElement.value?.id === item.id && ['chart'].includes(item.type);
75
+ };
76
+
71
77
  let _isElementSwitching = false;
72
78
  import { omit, cloneDeep } from 'lodash-es';
73
79
 
@@ -79,7 +85,7 @@ watch(
79
85
  if (newId && activeElement.value?.section !== props.sectionKey) return;
80
86
 
81
87
  if (!newId) {
82
- console.l
88
+ console.l;
83
89
  setActiveDesign(null);
84
90
  setActiveMenu(null);
85
91
  }
@@ -41,11 +41,11 @@
41
41
  :rootId="item.id"
42
42
  :ref="setRef"
43
43
  v-bind="item"
44
+ :isHovable="isHovable"
44
45
  class="hover:opacity-80"
45
- :class="activeEditMode ? `pointer-events-auto ` : `pointer-events-none`"
46
- @set:defaultStyle="setDefaultStyle"
46
+ :class="activeEditMode || isHovable ? `pointer-events-auto ` : `pointer-events-none`"
47
+ @set:defaultStyle="setDefaultStyle"
47
48
  />
48
-
49
49
  <!-- 오버레이 -->
50
50
  <div v-if="activeEditMode && item.id !== activeId" class="absolute inset-0 bg-black opacity-50 z-30"></div>
51
51
  </template>
@@ -69,6 +69,7 @@ const props = defineProps({
69
69
  item: { type: Object, required: true },
70
70
  polarvo: { type: Object, required: true },
71
71
  sectionKey: { type: String, required: true },
72
+ isHovable: { type: Boolean, required: true },
72
73
  });
73
74
 
74
75
  const { activeId } = toRefs(props.polarvo.gridDrop.state);
@@ -6,6 +6,7 @@
6
6
  :item="item"
7
7
  :polarvo="props.polarvo"
8
8
  :sectionKey="props.sectionKey"
9
+ :isHovable="isHovable(item)"
9
10
  ></GridItem>
10
11
 
11
12
  <!-- 행 크기 조절 -->
@@ -107,6 +108,11 @@ const { activeDesign } = toRefs(props.polarvo.display.state);
107
108
  const selectedElement = inject('selectedElement');
108
109
  const activeEditMode = inject('activeEditMode');
109
110
 
111
+ const isHovable = (item) => {
112
+ if (!item || props.preview) return true;
113
+ return activeElement.value?.id === item.id && ['chart'].includes(item.type);
114
+ };
115
+
110
116
  import { omit, cloneDeep, debounce } from 'lodash-es';
111
117
 
112
118
  const gridColumns = ref(3); // 동적으로 계산
@@ -1,7 +1,7 @@
1
1
  <template>
2
2
  <div class="gap-4 space-y-4">
3
3
  <div
4
- v-for="(item, index) in allElements"
4
+ v-for="(item, index) in currentElements"
5
5
  :key="index"
6
6
  class="flex flex-col items-center justify-center border border-gray-200 rounded-lg p-2 hover:bg-gray-50 transition-colors cursor-pointer active:scale-95"
7
7
  @mousedown.stop="sectionMode == 'free' ? addElementToFree($event, item) : addElementToGrid(item)"
@@ -12,6 +12,11 @@
12
12
  </div>
13
13
  </template>
14
14
 
15
+ <script>
16
+ let cachedDefaultElements = null;
17
+ let cachedCustomElements = null;
18
+ </script>
19
+
15
20
  <script setup>
16
21
  import { ref, onBeforeMount, toRefs, computed } from 'vue';
17
22
 
@@ -25,14 +30,32 @@ const props = defineProps({
25
30
  required: false,
26
31
  default: '',
27
32
  },
33
+ elType: {
34
+ type: String,
35
+ required: false,
36
+ default: 'default',
37
+ },
38
+ customElements: {
39
+ type: Array,
40
+ required: false,
41
+ default: () => [],
42
+ },
28
43
  });
44
+
29
45
  const { addElement: addElementToFree } = props.polarvo.freeDrop;
30
46
  const { addElement: addElementToGrid } = props.polarvo.gridDrop;
31
47
 
32
48
  const { activeMode } = toRefs(props.polarvo.layout.state);
33
49
  const sectionMode = computed(() => activeMode.value);
34
50
 
35
- const allElements = ref([]);
51
+ const allElements = ref({
52
+ default: [],
53
+ custom: props.customElements || [],
54
+ });
55
+
56
+ const currentElements = computed(() => {
57
+ return allElements.value[props.elType] || [];
58
+ });
36
59
 
37
60
  /** 프로젝트 폴더에서 요소 컴포넌트 주소를 맞춰줘야 정상 작동합니다.
38
61
  * (현재 /src/components/elements/ 내부에 모든 요소 컴포넌트가 있어야 함) */
@@ -42,56 +65,77 @@ const imageModules = import.meta.glob('@/assets/el_img/*.{png,gif}', { eager: tr
42
65
  function getPropsDefaults(props) {
43
66
  if (!props) return {};
44
67
 
45
- return Object.fromEntries(Object.entries(props).map(([key, prop]) => {
46
- if (['size', 'preview'].includes(key)) return null;
68
+ return Object.fromEntries(
69
+ Object.entries(props)
70
+ .map(([key, prop]) => {
71
+ if (['size', 'preview'].includes(key)) return null;
47
72
 
48
- if (prop.default !== undefined) {
49
- return [key, typeof prop.default === 'function' ? prop.default() : prop.default];
50
- }
51
- return null; // 기본값이 없는 경우 null 반환
52
- }).filter(entry => entry !== null));
73
+ if (prop.default !== undefined) {
74
+ return [key, typeof prop.default === 'function' ? prop.default() : prop.default];
75
+ }
76
+ return null; // 기본값이 없는 경우 null 반환
77
+ })
78
+ .filter((entry) => entry !== null),
79
+ );
53
80
  }
54
81
 
55
- async function getElements() {
56
- // 특정 컴포넌트는 제외
57
- const excludedElements = [
58
- 'button',
59
- 'labelInput',
60
- 'labelSelect',
61
- 'dataList',
62
- 'multiCheckRadio',
63
- 'labelInputRows',
64
- 'refLabel',
65
- 'labelTextarea',
66
- 'loginForm',
67
- 'searchAddress'
68
- ];
69
-
70
- const elementsData = Object.keys(modules)
71
- .filter((path) => {
72
- const elName = path.split('/').pop().replace('.vue', '');
73
- return !excludedElements.includes(elName);
74
- })
75
- .map((path) => {
76
- const elName = path.split('/').pop().replace('.vue', '');
77
- const propDefaults = getPropsDefaults(modules[path].default?.props);
78
-
79
- // 확장자 조건 설정
82
+ // 기본 요소 목록에서 제외할 컴포넌트
83
+ const EXCLUDED_ELEMENTS = [
84
+ 'button',
85
+ 'labelInput',
86
+ 'labelSelect',
87
+ 'dataList',
88
+ 'multiCheckRadio',
89
+ 'labelInputRows',
90
+ 'refLabel',
91
+ 'labelTextarea',
92
+ 'loginForm',
93
+ 'searchAddress',
94
+ ];
95
+
96
+ function buildDefaultElements() {
97
+ if (cachedDefaultElements) return cachedDefaultElements;
98
+
99
+ cachedDefaultElements = Object.keys(modules)
100
+ .map((path) => ({ path, elName: path.split('/').pop().replace('.vue', '') }))
101
+ .filter(({ elName }) => !EXCLUDED_ELEMENTS.includes(elName))
102
+ .map(({ path, elName }) => {
80
103
  const ext = elName === 'dataList' ? 'gif' : 'png';
81
104
  const imgKey = `/src/assets/el_img/${elName}.${ext}`;
82
105
 
83
- let result = {
106
+ return {
107
+ elType: 'default',
84
108
  elName,
85
- propDefaults: propDefaults,
86
- // imgurl: new URL(`../../assets/el_img/${elName}.${ext}`, props.urlBase),
109
+ propDefaults: getPropsDefaults(modules[path].default?.props),
87
110
  imgurl: imageModules[imgKey]?.default ?? '',
88
- // component: markRaw(defineAsyncComponent(modules[path]))
89
111
  };
90
-
91
- return result;
92
112
  });
93
113
 
94
- allElements.value = elementsData;
114
+ return cachedDefaultElements;
115
+ }
116
+
117
+ function buildCustomElements() {
118
+ if (cachedCustomElements) return cachedCustomElements;
119
+
120
+ const imgurl = imageModules['/src/assets/el_img/customDefault.png']?.default ?? '';
121
+
122
+ cachedCustomElements = props.customElements.map((el) => {
123
+ const { elName, mode, position, size, section, isLocked, ...propDefaults } = el;
124
+
125
+ return {
126
+ elType: 'custom',
127
+ elName,
128
+ propDefaults,
129
+ imgurl,
130
+ };
131
+ });
132
+
133
+ return cachedCustomElements;
134
+ }
135
+
136
+ function getElements() {
137
+ allElements.value.default = buildDefaultElements();
138
+ allElements.value.custom = buildCustomElements();
95
139
  }
96
140
 
97
141
  onBeforeMount(() => {