Skip to content

Instantly share code, notes, and snippets.

@iMerica
Last active January 30, 2020 23:37
Show Gist options
  • Save iMerica/c1112b61509ddef1693b0abecf9726c7 to your computer and use it in GitHub Desktop.
Save iMerica/c1112b61509ddef1693b0abecf9726c7 to your computer and use it in GitHub Desktop.
Fixes Grommet Focus Issue
import React, { Children, forwardRef, cloneElement, useContext, useState } from "react";
import { StyledButton } from "grommet/components/Button/StyledButton"
import { colorIsDark, normalizeColor } from "grommet/utils/colors"
import { defaultProps } from "grommet"
import { normalizeBackground } from "grommet/utils/background"
import { ThemeContext } from "grommet"
const Button = forwardRef(
(
{
a11yTitle,
color,
children,
disabled,
icon,
focusIndicator = false,
gap = 'small',
fill,
href,
label,
onBlur,
onClick,
onFocus,
onMouseOut,
onMouseOver,
plain,
primary,
reverse,
type = 'button',
as,
...rest
},
ref,
) => {
const theme = useContext(ThemeContext) || defaultProps.theme;
const [focus, setFocus] = useState();
if ((icon || label) && children) {
console.warn(
'Button should not have children if icon or label is provided',
);
}
const isDarkBackground = () => {
const backgroundColor = normalizeBackground(
normalizeColor(
color ||
theme.button.primary.color ||
theme.global.colors.control ||
'brand',
theme,
),
theme,
);
return colorIsDark(backgroundColor, theme);
};
const [hover, setHover] = useState(false);
let buttonIcon = icon;
// only change color if user did not specify the color themselves...
if (primary && icon && !icon.props.color) {
buttonIcon = cloneElement(icon, {
color: theme.global.colors.text[isDarkBackground() ? 'dark' : 'light'],
});
}
const domTag = !as && href ? 'a' : as;
const first = reverse ? label : buttonIcon;
const second = reverse ? buttonIcon : label;
let contents;
if (first && second) {
contents = (
<Box direction="row" align="center" justify="center" gap={gap}>
{first}
{second}
</Box>
);
} else if (typeof children === 'function') {
contents = children({ hover, focus });
} else {
contents = first || second || children;
}
return (
<StyledButton
{...rest}
as={domTag}
ref={ref}
aria-label={a11yTitle}
colorValue={color}
disabled={disabled}
hasIcon={!!icon}
gap={gap}
hasLabel={!!label}
fillContainer={fill}
focus={focus}
focusIndicator={focusIndicator}
href={href}
onClick={onClick}
pad={!plain}
plain={
typeof plain !== 'undefined'
? plain
: Children.count(children) > 0 || (icon && !label)
}
primary={primary}
type={!href ? type : undefined}>
{contents}
</StyledButton>
);
},
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment