RadioButton: Make description appear in a Tooltip component (#78010)
This commit is contained in:
@@ -10,6 +10,9 @@
|
||||
* @alpha
|
||||
*/
|
||||
export const Components = {
|
||||
RadioButton: {
|
||||
container: 'data-testid radio-button',
|
||||
},
|
||||
Breadcrumbs: {
|
||||
breadcrumb: (title: string) => `data-testid ${title} breadcrumb`,
|
||||
},
|
||||
|
||||
@@ -2,10 +2,11 @@ import { css } from '@emotion/css';
|
||||
import React from 'react';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { StringSelector } from '@grafana/e2e-selectors';
|
||||
import { StringSelector, selectors } from '@grafana/e2e-selectors';
|
||||
|
||||
import { useStyles2 } from '../../../themes';
|
||||
import { getFocusStyles, getMouseFocusStyles } from '../../../themes/mixins';
|
||||
import { Tooltip } from '../../Tooltip/Tooltip';
|
||||
import { getPropertiesForButtonSize } from '../commonStyles';
|
||||
|
||||
export type RadioButtonSize = 'sm' | 'md';
|
||||
@@ -43,20 +44,32 @@ export const RadioButton = React.forwardRef<HTMLInputElement, RadioButtonProps>(
|
||||
) => {
|
||||
const styles = useStyles2(getRadioButtonStyles, size, fullWidth);
|
||||
|
||||
return (
|
||||
<div className={styles.radioOption}>
|
||||
<input
|
||||
type="radio"
|
||||
className={styles.radio}
|
||||
onChange={onChange}
|
||||
onClick={onClick}
|
||||
disabled={disabled}
|
||||
id={id}
|
||||
checked={active}
|
||||
name={name}
|
||||
aria-label={ariaLabel || description}
|
||||
ref={ref}
|
||||
/>
|
||||
const inputRadioButton = (
|
||||
<input
|
||||
type="radio"
|
||||
className={styles.radio}
|
||||
onChange={onChange}
|
||||
onClick={onClick}
|
||||
disabled={disabled}
|
||||
id={id}
|
||||
checked={active}
|
||||
name={name}
|
||||
aria-label={ariaLabel}
|
||||
ref={ref}
|
||||
/>
|
||||
);
|
||||
return description ? (
|
||||
<div className={styles.radioOption} data-testid={selectors.components.RadioButton.container}>
|
||||
<Tooltip content={description} placement="bottom">
|
||||
{inputRadioButton}
|
||||
</Tooltip>
|
||||
<label className={styles.radioLabel} htmlFor={id} title={description || ariaLabel}>
|
||||
{children}
|
||||
</label>
|
||||
</div>
|
||||
) : (
|
||||
<div className={styles.radioOption} data-testid={selectors.components.RadioButton.container}>
|
||||
{inputRadioButton}
|
||||
<label className={styles.radioLabel} htmlFor={id} title={description || ariaLabel}>
|
||||
{children}
|
||||
</label>
|
||||
@@ -86,15 +99,16 @@ const getRadioButtonStyles = (theme: GrafanaTheme2, size: RadioButtonSize, fullW
|
||||
radio: css({
|
||||
position: 'absolute',
|
||||
opacity: 0,
|
||||
zIndex: -1000,
|
||||
zIndex: 2,
|
||||
width: '100% !important',
|
||||
height: '100%',
|
||||
cursor: 'pointer',
|
||||
|
||||
'&:checked + label': {
|
||||
color: theme.colors.text.primary,
|
||||
fontWeight: theme.typography.fontWeightMedium,
|
||||
background: theme.colors.action.selected,
|
||||
zIndex: 3,
|
||||
zIndex: 1,
|
||||
},
|
||||
|
||||
'&:focus + label, &:focus-visible + label': getFocusStyles(theme),
|
||||
@@ -119,7 +133,6 @@ const getRadioButtonStyles = (theme: GrafanaTheme2, size: RadioButtonSize, fullW
|
||||
borderRadius: theme.shape.radius.default,
|
||||
background: theme.colors.background.primary,
|
||||
cursor: 'pointer',
|
||||
zIndex: 1,
|
||||
userSelect: 'none',
|
||||
whiteSpace: 'nowrap',
|
||||
flexGrow: 1,
|
||||
|
||||
@@ -76,7 +76,7 @@ export function RadioButtonGroup<T>({
|
||||
<div
|
||||
role="radiogroup"
|
||||
aria-label={ariaLabel}
|
||||
className={cx(styles.radioGroup, fullWidth && styles.fullWidth, className)}
|
||||
className={cx(styles.radioGroup, fullWidth && styles.fullWidth, invalid && styles.invalid, className)}
|
||||
>
|
||||
{options.map((opt, i) => {
|
||||
const isItemDisabled = disabledOptions && opt.value && disabledOptions.includes(opt.value);
|
||||
|
||||
@@ -81,15 +81,12 @@ export const Tooltip = React.forwardRef<HTMLElement, TooltipProps>(
|
||||
[forwardedRef, setTriggerRef]
|
||||
);
|
||||
|
||||
// if the child has an aria-label, this should take precedence over the tooltip content
|
||||
const childHasAriaLabel = 'aria-label' in children.props;
|
||||
|
||||
return (
|
||||
<>
|
||||
{React.cloneElement(children, {
|
||||
ref: handleRef,
|
||||
tabIndex: 0, // tooltip trigger should be keyboard focusable
|
||||
'aria-describedby': !childHasAriaLabel && visible ? tooltipId : undefined,
|
||||
'aria-describedby': visible ? tooltipId : undefined,
|
||||
})}
|
||||
{visible && (
|
||||
<Portal>
|
||||
|
||||
Reference in New Issue
Block a user