UNPKG

use-table-tools

Version:

react hook for building powerful table components

493 lines (484 loc) 20.1 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } var React = require('react'); var React__default = _interopDefault(React); var isClient = typeof window === 'object'; var useWindowSize = function (shouldDoCalculations) { if (shouldDoCalculations === void 0) { shouldDoCalculations = 'yes'; } var _a = React.useState({ width: isClient ? window.innerWidth : Infinity, height: isClient ? window.innerHeight : Infinity, }), state = _a[0], setState = _a[1]; React.useEffect(function () { if (isClient && shouldDoCalculations === 'yes') { var handler_1 = function () { setState({ width: window.innerWidth, height: window.innerHeight, }); }; window.addEventListener('resize', handler_1); return function () { return window.removeEventListener('resize', handler_1); }; } }, [shouldDoCalculations]); return state; }; var getObjectValueByString = function (obj, path) { return path.split('.').reduce(function (acc, part) { return acc && acc[part]; }, obj); }; var getOffsetColumns = function (visibleColumns, columns, includeVisible) { if (includeVisible === void 0) { includeVisible = false; } if (visibleColumns.length) { var visible_1 = visibleColumns.map(function (_a) { var sortKey = _a.sortKey; return sortKey; }); return columns .filter(function (_a) { var isLocked = _a.isLocked; return !isLocked; }) .map(function (column) { if (visible_1.includes(column.sortKey)) { return Object.assign(column, { visible: true }); } else { return Object.assign(column, { visible: false }); } }) .filter(function (_a) { var visible = _a.visible; return (includeVisible ? true : !visible); }); } else { return []; } }; var callAllEventHandlers = function () { var fns = []; for (var _i = 0; _i < arguments.length; _i++) { fns[_i] = arguments[_i]; } return function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } return fns.some(function (fn) { if (fn) { fn.apply(void 0, args); } }); }; }; var __assign = (undefined && undefined.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; var __rest = (undefined && undefined.__rest) || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; }; var __spreadArrays = (undefined && undefined.__spreadArrays) || function () { for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; for (var r = Array(s), k = 0, i = 0; i < il; i++) for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) r[k] = a[j]; return r; }; var actionTypes = { updateState: 'updateState', switchColumns: 'switchColumns', switchCurrentLayout: 'switchCurrentLayout', deselectAll: 'deselectAll', selectAll: 'selectAll', checkboxToggle: 'checkboxToggle', checkboxShiftToggle: 'checkboxShiftToggle', changeSortDirection: 'changeSortDirection', toggleSortDirection: 'toggleSortDirection', toggleSortByKey: 'toggleSortByKey', sortData: 'sortData', }; var tableToolsReducer = function (state, action) { switch (action.type) { case actionTypes.updateState: { return __assign(__assign({}, state), action.payload); } case actionTypes.switchColumns: { var _a = action.payload, to_1 = _a.to, from_1 = _a.from; var columns = state.visibleColumns; var index = columns.findIndex(function (x) { return x.sortKey === from_1; }); var visibleColumns = columns.filter(function (col) { return col.sortKey !== from_1; }); var replacement = getOffsetColumns(state.visibleColumns, state.columns).find(function (_a) { var sortKey = _a.sortKey; return sortKey === to_1; }); if (replacement) { visibleColumns.splice(index, 0, replacement); } return __assign(__assign({}, state), { visibleColumns: visibleColumns }); } case actionTypes.switchCurrentLayout: { var currentLayout = action.payload.currentLayout; var visibleSortFields_1 = state.visibleColumns .map(function (_a) { var sortField = _a.sortField; return sortField; }) .reverse(); return __assign(__assign({}, state), { currentLayout: currentLayout, visibleColumns: state.columns .sort(function (a, b) { return (visibleSortFields_1.indexOf(b.sortKey) - visibleSortFields_1.indexOf(a.sortKey)); }) .slice(0, currentLayout.length) }); } case actionTypes.deselectAll: { return __assign(__assign({}, state), { selectAllCheckboxState: 'none', checkedItems: [] }); } case actionTypes.selectAll: { var items = action.payload.items; return __assign(__assign({}, state), { checkedItems: items, selectAllCheckboxState: state.totalItems === items.length ? 'all' : 'some' }); } case actionTypes.checkboxToggle: { var _b = action.payload, id = _b.id, rowId_1 = _b.value; var checkedItems = state.checkedItems; if (!checkedItems.includes(rowId_1)) { var allCheckedItems = __spreadArrays(state.checkedItems, [rowId_1]); return __assign(__assign({}, state), { lastChecked: { id: id, value: rowId_1 }, checkedItems: allCheckedItems, selectAllCheckboxState: state.totalItems === allCheckedItems.length ? 'all' : 'some' }); } else { var allCheckedItems = checkedItems.filter(function (id) { return id !== rowId_1; }); return __assign(__assign({}, state), { lastChecked: { id: id, value: rowId_1 }, checkedItems: allCheckedItems, selectAllCheckboxState: allCheckedItems.length ? 'some' : 'none' }); } } case actionTypes.checkboxShiftToggle: { var checkedItems = state.checkedItems, lastChecked = state.lastChecked; var _c = action.payload, id = _c.id, value = _c.value, refs = _c.refs; if (lastChecked) { var rows = Array.from(refs); var lastCheckedId = parseInt(lastChecked.id); var currentCheckedId = parseInt(id); var slicedInputs = void 0; var checked = []; if (lastCheckedId < currentCheckedId) { slicedInputs = rows.slice(lastCheckedId, currentCheckedId + 1); } else { slicedInputs = rows.slice(currentCheckedId, lastCheckedId + 1); } var rangeIds_1 = slicedInputs.map(function (ref) { return ref.value; }); if (checkedItems.includes(lastChecked.value) && !checkedItems.includes(value)) { checked = checkedItems.concat(rangeIds_1); } else if (!checkedItems.includes(lastChecked.value) && !checkedItems.includes(value)) { checked = checkedItems.concat(rangeIds_1); } else { checked = checkedItems.filter(function (id) { return rangeIds_1.includes(id) ? false : true; }); } return __assign(__assign({}, state), { lastChecked: { id: id, value: value }, checkedItems: checked, selectAllCheckboxState: checked.length ? state.totalItems === checked.length ? 'all' : 'some' : 'none' }); } else { return __assign(__assign({}, state), { lastChecked: { id: id, value: value } }); } } case actionTypes.changeSortDirection: { return __assign(__assign({}, state), { currentSort: { fieldKey: state.currentSort.fieldKey, direction: action.payload.direction, } }); } case actionTypes.toggleSortDirection: { var currentSort = state.currentSort; return __assign(__assign({}, state), { currentSort: { direction: currentSort.direction === 'asc' ? 'dsc' : 'asc', fieldKey: currentSort.fieldKey, } }); } case actionTypes.toggleSortByKey: { var currentSort = state.currentSort; var fieldKey = action.payload.fieldKey; return __assign(__assign({}, state), { currentSort: { fieldKey: fieldKey, direction: currentSort.direction === 'asc' ? 'desc' : 'asc', } }); } case actionTypes.sortData: { var _d = action.payload, fieldKey = _d.fieldKey, direction = _d.direction; return __assign(__assign({}, state), { currentSort: { fieldKey: fieldKey, direction: direction } }); } default: { throw new Error("Unhandled type: " + action.type); } } }; var useTableTools = function (_a, reducer) { var _b = _a.layout, layout = _b === void 0 ? ['0 0 25%', '1 1 35%', '0 0 20%', '0 0 20%'] : _b, _c = _a.totalItems, totalItems = _c === void 0 ? 0 : _c, _d = _a.clientSortBy, clientSortBy = _d === void 0 ? { direction: 'asc', fieldKey: '' } : _d, _e = _a.columns, columns = _e === void 0 ? [] : _e, _f = _a.checkedItems, checkedItems = _f === void 0 ? [] : _f; if (reducer === void 0) { reducer = tableToolsReducer; } var checkboxRefs = new Set(); var width = useWindowSize(Array.isArray(layout) ? 'no' : 'yes').width; var _g = React.useReducer(reducer, { currentLayout: [], visibleColumns: [], columns: columns, totalItems: totalItems, currentSort: clientSortBy, checkedItems: checkedItems, selectAllCheckboxState: 'none', lastChecked: null, }), state = _g[0], send = _g[1]; React.useLayoutEffect(function () { if (Array.isArray(layout)) { return send({ type: actionTypes.updateState, payload: { currentLayout: layout, visibleColumns: columns.slice(0, layout.length), }, }); } Object.keys(layout).map(function (breakpoint) { if (breakpoint < width) { switchCurrentLayout(layout[breakpoint]); } return undefined; }); }, [width]); var switchColumns = function (from, to) { send({ type: actionTypes.switchColumns, payload: { to: to, from: from } }); }; var switchCurrentLayout = function (nextLayout) { send({ type: actionTypes.switchCurrentLayout, payload: { currentLayout: nextLayout }, }); }; var offsetColumns = React.useCallback(function (_a) { var includeVisible = (_a === void 0 ? {} : _a).includeVisible; return getOffsetColumns(state.visibleColumns, state.columns, includeVisible); }, [state.visibleColumns, state.columns]); var onSelection = function (items) { switch (state.selectAllCheckboxState) { case 'all': return deselectAll(); case 'some': return deselectAll(); case 'none': return selectAll(items); default: return deselectAll(); } }; var deselectAll = function () { send({ type: actionTypes.deselectAll }); }; var selectAll = function (items) { send({ type: actionTypes.selectAll, payload: { items: items.map(function (item) { return String(item); }) }, }); }; var checkboxToggle = function (evt) { send({ type: actionTypes.checkboxToggle, payload: { id: String(evt.target.id), value: String(evt.target.value) }, }); }; var checkboxShiftToggle = function (evt) { if (evt.shiftKey && state.lastChecked) { send({ type: actionTypes.checkboxShiftToggle, payload: { id: String(evt.target.id), value: String(evt.target.value), refs: checkboxRefs, }, }); return; } send({ type: actionTypes.checkboxToggle, payload: { id: String(evt.target.id), value: String(evt.target.value) }, }); }; var checkboxState = function (itemId) { if (!state.checkedItems || state.checkedItems.length < 1) { return false; } return state.checkedItems.includes(String(itemId)); }; var clientSortMethod = function (a, b) { var _a = state.currentSort, fieldKey = _a.fieldKey, direction = _a.direction; if (fieldKey && direction) { var valueA = getObjectValueByString(a, fieldKey); var valueB = getObjectValueByString(b, fieldKey); valueA = valueA === null || valueA === undefined ? '' : valueA; valueB = valueB === null || valueB === undefined ? '' : valueB; valueA = typeof valueA === 'string' ? valueA.toLowerCase() : valueA; valueB = typeof valueB === 'string' ? valueB.toLowerCase() : valueB; if (direction.toLowerCase() === 'asc') { if (valueA < valueB) { return -1; } else if (valueA > valueB) { return 1; } else { return 0; } } if (direction.toLowerCase() === 'desc') { if (valueA > valueB) { return -1; } else if (valueA < valueB) { return 1; } else { return 0; } } return 0; } return 0; }; var changeSortDirection = function (direction) { send({ type: actionTypes.changeSortDirection, payload: { direction: direction } }); }; var toggleSortDirection = function () { send({ type: actionTypes.toggleSortDirection, }); }; var toggleSortByKey = function (fieldKey) { send({ type: actionTypes.toggleSortByKey, payload: { fieldKey: fieldKey }, }); }; var sortData = function (_a) { var direction = _a.direction, fieldKey = _a.fieldKey; send({ type: actionTypes.sortData, payload: { direction: direction, fieldKey: fieldKey } }); }; var activeSort = function (_a) { var direction = _a.direction, fieldKey = _a.fieldKey; var currentSort = state.currentSort; var isActive = currentSort.fieldKey === fieldKey; var isCurrentSortDir = currentSort.direction === direction; return isActive && isCurrentSortDir; }; var activeSortKey = function (fieldKey) { var currentSort = state.currentSort; return currentSort.fieldKey === fieldKey; }; var getCheckboxProps = function (_a) { if (_a === void 0) { _a = {}; } var _b = _a.master, master = _b === void 0 ? false : _b, rest = __rest(_a, ["master"]); if (master) { return __assign({}, rest); } return __assign({ ref: function (ref) { return ref && checkboxRefs.add(ref); } }, rest); }; return Object.assign(state, { switchColumns: switchColumns, switchCurrentLayout: switchCurrentLayout, onSelection: onSelection, deselectAll: deselectAll, selectAll: selectAll, offsetColumns: offsetColumns, checkboxToggle: checkboxToggle, checkboxShiftToggle: checkboxShiftToggle, checkboxState: checkboxState, clientSortMethod: clientSortMethod, changeSortDirection: changeSortDirection, toggleSortDirection: toggleSortDirection, toggleSortByKey: toggleSortByKey, sortData: sortData, activeSort: activeSort, activeSortKey: activeSortKey, getCheckboxProps: getCheckboxProps, }); }; var __rest$1 = (undefined && undefined.__rest) || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; }; var TableToolsContext = React.createContext({ currentLayout: [], visibleColumns: [], totalItems: 0, columns: [], checkedItems: [], selectAllCheckboxState: 'none', currentSort: { direction: 'asc', fieldKey: '' }, lastChecked: null, switchColumns: function () { }, switchCurrentLayout: function () { }, offsetColumns: function () { return []; }, onSelection: function () { }, deselectAll: function () { }, selectAll: function () { }, checkboxToggle: function () { }, checkboxShiftToggle: function () { }, checkboxState: function () { return false; }, clientSortMethod: function () { return 0; }, changeSortDirection: function () { }, toggleSortDirection: function () { }, toggleSortByKey: function () { }, sortData: function () { }, activeSort: function () { return false; }, activeSortKey: function () { return false; }, getCheckboxProps: function () { }, }); var TableTools = function (_a) { var children = _a.children, stateReducer = _a.stateReducer, rest = __rest$1(_a, ["children", "stateReducer"]); var utils = useTableTools(rest, stateReducer); var ui = typeof children === 'function' ? children(utils) : children; return (React__default.createElement(TableToolsContext.Provider, { value: utils }, ui)); }; var useTableToolsContext = function () { var utils = React.useContext(TableToolsContext); return utils; }; exports.TableTools = TableTools; exports.actionTypes = actionTypes; exports.callAllEventHandlers = callAllEventHandlers; exports.default = useTableTools; exports.getObjectValueByString = getObjectValueByString; exports.getOffsetColumns = getOffsetColumns; exports.tableToolsReducer = tableToolsReducer; exports.useTableTools = useTableTools; exports.useTableToolsContext = useTableToolsContext; //# sourceMappingURL=index.cjs.js.map