Commit 6dde81d8 by Andrej Ocenas Committed by GitHub

grafana/ui: fix button icon styles (#20084)

Fix spacing and margins in case you use icon only button.
parent a5e8e0e2
...@@ -24,8 +24,13 @@ export const Button: React.FunctionComponent<ButtonProps> = props => { ...@@ -24,8 +24,13 @@ export const Button: React.FunctionComponent<ButtonProps> = props => {
// Default this to 'button', otherwise html defaults to 'submit' which then submits any form it is in. // Default this to 'button', otherwise html defaults to 'submit' which then submits any form it is in.
buttonProps.type = buttonProps.type || 'button'; buttonProps.type = buttonProps.type || 'button';
const styles = const styles: ButtonStyles =
stylesProp || getButtonStyles({ theme, size: size || 'md', variant: variant || 'primary', withIcon: !!icon }); stylesProp ||
getButtonStyles({
theme,
size: size || 'md',
variant: variant || 'primary',
});
return ( return (
<button className={cx(styles.button, className)} {...buttonProps}> <button className={cx(styles.button, className)} {...buttonProps}>
...@@ -46,8 +51,13 @@ type LinkButtonProps = CommonProps & ...@@ -46,8 +51,13 @@ type LinkButtonProps = CommonProps &
export const LinkButton: React.FunctionComponent<LinkButtonProps> = props => { export const LinkButton: React.FunctionComponent<LinkButtonProps> = props => {
const theme = useContext(ThemeContext); const theme = useContext(ThemeContext);
const { size, variant, icon, children, className, styles: stylesProp, ...anchorProps } = props; const { size, variant, icon, children, className, styles: stylesProp, ...anchorProps } = props;
const styles = const styles: ButtonStyles =
stylesProp || getButtonStyles({ theme, size: size || 'md', variant: variant || 'primary', withIcon: !!icon }); stylesProp ||
getButtonStyles({
theme,
size: size || 'md',
variant: variant || 'primary',
});
return ( return (
<a className={cx(styles.button, className)} {...anchorProps}> <a className={cx(styles.button, className)} {...anchorProps}>
......
import React from 'react'; import React from 'react';
import cx from 'classnames'; import cx from 'classnames';
import { css } from 'emotion';
import { stylesFactory } from '../../themes';
const getStyles = stylesFactory(() => ({
content: css`
white-space: nowrap;
`,
}));
type Props = { type Props = {
icon?: string; icon?: string;
className: string; className?: string;
iconClassName: string; iconClassName?: string;
children: React.ReactNode; children: React.ReactNode;
}; };
export function ButtonContent(props: Props) { export function ButtonContent(props: Props) {
const { icon, className, iconClassName, children } = props; const { icon, className, iconClassName, children } = props;
const styles = getStyles();
return icon ? ( return icon ? (
<span className={className}> <span className={cx(styles.content, className)}>
<i className={cx([icon, iconClassName])} /> <i className={cx([icon, iconClassName])} />
&nbsp; &nbsp;
<span>{children}</span> <span>{children}</span>
</span> </span>
) : ( ) : (
<>{children}</> <span className={styles.content}>{children}</span>
); );
} }
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Button renders correct html 1`] = `"<button class=\\"css-pdywgc-button\\" type=\\"button\\"><span class=\\"css-1dxly9g-button-icon-wrap\\"><i class=\\"fa fa-plus css-iu6xgj-button-icon\\"></i><span>Click me</span></span></button>"`; exports[`Button renders correct html 1`] = `"<button class=\\"css-1ffx2x7-button\\" type=\\"button\\"><span class=\\"css-16tmax3 css-1dxly9g-button-icon-wrap\\"><i class=\\"fa fa-plus\\"></i>&nbsp; &nbsp;<span>Click me</span></span></button>"`;
exports[`LinkButton renders correct html 1`] = `"<a class=\\"css-pdywgc-button\\"><span class=\\"css-1dxly9g-button-icon-wrap\\"><i class=\\"fa fa-plus css-iu6xgj-button-icon\\"></i><span>Click me</span></span></a>"`; exports[`LinkButton renders correct html 1`] = `"<a class=\\"css-1ffx2x7-button\\"><span class=\\"css-16tmax3 css-1dxly9g-button-icon-wrap\\"><i class=\\"fa fa-plus\\"></i>&nbsp; &nbsp;<span>Click me</span></span></a>"`;
...@@ -24,12 +24,11 @@ const buttonVariantStyles = ( ...@@ -24,12 +24,11 @@ const buttonVariantStyles = (
} }
`; `;
export const getButtonStyles = stylesFactory(({ theme, size, variant, withIcon }: StyleDeps) => { export const getButtonStyles = stylesFactory(({ theme, size, variant }: StyleDeps) => {
const borderRadius = theme.border.radius.sm; const borderRadius = theme.border.radius.sm;
let padding, let padding,
background, background,
fontSize, fontSize,
iconDistance,
height, height,
fontWeight = theme.typography.weight.semibold; fontWeight = theme.typography.weight.semibold;
...@@ -37,14 +36,12 @@ export const getButtonStyles = stylesFactory(({ theme, size, variant, withIcon } ...@@ -37,14 +36,12 @@ export const getButtonStyles = stylesFactory(({ theme, size, variant, withIcon }
case 'sm': case 'sm':
padding = `${theme.spacing.xs} ${theme.spacing.sm}`; padding = `${theme.spacing.xs} ${theme.spacing.sm}`;
fontSize = theme.typography.size.sm; fontSize = theme.typography.size.sm;
iconDistance = theme.spacing.xs;
height = theme.height.sm; height = theme.height.sm;
break; break;
case 'md': case 'md':
padding = `${theme.spacing.sm} ${theme.spacing.md}`; padding = `${theme.spacing.sm} ${theme.spacing.md}`;
fontSize = theme.typography.size.md; fontSize = theme.typography.size.md;
iconDistance = theme.spacing.sm;
height = theme.height.md; height = theme.height.md;
break; break;
...@@ -52,13 +49,11 @@ export const getButtonStyles = stylesFactory(({ theme, size, variant, withIcon } ...@@ -52,13 +49,11 @@ export const getButtonStyles = stylesFactory(({ theme, size, variant, withIcon }
padding = `${theme.spacing.md} ${theme.spacing.lg}`; padding = `${theme.spacing.md} ${theme.spacing.lg}`;
fontSize = theme.typography.size.lg; fontSize = theme.typography.size.lg;
fontWeight = theme.typography.weight.regular; fontWeight = theme.typography.weight.regular;
iconDistance = theme.spacing.sm;
height = theme.height.lg; height = theme.height.lg;
break; break;
default: default:
padding = `${theme.spacing.sm} ${theme.spacing.md}`; padding = `${theme.spacing.sm} ${theme.spacing.md}`;
iconDistance = theme.spacing.sm;
fontSize = theme.typography.size.base; fontSize = theme.typography.size.base;
height = theme.height.md; height = theme.height.md;
} }
...@@ -111,7 +106,6 @@ export const getButtonStyles = stylesFactory(({ theme, size, variant, withIcon } ...@@ -111,7 +106,6 @@ export const getButtonStyles = stylesFactory(({ theme, size, variant, withIcon }
font-family: ${theme.typography.fontFamily.sansSerif}; font-family: ${theme.typography.fontFamily.sansSerif};
line-height: ${theme.typography.lineHeight.xs}; line-height: ${theme.typography.lineHeight.xs};
padding: ${padding}; padding: ${padding};
text-align: ${withIcon ? 'left' : 'center'};
vertical-align: middle; vertical-align: middle;
cursor: pointer; cursor: pointer;
border: none; border: none;
...@@ -131,10 +125,5 @@ export const getButtonStyles = stylesFactory(({ theme, size, variant, withIcon } ...@@ -131,10 +125,5 @@ export const getButtonStyles = stylesFactory(({ theme, size, variant, withIcon }
display: flex; display: flex;
align-items: center; align-items: center;
`, `,
icon: css`
label: button-icon;
margin-right: ${iconDistance};
filter: brightness(100);
`,
}; };
}); });
...@@ -8,11 +8,10 @@ export interface StyleDeps { ...@@ -8,11 +8,10 @@ export interface StyleDeps {
theme: GrafanaTheme; theme: GrafanaTheme;
size: ButtonSize; size: ButtonSize;
variant: ButtonVariant; variant: ButtonVariant;
withIcon: boolean;
} }
export interface ButtonStyles { export interface ButtonStyles {
button: string; button: string;
iconWrap: string; iconWrap: string;
icon: string; icon?: string;
} }
...@@ -27,7 +27,6 @@ const getPropertiesForSize = (theme: GrafanaTheme, size: ButtonSize) => { ...@@ -27,7 +27,6 @@ const getPropertiesForSize = (theme: GrafanaTheme, size: ButtonSize) => {
return { return {
padding: `0 ${theme.spacing.sm}`, padding: `0 ${theme.spacing.sm}`,
fontSize: theme.typography.size.sm, fontSize: theme.typography.size.sm,
iconDistance: theme.spacing.xs,
height: theme.height.sm, height: theme.height.sm,
}; };
...@@ -35,7 +34,6 @@ const getPropertiesForSize = (theme: GrafanaTheme, size: ButtonSize) => { ...@@ -35,7 +34,6 @@ const getPropertiesForSize = (theme: GrafanaTheme, size: ButtonSize) => {
return { return {
padding: `0 ${theme.spacing.md}`, padding: `0 ${theme.spacing.md}`,
fontSize: theme.typography.size.md, fontSize: theme.typography.size.md,
iconDistance: theme.spacing.sm,
height: `${theme.spacing.formButtonHeight}px`, height: `${theme.spacing.formButtonHeight}px`,
}; };
...@@ -43,14 +41,12 @@ const getPropertiesForSize = (theme: GrafanaTheme, size: ButtonSize) => { ...@@ -43,14 +41,12 @@ const getPropertiesForSize = (theme: GrafanaTheme, size: ButtonSize) => {
return { return {
padding: `0 ${theme.spacing.lg}`, padding: `0 ${theme.spacing.lg}`,
fontSize: theme.typography.size.lg, fontSize: theme.typography.size.lg,
iconDistance: theme.spacing.sm,
height: theme.height.lg, height: theme.height.lg,
}; };
default: default:
return { return {
padding: `0 ${theme.spacing.md}`, padding: `0 ${theme.spacing.md}`,
iconDistance: theme.spacing.sm,
fontSize: theme.typography.size.base, fontSize: theme.typography.size.base,
height: theme.height.md, height: theme.height.md,
}; };
...@@ -98,8 +94,8 @@ const getPropertiesForVariant = (theme: GrafanaTheme, variant: ButtonVariant) => ...@@ -98,8 +94,8 @@ const getPropertiesForVariant = (theme: GrafanaTheme, variant: ButtonVariant) =>
// Need to do this because of mismatch between variants in standard buttons and here // Need to do this because of mismatch between variants in standard buttons and here
type StyleProps = Omit<StyleDeps, 'variant'> & { variant: ButtonVariant }; type StyleProps = Omit<StyleDeps, 'variant'> & { variant: ButtonVariant };
export const getButtonStyles = stylesFactory(({ theme, size, variant, withIcon }: StyleProps) => { export const getButtonStyles = stylesFactory(({ theme, size, variant }: StyleProps) => {
const { padding, fontSize, iconDistance, height } = getPropertiesForSize(theme, size); const { padding, fontSize, height } = getPropertiesForSize(theme, size);
const { background, borderColor } = getPropertiesForVariant(theme, variant); const { background, borderColor } = getPropertiesForVariant(theme, variant);
return { return {
...@@ -114,7 +110,6 @@ export const getButtonStyles = stylesFactory(({ theme, size, variant, withIcon } ...@@ -114,7 +110,6 @@ export const getButtonStyles = stylesFactory(({ theme, size, variant, withIcon }
font-family: ${theme.typography.fontFamily.sansSerif}; font-family: ${theme.typography.fontFamily.sansSerif};
line-height: ${theme.typography.lineHeight.sm}; line-height: ${theme.typography.lineHeight.sm};
padding: ${padding}; padding: ${padding};
text-align: ${withIcon ? 'left' : 'center'};
vertical-align: middle; vertical-align: middle;
cursor: pointer; cursor: pointer;
border: 1px solid ${borderColor}; border: 1px solid ${borderColor};
...@@ -136,11 +131,6 @@ export const getButtonStyles = stylesFactory(({ theme, size, variant, withIcon } ...@@ -136,11 +131,6 @@ export const getButtonStyles = stylesFactory(({ theme, size, variant, withIcon }
display: flex; display: flex;
align-items: center; align-items: center;
`, `,
icon: css`
label: button-icon;
margin-right: ${iconDistance};
filter: brightness(100);
`,
}; };
}); });
...@@ -163,7 +153,6 @@ export const Button = (props: ButtonProps) => { ...@@ -163,7 +153,6 @@ export const Button = (props: ButtonProps) => {
theme, theme,
size: props.size || 'md', size: props.size || 'md',
variant: props.variant || 'primary', variant: props.variant || 'primary',
withIcon: !!props.icon,
}); });
return <DefaultButton {...props} styles={styles} />; return <DefaultButton {...props} styles={styles} />;
}; };
...@@ -175,7 +164,6 @@ export const LinkButton = (props: ButtonLinkProps) => { ...@@ -175,7 +164,6 @@ export const LinkButton = (props: ButtonLinkProps) => {
theme, theme,
size: props.size || 'md', size: props.size || 'md',
variant: props.variant || 'primary', variant: props.variant || 'primary',
withIcon: !!props.icon,
}); });
return <DefaultLinkButton {...props} styles={styles} />; return <DefaultLinkButton {...props} styles={styles} />;
}; };
...@@ -3,13 +3,20 @@ import { GrafanaTheme } from '@grafana/data'; ...@@ -3,13 +3,20 @@ import { GrafanaTheme } from '@grafana/data';
import { getLabelStyles } from './Label'; import { getLabelStyles } from './Label';
import { getLegendStyles } from './Legend'; import { getLegendStyles } from './Legend';
import { getFieldValidationMessageStyles } from './FieldValidationMessage'; import { getFieldValidationMessageStyles } from './FieldValidationMessage';
import { getButtonStyles } from './Button'; import { getButtonStyles, ButtonVariant } from './Button';
import { ButtonSize } from '../Button/types';
export const getFormStyles = stylesFactory((theme: GrafanaTheme, options?: any) => { export const getFormStyles = stylesFactory(
return { (theme: GrafanaTheme, options: { variant: ButtonVariant; size: ButtonSize }) => {
...getLabelStyles(theme), return {
...getLegendStyles(theme), ...getLabelStyles(theme),
...getFieldValidationMessageStyles(theme), ...getLegendStyles(theme),
...getButtonStyles({ theme, variant: options.variant, size: options.size, withIcon: options.withIcon }), ...getFieldValidationMessageStyles(theme),
}; ...getButtonStyles({
}); theme,
variant: options.variant,
size: options.size,
}),
};
}
);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment