@grafana/alerting
Version:
Grafana Alerting Library – Build vertical integrations on top of the industry-leading alerting solution
154 lines (151 loc) • 5.77 kB
JavaScript
import { jsxs, jsx } from 'react/jsx-runtime';
import { cx, css } from '@emotion/css';
import { useMemo } from 'react';
import tinycolor2 from 'tinycolor2';
import { useStyles2, Stack, Icon, getTagColorsFromName } from '@grafana/ui';
"use strict";
const AlertLabel = (props) => {
const { labelKey, value, icon, color, colorBy, size = "md", onClick, ...rest } = props;
const theColor = getColorFromProps({ color, colorBy, labelKey, value });
const styles = useStyles2(getStyles, theColor, size);
const ariaLabel = `${labelKey}: ${value}`;
const keyless = !Boolean(labelKey);
const innerLabel = useMemo(
() => /* @__PURE__ */ jsxs(Stack, { direction: "row", gap: 0, alignItems: "stretch", children: [
labelKey && /* @__PURE__ */ jsx("div", { className: styles.label, children: /* @__PURE__ */ jsxs(Stack, { direction: "row", gap: 0.5, alignItems: "center", children: [
icon && /* @__PURE__ */ jsx(Icon, { name: icon }),
labelKey && /* @__PURE__ */ jsx("span", { className: styles.labelText, title: labelKey.toString(), children: labelKey != null ? labelKey : "" })
] }) }),
/* @__PURE__ */ jsx("div", { className: cx(styles.value, keyless && styles.valueWithoutKey), title: value == null ? void 0 : value.toString(), children: value != null ? value : "-" })
] }),
[labelKey, styles.label, styles.labelText, styles.value, styles.valueWithoutKey, icon, keyless, value]
);
return /* @__PURE__ */ jsx("div", { className: styles.wrapper, "aria-label": ariaLabel, "data-testid": "label-value", ...rest, children: onClick && (labelKey || value) ? /* @__PURE__ */ jsx(
"button",
{
type: "button",
className: styles.clickable,
onClick: () => onClick == null ? void 0 : onClick([value != null ? value : "", labelKey != null ? labelKey : ""]),
children: innerLabel
},
`${labelKey != null ? labelKey : ""}${value != null ? value : ""}`
) : innerLabel });
};
function getAccessibleTagColor(name) {
if (!name) {
return;
}
const attempts = Array.from({ length: 6 }, (_, i) => name + "-".repeat(i));
const readableAttempt = attempts.find((attempt) => {
const candidate = getTagColorsFromName(attempt).color;
return tinycolor2.isReadable(candidate, "#000", { level: "AA", size: "small" }) || tinycolor2.isReadable(candidate, "#fff", { level: "AA", size: "small" });
});
const chosen = readableAttempt != null ? readableAttempt : name;
return getTagColorsFromName(chosen).color;
}
function getColorFromProps({
color,
colorBy,
labelKey,
value
}) {
if (color) {
return getAccessibleTagColor(color);
}
if (colorBy === "key") {
return getAccessibleTagColor(labelKey);
}
if (colorBy === "value") {
return getAccessibleTagColor(value);
}
if (colorBy === "both" && labelKey && value) {
return getAccessibleTagColor(labelKey + value);
}
return;
}
function getReadableFontColor(bg, fallback) {
if (tinycolor2.isReadable(bg, "#000", { level: "AA", size: "small" })) {
return "#000";
}
if (tinycolor2.isReadable(bg, "#fff", { level: "AA", size: "small" })) {
return "#fff";
}
if (tinycolor2.isReadable(bg, fallback, { level: "AA", size: "small" })) {
return tinycolor2(fallback).toHexString();
}
return tinycolor2.mostReadable(bg, ["#000", "#fff", fallback], {
includeFallbackColors: true
}).toHexString();
}
const getStyles = (theme, color, size) => {
const backgroundColor = color != null ? color : theme.colors.secondary.main;
const borderColor = theme.isDark ? tinycolor2(backgroundColor).lighten(5).toString() : tinycolor2(backgroundColor).darken(5).toString();
const valueBackgroundColor = theme.isDark ? tinycolor2(backgroundColor).darken(5).toString() : tinycolor2(backgroundColor).lighten(5).toString();
const labelFontColor = color ? getReadableFontColor(backgroundColor, theme.colors.text.primary) : theme.colors.text.primary;
const valueFontColor = color ? getReadableFontColor(valueBackgroundColor, theme.colors.text.primary) : theme.colors.text.primary;
let padding = theme.spacing(0.33, 1);
switch (size) {
case "sm":
padding = theme.spacing(0.2, 0.6);
break;
case "xs":
padding = theme.spacing(0, 0.5);
break;
default:
break;
}
return {
wrapper: css({
fontSize: theme.typography.bodySmall.fontSize,
borderRadius: theme.shape.borderRadius(2)
}),
labelText: css({
whiteSpace: "nowrap",
overflow: "hidden",
textOverflow: "ellipsis",
maxWidth: "300px"
}),
label: css({
display: "flex",
alignItems: "center",
color: labelFontColor,
padding,
background: backgroundColor,
border: `solid 1px ${borderColor}`,
borderTopLeftRadius: theme.shape.borderRadius(2),
borderBottomLeftRadius: theme.shape.borderRadius(2)
}),
clickable: css({
border: "none",
background: "none",
outline: "none",
boxShadow: "none",
padding: 0,
margin: 0,
"&:hover": {
opacity: 0.8,
cursor: "pointer"
}
}),
value: css({
color: valueFontColor,
padding,
background: valueBackgroundColor,
border: `solid 1px ${borderColor}`,
borderLeft: "none",
borderTopRightRadius: theme.shape.borderRadius(2),
borderBottomRightRadius: theme.shape.borderRadius(2),
whiteSpace: "pre",
overflow: "hidden",
textOverflow: "ellipsis",
maxWidth: "300px"
}),
valueWithoutKey: css({
borderTopLeftRadius: theme.shape.borderRadius(2),
borderBottomLeftRadius: theme.shape.borderRadius(2),
borderLeft: `solid 1px ${borderColor}`
})
};
};
export { AlertLabel };
//# sourceMappingURL=AlertLabel.mjs.map