bigbluebutton-Github/bigbluebutton-html5/imports/ui/components/common/button/base/component.jsx

198 lines
5.2 KiB
React
Raw Normal View History

import React from 'react';
import PropTypes from 'prop-types';
2023-02-21 21:29:51 +08:00
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,
};
2016-08-06 02:39:24 +08:00
/**
* 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);
2016-08-03 06:55:20 +08:00
// 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);
}
2016-08-24 03:18:49 +08:00
validateDisabled(eventHandler, ...args) {
2016-08-03 06:55:20 +08:00
if (!this.props.disabled && typeof eventHandler === 'function') {
return eventHandler(...args);
}
return null;
2016-08-03 06:55:20 +08:00
}
// Define Mouse Event Handlers
internalClickHandler(...args) {
return this.validateDisabled(this.props.onClick, ...args);
2016-08-03 06:55:20 +08:00
}
internalDoubleClickHandler(...args) {
return this.validateDisabled(this.props.onDoubleClick, ...args);
2016-08-03 06:55:20 +08:00
}
internalMouseDownHandler(...args) {
return this.validateDisabled(this.props.onMouseDown, ...args);
2016-08-03 06:55:20 +08:00
}
internalMouseUpHandler(...args) {
return this.validateDisabled(this.props.onMouseUp, ...args);
2016-08-03 06:55:20 +08:00
}
// Define Keyboard Event Handlers
internalKeyPressHandler(...args) {
return this.validateDisabled(this.props.onKeyPress, ...args);
2016-08-03 06:55:20 +08:00
}
internalKeyDownHandler(...args) {
return this.validateDisabled(this.props.onKeyDown, ...args);
2016-08-03 06:55:20 +08:00
}
internalKeyUpHandler(...args) {
return this.validateDisabled(this.props.onKeyUp, ...args);
}
render() {
2017-06-03 03:25:02 +08:00
const Component = this.props.tagName;
2016-07-12 04:10:55 +08:00
const remainingProps = Object.assign({}, this.props);
delete remainingProps.label;
delete remainingProps.tagName;
2016-08-03 06:55:20 +08:00
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;
2016-07-12 04:10:55 +08:00
// Delete setRef callback if it exists
delete remainingProps.setRef;
2021-11-11 21:36:00 +08:00
const styleProps = [
'ghost',
'circle',
'block',
'hasNotification',
'isStyled',
'isDownloadable',
'animations',
'small',
'full',
'iconRight',
'isVisualEffects',
2022-09-09 21:14:20 +08:00
'panning',
2023-04-13 22:13:20 +08:00
'panSelected',
2021-11-11 21:36:00 +08:00
];
return (
2016-08-03 06:55:20 +08:00
<Component
ref={this.props.setRef}
2016-08-03 06:55:20 +08:00
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}
2021-11-11 21:36:00 +08:00
// remove props used in styled-components
2023-02-21 21:29:51 +08:00
{...omit(remainingProps, styleProps)}
2016-08-03 06:55:20 +08:00
>
{this.props.children}
</Component>
);
}
}
ButtonBase.propTypes = propTypes;
ButtonBase.defaultProps = defaultProps;