mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Refactor buttons (#17611)
This commit is contained in:
parent
8192fa538e
commit
6de75de755
@ -4,21 +4,9 @@ import { css, cx } from 'emotion';
|
||||
import { Themeable, GrafanaTheme } from '../../types';
|
||||
import { selectThemeVariant } from '../../themes/selectThemeVariant';
|
||||
|
||||
export enum ButtonVariant {
|
||||
Primary = 'primary',
|
||||
Secondary = 'secondary',
|
||||
Danger = 'danger',
|
||||
Inverse = 'inverse',
|
||||
Transparent = 'transparent',
|
||||
}
|
||||
export type ButtonVariant = 'primary' | 'secondary' | 'danger' | 'inverse' | 'transparent';
|
||||
|
||||
export enum ButtonSize {
|
||||
ExtraSmall = 'xs',
|
||||
Small = 'sm',
|
||||
Medium = 'md',
|
||||
Large = 'lg',
|
||||
ExtraLarge = 'xl',
|
||||
}
|
||||
export type ButtonSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';
|
||||
|
||||
export interface CommonButtonProps {
|
||||
size?: ButtonSize;
|
||||
@ -69,19 +57,19 @@ const getButtonStyles = (theme: GrafanaTheme, size: ButtonSize, variant: ButtonV
|
||||
fontWeight = theme.typography.weight.semibold;
|
||||
|
||||
switch (size) {
|
||||
case ButtonSize.Small:
|
||||
case 'sm':
|
||||
padding = `${theme.spacing.xs} ${theme.spacing.sm}`;
|
||||
fontSize = theme.typography.size.sm;
|
||||
iconDistance = theme.spacing.xs;
|
||||
height = theme.height.sm;
|
||||
break;
|
||||
case ButtonSize.Medium:
|
||||
case 'md':
|
||||
padding = `${theme.spacing.sm} ${theme.spacing.md}`;
|
||||
fontSize = theme.typography.size.md;
|
||||
iconDistance = theme.spacing.sm;
|
||||
height = theme.height.md;
|
||||
break;
|
||||
case ButtonSize.Large:
|
||||
case 'lg':
|
||||
padding = `${theme.spacing.md} ${theme.spacing.lg}`;
|
||||
fontSize = theme.typography.size.lg;
|
||||
fontWeight = theme.typography.weight.regular;
|
||||
@ -96,16 +84,16 @@ const getButtonStyles = (theme: GrafanaTheme, size: ButtonSize, variant: ButtonV
|
||||
}
|
||||
|
||||
switch (variant) {
|
||||
case ButtonVariant.Primary:
|
||||
case 'primary':
|
||||
background = buttonVariantStyles(theme.colors.greenBase, theme.colors.greenShade, theme.colors.white);
|
||||
break;
|
||||
case ButtonVariant.Secondary:
|
||||
case 'secondary':
|
||||
background = buttonVariantStyles(theme.colors.blueBase, theme.colors.blueShade, theme.colors.white);
|
||||
break;
|
||||
case ButtonVariant.Danger:
|
||||
case 'danger':
|
||||
background = buttonVariantStyles(theme.colors.redBase, theme.colors.redShade, theme.colors.white);
|
||||
break;
|
||||
case ButtonVariant.Inverse:
|
||||
case 'inverse':
|
||||
const from = selectThemeVariant({ light: theme.colors.gray5, dark: theme.colors.dark6 }, theme.type) as string;
|
||||
const to = selectThemeVariant(
|
||||
{
|
||||
@ -121,7 +109,7 @@ const getButtonStyles = (theme: GrafanaTheme, size: ButtonSize, variant: ButtonV
|
||||
|
||||
background = buttonVariantStyles(from, to, theme.colors.link, 'rgba(0, 0, 0, 0.1)', true);
|
||||
break;
|
||||
case ButtonVariant.Transparent:
|
||||
case 'transparent':
|
||||
background = css`
|
||||
${buttonVariantStyles('', '', theme.colors.link, 'rgba(0, 0, 0, 0.1)', true)};
|
||||
background: transparent;
|
||||
@ -170,8 +158,8 @@ const getButtonStyles = (theme: GrafanaTheme, size: ButtonSize, variant: ButtonV
|
||||
export const AbstractButton: React.FunctionComponent<AbstractButtonProps> = ({
|
||||
renderAs,
|
||||
theme,
|
||||
size = ButtonSize.Medium,
|
||||
variant = ButtonVariant.Primary,
|
||||
size = 'md',
|
||||
variant = 'primary',
|
||||
className,
|
||||
icon,
|
||||
children,
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { storiesOf } from '@storybook/react';
|
||||
import { Button, LinkButton } from './Button';
|
||||
import { ButtonSize, ButtonVariant, CommonButtonProps } from './AbstractButton';
|
||||
import { CommonButtonProps } from './AbstractButton';
|
||||
// @ts-ignore
|
||||
import withPropsCombinations from 'react-storybook-addon-props-combinations';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
@ -15,14 +15,8 @@ const defaultProps = {
|
||||
};
|
||||
|
||||
const variants = {
|
||||
size: [ButtonSize.ExtraSmall, ButtonSize.Small, ButtonSize.Medium, ButtonSize.Large, ButtonSize.ExtraLarge],
|
||||
variant: [
|
||||
ButtonVariant.Primary,
|
||||
ButtonVariant.Secondary,
|
||||
ButtonVariant.Danger,
|
||||
ButtonVariant.Inverse,
|
||||
ButtonVariant.Transparent,
|
||||
],
|
||||
size: ['xs', 'sm', 'md', 'lg', 'xl'],
|
||||
variant: ['primary', 'secondary', 'danger', 'inverse', 'transparent'],
|
||||
};
|
||||
const combinationOptions = {
|
||||
CombinationRenderer: ThemeableCombinationsRowRenderer,
|
||||
|
@ -1,36 +1,7 @@
|
||||
import React, { useContext } from 'react';
|
||||
import { AbstractButton, ButtonProps, ButtonSize, LinkButtonProps } from './AbstractButton';
|
||||
import { AbstractButton, ButtonProps, LinkButtonProps } from './AbstractButton';
|
||||
import { ThemeContext } from '../../themes';
|
||||
|
||||
const getSizeNameComponentSegment = (size: ButtonSize) => {
|
||||
switch (size) {
|
||||
case ButtonSize.ExtraSmall:
|
||||
return 'ExtraSmall';
|
||||
case ButtonSize.Small:
|
||||
return 'Small';
|
||||
case ButtonSize.Large:
|
||||
return 'Large';
|
||||
case ButtonSize.ExtraLarge:
|
||||
return 'ExtraLarge';
|
||||
default:
|
||||
return 'Medium';
|
||||
}
|
||||
};
|
||||
|
||||
const buttonFactory: <T>(renderAs: string, size: ButtonSize, displayName: string) => React.ComponentType<T> = (
|
||||
renderAs,
|
||||
size,
|
||||
displayName
|
||||
) => {
|
||||
const ButtonComponent: React.FunctionComponent<any> = props => {
|
||||
const theme = useContext(ThemeContext);
|
||||
return <AbstractButton {...props} size={size} renderAs={renderAs} theme={theme} />;
|
||||
};
|
||||
ButtonComponent.displayName = displayName;
|
||||
|
||||
return ButtonComponent;
|
||||
};
|
||||
|
||||
export const Button: React.FunctionComponent<ButtonProps> = props => {
|
||||
const theme = useContext(ThemeContext);
|
||||
return <AbstractButton {...props} renderAs="button" theme={theme} />;
|
||||
@ -42,45 +13,3 @@ export const LinkButton: React.FunctionComponent<LinkButtonProps> = props => {
|
||||
return <AbstractButton {...props} renderAs="a" theme={theme} />;
|
||||
};
|
||||
LinkButton.displayName = 'LinkButton';
|
||||
|
||||
export const ExtraSmallButton = buttonFactory<ButtonProps>(
|
||||
'button',
|
||||
ButtonSize.ExtraSmall,
|
||||
`${getSizeNameComponentSegment(ButtonSize.ExtraSmall)}Button`
|
||||
);
|
||||
export const SmallButton = buttonFactory<ButtonProps>(
|
||||
'button',
|
||||
ButtonSize.Small,
|
||||
`${getSizeNameComponentSegment(ButtonSize.Small)}Button`
|
||||
);
|
||||
export const LargeButton = buttonFactory<ButtonProps>(
|
||||
'button',
|
||||
ButtonSize.Large,
|
||||
`${getSizeNameComponentSegment(ButtonSize.Large)}Button`
|
||||
);
|
||||
export const ExtraLargeButton = buttonFactory<ButtonProps>(
|
||||
'button',
|
||||
ButtonSize.ExtraLarge,
|
||||
`${getSizeNameComponentSegment(ButtonSize.ExtraLarge)}Button`
|
||||
);
|
||||
|
||||
export const ExtraSmallLinkButton = buttonFactory<LinkButtonProps>(
|
||||
'a',
|
||||
ButtonSize.ExtraSmall,
|
||||
`${getSizeNameComponentSegment(ButtonSize.ExtraSmall)}LinkButton`
|
||||
);
|
||||
export const SmallLinkButton = buttonFactory<LinkButtonProps>(
|
||||
'a',
|
||||
ButtonSize.Small,
|
||||
`${getSizeNameComponentSegment(ButtonSize.Small)}LinkButton`
|
||||
);
|
||||
export const LargeLinkButton = buttonFactory<LinkButtonProps>(
|
||||
'a',
|
||||
ButtonSize.Large,
|
||||
`${getSizeNameComponentSegment(ButtonSize.Large)}LinkButton`
|
||||
);
|
||||
export const ExtraLargeLinkButton = buttonFactory<LinkButtonProps>(
|
||||
'a',
|
||||
ButtonSize.ExtraLarge,
|
||||
`${getSizeNameComponentSegment(ButtonSize.ExtraLarge)}LinkButton`
|
||||
);
|
||||
|
@ -3,7 +3,7 @@ import { storiesOf } from '@storybook/react';
|
||||
import { renderComponentWithTheme } from '../../utils/storybook/withTheme';
|
||||
import { CallToActionCard } from './CallToActionCard';
|
||||
import { select, text } from '@storybook/addon-knobs';
|
||||
import { LargeButton } from '../Button/Button';
|
||||
import { Button } from '../Button/Button';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
|
||||
const CallToActionCardStories = storiesOf('UI/CallToActionCard', module);
|
||||
@ -12,9 +12,9 @@ CallToActionCardStories.add('default', () => {
|
||||
const ctaElements: { [key: string]: JSX.Element } = {
|
||||
custom: <h1>This is just H1 tag, you can any component as CTA element</h1>,
|
||||
button: (
|
||||
<LargeButton icon="fa fa-plus" onClick={action('cta button clicked')}>
|
||||
<Button size="lg" icon="fa fa-plus" onClick={action('cta button clicked')}>
|
||||
Add datasource
|
||||
</LargeButton>
|
||||
</Button>
|
||||
),
|
||||
};
|
||||
const ctaElement = select(
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React, { useContext } from 'react';
|
||||
import { CallToActionCard, LargeLinkButton, ThemeContext } from '@grafana/ui';
|
||||
import { CallToActionCard, LinkButton, ThemeContext } from '@grafana/ui';
|
||||
import { css } from 'emotion';
|
||||
export interface Props {
|
||||
model: any;
|
||||
@ -37,9 +37,9 @@ const EmptyListCTA: React.FunctionComponent<Props> = props => {
|
||||
: '';
|
||||
|
||||
const ctaElement = (
|
||||
<LargeLinkButton onClick={onClick} href={buttonLink} icon={buttonIcon} className={ctaElementClassName}>
|
||||
<LinkButton size="lg" onClick={onClick} href={buttonLink} icon={buttonIcon} className={ctaElementClassName}>
|
||||
{buttonTitle}
|
||||
</LargeLinkButton>
|
||||
</LinkButton>
|
||||
);
|
||||
|
||||
return <CallToActionCard message={title} footer={footer} callToActionElement={ctaElement} theme={theme} />;
|
||||
|
@ -11,7 +11,6 @@ import {
|
||||
} from '@grafana/ui';
|
||||
|
||||
import ElapsedTime from './ElapsedTime';
|
||||
import { ButtonSize, ButtonVariant } from '@grafana/ui/src/components/Button/AbstractButton';
|
||||
|
||||
const getStyles = (theme: GrafanaTheme) => ({
|
||||
logsRowsLive: css`
|
||||
@ -110,8 +109,8 @@ class LiveLogs extends PureComponent<Props, State> {
|
||||
</span>
|
||||
<LinkButton
|
||||
onClick={this.props.stopLive}
|
||||
size={ButtonSize.Medium}
|
||||
variant={ButtonVariant.Transparent}
|
||||
size="md"
|
||||
variant="transparent"
|
||||
style={{ color: theme.colors.orange }}
|
||||
>
|
||||
Stop Live
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React, { useContext } from 'react';
|
||||
import { css } from 'emotion';
|
||||
import { ThemeContext, LargeLinkButton, CallToActionCard } from '@grafana/ui';
|
||||
import { ThemeContext, LinkButton, CallToActionCard } from '@grafana/ui';
|
||||
|
||||
export const NoDataSourceCallToAction = () => {
|
||||
const theme = useContext(ThemeContext);
|
||||
@ -22,9 +22,9 @@ export const NoDataSourceCallToAction = () => {
|
||||
);
|
||||
|
||||
const ctaElement = (
|
||||
<LargeLinkButton href="/datasources/new" icon="gicon gicon-datasources">
|
||||
<LinkButton size="lg" href="/datasources/new" icon="gicon gicon-datasources">
|
||||
Add data source
|
||||
</LargeLinkButton>
|
||||
</LinkButton>
|
||||
);
|
||||
|
||||
const cardClassName = css`
|
||||
|
@ -7,7 +7,6 @@ import { PluginMeta, AppPlugin, Button } from '@grafana/ui';
|
||||
|
||||
import { AngularComponent, getAngularLoader } from '@grafana/runtime';
|
||||
import { getBackendSrv } from 'app/core/services/backend_srv';
|
||||
import { ButtonVariant } from '@grafana/ui/src/components/Button/AbstractButton';
|
||||
import { css } from 'emotion';
|
||||
|
||||
interface Props {
|
||||
@ -71,17 +70,17 @@ export class AppConfigCtrlWrapper extends PureComponent<Props, State> {
|
||||
{model && (
|
||||
<div className="gf-form">
|
||||
{!model.enabled && (
|
||||
<Button variant={ButtonVariant.Primary} onClick={this.enable} className={withRightMargin}>
|
||||
<Button variant="primary" onClick={this.enable} className={withRightMargin}>
|
||||
Enable
|
||||
</Button>
|
||||
)}
|
||||
{model.enabled && (
|
||||
<Button variant={ButtonVariant.Primary} onClick={this.update} className={withRightMargin}>
|
||||
<Button variant="primary" onClick={this.update} className={withRightMargin}>
|
||||
Update
|
||||
</Button>
|
||||
)}
|
||||
{model.enabled && (
|
||||
<Button variant={ButtonVariant.Danger} onClick={this.disable} className={withRightMargin}>
|
||||
<Button variant="danger" onClick={this.disable} className={withRightMargin}>
|
||||
Disable
|
||||
</Button>
|
||||
)}
|
||||
|
Loading…
Reference in New Issue
Block a user