A basic button React component

A basic button React component.

props:

  • {string} bsClass - Base CSS class and prefix for the component. Generally one should only change bsClass to provide new, non-Bootstrap, CSS styles for a component. default is btn.
  • {'lg'|'large'|'sm'|'small'|'xs'|'xsmall'} bsSize - Component size variations.
  • `{’success’|’warning’|’danger’|’info’|’default’|’primary’|’link’} bsStyle - Component visual or contextual style variants.
  • {bool} active - deafult is false.
  • {bool} block - default is false.
  • {bool} disabled - default is false.
  • {func} onClick - to be invoked on button click.
  • {elementType} componentClass - which component type to render as button - default is <button>.
  • {string} href - an optional url to be provided in order to make the button a hyperlink.
  • {'button'|'reset'|'submit'} type - defines HTML button type attribute - deafult is button.

Use any of the available button style types to quickly create a styled button. Just modify the bsStyle prop.

const buttonsInstance = (
 <ButtonToolbar>
   // Standard button
   <Button>Default</Button>

   // Provides extra visual weight and identifies the primary action in a set of buttons
   <Button bsStyle="primary">Primary</Button>

   // Indicates a successful or positive action
   <Button bsStyle="success">Success</Button>

   // Contextual button for informational alert messages
   <Button bsStyle="info">Info</Button>

   // Indicates caution should be taken with this action
   <Button bsStyle="warning">Warning</Button>

   // Indicates a dangerous or potentially negative action
   <Button bsStyle="danger">Danger</Button>

   // Deemphasize a button by making it look like a link while maintaining button behavior
   <Button bsStyle="link">Link</Button>
 </ButtonToolbar>
);

ReactDOM.render(buttonsInstance, mountNode);

Button spacing

Because React doesn’t output newlines between elements, buttons on the same line are displayed flush against each other. To preserve the spacing between multiple inline buttons, wrap your button group in <ButtonToolbar />.

Sizes

Fancy larger or smaller buttons? Add bsSize="large", bsSize="small", or bsSize="xsmall" for additional sizes.

const buttonsInstance = (
 <div>
   <ButtonToolbar>
     <Button bsStyle="primary" bsSize="large">Large button</Button>
     <Button bsSize="large">Large button</Button>
   </ButtonToolbar>
   <ButtonToolbar>
     <Button bsStyle="primary">Default button</Button>
     <Button>Default button</Button>
   </ButtonToolbar>
   <ButtonToolbar>
     <Button bsStyle="primary" bsSize="small">Small button</Button>
     <Button bsSize="small">Small button</Button>
   </ButtonToolbar>
   <ButtonToolbar>
     <Button bsStyle="primary" bsSize="xsmall">Extra small button</Button>
     <Button bsSize="xsmall">Extra small button</Button>
   </ButtonToolbar>
 </div>
);

ReactDOM.render(buttonsInstance, mountNode);

Create block level buttons—those that span the full width of a parent— by adding the block prop.

const wellStyles = {maxWidth: 400, margin: '0 auto 10px'};

const buttonsInstance = (
 <div className="well" style={wellStyles}>
   <Button bsStyle="primary" bsSize="large" block>Block level button</Button>
   <Button bsSize="large" block>Block level button</Button>
 </div>
);

ReactDOM.render(buttonsInstance, mountNode);

Active state

To set a buttons active state simply set the components active prop.

const buttonsInstance = (
 <ButtonToolbar>
   <Button bsStyle="primary" bsSize="large" active>Primary button</Button>
   <Button bsSize="large" active>Button</Button>
 </ButtonToolbar>
);

ReactDOM.render(buttonsInstance, mountNode);

Button tags

The DOM element tag is choosen automatically for you based on the props you supply. Passing a href will result in the button using a <a /> element otherwise a <button /> element will be used.

 const buttonsInstance = (
   <ButtonToolbar>
     <Button href="#">Link</Button>
     <Button>Button</Button>
   </ButtonToolbar>
 );

ReactDOM.render(buttonsInstance, mountNode);

Disabled state

Make buttons look unclickable by fading them back 50%. To do this add the disabled attribute to buttons.

const buttonsInstance = (
 <ButtonToolbar>
   <Button bsStyle="primary" bsSize="large" disabled>Primary button</Button>
   <Button bsSize="large" disabled>Button</Button>
 </ButtonToolbar>
);

ReactDOM.render(buttonsInstance, mountNode);

Cross-Browser compatibility

Because <Button /> will render an <a> tag in certain situations. Since anchor tags can’t be disabled, the behavior is emulated as best it can be. Specifically, pointer-events: none; style is added to the anchor to prevent focusing, which is only supported in newer browser versions.

Button loading state

When activating an asynchronous action from a button it is a good UX pattern to give the user feedback as to the loading state, this can easily be done by updating your <Button />’s props from a state change like below.

const LoadingButton = React.createClass({
 getInitialState() {
   return {
     isLoading: false
   };
 },

 render() {
   let isLoading = this.state.isLoading;
   return (
     <Button
       bsStyle="primary"
       disabled={isLoading}
       onClick={!isLoading ? this.handleClick : null}>
       {isLoading ? 'Loading...' : 'Loading state'}
     </Button>
   );
 },

 handleClick() {
   this.setState({isLoading: true});

   // This probably where you would have an `ajax` call
   setTimeout(() => {
     // Completed of async action, set loading state back
     this.setState({isLoading: false});
   }, 2000);
 }
});

ReactDOM.render(<LoadingButton />, mountNode);

Test Summary

<Button> Should output a buttonTests didn't run
<Button> Should have type=button by defaultTests didn't run
<Button> Should show the type if passed oneTests didn't run
<Button> Should output an anchor if called with a hrefTests didn't run
<Button> Should call onClick callbackTests didn't run
<Button> Should be disabledTests didn't run
<Button> Should be disabled linkTests didn't run
<Button> Should have block classTests didn't run
<Button> Should apply bsStyle classTests didn't run
<Button> Should honour additional classes passed in, adding not overridingTests didn't run
<Button> Should default to bsStyle="default"Tests didn't run
<Button> Should be activeTests didn't run