198 lines
5.2 KiB
JavaScript
198 lines
5.2 KiB
JavaScript
import React from 'react';
|
|
import PropTypes from 'prop-types';
|
|
import { omit } from 'radash';
|
|
|
|
const propTypes = {
|
|
/**
|
|
* Defines HTML disable Attribute
|
|
* @defaultValue false
|
|
*/
|
|
disabled: PropTypes.bool,
|
|
|
|
/**
|
|
* Defines HTML Tag
|
|
* @defaultValue 'button'
|
|
*/
|
|
tagName: PropTypes.string,
|
|
|
|
/**
|
|
* Defines the button label
|
|
* @defaultValue undefined
|
|
*/
|
|
label: PropTypes.string.isRequired,
|
|
|
|
/**
|
|
* Defines the button click handler
|
|
* @defaultValue undefined
|
|
*/
|
|
onClick: (props, propName, componentName) => {
|
|
if (!props.onClick && !props.onMouseDown && !props.onMouseUp) {
|
|
return new Error('One of props \'onClick\' or \'onMouseDown\' or' +
|
|
` 'onMouseUp' was not specified in '${componentName}'.`);
|
|
}
|
|
|
|
return null;
|
|
},
|
|
onMouseDown: (props, propName, componentName) => {
|
|
if (!props.onClick && !props.onMouseDown && !props.onMouseUp) {
|
|
return new Error('One of props \'onClick\' or \'onMouseDown\' or' +
|
|
` 'onMouseUp' was not specified in '${componentName}'.`);
|
|
}
|
|
|
|
return null;
|
|
},
|
|
onMouseUp: (props, propName, componentName) => {
|
|
if (!props.onClick && !props.onMouseDown && !props.onMouseUp) {
|
|
return new Error('One of props \'onClick\' or \'onMouseDown\' or' +
|
|
` 'onMouseUp' was not specified in '${componentName}'.`);
|
|
}
|
|
|
|
return null;
|
|
},
|
|
|
|
onKeyPress: PropTypes.func,
|
|
onKeyDown: PropTypes.func,
|
|
onKeyUp: PropTypes.func,
|
|
setRef: PropTypes.func,
|
|
};
|
|
|
|
const defaultProps = {
|
|
disabled: false,
|
|
tagName: 'button',
|
|
onClick: undefined,
|
|
onMouseDown: undefined,
|
|
onMouseUp: undefined,
|
|
onKeyPress: undefined,
|
|
onKeyDown: undefined,
|
|
onKeyUp: undefined,
|
|
setRef: undefined,
|
|
};
|
|
|
|
/**
|
|
* Event handlers below are used to intercept a parent event handler from
|
|
* firing when the Button is disabled.
|
|
* Key press event handlers intercept firing for
|
|
* keyboard users to comply with ARIA standards.
|
|
*/
|
|
|
|
export default class ButtonBase extends React.Component {
|
|
constructor(props) {
|
|
super(props);
|
|
|
|
// Bind Mouse Event Handlers
|
|
this.internalClickHandler = this.internalClickHandler.bind(this);
|
|
this.internalDoubleClickHandler = this.internalDoubleClickHandler.bind(this);
|
|
this.internalMouseDownHandler = this.internalMouseDownHandler.bind(this);
|
|
this.internalMouseUpHandler = this.internalMouseUpHandler.bind(this);
|
|
|
|
// Bind Keyboard Event Handlers
|
|
this.internalKeyPressHandler = this.internalKeyPressHandler.bind(this);
|
|
this.internalKeyDownHandler = this.internalKeyDownHandler.bind(this);
|
|
this.internalKeyUpHandler = this.internalKeyUpHandler.bind(this);
|
|
}
|
|
|
|
validateDisabled(eventHandler, ...args) {
|
|
if (!this.props.disabled && typeof eventHandler === 'function') {
|
|
return eventHandler(...args);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
// Define Mouse Event Handlers
|
|
internalClickHandler(...args) {
|
|
return this.validateDisabled(this.props.onClick, ...args);
|
|
}
|
|
|
|
internalDoubleClickHandler(...args) {
|
|
return this.validateDisabled(this.props.onDoubleClick, ...args);
|
|
}
|
|
|
|
internalMouseDownHandler(...args) {
|
|
return this.validateDisabled(this.props.onMouseDown, ...args);
|
|
}
|
|
|
|
internalMouseUpHandler(...args) {
|
|
return this.validateDisabled(this.props.onMouseUp, ...args);
|
|
}
|
|
|
|
// Define Keyboard Event Handlers
|
|
internalKeyPressHandler(...args) {
|
|
return this.validateDisabled(this.props.onKeyPress, ...args);
|
|
}
|
|
|
|
internalKeyDownHandler(...args) {
|
|
return this.validateDisabled(this.props.onKeyDown, ...args);
|
|
}
|
|
|
|
internalKeyUpHandler(...args) {
|
|
return this.validateDisabled(this.props.onKeyUp, ...args);
|
|
}
|
|
|
|
render() {
|
|
const Component = this.props.tagName;
|
|
|
|
const remainingProps = Object.assign({}, this.props);
|
|
delete remainingProps.label;
|
|
delete remainingProps.tagName;
|
|
delete remainingProps.disabled;
|
|
|
|
// Delete Mouse event handlers
|
|
delete remainingProps.onClick;
|
|
delete remainingProps.onDoubleClick;
|
|
delete remainingProps.onMouseDown;
|
|
delete remainingProps.onMouseUp;
|
|
|
|
// Delete Keyboard event handlers
|
|
delete remainingProps.onKeyPress;
|
|
delete remainingProps.onKeyDown;
|
|
delete remainingProps.onKeyUp;
|
|
|
|
// Delete setRef callback if it exists
|
|
delete remainingProps.setRef;
|
|
|
|
const styleProps = [
|
|
'ghost',
|
|
'circle',
|
|
'block',
|
|
'hasNotification',
|
|
'isStyled',
|
|
'isDownloadable',
|
|
'animations',
|
|
'small',
|
|
'full',
|
|
'iconRight',
|
|
'isVisualEffects',
|
|
'panning',
|
|
'panSelected',
|
|
];
|
|
|
|
return (
|
|
<Component
|
|
ref={this.props.setRef}
|
|
aria-label={this.props.label}
|
|
aria-disabled={this.props.disabled}
|
|
|
|
// Render Mouse event handlers
|
|
onClick={this.internalClickHandler}
|
|
onDoubleClick={this.internalDoubleClickHandler}
|
|
onMouseDown={this.internalMouseDownHandler}
|
|
onMouseUp={this.internalMouseUpHandler}
|
|
|
|
// Render Keyboard event handlers
|
|
onKeyPress={this.internalKeyPressHandler}
|
|
onKeyDown={this.internalKeyDownHandler}
|
|
onKeyUp={this.internalKeyUpHandler}
|
|
|
|
// remove props used in styled-components
|
|
{...omit(remainingProps, styleProps)}
|
|
>
|
|
{this.props.children}
|
|
</Component>
|
|
);
|
|
}
|
|
}
|
|
|
|
ButtonBase.propTypes = propTypes;
|
|
ButtonBase.defaultProps = defaultProps;
|