@elastic/eui
Version:
Elastic UI Component Library
224 lines (218 loc) • 10.1 kB
JavaScript
import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
import _defineProperty from "@babel/runtime/helpers/defineProperty";
import _extends from "@babel/runtime/helpers/extends";
var _excluded = ["children", "align", "onSort", "isSorted", "isSortAscending", "className", "scope", "mobileOptions", "width", "minWidth", "maxWidth", "style", "readOnly", "tooltipProps", "description", "append", "sticky"];
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import React, { useEffect, useCallback, useRef } from 'react';
import classNames from 'classnames';
import { useEuiMemoizedStyles, LEFT_ALIGNMENT } from '../../services';
import { EuiI18n } from '../i18n';
import { EuiScreenReaderOnly } from '../accessibility';
import { EuiIcon } from '../icon';
import { EuiInnerText } from '../inner_text';
import { EuiIconTip, EuiToolTip } from '../tool_tip';
import { resolveWidthPropsAsStyle } from './utils';
import { useEuiTableIsResponsive } from './mobile/responsive_context';
import { EuiTableCellContent } from './_table_cell_content';
import { euiTableHeaderFooterCellStyles, _useEuiTableStickyCellStyles } from './table_cells_shared.styles';
import { useEuiTableColumnDataStore } from './store/provider';
import { useEuiTableWithinStickyHeader } from './sticky_header';
import { useEuiTableStoreUniqueColumnId } from './store/use_unique_column_id';
import { jsx as ___EmotionJSX } from "@emotion/react";
var CellContents = function CellContents(_ref) {
var className = _ref.className,
align = _ref.align,
tooltipProps = _ref.tooltipProps,
description = _ref.description,
children = _ref.children,
canSort = _ref.canSort,
isSorted = _ref.isSorted,
isSortAscending = _ref.isSortAscending;
var tooltipIcon = tooltipProps ? canSort ? ___EmotionJSX(EuiIcon, _extends({
className: "euiTableSortIcon",
type: tooltipProps.icon || 'question',
size: "m",
color: "subdued"
}, tooltipProps.iconProps)) : ___EmotionJSX(EuiIconTip, _extends({
content: tooltipProps.content,
type: tooltipProps.icon || 'question',
size: "m",
color: "subdued",
position: "top",
iconProps: _objectSpread({
role: 'button'
}, tooltipProps.iconProps)
}, tooltipProps.tooltipProps)) : null;
return ___EmotionJSX(EuiTableCellContent, {
className: className,
align: align,
textOnly: false,
truncateText: null
}, ___EmotionJSX(EuiInnerText, null, function (ref, innerText) {
return ___EmotionJSX(EuiI18n, {
token: "euiTableHeaderCell.titleTextWithDesc",
default: "{innerText}; {description}",
values: {
innerText: innerText,
description: description
}
}, function (titleTextWithDesc) {
return ___EmotionJSX("span", {
title: description ? titleTextWithDesc : innerText,
ref: ref,
className: "eui-textTruncate"
}, children);
});
}), description && ___EmotionJSX(EuiScreenReaderOnly, null, ___EmotionJSX("span", null, description)), tooltipIcon, isSorted ? ___EmotionJSX(EuiIcon, {
className: "euiTableSortIcon",
type: isSortAscending ? 'sortUp' : 'sortDown',
size: "m"
}) : canSort ? ___EmotionJSX(EuiIcon, {
className: "euiTableSortIcon euiTableSortIcon--sortable",
type: "sortable",
size: "m",
color: "subdued" // Tinted a bit further via CSS
}) : null);
};
export var EuiTableHeaderCell = function EuiTableHeaderCell(_ref2) {
var children = _ref2.children,
_ref2$align = _ref2.align,
align = _ref2$align === void 0 ? LEFT_ALIGNMENT : _ref2$align,
onSort = _ref2.onSort,
isSorted = _ref2.isSorted,
isSortAscending = _ref2.isSortAscending,
className = _ref2.className,
scope = _ref2.scope,
mobileOptions = _ref2.mobileOptions,
width = _ref2.width,
minWidth = _ref2.minWidth,
maxWidth = _ref2.maxWidth,
_style = _ref2.style,
readOnly = _ref2.readOnly,
tooltipProps = _ref2.tooltipProps,
description = _ref2.description,
append = _ref2.append,
sticky = _ref2.sticky,
rest = _objectWithoutProperties(_ref2, _excluded);
var selfRef = useRef(null);
var storeCellId = useEuiTableStoreUniqueColumnId();
var store = useEuiTableColumnDataStore();
var isWithinStickyHeader = useEuiTableWithinStickyHeader();
var styles = useEuiMemoizedStyles(euiTableHeaderFooterCellStyles);
var stickyStyles = _useEuiTableStickyCellStyles(sticky);
var isResponsive = useEuiTableIsResponsive();
var hideForDesktop = !isResponsive && (mobileOptions === null || mobileOptions === void 0 ? void 0 : mobileOptions.only);
var hideForMobile = isResponsive && (mobileOptions === null || mobileOptions === void 0 ? void 0 : mobileOptions.show) === false;
var renderHeaderCellRef = useRef();
renderHeaderCellRef.current = function (extraProps) {
if (hideForDesktop || hideForMobile) return null;
var classes = classNames('euiTableHeaderCell', className);
var cssStyles = [styles.euiTableHeaderCell, !isResponsive && stickyStyles];
var inlineWidthStyles = resolveWidthPropsAsStyle(_style, {
width: width,
minWidth: minWidth,
maxWidth: maxWidth
});
var CellComponent = children ? 'th' : 'td';
var cellScope = CellComponent === 'th' ? scope !== null && scope !== void 0 ? scope : 'col' : undefined; // `scope` is only valid on `th` elements
var canSort = !!(onSort && !readOnly);
var ariaSortValue;
if (isSorted) {
ariaSortValue = isSortAscending ? 'ascending' : 'descending';
} else if (canSort) {
ariaSortValue = 'none';
}
var cellContentsProps = {
css: styles.euiTableHeaderCell__content,
align: align,
tooltipProps: tooltipProps,
description: description,
canSort: canSort,
isSorted: isSorted,
isSortAscending: isSortAscending,
children: children
};
return ___EmotionJSX(CellComponent, _extends({
css: cssStyles,
className: classes,
scope: cellScope,
role: "columnheader",
"aria-sort": ariaSortValue,
"data-sticky": !isResponsive && (sticky === null || sticky === void 0 ? void 0 : sticky.side) || undefined,
style: _objectSpread(_objectSpread({}, _style), inlineWidthStyles)
}, rest, extraProps), canSort ? ___EmotionJSX(EuiToolTip, _extends({
content: tooltipProps === null || tooltipProps === void 0 ? void 0 : tooltipProps.content
}, tooltipProps === null || tooltipProps === void 0 ? void 0 : tooltipProps.tooltipProps, {
display: "block"
}), ___EmotionJSX("button", {
type: "button",
css: styles.euiTableHeaderCell__button,
className: classNames('euiTableHeaderButton', {
'euiTableHeaderButton-isSorted': isSorted
}),
onClick: onSort,
"data-test-subj": "tableHeaderSortButton"
}, ___EmotionJSX(CellContents, cellContentsProps))) : ___EmotionJSX(CellContents, cellContentsProps), append);
};
var handleResize = useCallback(function (entries) {
var entry = entries[0];
if (!entry) {
return;
}
store.updateColumnWidth(storeCellId, entry.contentRect.width);
}, [store, storeCellId]);
useEffect(function () {
// Don't register the column inside the sticky header as the original
// column is already registered. This would cause an infinite loop.
if (isWithinStickyHeader || !selfRef.current || !renderHeaderCellRef.current) {
return;
}
var unregisterColumn = store.registerColumn(storeCellId, {
renderHeaderCellRef: renderHeaderCellRef,
// getBoundingClientRect is not the cheapest, but we call it only once
currentWidth: selfRef.current.getBoundingClientRect().width
});
// ResizeObserver is available in all supported browsers,
// but jsdom and jest don't provide a polyfill for it.
var resizeObserver;
if (typeof window.ResizeObserver !== 'undefined') {
resizeObserver = new ResizeObserver(handleResize);
// Note: This _could_ be optimized by using a single ResizeObserver
// for the whole EuiTable, but it would need to be changed back to this
// if/when we implement resizable columns
resizeObserver.observe(selfRef.current);
}
return function () {
var _resizeObserver;
unregisterColumn();
(_resizeObserver = resizeObserver) === null || _resizeObserver === void 0 || _resizeObserver.disconnect();
};
}, [store, isWithinStickyHeader, handleResize, storeCellId]);
// Notify the store on every render so the sticky header stays in sync.
// React's reconciliation will efficiently handle any duplicate renders.
useEffect(function () {
// Don't update the store if the component is rendered within EuiTableStickyHeader
if (isWithinStickyHeader) {
return;
}
// Don't update the store if the element doesn't exist. The render function
// in `renderHeaderCellRef` sometimes renders null - e.g., in mobile layout
if (!selfRef.current) {
return;
}
store.updateColumn(storeCellId, {
renderHeaderCellRef: renderHeaderCellRef
});
});
return renderHeaderCellRef.current({
ref: selfRef
});
};