@eccenca/gui-elements
Version:
Collection of low-level GUI elements like Buttons, Icons or Alerts. Also includes core styles for those elements.
217 lines (189 loc) • 6.07 kB
JSX
import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import ReactMDLButton from 'react-mdl/lib/Button';
import ReactMDLFabButton from 'react-mdl/lib/FABButton';
import Tooltip from '../Tooltip/Tooltip';
import Icon from '../Icon/Icon';
import canonicalTooltips from '../Icon/canonicaltooltips.json';
/**
Read the [GUI spec about button usage](https://confluence.brox.de/display/ECCGMBH/GUI+Specifications#GUISpecifications-Buttons).
```js
import {Button} from '@eccenca/gui-elements';
const Page = React.createClass({
// template rendering
render() {
return (
<Button>
Flat button
</Button>
// use the button parameters according to MDL-API, @see https://getmdl.io/components/index.html#buttons-section
<Button
raised
accent
colored
ripple
disabled
badge="5"
>
Button label
</Button>
// you can apply all other button properties on icon buttons, too (e.g. affirmative, accent, ripple, ...)
<Button
iconName="menu_more"
tooltip="This is a Test!"
fabSize="mini"
/>
)
},
// ....
});
```
*/
const Button = props => {
/* TODO:
* add label/content as tooltip for icon/fab buttons
* add label as tooltip if children content is available
*/
const {
badge,
className,
fabSize,
iconName,
affirmative,
dismissive,
disruptive,
tooltip: defaultTooltip,
children: defaultChildren,
ripple: defaultRipple,
...otherProps
} = props;
const semanticConfig = {};
if (affirmative === true) {
semanticConfig.accent = true;
semanticConfig.colored = false;
}
if (dismissive === true || disruptive === true) {
semanticConfig.accent = false;
semanticConfig.colored = false;
}
const classes = classNames(
{
'mdl-button--icon': typeof iconName !== 'undefined',
'mdl-button--danger': disruptive === true,
'mdl-badge mdl-badge--overlap': typeof badge !== 'undefined',
},
className
);
const ripple = defaultRipple === true; // disable ripple by default
let tooltip = defaultTooltip;
// if tooltip is empty check for default one
if (
!tooltip
&& tooltip !== false
&& typeof canonicalTooltips[iconName] !== 'undefined'
) {
tooltip = canonicalTooltips[iconName];
}
let button = '';
let buttonContent = defaultChildren;
if (iconName) {
buttonContent = (
// if tooltip already exist send 'false' to prevent adding additional default tooltip in <Icon/>
<Icon
name={iconName}
tooltip={tooltip || tooltip === false ? false : ''}
badge={badge || false}
/>
);
}
if (badge && !iconName) {
otherProps['data-badge'] = badge;
}
if (fabSize) {
button = (
<ReactMDLFabButton
className={classes}
ripple={ripple}
mini={fabSize === 'mini'}
{...otherProps}
{...semanticConfig}
>
{buttonContent}
</ReactMDLFabButton>
);
} else {
button = (
<ReactMDLButton
className={classes}
ripple={ripple}
{...otherProps}
{...semanticConfig}
>
{buttonContent}
</ReactMDLButton>
);
}
if (tooltip && !props.disabled) {
button = <Tooltip label={tooltip}>{button}</Tooltip>;
}
return button;
};
Button.propTypes = {
children: PropTypes.oneOfType([PropTypes.node]),
/**
string (optional): use badge if the (icon) button need to be enhanced by
a small badge containing 1 to 3 chars or digits
*/
badge: PropTypes.string,
/**
string (optional): additional CSS class name
*/
className: PropTypes.string,
/**
boolean (default: false): button is disabled and cannot get used to trigger an action
*/
disabled: PropTypes.bool,
/**
string 'mini|large' (optional): use fabSize only if it is a Material Design floating action button (FAB)
*/
fabSize: PropTypes.string,
/**
string (optional): icon name if it is an Material Design icon button
We defined some canonical names for icons and their meanings:
- 'edit': edit data
- 'remove': remove data
- 'arrow_nextpage': go to next page
- 'arrow_prevpage': go to previous page
- 'arrow_lastpage': go to last page
- 'arrow_firstpage': go to first page
- 'arrow_dropdown': open dropdown select
- 'expand_more': expand GUI element to show more details
- 'expand_less': reduce GUI element to show less details
- 'menu_more': open context menu
- 'filter': filter data
- 'sort': sort data
- 'hide': hide (or close/remove) GUI elements
- 'access_forbidden': no access to read and write data
For other symbols and icon names @see https://material.io/icons/
*/
iconName: PropTypes.string,
/**
boolean (default: false): activate ripple effect on button
*/
ripple: PropTypes.bool,
/**
React node or boolean (optional): tooltip text, some icons have fallback
tooltips, set it to false if you need to prevent them
*/
tooltip: PropTypes.oneOfType([
PropTypes.node,
PropTypes.bool,
]),
// internal properties, used by button sub types
affirmative: PropTypes.bool,
dismissive: PropTypes.bool,
disruptive: PropTypes.bool,
};
Button.displayName = 'Button';
export default Button;