feat: 모든 자산 목록 뷰에 마우스 드래그를 이용한 테이블 컬럼 너비 조절(Resizable Columns) 기능 추가
This commit is contained in:
@@ -670,7 +670,7 @@ export function createListView(container: HTMLElement, config: ListViewConfig) {
|
|||||||
thead.innerHTML = `<tr>${config.columns.map(col => {
|
thead.innerHTML = `<tr>${config.columns.map(col => {
|
||||||
const isDateCol = col.header.includes('일') || col.header.includes('날짜') || col.header.includes('연월');
|
const isDateCol = col.header.includes('일') || col.header.includes('날짜') || col.header.includes('연월');
|
||||||
const alignmentClass = col.align ? `text-${col.align}` : (isDateCol ? 'text-center' : '');
|
const alignmentClass = col.align ? `text-${col.align}` : (isDateCol ? 'text-center' : '');
|
||||||
return `<th class="${alignmentClass}" ${col.sortKey ? `data-sort="${col.sortKey}"` : ''} style="${col.width ? `width:${col.width};` : ''}">${col.header}</th>`;
|
return `<th class="${alignmentClass}" ${col.sortKey ? `data-sort="${col.sortKey}"` : ''} style="${col.width ? `width:${col.width};` : ''}">${col.header}<div class="resizer"></div></th>`;
|
||||||
}).join('')}</tr>`;
|
}).join('')}</tr>`;
|
||||||
|
|
||||||
tbody.innerHTML = filtered.length === 0 ? `<tr><td colspan="${config.columns.length}" class="text-center empty-cell">${UI_TEXT.MESSAGES.NO_DATA}</td></tr>`
|
tbody.innerHTML = filtered.length === 0 ? `<tr><td colspan="${config.columns.length}" class="text-center empty-cell">${UI_TEXT.MESSAGES.NO_DATA}</td></tr>`
|
||||||
@@ -698,8 +698,45 @@ export function createListView(container: HTMLElement, config: ListViewConfig) {
|
|||||||
|
|
||||||
tbody.querySelectorAll('.asset-row').forEach((tr, idx) => { tr.addEventListener('click', () => config.onRowClick && config.onRowClick(filtered[idx])); });
|
tbody.querySelectorAll('.asset-row').forEach((tr, idx) => { tr.addEventListener('click', () => config.onRowClick && config.onRowClick(filtered[idx])); });
|
||||||
setupTableSorting(table, sortState, (key, dir) => { sortState = { key, direction: dir }; updateTable(); });
|
setupTableSorting(table, sortState, (key, dir) => { sortState = { key, direction: dir }; updateTable(); });
|
||||||
|
makeColumnsResizable(table);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function makeColumnsResizable(tableElement: HTMLTableElement) {
|
||||||
|
const headers = tableElement.querySelectorAll('th');
|
||||||
|
headers.forEach(th => {
|
||||||
|
const resizer = th.querySelector('.resizer') as HTMLElement;
|
||||||
|
if (!resizer) return;
|
||||||
|
|
||||||
|
let startX = 0;
|
||||||
|
let startWidth = 0;
|
||||||
|
|
||||||
|
const onMouseMove = (e: MouseEvent) => {
|
||||||
|
const dx = e.clientX - startX;
|
||||||
|
const newWidth = Math.max(50, startWidth + dx);
|
||||||
|
th.style.width = `${newWidth}px`;
|
||||||
|
};
|
||||||
|
|
||||||
|
const onMouseUp = () => {
|
||||||
|
resizer.classList.remove('resizing');
|
||||||
|
document.removeEventListener('mousemove', onMouseMove);
|
||||||
|
document.removeEventListener('mouseup', onMouseUp);
|
||||||
|
};
|
||||||
|
|
||||||
|
resizer.addEventListener('mousedown', (e: MouseEvent) => {
|
||||||
|
// Prevents header click sorting trigger from firing
|
||||||
|
e.stopPropagation();
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
startX = e.clientX;
|
||||||
|
startWidth = th.offsetWidth;
|
||||||
|
|
||||||
|
resizer.classList.add('resizing');
|
||||||
|
document.addEventListener('mousemove', onMouseMove);
|
||||||
|
document.addEventListener('mouseup', onMouseUp);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const switchView = () => {
|
const switchView = () => {
|
||||||
contentWrapper.innerHTML = '';
|
contentWrapper.innerHTML = '';
|
||||||
const isAssetMode = !isServer || state.viewMode === 'list';
|
const isAssetMode = !isServer || state.viewMode === 'list';
|
||||||
|
|||||||
@@ -68,6 +68,25 @@ th {
|
|||||||
letter-spacing: -0.02em;
|
letter-spacing: -0.02em;
|
||||||
box-shadow: inset 0 -1px 0 var(--hairline);
|
box-shadow: inset 0 -1px 0 var(--hairline);
|
||||||
text-align: center; /* Set default header alignment to center */
|
text-align: center; /* Set default header alignment to center */
|
||||||
|
position: relative; /* Essential for absolute positioning of resizer handles */
|
||||||
|
}
|
||||||
|
|
||||||
|
.resizer {
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
width: 6px;
|
||||||
|
height: 100%;
|
||||||
|
cursor: col-resize;
|
||||||
|
user-select: none;
|
||||||
|
z-index: 60; /* Higher than thead's sticky z-index (50) to catch mouse events */
|
||||||
|
}
|
||||||
|
|
||||||
|
.resizer:hover,
|
||||||
|
.resizer.resizing {
|
||||||
|
background-color: var(--primary, #1e5149);
|
||||||
|
opacity: 0.8;
|
||||||
|
width: 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
td {
|
td {
|
||||||
|
|||||||
Reference in New Issue
Block a user