From cc9e70be5cd8b933bbd086d18eea6067bc7b99e5 Mon Sep 17 00:00:00 2001 From: kay delaney <45561153+kaydelaney@users.noreply.github.com> Date: Mon, 10 Jan 2022 15:41:19 +0000 Subject: [PATCH] Tags: Make Tags component more a11y-friendly (#43808) --- .../grafana-ui/src/components/Tags/Tag.tsx | 25 +++++++++++-------- .../src/components/Tags/TagList.tsx | 19 +++++++++----- .../features/search/components/SearchItem.tsx | 2 +- 3 files changed, 28 insertions(+), 18 deletions(-) diff --git a/packages/grafana-ui/src/components/Tags/Tag.tsx b/packages/grafana-ui/src/components/Tags/Tag.tsx index fb7bfe8c536..c4c05dc9c48 100644 --- a/packages/grafana-ui/src/components/Tags/Tag.tsx +++ b/packages/grafana-ui/src/components/Tags/Tag.tsx @@ -22,19 +22,20 @@ export const Tag = forwardRef(({ name, onClick, className, c const styles = getTagStyles(theme, name, colorIndex); const onTagClick = (event: React.MouseEvent) => { - if (onClick) { - onClick(name, event); - } + event.preventDefault(); + event.stopPropagation(); + + onClick?.(name, event); }; - return ( - + const classes = cx(styles.wrapper, className, { [styles.hover]: onClick !== undefined }); + + return onClick ? ( + + ) : ( + {name} ); @@ -51,6 +52,8 @@ const getTagStyles = (theme: GrafanaTheme, name: string, colorIndex?: number) => } return { wrapper: css` + appearance: none; + border-style: none; font-weight: ${theme.typography.weight.semibold}; font-size: ${theme.typography.size.sm}; line-height: ${theme.typography.lineHeight.xs}; diff --git a/packages/grafana-ui/src/components/Tags/TagList.tsx b/packages/grafana-ui/src/components/Tags/TagList.tsx index 320898790bd..6d82cc2a64b 100644 --- a/packages/grafana-ui/src/components/Tags/TagList.tsx +++ b/packages/grafana-ui/src/components/Tags/TagList.tsx @@ -10,21 +10,24 @@ export interface Props { onClick?: OnTagClick; /** Custom styles for the wrapper component */ className?: string; + /** aria-label for the `i`-th Tag component */ + getAriaLabel?: (name: string, i: number) => string; } -export const TagList: FC = memo(({ displayMax, tags, onClick, className }) => { +export const TagList: FC = memo(({ displayMax, tags, onClick, className, getAriaLabel }) => { const theme = useTheme2(); const styles = getStyles(theme, Boolean(displayMax && displayMax > 0)); const numTags = tags.length; const tagsToDisplay = displayMax ? tags.slice(0, displayMax) : tags; - return ( - - {tagsToDisplay.map((tag) => ( - +
    + {tagsToDisplay.map((tag, i) => ( +
  • + +
  • ))} {displayMax && displayMax > 0 && numTags - 1 > 0 && + {numTags - 1}} - +
); }); @@ -33,6 +36,7 @@ TagList.displayName = 'TagList'; const getStyles = (theme: GrafanaTheme2, isTruncated: boolean) => { return { wrapper: css` + position: relative; align-items: ${isTruncated ? 'center' : 'unset'}; display: flex; flex: 1 1 auto; @@ -45,5 +49,8 @@ const getStyles = (theme: GrafanaTheme2, isTruncated: boolean) => { color: ${theme.colors.text.secondary}; font-size: ${theme.typography.size.sm}; `, + li: css({ + listStyle: 'none', + }), }; }; diff --git a/public/app/features/search/components/SearchItem.tsx b/public/app/features/search/components/SearchItem.tsx index 5ba6b4449f8..920bd52e1f8 100644 --- a/public/app/features/search/components/SearchItem.tsx +++ b/public/app/features/search/components/SearchItem.tsx @@ -78,7 +78,7 @@ export const SearchItem: FC = ({ item, editable, onToggleChecked, onTagSe )} - + `Filter by tag "${tag}"`} /> );