evui 3.3.2 → 3.3.3
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/dist/evui.common.js +363 -323
- package/dist/evui.common.js.map +1 -1
- package/dist/evui.umd.js +363 -323
- package/dist/evui.umd.js.map +1 -1
- package/dist/evui.umd.min.js +1 -1
- package/dist/evui.umd.min.js.map +1 -1
- package/package.json +1 -1
- package/src/components/button/Button.vue +16 -0
- package/src/components/grid/Grid.vue +5 -2
- package/src/components/grid/uses.js +38 -36
- package/src/components/messageBox/MessageBox.vue +35 -6
- package/src/components/treeGrid/TreeGrid.vue +6 -4
- package/src/components/treeGrid/uses.js +39 -35
package/package.json
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<button
|
|
3
|
+
ref="buttonRef"
|
|
3
4
|
class="ev-button"
|
|
4
5
|
:class="{
|
|
5
6
|
disabled,
|
|
@@ -17,6 +18,8 @@
|
|
|
17
18
|
</template>
|
|
18
19
|
|
|
19
20
|
<script>
|
|
21
|
+
import { onMounted, ref } from 'vue';
|
|
22
|
+
|
|
20
23
|
export default {
|
|
21
24
|
name: 'EvButton',
|
|
22
25
|
props: {
|
|
@@ -52,6 +55,19 @@ export default {
|
|
|
52
55
|
emits: {
|
|
53
56
|
click: null,
|
|
54
57
|
},
|
|
58
|
+
setup(props) {
|
|
59
|
+
const buttonRef = ref(null);
|
|
60
|
+
|
|
61
|
+
onMounted(() => {
|
|
62
|
+
if (props.autoFocus) {
|
|
63
|
+
buttonRef.value.focus();
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
return {
|
|
68
|
+
buttonRef,
|
|
69
|
+
};
|
|
70
|
+
},
|
|
55
71
|
};
|
|
56
72
|
</script>
|
|
57
73
|
|
|
@@ -471,7 +471,7 @@ export default {
|
|
|
471
471
|
setStore(props.rows);
|
|
472
472
|
});
|
|
473
473
|
onActivated(() => {
|
|
474
|
-
|
|
474
|
+
onResize();
|
|
475
475
|
});
|
|
476
476
|
const ROW_INDEX = 0;
|
|
477
477
|
const ROW_CHECK_INDEX = 1;
|
|
@@ -584,7 +584,10 @@ export default {
|
|
|
584
584
|
watch(
|
|
585
585
|
() => filterInfo.searchValue,
|
|
586
586
|
(value) => {
|
|
587
|
-
|
|
587
|
+
const searchValue = value?.value ?? value;
|
|
588
|
+
if (searchValue) {
|
|
589
|
+
onSearch(searchValue);
|
|
590
|
+
}
|
|
588
591
|
}, { immediate: true },
|
|
589
592
|
);
|
|
590
593
|
const isFilterButton = field => filterInfo.isFiltering && field !== 'db-icon' && field !== 'user-icon';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getCurrentInstance } from 'vue';
|
|
1
|
+
import { getCurrentInstance, nextTick } from 'vue';
|
|
2
2
|
import { isEqual, uniqBy } from 'lodash-es';
|
|
3
3
|
import { numberWithComma } from '@/common/utils';
|
|
4
4
|
|
|
@@ -75,23 +75,25 @@ export const scrollEvent = (params) => {
|
|
|
75
75
|
const updateVScroll = () => {
|
|
76
76
|
const bodyEl = elementInfo.body;
|
|
77
77
|
const rowHeight = resizeInfo.rowHeight;
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
firstVisibleIndex
|
|
84
|
-
|
|
78
|
+
if (bodyEl) {
|
|
79
|
+
const rowCount = bodyEl.clientHeight > rowHeight
|
|
80
|
+
? Math.ceil(bodyEl.clientHeight / rowHeight) : stores.store.length;
|
|
81
|
+
const totalScrollHeight = stores.store.length * rowHeight;
|
|
82
|
+
let firstVisibleIndex = Math.floor(bodyEl.scrollTop / rowHeight);
|
|
83
|
+
if (firstVisibleIndex > stores.store.length - 1) {
|
|
84
|
+
firstVisibleIndex = 0;
|
|
85
|
+
}
|
|
85
86
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
87
|
+
const lastVisibleIndex = firstVisibleIndex + rowCount;
|
|
88
|
+
const firstIndex = Math.max(firstVisibleIndex, 0);
|
|
89
|
+
const lastIndex = lastVisibleIndex;
|
|
89
90
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
91
|
+
stores.viewStore = stores.store.slice(firstIndex, lastIndex);
|
|
92
|
+
scrollInfo.hasVerticalScrollBar = rowCount < stores.store.length;
|
|
93
|
+
scrollInfo.vScrollTopHeight = firstIndex * rowHeight;
|
|
94
|
+
scrollInfo.vScrollBottomHeight = totalScrollHeight - (stores.viewStore.length * rowHeight)
|
|
95
|
+
- scrollInfo.vScrollTopHeight;
|
|
96
|
+
}
|
|
95
97
|
};
|
|
96
98
|
/**
|
|
97
99
|
* 수평 스크롤의 위치 계산 후 적용한다.
|
|
@@ -114,7 +116,7 @@ export const scrollEvent = (params) => {
|
|
|
114
116
|
const isHorizontal = !(scrollLeft === lastLeft);
|
|
115
117
|
const isVertical = !(scrollTop === lastTop);
|
|
116
118
|
|
|
117
|
-
if (isVertical && bodyEl
|
|
119
|
+
if (isVertical && bodyEl?.clientHeight) {
|
|
118
120
|
updateVScroll();
|
|
119
121
|
}
|
|
120
122
|
|
|
@@ -223,22 +225,24 @@ export const resizeEvent = (params) => {
|
|
|
223
225
|
* grid resize 이벤트를 처리한다.
|
|
224
226
|
*/
|
|
225
227
|
const onResize = () => {
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
228
|
+
nextTick(() => {
|
|
229
|
+
if (resizeInfo.adjust) {
|
|
230
|
+
stores.orderedColumns.map((column) => {
|
|
231
|
+
const item = column;
|
|
229
232
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
+
if (!props.columns[column.index].width && !item.resized) {
|
|
234
|
+
item.width = 0;
|
|
235
|
+
}
|
|
233
236
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
+
return item;
|
|
238
|
+
}, this);
|
|
239
|
+
}
|
|
237
240
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
241
|
+
calculatedColumn();
|
|
242
|
+
if (elementInfo.body?.clientHeight) {
|
|
243
|
+
updateVScroll();
|
|
244
|
+
}
|
|
245
|
+
});
|
|
242
246
|
};
|
|
243
247
|
|
|
244
248
|
const onShow = (isVisible) => {
|
|
@@ -747,14 +751,12 @@ export const filterEvent = (params) => {
|
|
|
747
751
|
}
|
|
748
752
|
const store = stores.store;
|
|
749
753
|
let checkedCount = 0;
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
754
|
+
store.forEach((row) => {
|
|
755
|
+
row[ROW_CHECK_INDEX] = checkInfo.checkedRows.includes(row[ROW_DATA_INDEX]);
|
|
756
|
+
if (row[ROW_CHECK_INDEX]) {
|
|
753
757
|
checkedCount += 1;
|
|
754
|
-
} else {
|
|
755
|
-
store[ix][ROW_CHECK_INDEX] = false;
|
|
756
758
|
}
|
|
757
|
-
}
|
|
759
|
+
});
|
|
758
760
|
if (store.length && store.length === checkedCount) {
|
|
759
761
|
checkInfo.isHeaderChecked = true;
|
|
760
762
|
} else {
|
|
@@ -14,11 +14,12 @@
|
|
|
14
14
|
ref="msgRef"
|
|
15
15
|
class="ev-message-box"
|
|
16
16
|
:class="{
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
17
|
+
[`type-${type}`]: !!type,
|
|
18
|
+
'show-close': showClose,
|
|
19
|
+
'has-icon': !!iconClass,
|
|
20
|
+
'has-title': !!title,
|
|
21
|
+
}"
|
|
22
|
+
tabindex="-1"
|
|
22
23
|
>
|
|
23
24
|
<span
|
|
24
25
|
v-if="iconClass"
|
|
@@ -52,6 +53,7 @@
|
|
|
52
53
|
v-if="showCancelBtn"
|
|
53
54
|
size="small"
|
|
54
55
|
class="ev-message-box-cancel"
|
|
56
|
+
:auto-focus="hasFocus('cancelBtn')"
|
|
55
57
|
@click="closeMsg('cancel')"
|
|
56
58
|
>
|
|
57
59
|
{{ cancelBtnText }}
|
|
@@ -61,6 +63,7 @@
|
|
|
61
63
|
type="primary"
|
|
62
64
|
size="small"
|
|
63
65
|
class="ev-message-box-confirm"
|
|
66
|
+
:auto-focus="hasFocus('confirmBtn')"
|
|
64
67
|
@click="closeMsg('ok')"
|
|
65
68
|
>
|
|
66
69
|
{{ confirmBtnText }}
|
|
@@ -80,7 +83,7 @@
|
|
|
80
83
|
</template>
|
|
81
84
|
|
|
82
85
|
<script>
|
|
83
|
-
import { reactive, toRefs, watch, onMounted } from 'vue';
|
|
86
|
+
import { reactive, toRefs, watch, onMounted, ref } from 'vue';
|
|
84
87
|
import EvButton from '@/components/button/Button.vue';
|
|
85
88
|
|
|
86
89
|
export default {
|
|
@@ -142,8 +145,14 @@ export default {
|
|
|
142
145
|
type: Function,
|
|
143
146
|
default: null,
|
|
144
147
|
},
|
|
148
|
+
focusable: {
|
|
149
|
+
type: Boolean,
|
|
150
|
+
default: false,
|
|
151
|
+
},
|
|
145
152
|
},
|
|
146
153
|
setup(props) {
|
|
154
|
+
const msgRef = ref(null);
|
|
155
|
+
|
|
147
156
|
const state = reactive({
|
|
148
157
|
isShow: true,
|
|
149
158
|
iconClass: '',
|
|
@@ -190,9 +199,27 @@ export default {
|
|
|
190
199
|
}
|
|
191
200
|
};
|
|
192
201
|
|
|
202
|
+
const hasFocus = (type) => {
|
|
203
|
+
if (!props.focusable) return false;
|
|
204
|
+
|
|
205
|
+
switch (type) {
|
|
206
|
+
case 'confirmBtn':
|
|
207
|
+
return props.showConfirmBtn;
|
|
208
|
+
case 'cancelBtn':
|
|
209
|
+
return !props.showConfirmBtn && props.showCancelBtn;
|
|
210
|
+
case 'messagebox':
|
|
211
|
+
return !props.showConfirmBtn && !props.showCancelBtn;
|
|
212
|
+
default:
|
|
213
|
+
return false;
|
|
214
|
+
}
|
|
215
|
+
};
|
|
216
|
+
|
|
193
217
|
onMounted(() => {
|
|
194
218
|
setState();
|
|
195
219
|
document.addEventListener('keydown', keydown);
|
|
220
|
+
if (hasFocus('messagebox')) {
|
|
221
|
+
msgRef.value.focus();
|
|
222
|
+
}
|
|
196
223
|
});
|
|
197
224
|
watch(() => state.isShow, (val) => {
|
|
198
225
|
if (!val) {
|
|
@@ -202,6 +229,8 @@ export default {
|
|
|
202
229
|
return {
|
|
203
230
|
closeMsg,
|
|
204
231
|
...toRefs(state),
|
|
232
|
+
msgRef,
|
|
233
|
+
hasFocus,
|
|
205
234
|
};
|
|
206
235
|
},
|
|
207
236
|
};
|
|
@@ -332,13 +332,13 @@ export default {
|
|
|
332
332
|
|
|
333
333
|
const {
|
|
334
334
|
onSearch,
|
|
335
|
-
} = filterEvent({ checkInfo, stores, getConvertValue,
|
|
335
|
+
} = filterEvent({ checkInfo, stores, getConvertValue, onResize });
|
|
336
336
|
|
|
337
337
|
onMounted(() => {
|
|
338
338
|
stores.treeStore = setTreeNodeStore();
|
|
339
339
|
});
|
|
340
340
|
onActivated(() => {
|
|
341
|
-
|
|
341
|
+
onResize();
|
|
342
342
|
});
|
|
343
343
|
watch(
|
|
344
344
|
() => props.checked,
|
|
@@ -377,7 +377,6 @@ export default {
|
|
|
377
377
|
stores.treeRows = newData;
|
|
378
378
|
stores.treeStore = setTreeNodeStore();
|
|
379
379
|
onResize();
|
|
380
|
-
updateVScroll();
|
|
381
380
|
}, { deep: true },
|
|
382
381
|
);
|
|
383
382
|
watch(
|
|
@@ -400,7 +399,10 @@ export default {
|
|
|
400
399
|
watch(
|
|
401
400
|
() => searchValue.value,
|
|
402
401
|
(value) => {
|
|
403
|
-
|
|
402
|
+
const searchWord = value?.value ?? value;
|
|
403
|
+
if (searchWord) {
|
|
404
|
+
onSearch(searchWord);
|
|
405
|
+
}
|
|
404
406
|
}, { immediate: true },
|
|
405
407
|
);
|
|
406
408
|
const gridStyle = computed(() => ({
|
|
@@ -70,24 +70,26 @@ export const scrollEvent = (params) => {
|
|
|
70
70
|
const updateVScroll = () => {
|
|
71
71
|
const store = stores.showTreeStore;
|
|
72
72
|
const bodyEl = elementInfo.body;
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
firstVisibleIndex
|
|
80
|
-
|
|
73
|
+
if (bodyEl) {
|
|
74
|
+
const rowHeight = resizeInfo.rowHeight;
|
|
75
|
+
const rowCount = bodyEl.clientHeight > rowHeight
|
|
76
|
+
? Math.ceil(bodyEl.clientHeight / rowHeight) : store.length;
|
|
77
|
+
const totalScrollHeight = store.length * rowHeight;
|
|
78
|
+
let firstVisibleIndex = Math.floor(bodyEl.scrollTop / rowHeight);
|
|
79
|
+
if (firstVisibleIndex > store.length - 1) {
|
|
80
|
+
firstVisibleIndex = 0;
|
|
81
|
+
}
|
|
81
82
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
83
|
+
const lastVisibleIndex = firstVisibleIndex + rowCount;
|
|
84
|
+
const firstIndex = Math.max(firstVisibleIndex, 0);
|
|
85
|
+
const lastIndex = lastVisibleIndex;
|
|
85
86
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
87
|
+
stores.viewStore = store.slice(firstIndex, lastIndex);
|
|
88
|
+
scrollInfo.hasVerticalScrollBar = rowCount < store.length;
|
|
89
|
+
scrollInfo.vScrollTopHeight = firstIndex * rowHeight;
|
|
90
|
+
scrollInfo.vScrollBottomHeight = totalScrollHeight - (stores.viewStore.length * rowHeight)
|
|
91
|
+
- scrollInfo.vScrollTopHeight;
|
|
92
|
+
}
|
|
91
93
|
};
|
|
92
94
|
/**
|
|
93
95
|
* 수평 스크롤의 위치 계산 후 적용한다.
|
|
@@ -110,7 +112,7 @@ export const scrollEvent = (params) => {
|
|
|
110
112
|
const isHorizontal = !(scrollLeft === lastLeft);
|
|
111
113
|
const isVertical = !(scrollTop === lastTop);
|
|
112
114
|
|
|
113
|
-
if (isVertical) {
|
|
115
|
+
if (isVertical && bodyEl.clientHeight) {
|
|
114
116
|
updateVScroll();
|
|
115
117
|
}
|
|
116
118
|
|
|
@@ -223,22 +225,25 @@ export const resizeEvent = (params) => {
|
|
|
223
225
|
/**
|
|
224
226
|
* grid resize 이벤트를 처리한다.
|
|
225
227
|
*/
|
|
226
|
-
const onResize =
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
228
|
+
const onResize = () => {
|
|
229
|
+
nextTick(() => {
|
|
230
|
+
if (resizeInfo.adjust) {
|
|
231
|
+
stores.orderedColumns.map((column) => {
|
|
232
|
+
const item = column;
|
|
233
|
+
|
|
234
|
+
if (!props.columns[column.index].width && !item.resized) {
|
|
235
|
+
item.width = 0;
|
|
236
|
+
}
|
|
235
237
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
238
|
+
return item;
|
|
239
|
+
}, this);
|
|
240
|
+
}
|
|
239
241
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
+
calculatedColumn();
|
|
243
|
+
if (elementInfo.body?.clientHeight) {
|
|
244
|
+
updateVScroll();
|
|
245
|
+
}
|
|
246
|
+
});
|
|
242
247
|
};
|
|
243
248
|
const onShow = (isVisible) => {
|
|
244
249
|
if (isVisible) {
|
|
@@ -603,7 +608,7 @@ export const treeEvent = (params) => {
|
|
|
603
608
|
|
|
604
609
|
nodeList.push(node);
|
|
605
610
|
|
|
606
|
-
if (
|
|
611
|
+
if (!Object.hasOwnProperty.call(node, 'parent')) {
|
|
607
612
|
node.parent = parent;
|
|
608
613
|
}
|
|
609
614
|
if (node.children) {
|
|
@@ -648,7 +653,7 @@ export const treeEvent = (params) => {
|
|
|
648
653
|
};
|
|
649
654
|
|
|
650
655
|
export const filterEvent = (params) => {
|
|
651
|
-
const { checkInfo, stores, getConvertValue,
|
|
656
|
+
const { checkInfo, stores, getConvertValue, onResize } = params;
|
|
652
657
|
const makeParentShow = (data) => {
|
|
653
658
|
if (!data?.parent) {
|
|
654
659
|
return;
|
|
@@ -735,8 +740,7 @@ export const filterEvent = (params) => {
|
|
|
735
740
|
}
|
|
736
741
|
const isCheck = store.length > 0 && store.every(n => n.checked === true);
|
|
737
742
|
checkInfo.isHeaderChecked = isCheck;
|
|
738
|
-
|
|
739
|
-
updateVScroll();
|
|
743
|
+
onResize();
|
|
740
744
|
}, 500);
|
|
741
745
|
};
|
|
742
746
|
return { onSearch };
|