드롭다운 UI 개선: 다중 드롭다운 제어 로직 추가, 전역 인스턴스 관리 및 키보드 네비게이션 상태 처리 기능 구현

dev
박성영 4 months ago
parent 262caf8829
commit c81ca72dac

@ -751,6 +751,14 @@ function closeChildPopupsAndSelf(childPopups) {
return childPopups;
}
/**
* 전역 드롭다운 인스턴스 관리
* 중요한 로직 주석: 활성화된 드롭다운들을 추적하여 다중 오픈 제어
*/
if (typeof window.XitDropdownInstances === 'undefined') {
window.XitDropdownInstances = [];
}
/**
* XIT 공통 드롭다운 컴포넌트
* 중요한 로직 주석: 재사용 가능한 드롭다운 컴포넌트로 여러 페이지에서 사용할 있다.
@ -770,7 +778,8 @@ function XitDropdown(options) {
placeholder: '검색어를 입력하세요', // placeholder 텍스트
noResultsText: '검색 결과가 없습니다', // 검색 결과 없음 텍스트
cssClass: 'xit-dropdown', // CSS 클래스명
disabled: false // 비활성화 여부
disabled: false, // 비활성화 여부
allowMultiple: false // 다중 드롭다운 허용 여부 (기본값: false)
}, options);
// 필수 옵션 검증
@ -784,8 +793,12 @@ function XitDropdown(options) {
this.filteredData = [];
this.selectedIndex = -1;
this.isOpen = false;
this.keyboardNavActive = false; // 키보드 네비게이션 상태 추적
this.dropdownId = 'xit-dropdown-' + Date.now() + Math.random().toString(36).substr(2, 9);
// 전역 드롭다운 인스턴스 배열에 현재 인스턴스 등록
window.XitDropdownInstances.push(this);
this.init();
}
@ -959,6 +972,15 @@ XitDropdown.prototype = {
var html = '';
var self = this;
// 다중 드롭다운 허용하지 않는 경우 다른 드롭다운들 모두 닫기
if (!this.options.allowMultiple) {
window.XitDropdownInstances.forEach(function(instance) {
if (instance !== self && instance.isOpen) {
instance.hideDropdown();
}
});
}
if (this.filteredData.length === 0) {
html = '<div class="' + this.options.cssClass + '-item no-results" style="padding: 10px 12px; color: #666; font-style: italic; text-align: center; cursor: default;">' + this.options.noResultsText + '</div>';
} else {
@ -991,17 +1013,30 @@ XitDropdown.prototype = {
self.selectItem(index);
});
// hover 효과 추가 - 키보드 방향키 하이라이트 색상과 동일하게 설정
// hover 효과 추가 - 키보드 네비게이션과 상호 배타적으로 동작
this.$dropdown.find('.' + this.options.cssClass + '-item:not(.no-results)').hover(
function() {
$(this).css('background-color', '#e3f2fd');
// 키보드 네비게이션이 활성화된 상태가 아닐 때만 hover 효과 적용
if (!self.keyboardNavActive) {
$(this).css('background-color', '#e3f2fd');
}
},
function() {
if (!$(this).hasClass('selected')) {
// 키보드 네비게이션이 활성화된 상태가 아니고 선택되지 않은 항목일 때만 스타일 초기화
if (!self.keyboardNavActive && !$(this).hasClass('selected')) {
$(this).css('background-color', '');
}
}
);
// 마우스가 드롭다운 영역에 들어올 때 키보드 네비게이션 상태 초기화
this.$dropdown.on('mouseenter', function() {
if (self.keyboardNavActive) {
self.keyboardNavActive = false;
self.selectedIndex = -1;
self.$dropdown.find('.' + self.options.cssClass + '-item').removeClass('selected').css('background-color', '');
}
});
},
/**
@ -1011,6 +1046,7 @@ XitDropdown.prototype = {
this.$dropdown.hide();
this.isOpen = false;
this.selectedIndex = -1;
this.keyboardNavActive = false; // 키보드 네비게이션 상태 초기화
},
/**
@ -1021,6 +1057,9 @@ XitDropdown.prototype = {
var $items = this.$dropdown.find('.' + this.options.cssClass + '-item:not(.no-results)');
if ($items.length === 0) return;
// 키보드 네비게이션 활성화 상태로 설정
this.keyboardNavActive = true;
// 이전 선택 항목 하이라이트 제거
$items.removeClass('selected').css('background-color', '');
@ -1088,6 +1127,12 @@ XitDropdown.prototype = {
* 드롭다운 파괴
*/
destroy: function() {
// 전역 인스턴스 배열에서 현재 인스턴스 제거
var index = window.XitDropdownInstances.indexOf(this);
if (index > -1) {
window.XitDropdownInstances.splice(index, 1);
}
// 이벤트 제거
this.$input.off('.xitdropdown');
$(document).off('.xitdropdown-' + this.dropdownId);

Loading…
Cancel
Save