Button/Link Focus: Use focus-visible for keyboard focus (#33066)

* outside react approach

* fixed ts issues and updated radio button

* css only solution

* Removed a bit

* Updated radio button design and fixed focus state on ToolbarButton

* Fixes

* Added missing fullWidth
This commit is contained in:
Torkel Ödegaard
2021-04-16 15:22:31 +02:00
committed by GitHub
parent 555da77527
commit 733bb45172
11 changed files with 152 additions and 165 deletions

View File

@ -5,7 +5,7 @@ import { IconName } from '../../types/icon';
import { getPropertiesForButtonSize } from '../Forms/commonStyles';
import { colorManipulator, GrafanaTheme, GrafanaThemeV2, ThemePaletteColor } from '@grafana/data';
import { ComponentSize } from '../../types/size';
import { getFocusStyles } from '../../themes/mixins';
import { getFocusStyles, getMouseFocusStyles } from '../../themes/mixins';
import { Icon } from '../Icon/Icon';
export type ButtonVariant = 'primary' | 'secondary' | 'destructive' | 'link';
@ -34,7 +34,7 @@ export const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
});
return (
<button className={cx(styles.button, className)} {...otherProps} ref={ref}>
<button className={cx(styles.button, className)} {...otherProps}>
{icon && <Icon name={icon} size={size} className={styles.icon} />}
{children && <span className={styles.content}>{children}</span>}
</button>
@ -47,7 +47,21 @@ Button.displayName = 'Button';
type ButtonLinkProps = CommonProps & ButtonHTMLAttributes<HTMLButtonElement> & AnchorHTMLAttributes<HTMLAnchorElement>;
export const LinkButton = React.forwardRef<HTMLAnchorElement, ButtonLinkProps>(
({ variant = 'primary', size = 'md', icon, fullWidth, children, className, disabled, ...otherProps }, ref) => {
(
{
variant = 'primary',
size = 'md',
icon,
fullWidth,
children,
className,
onBlur,
onFocus,
disabled,
...otherProps
},
ref
) => {
const theme = useTheme();
const styles = getButtonStyles({
theme,
@ -60,7 +74,7 @@ export const LinkButton = React.forwardRef<HTMLAnchorElement, ButtonLinkProps>(
const linkButtonStyles = cx(styles.button, { [styles.disabled]: disabled }, className);
return (
<a className={linkButtonStyles} {...otherProps} ref={ref} tabIndex={disabled ? -1 : 0}>
<a className={linkButtonStyles} {...otherProps} tabIndex={disabled ? -1 : 0}>
{icon && <Icon name={icon} size={size} className={styles.icon} />}
{children && <span className={styles.content}>{children}</span>}
</a>
@ -99,6 +113,8 @@ export const getButtonStyles = (props: StyleProps) => {
},
};
const focusStyle = getFocusStyles(theme.v2);
return {
button: css({
label: 'button',
@ -114,6 +130,9 @@ export const getButtonStyles = (props: StyleProps) => {
verticalAlign: 'middle',
cursor: 'pointer',
borderRadius: theme.v2.shape.borderRadius(1),
'&:focus': focusStyle,
'&:focus-visible': focusStyle,
'&:focus:not(:focus-visible)': getMouseFocusStyles(theme.v2),
...(fullWidth && {
flexGrow: 1,
justifyContent: 'center',
@ -155,10 +174,6 @@ function getButtonVariantStyles(theme: GrafanaThemeV2, color: ThemePaletteColor)
color: color.contrastText,
boxShadow: theme.shadows.z2,
},
'&:focus': {
...getFocusStyles(theme),
},
};
}