feat(ui): implement frozen columns and refine menu positioning & scrolling
This commit is contained in:
parent
8bd7e9cbd9
commit
b76ae9fbf5
23
src/index.js
23
src/index.js
@ -63,6 +63,7 @@ Component.register('DataTable', container => {
|
|||||||
|
|
||||||
container.onScroll = () => {
|
container.onScroll = () => {
|
||||||
perf.onScroll(); scroll.refresh();
|
perf.onScroll(); scroll.refresh();
|
||||||
|
container.hideColumnMenu();
|
||||||
const prev = container.querySelector('.dt-spacer-prev'), post = container.querySelector('.dt-spacer-post');
|
const prev = container.querySelector('.dt-spacer-prev'), post = container.querySelector('.dt-spacer-post');
|
||||||
if (prev) { prev.style.height = (state.prevHeight || 0) + 'px'; prev.style.display = state.prevHeight > 0 ? 'block' : 'none'; }
|
if (prev) { prev.style.height = (state.prevHeight || 0) + 'px'; prev.style.display = state.prevHeight > 0 ? 'block' : 'none'; }
|
||||||
if (post) { post.style.height = (state.postHeight || 0) + 'px'; post.style.display = state.postHeight > 0 ? 'block' : 'none'; }
|
if (post) { post.style.height = (state.postHeight || 0) + 'px'; post.style.display = state.postHeight > 0 ? 'block' : 'none'; }
|
||||||
@ -120,7 +121,8 @@ Component.register('DataTable', container => {
|
|||||||
}
|
}
|
||||||
state.activeField = field; state.activeFieldId = field.id;
|
state.activeField = field; state.activeFieldId = field.id;
|
||||||
menu.style.display = 'block';
|
menu.style.display = 'block';
|
||||||
const rect = btn.getBoundingClientRect(), rootRect = container.getBoundingClientRect();
|
const cellNode = btn.closest('.dt-cell');
|
||||||
|
const rect = cellNode.getBoundingClientRect(), rootRect = container.getBoundingClientRect();
|
||||||
const menuWidth = menu.offsetWidth || 260;
|
const menuWidth = menu.offsetWidth || 260;
|
||||||
let leftPos = rect.right - rootRect.left - menuWidth;
|
let leftPos = rect.right - rootRect.left - menuWidth;
|
||||||
if (leftPos < 0) leftPos = Math.max(0, rect.left - rootRect.left);
|
if (leftPos < 0) leftPos = Math.max(0, rect.left - rootRect.left);
|
||||||
@ -185,6 +187,21 @@ Component.register('DataTable', container => {
|
|||||||
state._fieldsDirty = true;
|
state._fieldsDirty = true;
|
||||||
container.style.setProperty('--dt-grid-template', fields.map(f => `var(--w-${f.id}, ${f.width || 150}px)`).join(' '));
|
container.style.setProperty('--dt-grid-template', fields.map(f => `var(--w-${f.id}, ${f.width || 150}px)`).join(' '));
|
||||||
container.style.setProperty('--dt-row-width', fields.reduce((sum, f) => sum + (f.width || 150), 0) + 'px');
|
container.style.setProperty('--dt-row-width', fields.reduce((sum, f) => sum + (f.width || 150), 0) + 'px');
|
||||||
|
|
||||||
|
let leftSum = 0;
|
||||||
|
fields.forEach(f => {
|
||||||
|
if (f.pinned === 'left') {
|
||||||
|
container.style.setProperty(`--l-${f.id}`, leftSum + 'px');
|
||||||
|
leftSum += (f.width || 150);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
let rightSum = 0;
|
||||||
|
[...fields].reverse().forEach(f => {
|
||||||
|
if (f.pinned === 'right') {
|
||||||
|
container.style.setProperty(`--r-${f.id}`, rightSum + 'px');
|
||||||
|
rightSum += (f.width || 150);
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
state.__watch('list', list => {
|
state.__watch('list', list => {
|
||||||
@ -283,7 +300,7 @@ Component.register('DataTable', container => {
|
|||||||
<div class="dt-header border-bottom bg-light sticky-top" style="z-index:20">
|
<div class="dt-header border-bottom bg-light sticky-top" style="z-index:20">
|
||||||
<div class="dt-header-row fw-bold text-muted small">
|
<div class="dt-header-row fw-bold text-muted small">
|
||||||
<template $each="this.state?.fields || []">
|
<template $each="this.state?.fields || []">
|
||||||
<div $data-id="item.id" class="dt-cell dt-col border-end d-flex align-items-center header-cell" style="position:relative; padding: 0">
|
<div $data-id="item.id" $class="'dt-cell dt-col border-end d-flex align-items-center header-cell' + (item.pinned ? ' pinned-' + item.pinned : '')" $style="(item.pinned ? 'position: sticky; z-index: 11; background-color: inherit; ' : 'position:relative; ') + 'padding: 0; ' + (item.pinned === 'left' ? 'left: var(--l-' + item.id + '); border-right: 1px solid var(--bs-border-color); box-shadow: 2px 0 5px -2px rgba(0,0,0,0.1);' : (item.pinned === 'right' ? 'right: var(--r-' + item.id + '); border-left: 1px solid var(--bs-border-color); box-shadow: -2px 0 5px -2px rgba(0,0,0,0.1);' : ''))">
|
||||||
<div class="d-flex align-items-center overflow-hidden flex-grow-1 h-100 px-2 cursor-pointer" $onclick="this.showColumnMenu(item, event)">
|
<div class="d-flex align-items-center overflow-hidden flex-grow-1 h-100 px-2 cursor-pointer" $onclick="this.showColumnMenu(item, event)">
|
||||||
<i $if="this.state?.filterConfig?.[item.id] && (this.state.filterConfig[item.id].value || this.state.filterConfig[item.id].selectedValues?.length)" class="bi bi-filter me-1 text-primary"></i>
|
<i $if="this.state?.filterConfig?.[item.id] && (this.state.filterConfig[item.id].value || this.state.filterConfig[item.id].selectedValues?.length)" class="bi bi-filter me-1 text-primary"></i>
|
||||||
<i $if="this.state?.sortConfig?.fieldId === item.id && this.state.sortConfig.direction" $class="'bi bi-sort-' + (this.state.sortConfig.direction === 'asc' ? 'down' : 'up-alt') + ' me-1 text-primary'"></i>
|
<i $if="this.state?.sortConfig?.fieldId === item.id && this.state.sortConfig.direction" $class="'bi bi-sort-' + (this.state.sortConfig.direction === 'asc' ? 'down' : 'up-alt') + ' me-1 text-primary'"></i>
|
||||||
@ -299,7 +316,7 @@ Component.register('DataTable', container => {
|
|||||||
<div class="dt-spacer-prev flex-shrink-0" style="display:none"></div>
|
<div class="dt-spacer-prev flex-shrink-0" style="display:none"></div>
|
||||||
<template $each="this.state?._renderedList || []" key="id" index="rIdx">
|
<template $each="this.state?._renderedList || []" key="id" index="rIdx">
|
||||||
<div class="dt-row dt-body-row border-bottom bg-white" $.="this._initRow(thisNode)">
|
<div class="dt-row dt-body-row border-bottom bg-white" $.="this._initRow(thisNode)">
|
||||||
<template as="f"><div class="dt-cell border-end px-2 d-flex align-items-center"><span $text="this.format(item[f.id], f)" class="text-truncate"></span></div></template>
|
<template as="f"><div $class="'dt-cell border-end px-2 d-flex align-items-center' + (f.pinned ? ' pinned-' + f.pinned : '')" $style="(f.pinned ? 'position: sticky; z-index: 1; background-color: inherit; ' : '') + (f.pinned === 'left' ? 'left: var(--l-' + f.id + '); border-right: 1px solid var(--bs-border-color); box-shadow: 2px 0 5px -2px rgba(0,0,0,0.1);' : (f.pinned === 'right' ? 'right: var(--r-' + f.id + '); border-left: 1px solid var(--bs-border-color); box-shadow: -2px 0 5px -2px rgba(0,0,0,0.1);' : ''))"><span $text="this.format(item[f.id], f)" class="text-truncate"></span></div></template>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<div class="dt-spacer-post flex-shrink-0" style="display:none"></div>
|
<div class="dt-spacer-post flex-shrink-0" style="display:none"></div>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user