feat: custom show/hide datatable col

This commit is contained in:
pa
2026-03-04 23:12:41 +09:00
parent 1decec4c69
commit 1be9d13cd4
11 changed files with 400 additions and 104 deletions

View File

@@ -198,4 +198,73 @@ describe('useVrcxVueTable persistence', () => {
);
expect(stored?.columnOrder).toBeUndefined();
});
it('persists columnVisibility to localStorage when visibility changes', async () => {
const { columnVisibility } = useVrcxVueTable({
data: [],
columns: makeColumns('name', 'date', 'status'),
persistKey: 'test-col-vis'
});
columnVisibility.value = { name: false, status: true };
await new Promise((r) => setTimeout(r, 300));
const stored = JSON.parse(
localStorage.getItem('vrcx:table:test-col-vis')
);
expect(stored).toBeTruthy();
expect(stored.columnVisibility).toEqual({ name: false, status: true });
});
it('restores persisted columnVisibility on init', () => {
localStorage.setItem(
'vrcx:table:test-restore-vis',
JSON.stringify({ columnVisibility: { date: false } })
);
const { columnVisibility } = useVrcxVueTable({
data: [],
columns: makeColumns('name', 'date', 'status'),
persistKey: 'test-restore-vis'
});
expect(columnVisibility.value).toEqual({ date: false });
});
it('filters stale columnVisibility entries on persist', async () => {
const { columnVisibility } = useVrcxVueTable({
data: [],
columns: makeColumns('name', 'date'),
persistKey: 'test-stale-vis'
});
columnVisibility.value = { removed_col: false, name: false };
await new Promise((r) => setTimeout(r, 300));
const stored = JSON.parse(
localStorage.getItem('vrcx:table:test-stale-vis')
);
expect(stored).toBeTruthy();
expect(stored.columnVisibility).toEqual({ name: false });
});
it('does not persist columnVisibility when persistColumnVisibility is false', async () => {
const { columnVisibility } = useVrcxVueTable({
data: [],
columns: makeColumns('name', 'date'),
persistKey: 'test-no-persist-vis',
persistColumnVisibility: false
});
columnVisibility.value = { name: false };
await new Promise((r) => setTimeout(r, 300));
const stored = JSON.parse(
localStorage.getItem('vrcx:table:test-no-persist-vis')
);
expect(stored?.columnVisibility).toBeUndefined();
});
});

View File

@@ -84,6 +84,25 @@ function filterOrderByColumns(order, columns) {
return order.filter((id) => ids.has(id));
}
/**
*
* @param visibility
* @param columns
*/
function filterVisibilityByColumns(visibility, columns) {
if (!visibility || typeof visibility !== 'object') {
return {};
}
const ids = new Set((columns ?? []).map((c) => c?.id).filter(Boolean));
const out = {};
for (const [key, value] of Object.entries(visibility)) {
if (ids.has(key)) {
out[key] = value;
}
}
return out;
}
/**
*
* @param col
@@ -200,6 +219,9 @@ export function useVrcxVueTable(options) {
enableColumnReorder = true,
initialColumnOrder,
enableColumnVisibility = true,
initialColumnVisibility,
fillRemainingSpace = true,
spacerColumnId = '__spacer',
@@ -207,6 +229,7 @@ export function useVrcxVueTable(options) {
persistColumnSizing = true,
persistSorting = true,
persistColumnOrder = true,
persistColumnVisibility = true,
persistDebounceMs = 200,
tableOptions = {}
@@ -222,6 +245,7 @@ export function useVrcxVueTable(options) {
const columnPinning = ref(initialColumnPinning ?? { left: [], right: [] });
const columnSizing = ref(initialColumnSizing ?? {});
const columnOrder = ref(initialColumnOrder ?? []);
const columnVisibility = ref(initialColumnVisibility ?? {});
const storageKey = persistKey ? `vrcx:table:${persistKey}` : null;
@@ -268,6 +292,10 @@ export function useVrcxVueTable(options) {
columnOrder.value = persisted.columnOrder;
}
if (persisted && persistColumnVisibility && persisted.columnVisibility) {
columnVisibility.value = persisted.columnVisibility;
}
const state = {};
const handlers = {};
const rowModels = {};
@@ -337,6 +365,13 @@ export function useVrcxVueTable(options) {
'onColumnOrderChange'
);
register(
enableColumnVisibility,
'columnVisibility',
columnVisibility,
'onColumnVisibilityChange'
);
if (enableFiltering) {
Object.assign(rowModels, {
getFilteredRowModel: getFilteredRowModel()
@@ -433,6 +468,19 @@ export function useVrcxVueTable(options) {
);
}
if (storageKey && persistColumnVisibility) {
watch(
columnVisibility,
(val) => {
const cols = table.getAllLeafColumns?.() ?? [];
persistWrite({
columnVisibility: filterVisibilityByColumns(val, cols)
});
},
{ deep: true }
);
}
return {
table,
sorting,
@@ -440,6 +488,7 @@ export function useVrcxVueTable(options) {
expanded,
columnPinning,
columnSizing,
columnOrder
columnOrder,
columnVisibility
};
}