UNPKG

@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
"use strict"; 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" }) }) }) })] }) })] })) })); }