@grafana/ui
Version:
Grafana Components Library
133 lines (130 loc) • 4.26 kB
JavaScript
import { jsxs, jsx } from 'react/jsx-runtime';
import { css } from '@emotion/css';
import { useRef, useLayoutEffect, useEffect } from 'react';
import '@grafana/data';
import { useStyles2 } from '../../../../themes/ThemeContext.mjs';
import 'micro-memoize';
import '@emotion/react';
import 'tinycolor2';
import '../../../../utils/skeleton.mjs';
import { getFieldTypeIcon } from '../../../../types/icon.mjs';
import { Icon } from '../../../Icon/Icon.mjs';
import { Filter } from '../Filter/Filter.mjs';
import { getDisplayName } from '../utils.mjs';
const HeaderCell = ({
column,
rows,
field,
onSort,
direction,
justifyContent,
filter,
setFilter,
onColumnResize,
headerCellRefs,
crossFilterOrder,
crossFilterRows,
showTypeIcons
}) => {
var _a, _b, _c, _d, _e, _f, _g;
const styles = useStyles2(getStyles, justifyContent);
const headerRef = useRef(null);
const filterable = (_c = (_b = (_a = field.config) == null ? void 0 : _a.custom) == null ? void 0 : _b.filterable) != null ? _c : false;
const displayName = getDisplayName(field);
let isColumnFilterable = filterable;
if (((_d = field.config.custom) == null ? void 0 : _d.filterable) !== filterable) {
isColumnFilterable = ((_e = field.config.custom) == null ? void 0 : _e.filterable) || false;
}
if (!isColumnFilterable && filter[displayName]) {
setFilter((filter2) => {
const newFilter = { ...filter2 };
delete newFilter[displayName];
return newFilter;
});
}
const handleSort = (event) => {
const isMultiSort = event.shiftKey;
onSort(column.key, direction === "ASC" ? "DESC" : "ASC", isMultiSort);
};
useLayoutEffect(() => {
if (headerRef.current) {
headerCellRefs.current[column.key] = headerRef.current;
}
}, [headerRef, column.key]);
useEffect(() => {
var _a2;
const headerCellParent = (_a2 = headerRef.current) == null ? void 0 : _a2.parentElement;
if (headerCellParent) {
const lastElement = headerCellParent.lastElementChild;
if (lastElement) {
const handleMouseUp = () => {
let newWidth = headerCellParent.clientWidth;
onColumnResize == null ? void 0 : onColumnResize(column.key, newWidth);
};
lastElement.addEventListener("click", handleMouseUp);
return () => {
lastElement.removeEventListener("click", handleMouseUp);
};
}
}
return;
}, [column]);
return /* @__PURE__ */ jsxs(
"div",
{
ref: headerRef,
className: styles.headerCell,
onKeyDown: (event) => {
if (event.key === " ") {
event.stopPropagation();
}
},
children: [
/* @__PURE__ */ jsxs("button", { className: styles.headerCellLabel, onClick: handleSort, children: [
showTypeIcons && /* @__PURE__ */ jsx(Icon, { name: getFieldTypeIcon(field), title: field == null ? void 0 : field.type, size: "sm" }),
/* @__PURE__ */ jsx("div", { children: (_g = (_f = field.state) == null ? void 0 : _f.displayName) != null ? _g : column.name }),
direction && (direction === "ASC" ? /* @__PURE__ */ jsx(Icon, { name: "arrow-up", size: "lg" }) : /* @__PURE__ */ jsx(Icon, { name: "arrow-down", size: "lg" }))
] }),
isColumnFilterable && /* @__PURE__ */ jsx(
Filter,
{
name: column.key,
rows,
filter,
setFilter,
field,
crossFilterOrder: crossFilterOrder.current,
crossFilterRows: crossFilterRows.current
}
)
]
}
);
};
const getStyles = (theme, justifyContent) => ({
headerCell: css({
display: "flex",
gap: theme.spacing(0.5),
justifyContent
}),
headerCellLabel: css({
border: "none",
padding: 0,
background: "inherit",
cursor: "pointer",
whiteSpace: "nowrap",
overflow: "hidden",
textOverflow: "ellipsis",
fontWeight: theme.typography.fontWeightMedium,
display: "flex",
alignItems: "center",
color: theme.colors.text.secondary,
gap: theme.spacing(1),
"&:hover": {
textDecoration: "underline",
color: theme.colors.text.link
}
})
});
export { HeaderCell };
//# sourceMappingURL=HeaderCell.mjs.map