UNPKG

@equinor/eds-data-grid-react

Version:

A feature-rich data-grid written in React, implementing the Equinor Design System

125 lines (122 loc) 5.2 kB
import { flexRender } from '@tanstack/react-table'; import { useTableContext } from '../EdsDataGridContext.js'; import { useMemo } from 'react'; import { FilterWrapper } from './FilterWrapper.js'; import { SortIndicator } from './SortIndicator.js'; import { Resizer, ResizeInner } from './Resizer.js'; import { TableCell, FilterVisibility } from './TableCell.js'; import styled from 'styled-components'; import { useEds } from '@equinor/eds-core-react'; import { jsx, jsxs } from 'react/jsx-runtime'; const SortButton = styled.button.withConfig({ displayName: "TableHeaderCell__SortButton", componentId: "sc-1n0j3v0-0" })(["cursor:pointer;height:100%;width:calc(100% - 5px);display:flex;flex-direction:row;align-items:center;background:transparent;border:none;padding-left:var(--eds_table__cell__padding_x,16px);padding-right:var(--eds_table__cell__padding_x,16px);margin:0;outline:none;color:inherit;text-align:left;font:inherit;"]); const TableHeaderCellLabel = styled.div.withConfig({ displayName: "TableHeaderCell__TableHeaderCellLabel", componentId: "sc-1n0j3v0-1" })(["display:flex;flex-direction:column;"]); const getSortLabel = sorted => { if (sorted) { return `${sorted}ending`; } return 'none'; }; function TableHeaderCell({ header, columnResizeMode }) { const ctx = useTableContext(); const table = ctx.table; const pinned = header.column.getIsPinned(); const isFiltered = header.column.getIsFiltered(); const filterValue = header.column.getFilterValue(); const hasActiveFilters = useMemo(() => { if (!isFiltered) return false; if (Array.isArray(filterValue)) { return filterValue.length > 0 && filterValue.some(v => !!v || v === 0); // avoid empty strings counting } return !!filterValue; }, [isFiltered, filterValue]); const canSort = header.column.getCanSort(); const canFilter = header.column.getCanFilter(); const offset = useMemo(() => { if (!pinned) { return null; } return pinned === 'left' ? header.getStart() : table.getTotalSize() - header.getStart() - header.getSize(); }, [pinned, header, table]); const { density } = useEds(); // Future improvement: If we down the line end up granting the ability to customize row height, we should move this to the table-context const rowHeight = density === 'compact' ? 32 : 48; const vertOffset = ctx.stickyHeader ? (header.depth - 1) * rowHeight : undefined; const tableCellPadding = useMemo(() => { if (canSort && canFilter) { return '0 var(--eds_table__cell__padding_x, 16px) 0 0'; } if (canSort) { return '0'; } return '0 var(--eds_table__cell__padding_x, 16px) 0 var(--eds_table__cell__padding_x, 16px)'; }, [canSort, canFilter]); return header.isPlaceholder ? /*#__PURE__*/jsx(TableCell, { $sticky: ctx.stickyHeader, $offset: offset, $pinned: pinned, className: ctx.headerClass ? ctx.headerClass(header.column) : '', style: { ...(ctx.headerStyle ? ctx.headerStyle(header.column) : {}), top: vertOffset }, "aria-hidden": true }) : /*#__PURE__*/jsxs(TableCell, { $sticky: ctx.stickyHeader, $offset: offset, $pinned: pinned, $activeFilter: hasActiveFilters, className: ctx.headerClass ? ctx.headerClass(header.column) : '', "aria-sort": getSortLabel(header.column.getIsSorted()), colSpan: header.colSpan, style: { width: header.getSize(), verticalAlign: ctx.enableColumnFiltering ? 'top' : 'middle', ...(ctx.headerStyle ? ctx.headerStyle(header.column) : {}), padding: tableCellPadding, top: vertOffset }, children: [canSort ? /*#__PURE__*/jsxs(SortButton, { tabIndex: -1, onClick: header.column.getToggleSortingHandler(), "data-testid": `sort-button-${header.id}`, children: [/*#__PURE__*/jsx(TableHeaderCellLabel, { className: "table-header-cell-label", children: flexRender(header.column.columnDef.header, header.getContext()) }), !header.column.columnDef.meta?.customFilterInput && /*#__PURE__*/jsx(SortIndicator, { column: header.column })] }) : /*#__PURE__*/jsx(TableHeaderCellLabel, { className: "table-header-cell-label", children: flexRender(header.column.columnDef.header, header.getContext()) }), canFilter && !header.column.columnDef.meta?.customFilterInput ? /*#__PURE__*/ // Supressing this warning - div is not interactive, but prevents propagation of events to avoid unintended sorting // eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions jsx(FilterVisibility, { onClick: e => e.stopPropagation(), children: /*#__PURE__*/jsx(FilterWrapper, { column: header.column }) }) : null, columnResizeMode && /*#__PURE__*/jsx(Resizer, { onMouseDown: header.getResizeHandler(), onTouchStart: header.getResizeHandler(), $isResizing: header.column.getIsResizing(), $columnResizeMode: columnResizeMode, className: 'resize-handle', "data-testid": 'resize-handle', children: /*#__PURE__*/jsx(ResizeInner, {}) })] }, header.id); } export { TableHeaderCell };