Browse Source

Refactor buttons (#17611)

Tobias Skarhed 6 years ago
parent
commit
6de75de755

+ 12 - 24
packages/grafana-ui/src/components/Button/AbstractButton.tsx

@@ -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,

+ 3 - 9
packages/grafana-ui/src/components/Button/Button.story.tsx

@@ -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 - 72
packages/grafana-ui/src/components/Button/Button.tsx

@@ -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 - 3
packages/grafana-ui/src/components/CallToActionCard/CallToActionCard.story.tsx

@@ -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(

+ 3 - 3
public/app/core/components/EmptyListCTA/EmptyListCTA.tsx

@@ -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} />;

+ 2 - 3
public/app/features/explore/LiveLogs.tsx

@@ -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

+ 3 - 3
public/app/features/explore/NoDataSourceCallToAction.tsx

@@ -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`

+ 3 - 4
public/app/features/plugins/wrappers/AppConfigWrapper.tsx

@@ -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>
             )}