UNPKG

@ackplus/react-tanstack-data-table

Version:

A powerful React data table component built with MUI and TanStack Table

246 lines (245 loc) 9.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SelectionFeature = void 0; /** * Custom Selection Feature for TanStack Table * * This feature adds custom selection capabilities to TanStack Table * following the official custom features pattern (same as CustomColumnFilterFeature) */ const react_table_1 = require("@tanstack/react-table"); // The custom selection feature implementation (same pattern as CustomColumnFilterFeature) exports.SelectionFeature = { // Define the feature's initial state getInitialState: (state) => { return { selectionState: { ids: [], type: 'include', selectMode: 'page', }, ...state, }; }, // Define the feature's default options getDefaultOptions: (table) => { return { enableAdvanceSelection: true, selectMode: 'page', onSelectionStateChange: (0, react_table_1.makeStateUpdater)('selectionState', table), }; }, // Define the feature's table instance methods createTable: (table) => { table.setSelectionState = (updater) => { var _a, _b; if (!table.options.enableAdvanceSelection) return; const safeUpdater = (old) => { const newState = (0, react_table_1.functionalUpdate)(updater, old); return newState; }; return (_b = (_a = table.options).onSelectionStateChange) === null || _b === void 0 ? void 0 : _b.call(_a, safeUpdater); }; // === BASIC SELECTION METHODS === table.selectRow = (rowId) => { if (!table.options.enableAdvanceSelection) return; if (!table.canSelectRow(rowId)) return; table.setSelectionState((old) => { if (old.type === 'exclude') { // In exclude mode, selecting means removing from exclude list return { ...old, ids: old.ids.filter(id => id !== rowId), }; } else { // In include mode, selecting means adding to include list const newIds = old.ids.includes(rowId) ? old.ids : [...old.ids, rowId]; return { ...old, ids: newIds, }; } }); }; table.deselectRow = (rowId) => { if (!table.options.enableAdvanceSelection) return; table.setSelectionState((old) => { if (old.type === 'exclude') { // In exclude mode, deselecting means adding to exclude list const newIds = old.ids.includes(rowId) ? old.ids : [...old.ids, rowId]; return { ...old, ids: newIds, }; } else { // In include mode, deselecting means removing from include list return { ...old, ids: old.ids.filter(id => id !== rowId), }; } }); }; table.toggleRowSelected = (rowId) => { if (!table.options.enableAdvanceSelection) return; if (table.getIsRowSelected(rowId)) { table.deselectRow(rowId); } else { table.selectRow(rowId); } }; table.selectAll = () => { var _a, _b; if (!table.options.enableAdvanceSelection) return; const selectMode = table.options.selectMode || 'page'; const currentRows = ((_b = (_a = table.getPaginationRowModel) === null || _a === void 0 ? void 0 : _a.call(table)) === null || _b === void 0 ? void 0 : _b.rows) || table.getRowModel().rows; if (selectMode === 'all') { // In 'all' mode, use exclude type with empty list (select all) table.setSelectionState((old) => ({ ...old, ids: [], type: 'exclude', })); } else { // In 'page' mode, select current page rows const selectableRowIds = currentRows .filter(row => table.canSelectRow(row.id)) .map(row => row.id); table.setSelectionState((old) => ({ ...old, ids: selectableRowIds, type: 'include', })); } }; table.deselectAll = () => { if (!table.options.enableAdvanceSelection) return; table.setSelectionState((old) => ({ ...old, ids: [], type: 'include', })); }; table.toggleAllRowsSelected = () => { if (!table.options.enableAdvanceSelection) return; if (table.getIsAllRowsSelected()) { table.deselectAll(); } else { table.selectAll(); } }; // === STATE CHECKERS === table.getIsRowSelected = (rowId) => { const state = table.getSelectionState(); if (state.type === 'exclude') { // In exclude mode, selected if NOT in exclude list return !state.ids.includes(rowId); } else { // In include mode, selected if in include list return state.ids.includes(rowId); } }; table.getIsAllRowsSelected = () => { var _a, _b; const state = table.getSelectionState(); const selectMode = table.options.selectMode || 'page'; if (selectMode === 'all') { const totalCount = table.getRowCount(); if (totalCount === 0) return false; if (state.type === 'exclude') { return state.ids.length === 0; } else { return state.ids.length === totalCount; } } else { // Page mode - check if all selectable rows on current page are selected const currentPageRows = ((_b = (_a = table.getPaginationRowModel) === null || _a === void 0 ? void 0 : _a.call(table)) === null || _b === void 0 ? void 0 : _b.rows) || table.getRowModel().rows; const selectableRows = currentPageRows.filter(row => table.canSelectRow(row.id)); if (selectableRows.length === 0) return false; return selectableRows.every(row => table.getIsRowSelected(row.id)); } }; table.getIsSomeRowsSelected = () => { const state = table.getSelectionState(); const selectMode = table.options.selectMode || 'page'; if (selectMode === 'all' && state.type === 'exclude') { // In exclude mode, we have some selected if not all are excluded const totalCount = table.getRowCount(); return totalCount > 0 && state.ids.length < totalCount; } else { // In include mode, we have some selected if list has items return state.ids.length > 0; } }; // === GETTERS === table.getSelectionState = () => { return table.getState().selectionState || { ids: [], type: 'include', selectMode: 'page', }; }; table.getSelectedCount = () => { const state = table.getSelectionState(); const selectMode = table.options.selectMode || 'page'; if (selectMode === 'all' && state.type === 'exclude') { // For server-side data, use rowCount which includes total from server // For client-side data, this will be the same as getRowModel().rows.length const totalCount = table.getRowCount(); return Math.max(0, totalCount - state.ids.length); } else { return state.ids.length; } }; table.getSelectedRowIds = () => { const state = table.getSelectionState(); if (state.type === 'exclude') { console.warn('[SelectionFeature] getSelectedRowIds() is not accurate in exclude mode. Use getSelectionState() to interpret selection properly.'); return []; // Return empty to avoid misleading API } return state.ids; }; table.getSelectedRows = () => { const state = table.getSelectionState(); const allRows = table.getRowModel().rows; if (state.type === 'exclude') { // Return all rows except excluded ones return allRows.filter(row => !state.ids.includes(row.id)); } else { // Return only included rows return allRows.filter(row => state.ids.includes(row.id)); } }; // === HELPER METHODS === table.canSelectRow = (rowId) => { if (!table.options.isRowSelectable) return true; const row = table.getRowModel().rows.find(r => r.id === rowId); if (!row) return false; return table.options.isRowSelectable({ row: row.original, id: rowId }); }; }, };