@ackplus/react-tanstack-data-table
Version:
A powerful React data table component built with MUI and TanStack Table
106 lines (105 loc) • 9.16 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ColumnPinningControl = ColumnPinningControl;
const jsx_runtime_1 = require("react/jsx-runtime");
const icons_material_1 = require("@mui/icons-material");
const material_1 = require("@mui/material");
const react_1 = require("react");
const menu_dropdown_1 = require("../droupdown/menu-dropdown");
const data_table_context_1 = require("../../contexts/data-table-context");
const icons_1 = require("../../icons");
const slot_helpers_1 = require("../../utils/slot-helpers");
function ColumnPinningControl() {
var _a, _b;
const { table, slots, slotProps } = (0, data_table_context_1.useDataTableContext)();
const PinIconSlot = (0, slot_helpers_1.getSlotComponent)(slots, 'pinIcon', icons_material_1.PushPinOutlined);
const UnpinIconSlot = (0, slot_helpers_1.getSlotComponent)(slots, 'unpinIcon', icons_1.UnpinIcon);
const LeftIconSlot = (0, slot_helpers_1.getSlotComponent)(slots, 'leftIcon', icons_material_1.ArrowLeftOutlined);
const RightIconSlot = (0, slot_helpers_1.getSlotComponent)(slots, 'rightIcon', icons_material_1.ArrowRightOutlined);
const columnPinning = table.getState().columnPinning;
const allColumns = (0, react_1.useMemo)(() => {
var _a, _b;
if ((_a = slotProps === null || slotProps === void 0 ? void 0 : slotProps.columnsPanel) === null || _a === void 0 ? void 0 : _a.getPinnableColumns) {
return (_b = slotProps === null || slotProps === void 0 ? void 0 : slotProps.columnsPanel) === null || _b === void 0 ? void 0 : _b.getPinnableColumns(table.getAllLeafColumns());
}
return table.getAllLeafColumns().filter(column => column.getCanPin());
}, [slotProps === null || slotProps === void 0 ? void 0 : slotProps.columnsPanel, table]);
const handlePinColumn = (columnId, position) => {
const currentPinning = table.getState().columnPinning;
const newPinning = Object.assign({}, currentPinning);
newPinning.left = (newPinning.left || []).filter(id => id !== columnId);
newPinning.right = (newPinning.right || []).filter(id => id !== columnId);
if (position === 'left') {
newPinning.left = [...(newPinning.left || []), columnId];
}
else if (position === 'right') {
newPinning.right = [...(newPinning.right || []), columnId];
}
table.setColumnPinning(newPinning);
};
const getColumnPinStatus = (columnId) => {
var _a, _b;
if ((_a = columnPinning.left) === null || _a === void 0 ? void 0 : _a.includes(columnId))
return 'left';
if ((_b = columnPinning.right) === null || _b === void 0 ? void 0 : _b.includes(columnId))
return 'right';
return 'none';
};
const getColumnDisplayName = (column) => {
if (typeof column.columnDef.header === 'string') {
return column.columnDef.header;
}
return column.id;
};
const handleUnpinAll = (0, react_1.useCallback)(() => {
table.setColumnPinning(table.initialState.columnPinning || {});
}, [table]);
const userPinnedLeft = (((_a = columnPinning.left) === null || _a === void 0 ? void 0 : _a.filter((id) => allColumns.some((column) => column.id === id))) || []);
const userPinnedRight = (((_b = columnPinning.right) === null || _b === void 0 ? void 0 : _b.filter((id) => allColumns.some((column) => column.id === id))) || []);
const totalPinned = userPinnedLeft.length + userPinnedRight.length;
return ((0, jsx_runtime_1.jsx)(menu_dropdown_1.MenuDropdown, { anchor: ((0, jsx_runtime_1.jsx)(material_1.Tooltip, { title: "Pin columns", children: (0, jsx_runtime_1.jsxs)(material_1.IconButton, { size: "small", sx: {
flexShrink: 0,
}, children: [(0, jsx_runtime_1.jsx)(PinIconSlot, Object.assign({}, slotProps === null || slotProps === void 0 ? void 0 : slotProps.pinIcon)), totalPinned > 0 && ((0, jsx_runtime_1.jsx)(material_1.Box, { sx: {
position: 'absolute',
top: -2,
right: -2,
backgroundColor: 'primary.main',
color: 'white',
borderRadius: '50%',
width: 16,
height: 16,
fontSize: 10,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
}, children: totalPinned }))] }) })), children: ({ handleClose }) => ((0, jsx_runtime_1.jsxs)(material_1.Box, { sx: {
minWidth: 300,
maxHeight: 400,
overflow: 'auto',
}, children: [(0, jsx_runtime_1.jsxs)(material_1.Box, { sx: {
p: 2,
pb: 1,
}, children: [(0, jsx_runtime_1.jsx)(material_1.Typography, { variant: "subtitle2", sx: { mb: 1 }, children: "Pin Columns" }), (0, jsx_runtime_1.jsx)(material_1.Typography, { variant: "caption", color: "text.secondary", children: "Pin columns to keep them visible while scrolling" })] }), (0, jsx_runtime_1.jsx)(material_1.Divider, {}), (0, jsx_runtime_1.jsx)(material_1.List, { dense: true, sx: { py: 0 }, children: allColumns.map((column) => {
const pinStatus = getColumnPinStatus(column.id);
const displayName = getColumnDisplayName(column);
return ((0, jsx_runtime_1.jsx)(material_1.ListItem, { sx: { py: 0.5 }, secondaryAction: ((0, jsx_runtime_1.jsxs)(material_1.Box, { sx: {
display: 'flex',
gap: 0.5,
}, children: [(0, jsx_runtime_1.jsx)(material_1.Tooltip, { title: "Pin left", children: (0, jsx_runtime_1.jsx)(material_1.IconButton, { size: "small", onClick: () => handlePinColumn(column.id, pinStatus === 'left' ? 'none' : 'left'), color: pinStatus === 'left' ? 'primary' : 'default', children: (0, jsx_runtime_1.jsx)(LeftIconSlot, Object.assign({ fontSize: "small" }, slotProps === null || slotProps === void 0 ? void 0 : slotProps.leftIcon)) }) }), (0, jsx_runtime_1.jsx)(material_1.Tooltip, { title: "Pin right", children: (0, jsx_runtime_1.jsx)(material_1.IconButton, { size: "small", onClick: () => handlePinColumn(column.id, pinStatus === 'right' ? 'none' : 'right'), color: pinStatus === 'right' ? 'secondary' : 'default', children: (0, jsx_runtime_1.jsx)(RightIconSlot, Object.assign({ fontSize: "small" }, slotProps === null || slotProps === void 0 ? void 0 : slotProps.rightIcon)) }) }), pinStatus !== 'none' && ((0, jsx_runtime_1.jsx)(material_1.Tooltip, { title: "Unpin", children: (0, jsx_runtime_1.jsx)(material_1.IconButton, { size: "small", onClick: () => handlePinColumn(column.id, 'none'), children: (0, jsx_runtime_1.jsx)(UnpinIconSlot, Object.assign({ fontSize: "small" }, slotProps === null || slotProps === void 0 ? void 0 : slotProps.unpinIcon)) }) }))] })), children: (0, jsx_runtime_1.jsx)(material_1.ListItemText, { primary: displayName, secondary: pinStatus !== 'none' ? ((0, jsx_runtime_1.jsxs)(material_1.Box, { sx: {
display: 'flex',
alignItems: 'center',
gap: 0.5,
mt: 0.5,
}, children: [pinStatus === 'left' ? ((0, jsx_runtime_1.jsx)(LeftIconSlot, Object.assign({ fontSize: "small" }, slotProps === null || slotProps === void 0 ? void 0 : slotProps.leftIcon))) : ((0, jsx_runtime_1.jsx)(RightIconSlot, Object.assign({ fontSize: "small" }, slotProps === null || slotProps === void 0 ? void 0 : slotProps.rightIcon))), (0, jsx_runtime_1.jsxs)(material_1.Typography, { variant: "caption", color: pinStatus === 'left' ? 'primary' : 'secondary', children: ["Pinned", ' ', pinStatus] })] })) : null }) }, column.id));
}) }), (0, jsx_runtime_1.jsx)(material_1.Divider, {}), (0, jsx_runtime_1.jsx)(material_1.Box, { sx: {
p: 2,
pt: 1,
}, children: (0, jsx_runtime_1.jsxs)(material_1.Box, { sx: {
display: 'flex',
gap: 1,
justifyContent: 'space-between',
}, children: [(0, jsx_runtime_1.jsx)(material_1.Typography, { variant: "caption", color: "text.secondary", children: "Quick actions:" }), (0, jsx_runtime_1.jsx)(material_1.Box, { sx: {
display: 'flex',
gap: 1,
}, children: (0, jsx_runtime_1.jsx)(material_1.Tooltip, { title: "Unpin all user columns", children: (0, jsx_runtime_1.jsx)(material_1.IconButton, { size: "small", onClick: handleUnpinAll, disabled: totalPinned === 0, children: (0, jsx_runtime_1.jsx)(icons_1.UnpinIcon, { fontSize: "small" }) }) }) })] }) })] })) }));
}