UNPKG

@itwin/itwinui-react

Version:

A react component library for iTwinUI

192 lines (191 loc) 5.48 kB
import * as React from 'react'; import { Box, ShadowRoot, lineClamp, SvgSortDown, SvgSortUp, useMergedRefs, } from '../../utils/index.js'; import { FilterToggle } from './filters/FilterToggle.js'; import { getCellStyle, getSubRowStyle, getStickyStyle, TableInstanceContext, } from './utils.js'; import cx from 'classnames'; export const ColumnHeader = React.forwardRef((props, forwardedRef) => { let { column, areFiltersSet, isResizable, columnResizeMode, enableColumnReordering, density, columnHasExpanders, isLast, isTableEmpty, ...rest } = props; let isHeaderDirectClick = React.useRef(false); let instance = React.useContext(TableInstanceContext); let COLUMN_MIN_WIDTHS = { default: 72, withExpander: 108, }; let showFilterButton = (column) => (!isTableEmpty || areFiltersSet) && column.canFilter && !!column.Filter; let showSortButton = (column) => !isTableEmpty && column.canSort; let { onClick, ...restSortProps } = column.getSortByToggleProps(); if ([void 0, 0].includes(column.minWidth)) { column.minWidth = columnHasExpanders ? COLUMN_MIN_WIDTHS.withExpander : COLUMN_MIN_WIDTHS.default; if ('number' == typeof column.width && column.minWidth > column.width) column.minWidth = column.width; } let columnProps = column.getHeaderProps({ ...restSortProps, className: cx( 'iui-table-cell', { 'iui-actionable': column.canSort, 'iui-sorted': column.isSorted, 'iui-table-cell-sticky': !!column.sticky, }, column.columnClassName, ), style: { ...getCellStyle(column, !!instance?.state.isTableResizing), ...(columnHasExpanders && getSubRowStyle({ density, })), ...getStickyStyle(column, instance?.visibleColumns ?? []), flexWrap: 'wrap', columnGap: 'var(--iui-size-xs)', }, }); return React.createElement( Box, { ...columnProps, ...rest, key: columnProps.key, title: void 0, ref: useMergedRefs( React.useCallback( (el) => { if (el) column.resizeWidth = el.getBoundingClientRect().width; }, [column], ), forwardedRef, ), onMouseDown: () => { isHeaderDirectClick.current = true; }, onClick: (e) => { if (isHeaderDirectClick.current) { onClick?.(e); isHeaderDirectClick.current = false; } }, tabIndex: showSortButton(column) ? 0 : void 0, onKeyDown: (e) => { if ('Enter' == e.key && showSortButton(column)) column.toggleSortBy(); }, }, React.createElement( React.Fragment, null, 'string' == typeof column.Header ? React.createElement( ShadowRoot, { css: lineClamp.css, }, React.createElement( 'div', { className: lineClamp.className, }, React.createElement('slot', null), ), React.createElement('slot', { name: 'actions', }), React.createElement('slot', { name: 'resizers', }), React.createElement('slot', { name: 'shadows', }), ) : null, column.render('Header'), (showFilterButton(column) || showSortButton(column)) && React.createElement( Box, { className: 'iui-table-header-actions-container', onKeyDown: (e) => e.stopPropagation(), slot: 'actions', }, showFilterButton(column) && React.createElement(FilterToggle, { column: column, }), showSortButton(column) && React.createElement( Box, { className: 'iui-table-cell-end-icon', }, column.isSortedDesc || (!column.isSorted && column.sortDescFirst) ? React.createElement(SvgSortDown, { className: 'iui-table-sort', 'aria-hidden': true, }) : React.createElement(SvgSortUp, { className: 'iui-table-sort', 'aria-hidden': true, }), ), ), isResizable && column.isResizerVisible && (!isLast || 'expand' === columnResizeMode) && React.createElement( Box, { ...column.getResizerProps(), className: 'iui-table-resizer', slot: 'resizers', }, React.createElement(Box, { className: 'iui-table-resizer-bar', }), ), enableColumnReordering && !column.disableReordering && React.createElement(Box, { className: 'iui-table-reorder-bar', slot: 'resizers', }), 'left' === column.sticky && instance?.state.sticky.isScrolledToRight && React.createElement(Box, { className: 'iui-table-cell-shadow-right', slot: 'shadows', }), 'right' === column.sticky && instance?.state.sticky.isScrolledToLeft && React.createElement(Box, { className: 'iui-table-cell-shadow-left', slot: 'shadows', }), ), ); });