polarvo-layout 1.0.64 → 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.64",
3
+ "version": "1.0.65",
4
4
  "type": "module",
5
5
  "author": "unigence <unigencelab@gmail.com>",
6
6
  "repository": {
@@ -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(() => {