UNPKG

@grafana/ui

Version:
199 lines (196 loc) • 6.65 kB
import { jsx, jsxs, Fragment } from 'react/jsx-runtime'; import { useMemo, createElement } from 'react'; import { cx, css } from '@emotion/css'; import { Trans } from '@grafana/i18n'; import { useStyles2 } from '../../themes/ThemeContext.mjs'; import { Button } from '../Button/Button.mjs'; import { Icon } from '../Icon/Icon.mjs'; import { useLimit } from '../List/hooks.mjs'; import { LegendTableItem } from './VizLegendTableItem.mjs'; "use strict"; const nameSortKey = "Name"; const naturalCompare = new Intl.Collator(void 0, { numeric: true, sensitivity: "base" }).compare; const VizLegendTable = ({ items, sortBy: sortKey, sortDesc, itemRenderer, className, onToggleSort, onLabelClick, onLabelMouseOver, onLabelMouseOut, readonly, isSortable, limit = 0, filterAction, placement, overflow }) => { var _a, _b; const styles = useStyles2(getStyles, placement); const header = { [nameSortKey]: "" }; for (const item of items) { if (item.getDisplayValues) { for (const displayValue of item.getDisplayValues()) { header[(_a = displayValue.title) != null ? _a : "?"] = (_b = displayValue.description) != null ? _b : ""; } } } if (sortKey != null) { let itemVals = /* @__PURE__ */ new Map(); items.forEach((item) => { if (sortKey !== nameSortKey && item.getDisplayValues) { const stat = item.getDisplayValues().find((stat2) => stat2.title === sortKey); const val = stat == null || Number.isNaN(stat.numeric) ? -Infinity : stat.numeric; itemVals.set(item, val); } }); let sortMult = sortDesc ? -1 : 1; if (sortKey === nameSortKey) { items.sort((a, b) => { return sortMult * naturalCompare(a.label, b.label); }); } else { items.sort((a, b) => { var _a2, _b2; const aVal = (_a2 = itemVals.get(a)) != null ? _a2 : 0; const bVal = (_b2 = itemVals.get(b)) != null ? _b2 : 0; return sortMult * (aVal - bVal); }); } } const [curLimit, setLimit] = useLimit(limit); const limitedItems = useMemo(() => curLimit > 0 ? items.slice(0, curLimit) : items, [items, curLimit]); const hasMixedAxes = useMemo(() => { var _a2, _b2; const firstYAxis = (_b2 = (_a2 = items[0]) == null ? void 0 : _a2.yAxis) != null ? _b2 : 1; return items.some((item) => item.yAxis !== firstYAxis); }, [items]); if (!itemRenderer) { itemRenderer = (item, index) => /* @__PURE__ */ jsx( LegendTableItem, { item, onLabelClick, onLabelMouseOver, onLabelMouseOut, readonly, hasMixedAxes, overflow }, `${item.label}-${index}` ); } return /* @__PURE__ */ jsxs(Fragment, { children: [ /* @__PURE__ */ jsxs( "table", { className: cx(styles.grid, className), style: { gridTemplateColumns: `min-content minmax(55px, auto) ${"min-content ".repeat(Object.keys(header).length - 1)}` }, children: [ /* @__PURE__ */ jsx("thead", { className: styles.header, children: /* @__PURE__ */ jsxs("tr", { children: [ /* @__PURE__ */ jsx("th", { children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: /* @__PURE__ */ jsx(Trans, { i18nKey: "legend.container.series-color-and-icon", children: "Series color" }) }) }), Object.keys(header).map((columnTitle, i) => /* @__PURE__ */ createElement( "th", { ...sortKey === columnTitle ? { "aria-sort": sortDesc ? "descending" : "ascending" } : null, title: header[columnTitle], key: columnTitle, className: cx({ [styles.headerSortable]: Boolean(onToggleSort), [styles.nameHeader]: isSortable, [styles.calcHeader]: i > 0, [styles.withIcon]: sortKey === columnTitle, "sr-only": !isSortable }), onClick: () => { if (onToggleSort && isSortable) { onToggleSort(columnTitle); } } }, columnTitle === nameSortKey && filterAction && // eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions /* @__PURE__ */ jsx("span", { className: styles.filterAction, onClick: (e) => e.stopPropagation(), children: filterAction }), columnTitle, sortKey === columnTitle && /* @__PURE__ */ jsx(Icon, { size: "xs", name: sortDesc ? "angle-down" : "angle-up" }) )) ] }) }), /* @__PURE__ */ jsx("tbody", { children: limitedItems.map(itemRenderer) }) ] } ), curLimit > 0 && items.length > curLimit && /* @__PURE__ */ jsx(Button, { fill: "text", variant: "primary", size: "sm", onClick: () => setLimit(0), className: styles.showAll, children: /* @__PURE__ */ jsxs(Trans, { i18nKey: "legend.container.show-all-series", className: styles.showAll, children: [ "...show all ", { total: items.length }, " items" ] }) }) ] }); }; const getStyles = (theme, placement = "bottom") => ({ header: css({ position: "sticky", top: 0, backgroundColor: theme.colors.background.primary, color: theme.colors.primary.text }), nameHeader: css({ textAlign: "left" }), calcHeader: css({ textAlign: "right" }), withIcon: css({ paddingRight: "4px" }), headerSortable: css({ cursor: "pointer" }), filterAction: css({ marginLeft: theme.spacing(0.5), display: "inline-flex", verticalAlign: "middle" }), showAll: css({ justifyContent: "right" }), grid: css({ display: "grid", width: "100%", // non-layout fontSize: theme.typography.bodySmall.fontSize, textAlign: "right", whiteSpace: "nowrap", "tbody,thead,tfoot,tr": { display: "grid", gridColumn: "1 / -1", gridTemplateColumns: "subgrid" }, tr: { borderBottom: `1px solid ${theme.colors.border.weak}` }, "th,td": { display: "block", alignContent: "center", whiteSpace: "nowrap", // non-layout padding: theme.spacing(0.25, 1), // series color/icon column "&:nth-child(1)": { paddingLeft: theme.spacing(1) }, // series name column "&:nth-child(2)": { overflow: "hidden", textOverflow: "ellipsis", maxWidth: placement === "right" ? 600 : void 0 } } }) }); export { VizLegendTable }; //# sourceMappingURL=VizLegendTable.mjs.map