Grafana-UI: Support theme color in TagsInput (#102293)

* Grafana-UI: Support theme color in TagsInput

* improve variable names

* rename prop + rejigger styles

* reword comment

---------

Co-authored-by: joshhunt <josh.hunt@grafana.com>
This commit is contained in:
Ezequiel Victorero
2025-04-07 12:43:59 +01:00
committed by GitHub
parent 9bc4fbe900
commit e1ec9bddbd
2 changed files with 26 additions and 6 deletions

View File

@ -1,4 +1,4 @@
import { css } from '@emotion/css';
import { css, cx } from '@emotion/css';
import { useMemo } from 'react';
import { GrafanaTheme2 } from '@grafana/data';
@ -12,18 +12,30 @@ interface Props {
name: string;
disabled?: boolean;
onRemove: (tag: string) => void;
/** Colours the tags 'randomly' based on the name. Defaults to true */
autoColors?: boolean;
}
/**
* @internal
* Only used internally by TagsInput
* */
export const TagItem = ({ name, disabled, onRemove }: Props) => {
const { color, borderColor } = useMemo(() => getTagColorsFromName(name), [name]);
export const TagItem = ({ name, disabled, onRemove, autoColors = true }: Props) => {
const styles = useStyles2(getStyles);
// If configured, use random colors based on name.
// Otherwise, a default class name will be applied to the tag.
const tagStyle = useMemo(() => {
if (autoColors) {
const { color, borderColor } = getTagColorsFromName(name);
return { backgroundColor: color, borderColor };
}
return undefined;
}, [name, autoColors]);
return (
<li className={styles.itemStyle} style={{ backgroundColor: color, borderColor }}>
<li className={cx(styles.itemStyle, !tagStyle && styles.defaultTagColor)} style={tagStyle}>
<span className={styles.nameStyle}>{name}</span>
<IconButton
name="times"
@ -47,7 +59,6 @@ const getStyles = (theme: GrafanaTheme2) => {
alignItems: 'center',
height: `${height}px`,
lineHeight: `${height - 2}px`,
color: '#fff',
borderWidth: '1px',
borderStyle: 'solid',
borderRadius: theme.shape.radius.default,
@ -56,6 +67,12 @@ const getStyles = (theme: GrafanaTheme2) => {
textShadow: 'none',
fontWeight: 500,
fontSize: theme.typography.size.sm,
color: '#fff',
}),
defaultTagColor: css({
backgroundColor: theme.colors.background.secondary,
borderColor: theme.components.input.borderColor,
color: theme.colors.text.primary,
}),
nameStyle: css({
maxWidth: '25ch',

View File

@ -25,6 +25,8 @@ export interface Props {
addOnBlur?: boolean;
/** Toggle invalid state */
invalid?: boolean;
/** Colours the tags 'randomly' based on the name. Defaults to true */
autoColors?: boolean;
}
export const TagsInput = ({
@ -37,6 +39,7 @@ export const TagsInput = ({
addOnBlur,
invalid,
id,
autoColors = true,
}: Props) => {
const [newTagName, setNewTagName] = useState('');
const styles = useStyles2(getStyles);
@ -96,7 +99,7 @@ export const TagsInput = ({
{tags?.length > 0 && (
<ul className={styles.tags}>
{tags.map((tag) => (
<TagItem key={tag} name={tag} onRemove={onRemove} disabled={disabled} />
<TagItem key={tag} name={tag} onRemove={onRemove} disabled={disabled} autoColors={autoColors} />
))}
</ul>
)}