@itwin/itwinui-react
Version:
A react component library for iTwinUI
192 lines (191 loc) • 5.48 kB
JavaScript
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',
}),
),
);
});