Skip to content

Commit

Permalink
[#1003][3.0] Window > ESC 기능 버그 수정 (#1007)
Browse files Browse the repository at this point in the history
  • Loading branch information
sej-dev authored Jan 5, 2022
1 parent 119a937 commit 4f04443
Show file tree
Hide file tree
Showing 2 changed files with 184 additions and 29 deletions.
135 changes: 135 additions & 0 deletions docs/views/window/example/Default.vue
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,111 @@
</button>
</div>
</div>

<div class="case">
<p class="case-title">Esc Key Close</p>
<!--Window 1개-->
<ev-window
v-model:visible="isVisible10"
title="Esc Close Available Window"
:esc-close="true"
>
<div>esc-close prop을 통해 윈도우를 여닫을 수 있습니다.</div>
</ev-window>

<!--Window 여러개-->
<ev-window
v-model:visible="isVisible11[0]"
title="첫번째 Window"
:esc-close="true"
maximizable
fullscreen
>
<div>
Nested + Maximizable Window
<br />
<button class="nested-btn">
Esc key로 닫을 수 있습니다.
</button>
</div>
</ev-window>
<ev-window
v-model:visible="isVisible11[1]"
title="두번째 Window"
:esc-close="true"
width="85%"
height="85%"
resizable
>
<div>
Resizable Window
<br />
<button class="nested-btn">
Esc key로 닫을 수 있습니다.
</button>
</div>
</ev-window>
<ev-window
v-model:visible="isVisible11[2]"
title="세번째 Window"
:esc-close="true"
:is-modal="false"
width="70%"
height="70%"
draggable
>
<div>
Draggable Window
<br />
<button class="nested-btn">
Esc key로 닫을 수 있습니다.
</button>
</div>
</ev-window>
<ev-window
v-model:visible="isVisible11[3]"
title="네번째 Window"
:esc-close="isEscClose"
width="60%"
height="60%"
draggable
>
<div>
Draggable Window
<div class="esc-close-toggle-box">
<label>
esc-close prop 토글
<ev-icon icon="ev-icon-allow2-right" />
</label>
<ev-toggle
v-model="isEscClose"
@change="changeEscClose"
/>
</div>
<p class="nested-btn">
가장 상단에 위치한 Window의 esc-close prop가 false인 경우,
<strong>수동으로 닫은 후</strong>에 아래에 있는 Window를 Esc 키로 닫을 수 있습니다.
</p>
</div>
</ev-window>

<div class="description">
<button
class="btn"
@click="clickButton10"
>
click to open window!
</button>
<br />
<br />
<button
class="btn"
@click="clickButton11"
>
click to open different types of windows!
</button>
</div>
</div>
</template>

<script>
Expand Down Expand Up @@ -228,6 +333,23 @@ export default {
isVisible9.value = true;
};
const isVisible10 = ref(false);
const clickButton10 = () => {
isVisible10.value = true;
};
const isVisible11 = ref([false, false, false, false]);
const clickButton11 = () => {
for (let i = 0; i < isVisible11.value.length; i++) {
isVisible11.value[i] = true;
}
};
const isEscClose = ref(false);
const changeEscClose = (newValue) => {
isEscClose.value = newValue;
};
const mousedown = clickedInfo => console.log('mousedown', clickedInfo);
const mouseup = event => console.log('mousedown-mouseup', event);
const mousemove = clickedInfo => console.log('mousedown-mousemove', clickedInfo);
Expand All @@ -252,6 +374,12 @@ export default {
clickButton8,
isVisible9,
clickButton9,
isVisible10,
clickButton10,
isVisible11,
clickButton11,
isEscClose,
changeEscClose,
mousedown,
mouseup,
mousemove,
Expand Down Expand Up @@ -289,4 +417,11 @@ export default {
.header-right-icon {
margin-left: 20px;
}
.esc-close-toggle-box {
display: flex;
& > * {
margin-right: 5px;
}
}
</style>
78 changes: 49 additions & 29 deletions src/components/window/uses.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
import {
getCurrentInstance, ref, computed, reactive, watch, nextTick, onMounted,
getCurrentInstance,
ref,
computed,
reactive,
watch,
nextTick,
onMounted,
onBeforeUnmount,
} from 'vue';

// 세로 스크롤 너비
Expand Down Expand Up @@ -611,10 +618,7 @@ const activeWindows = (() => {
return windows.length <= 0;
},
isFirstWindowOpen() {
return windows.length === 1;
},
isLastWindowClose() {
return windows.length === 0;
return sequence === 1;
},
};
})();
Expand All @@ -631,9 +635,10 @@ const useEscKeydownEvent = ({ closeWin, windowRef }) => {
const { props } = getCurrentInstance();

let sequence = null;
let isActiveStatus = false;

const addActiveWindow = () => {
sequence = activeWindows.add({
sequence = activeWindows.add({
sequence,
closeWin,
elem: windowRef.value,
Expand All @@ -651,62 +656,77 @@ const useEscKeydownEvent = ({ closeWin, windowRef }) => {
const { code } = event;
if (code !== 'Escape') return;

// zIndex 클수록, 최근에 열린 것일수록(sequence 클수록) 앞에 위치
// zIndex 클수록, 최근에 열린 것일수록(sequence 클수록) 뒤에 위치
const compare = (window1, window2) => {
if (window1.zIndex > window2.zIndex) return -1;
if (window1.zIndex < window2.zIndex) return 1;
if (window1.zIndex > window2.zIndex) return 1;
if (window1.zIndex < window2.zIndex) return -1;

if (window1.sequence > window2.sequence) return -1;
return 1;
if (window1.sequence > window2.sequence) return 1;
return -1;
};

const activeWindowSorted = Array.prototype.map.call(activeWindows.windows, activeWindow => ({
...activeWindow,
zIndex: getZIndexFromElement(activeWindow.elem),
})).sort(compare);

const topActiveWindow = activeWindowSorted[0];
const topActiveWindow = activeWindowSorted[activeWindowSorted.length - 1];

// 예시 상황) Nested에서 외부 Window의 escClose는 true이고, 내부 Window의 escClose는 false인 경우,
// esc 눌러도 외부 Window는 닫히지 않고, 가장 상단에 있는 내부 Window가 수동으로 닫힌 후에 닫히도록 하기 위해
if (topActiveWindow.escClose === false) return;
if (!topActiveWindow.escClose) return;

topActiveWindow.closeWin();
};

const addKeydownEvtHandler = () => {
const setWindowActive = () => {
isActiveStatus = true;
addActiveWindow();
if (activeWindows.isFirstWindowOpen()) {
document.addEventListener('keydown', keydownEsc);
}
};

const removeKeydownEvtHandler = () => {
if (activeWindows.isLastWindowClose()) {
document.removeEventListener('keydown', keydownEsc);
}
const setWindowInactive = () => {
const inactiveWindow = activeWindows.getWindowBySequence(sequence);
removeInactiveWindow(inactiveWindow);
isActiveStatus = false;
};

onMounted(() => {
// visible 초기값이 true
if (props.visible) {
addActiveWindow();
addKeydownEvtHandler();
if (props.visible && !isActiveStatus) {
setWindowActive();
}
});

onBeforeUnmount(() => {
if (props.visible && isActiveStatus) {
setWindowInactive();
}
});

watch(
() => props.visible,
(newVal) => {
(visible) => {
nextTick(() => {
if (newVal) {
addActiveWindow();
addKeydownEvtHandler();
} else {
const inactiveWindow = activeWindows.getWindowBySequence(sequence);
removeInactiveWindow(inactiveWindow);
removeKeydownEvtHandler();
if (visible && !isActiveStatus) {
// visible 값이 false -> true로 변경되었을 때
setWindowActive();
} else if (!visible && isActiveStatus) {
// visible 값이 true -> false로 변경되었을 때
setWindowInactive();
}
});
});

watch(
() => props.escClose,
(escClose) => {
if (isActiveStatus) {
const currentWindow = activeWindows.getWindowBySequence(sequence);
if (currentWindow) currentWindow.escClose = escClose;
}
},
);
};
Expand Down

0 comments on commit 4f04443

Please sign in to comment.