bigbluebutton-Github/bigbluebutton-html5/imports/ui/components/button/base/component.jsx
Oleksandr Zhurbenko cc457661ce Prevented wb toolbar from triggering focus on touch events
To make it work well with the text shape, which always keeps the focus. And we don't want the keyboard to jump if you decide to change the font settings on the fly
2017-11-15 16:34:50 -08:00

180 lines
4.9 KiB
JavaScript

import React from 'react';
import PropTypes from 'prop-types';
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;
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}
{...remainingProps}
>
{this.props.children}
</Component>
);
}
}
ButtonBase.propTypes = propTypes;
ButtonBase.defaultProps = defaultProps;