From ed27d76d7fb921dbb763b4b79bfd356fb0c5b614 Mon Sep 17 00:00:00 2001 From: Juan Cabanas Date: Wed, 23 Apr 2025 09:13:58 -0300 Subject: [PATCH] Grafana UI: Add `ref` to `TagsInput` (#104344) --- .../src/components/TagsInput/TagsInput.tsx | 152 +++++++++--------- 1 file changed, 80 insertions(+), 72 deletions(-) diff --git a/packages/grafana-ui/src/components/TagsInput/TagsInput.tsx b/packages/grafana-ui/src/components/TagsInput/TagsInput.tsx index d0d72febaf0..bb7f23cd332 100644 --- a/packages/grafana-ui/src/components/TagsInput/TagsInput.tsx +++ b/packages/grafana-ui/src/components/TagsInput/TagsInput.tsx @@ -1,5 +1,5 @@ import { css, cx } from '@emotion/css'; -import { useCallback, useState } from 'react'; +import { useCallback, useState, forwardRef } from 'react'; import * as React from 'react'; import { GrafanaTheme2 } from '@grafana/data'; @@ -29,83 +29,91 @@ export interface Props { autoColors?: boolean; } -export const TagsInput = ({ - placeholder = 'New tag (enter key to add)', - tags = [], - onChange, - width, - className, - disabled, - addOnBlur, - invalid, - id, - autoColors = true, -}: Props) => { - const [newTagName, setNewTagName] = useState(''); - const styles = useStyles2(getStyles); - const theme = useTheme2(); +export const TagsInput = forwardRef( + ( + { + placeholder = 'New tag (enter key to add)', + tags = [], + onChange, + width, + className, + disabled, + addOnBlur, + invalid, + id, + autoColors = true, + }, + ref + ) => { + const [newTagName, setNewTagName] = useState(''); + const styles = useStyles2(getStyles); + const theme = useTheme2(); - const onNameChange = useCallback((event: React.ChangeEvent) => { - setNewTagName(event.target.value); - }, []); + const onNameChange = useCallback((event: React.ChangeEvent) => { + setNewTagName(event.target.value); + }, []); - const onRemove = (tagToRemove: string) => { - onChange(tags.filter((x) => x !== tagToRemove)); - }; + const onRemove = (tagToRemove: string) => { + onChange(tags.filter((x) => x !== tagToRemove)); + }; - const onAdd = (event?: React.MouseEvent | React.KeyboardEvent) => { - event?.preventDefault(); - if (!tags.includes(newTagName)) { - onChange(tags.concat(newTagName)); - } - setNewTagName(''); - }; + const onAdd = (event?: React.MouseEvent | React.KeyboardEvent) => { + event?.preventDefault(); + if (!tags.includes(newTagName)) { + onChange(tags.concat(newTagName)); + } + setNewTagName(''); + }; - const onBlur = () => { - if (addOnBlur && newTagName) { - onAdd(); - } - }; + const onBlur = () => { + if (addOnBlur && newTagName) { + onAdd(); + } + }; - const onKeyboardAdd = (event: React.KeyboardEvent) => { - if (event.key === 'Enter' && newTagName !== '') { - onAdd(event); - } - }; + const onKeyboardAdd = (event: React.KeyboardEvent) => { + if (event.key === 'Enter' && newTagName !== '') { + onAdd(event); + } + }; - return ( -
- - Add - - } - /> - {tags?.length > 0 && ( -
    - {tags.map((tag) => ( - - ))} -
- )} -
- ); -}; + return ( +
+ + Add + + } + /> + {tags?.length > 0 && ( +
    + {tags.map((tag) => ( + + ))} +
+ )} +
+ ); + } +); + +TagsInput.displayName = 'TagsInput'; const getStyles = (theme: GrafanaTheme2) => ({ wrapper: css({