jitsi-meet/react/features/base/toolbox/components/AbstractToolboxItem.js
Lyubo Marinov 3aff4967f1 Keep buttons in their associated features
Contributing all buttons in one place goes against the designs that we
set out at the beginning of the project's rewrite and that multiple of
us have been following since then.
2018-05-15 14:12:38 -05:00

199 lines
4.3 KiB
JavaScript

// @flow
import { Component } from 'react';
export type Styles = {
/**
* Style for the item's icon.
*/
iconStyle: Object,
/**
* Style for the item itself.
*/
style: Object,
/**
* Color for the item underlay (shows when clicked).
*/
underlayColor: string
};
export type Props = {
/**
* A succinct description of what the item does. Used by accessibility
* tools and torture tests.
*/
accessibilityLabel: string,
/**
* Whether this item is disabled or not. When disabled, clicking an the item
* has no effect, and it may reflect on its style.
*/
disabled: boolean,
/**
* The name of the icon of this {@code ToolboxItem}.
*/
iconName: string,
/**
* The text associated with this item. When `showLabel` is set to
* {@code true}, it will be displayed alongside the icon.
*/
label: string,
/**
* On click handler.
*/
onClick: Function,
/**
* Whether to show the label or not.
*/
showLabel: boolean,
/**
* Collection of styles for the item. Used only on native.
*/
styles: ?Styles,
/**
* Invoked to obtain translated strings.
*/
t: ?Function,
/**
* The text to display in the tooltip. Used only on web.
*/
tooltip: string,
/**
* From which direction the tooltip should appear, relative to the
* item. Used only on web.
*/
tooltipPosition: string,
/**
* Whether this item is visible or not.
*/
visible: boolean
};
/**
* Abstract (base) class for an item in {@link Toolbox}. The item can be located
* anywhere in the {@link Toolbox}, it will morph its shape to accommodate it.
*
* @abstract
*/
export default class AbstractToolboxItem<P : Props> extends Component<P> {
/**
* Default values for {@code AbstractToolboxItem} component's properties.
*
* @static
*/
static defaultProps = {
disabled: false,
label: '',
showLabel: false,
t: undefined,
tooltip: '',
tooltipPosition: 'top',
visible: true
};
/**
* Initializes a new {@code AbstractToolboxItem} instance.
*
* @param {Object} props - The React {@code Component} props to initialize
* the new {@code AbstractToolboxItem} instance with.
*/
constructor(props: P) {
super(props);
// Bind event handlers so they are only bound once per instance.
this._onClick = this._onClick.bind(this);
}
/**
* Helper property to get the item label. If a translation function was
* provided then it will be translated using it.
*
* @protected
* @returns {string}
*/
get _label() {
return this._maybeTranslateAttribute(this.props.label);
}
/**
* Helper property to get the item tooltip. If a translation function was
* provided then it will be translated using it.
*
* @protected
* @returns {string}
*/
get _tooltip() {
return this._maybeTranslateAttribute(this.props.tooltip);
}
/**
* Utility function to translate the given string, if a translation
* function is available.
*
* @param {string} text - What needs translating.
* @private
* @returns {string}
*/
_maybeTranslateAttribute(text) {
const { t } = this.props;
if (typeof t === 'function') {
return t(text);
}
return text;
}
_onClick: (*) => void;
/**
* Handles clicking/pressing this {@code AbstractToolboxItem} by
* forwarding the event to the {@code onClick} prop of this instance if any.
*
* @protected
* @returns {void}
*/
_onClick(...args) {
const { disabled, onClick } = this.props;
!disabled && onClick && onClick(...args);
}
/**
* Handles rendering of the actual item.
*
* @protected
* @returns {ReactElement}
*/
_renderItem() {
// To be implemented by a subclass.
}
/**
* Implements React's {@link Component#render()}.
*
* @inheritdoc
* @returns {ReactElement}
*/
render() {
if (!this.props.visible) {
return null;
}
return this._renderItem();
}
}