@grafana/ui
Version:
Grafana Components Library
127 lines (124 loc) • 3.96 kB
JavaScript
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