UNPKG

@grafana/ui

Version:
127 lines (124 loc) 3.96 kB
import { jsx } from 'react/jsx-runtime'; import { css } from '@emotion/css'; import { useMemo } from 'react'; import { isDataFrame, colorManipulator, classicColors } from '@grafana/data'; import { useStyles2 } from '../../../../themes/ThemeContext.mjs'; const DEFAULT_PILL_BG_COLOR = "#FF780A"; function createPills(pillValues, cellOptions, field) { return pillValues.map((pill, index) => { const bgColor = getPillColor(pill, cellOptions, field); const textColor = colorManipulator.getContrastRatio("#FFFFFF", bgColor) >= 4.5 ? "#FFFFFF" : "#000000"; return { value: pill, key: `${pill}-${index}`, bgColor, color: textColor }; }); } function PillCell({ value, field, justifyContent, cellOptions }) { const styles = useStyles2(getStyles, justifyContent); const pills = useMemo(() => { const pillValues = inferPills(value); return createPills(pillValues, cellOptions, field); }, [value, cellOptions, field]); if (pills.length === 0) { return /* @__PURE__ */ jsx("div", { className: styles.cell, children: "-" }); } return /* @__PURE__ */ jsx("div", { className: styles.cell, children: /* @__PURE__ */ jsx("div", { className: styles.pillsContainer, children: pills.map((pill) => /* @__PURE__ */ jsx( "span", { className: styles.pill, style: { backgroundColor: pill.bgColor, color: pill.color }, children: pill.value }, pill.key )) }) }); } function inferPills(value) { if (!value) { return []; } if (isDataFrame(value)) { return []; } const stringValue = String(value); try { const parsed = JSON.parse(stringValue); if (Array.isArray(parsed)) { return parsed.filter((item) => item != null && item !== "").map(String).map((text) => text.trim()).filter((item) => item !== ""); } } catch (e) { } if (stringValue.includes(",")) { return stringValue.split(",").map((text) => text.trim()).filter((item) => item !== ""); } return [stringValue.replace(/["'`]/g, "").trim()]; } function isPillCellOptions(cellOptions) { return (cellOptions == null ? void 0 : cellOptions.type) === "pill"; } function getPillColor(pill, cellOptions, field) { if (!isPillCellOptions(cellOptions)) { return getDeterministicColor(pill); } const colorMode = cellOptions.colorMode || "auto"; if (colorMode === "fixed" && cellOptions.color) { return cellOptions.color; } if (colorMode === "mapped") { if (field.config.mappings && field.config.mappings.length > 0) { const displayValue = field.display(pill); if (displayValue.color) { return displayValue.color; } } return cellOptions.color || DEFAULT_PILL_BG_COLOR; } if (colorMode === "auto") { return getDeterministicColor(pill); } return DEFAULT_PILL_BG_COLOR; } function getDeterministicColor(text) { let hash = 0; for (let i = 0; i < text.length; i++) { const char = text.charCodeAt(i); hash = (hash << 5) - hash + char; hash = hash & hash; } const colorValues = Object.values(classicColors); const index = Math.abs(hash) % colorValues.length; return colorValues[index]; } const getStyles = (theme, justifyContent) => ({ cell: css({ display: "flex", justifyContent: justifyContent || "flex-start", alignItems: "center", height: "100%", padding: theme.spacing(0.5) }), pillsContainer: css({ display: "flex", flexWrap: "wrap", gap: theme.spacing(0.5), maxWidth: "100%" }), pill: css({ display: "inline-block", padding: theme.spacing(0.25, 0.75), borderRadius: theme.shape.radius.default, fontSize: theme.typography.bodySmall.fontSize, lineHeight: theme.typography.bodySmall.lineHeight, fontWeight: theme.typography.fontWeightMedium, whiteSpace: "nowrap", textAlign: "center", minWidth: "fit-content" }) }); export { PillCell, inferPills }; //# sourceMappingURL=PillCell.mjs.map