@s-ui/react-atom-button
Version:
Atom Element: SUI button
208 lines (192 loc) • 5.68 kB
JavaScript
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
import _extends from "@babel/runtime/helpers/esm/extends";
var _excluded = ["design", "color", "alignment", "link", "href"],
_excluded2 = ["as", "link", "linkFactory", "href", "target", "disabled"];
import { cloneElement } from 'react';
import ButtonLink from './ButtonLink.js';
/**
* Base class for the component
*/
export var CLASS = 'sui-AtomButton';
/**
* Different designs for the button
*/
export var DESIGNS = {
SOLID: 'solid',
OUTLINE: 'outline',
FLAT: 'flat',
LINK: 'link'
};
/**
* A set of elevations that define the box shadow
*/
export var ELEVATIONS = {
MEDIUM: 'medium',
LARGE: 'large'
};
export var ALIGNMENT = {
CENTER: 'center',
LEFT: 'left',
RIGHT: 'right'
};
/**
* Available colors for the button
*/
export var COLORS = {
PRIMARY: 'primary',
ACCENT: 'accent',
NEUTRAL: 'neutral',
SUCCESS: 'success',
ALERT: 'alert',
ERROR: 'error',
SOCIAL_FACEBOOK: 'social-facebook',
SOCIAL_TWITTER: 'social-twitter',
SOCIAL_GOOGLE: 'social-google',
SOCIAL_YOUTUBE: 'social-youtube',
SOCIAL_WHATSAPP: 'social-whatsapp',
SOCIAL_INSTAGRAM: 'social-instagram'
};
/**
* Positions to be used when the button is used on group
*/
export var GROUP_POSITIONS = {
FIRST: 'first',
MIDDLE: 'middle',
LAST: 'last'
};
/**
* Shapes for the button
*/
export var SHAPES = {
SQUARED: 'squared',
ROUNDED: 'rounded',
CIRCULAR: 'circular'
};
/**
* Sizes for the button
*/
export var SIZES = {
SMALL: 'small',
LARGE: 'large'
};
/**
* All the available modifiers for the button
*/
export var MODIFIERS = ['disabled', 'fullWidth', 'focused', 'negative', 'link'];
/**
* Icon available positions
*/
export var ICON_POSITIONS = {
LEFT: 'left',
RIGHT: 'right',
CENTER: 'center'
};
/**
* Props for the button to filter the rest of attributes
*/
export var OWN_PROPS = [].concat(Object.values(SIZES), ['alignment', 'children', 'className', 'color', 'design', 'isFitted', 'focused', 'fullWidth', 'groupPosition', 'isLoading', 'leftIcon', 'loadingText', 'negative', 'rightIcon', 'shape']);
/**
* Display Name for the AtomIcon component
*/
export var ATOM_ICON_DISPLAY_NAME = 'AtomIcon';
/**
* Map of sizes of the button with the AtomIcon usage
* The key is the size of the button
* The value is the size of the icon
*/
export var ATOM_ICON_SIZES_MAPPER = {
default: 'small',
small: 'small',
large: 'medium'
};
export var createClasses = function createClasses(array, sufix) {
if (sufix === void 0) {
sufix = '';
}
return array.reduce(function (res, key) {
var _extends2;
return _extends({}, res, (_extends2 = {}, _extends2[key] = CLASS + "--" + key + sufix, _extends2));
}, {});
};
export var CLASSES = createClasses([].concat(Object.values(COLORS), Object.values(DESIGNS), Object.values(ALIGNMENT), MODIFIERS, Object.values(SIZES), ['empty']));
/**
* Get props cleaning out AtomButton own props
* @param {Object} props
* @return {Object}
*/
export var cleanProps = function cleanProps(props) {
var newProps = _extends({}, props);
OWN_PROPS.forEach(function (key) {
return delete newProps[key];
});
return newProps;
};
/**
* Get modifiers to apply according to props
* @param {Object} props
* @return {Array<String>}
*/
export var getModifiers = function getModifiers(props) {
return Object.keys(props).filter(function (name) {
return props[name] && MODIFIERS.includes(name);
});
};
export var getPropsWithDefaultValues = function getPropsWithDefaultValues(_ref) {
var design = _ref.design,
color = _ref.color,
alignment = _ref.alignment,
link = _ref.link,
href = _ref.href,
other = _objectWithoutPropertiesLoose(_ref, _excluded);
return _extends({}, other, {
link: link,
design: design || (link || href ? DESIGNS.LINK : DESIGNS.SOLID),
color: color || COLORS.PRIMARY,
alignment: alignment || ALIGNMENT.CENTER
});
};
/**
* Detect if an element is an AtomIcon to force correct size
* @param {React.ReactElement} icon
*/
export var isAtomIcon = function isAtomIcon(icon) {
var _icon$type;
return (icon == null ? void 0 : (_icon$type = icon.type) == null ? void 0 : _icon$type.displayName) === ATOM_ICON_DISPLAY_NAME;
};
/**
* Prepare the AtomIcon element to use the correct size
* @param {React.ReactElement} atomIconElement
* @param {object} options
* @param {string} options.size Size of the button to grab the correct icon size
*/
export var prepareAtomIcon = function prepareAtomIcon(atomIconElement, _ref2) {
var _atomIconElement$prop;
var size = _ref2.size;
return /*#__PURE__*/cloneElement(atomIconElement, {
color: undefined,
size: (atomIconElement == null ? void 0 : (_atomIconElement$prop = atomIconElement.props) == null ? void 0 : _atomIconElement$prop.size) || ATOM_ICON_SIZES_MAPPER[size]
});
};
export var useElement = function useElement(_temp) {
var _ref3 = _temp === void 0 ? {} : _temp,
As = _ref3.as,
link = _ref3.link,
_ref3$linkFactory = _ref3.linkFactory,
Link = _ref3$linkFactory === void 0 ? ButtonLink : _ref3$linkFactory,
href = _ref3.href,
target = _ref3.target,
disabled = _ref3.disabled,
props = _objectWithoutPropertiesLoose(_ref3, _excluded2);
var isLink = !!link;
var Element = As || (isLink ? Link : 'button');
var defaultRel = target === '_blank' ? 'noopener' : undefined;
var rel = props.rel || defaultRel;
var propsToPass = _extends({}, props, Element === 'button' && {
disabled: disabled
}, isLink && {
href: href,
target: target,
rel: rel
});
return [Element, propsToPass];
};