@zohodesk/components
Version:
Dot UI is a customizable React component library built to deliver a clean, accessible, and developer-friendly UI experience. It offers a growing set of reusable components designed to align with modern design systems and streamline application development
203 lines (183 loc) • 6.98 kB
JavaScript
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
import React, { forwardRef, memo, useMemo } from 'react';
import { withComponentRegistrar } from '@zohodesk/dotkit/es/react/ComponentRegistry';
import Icon from '@zohodesk/icons/es/Icon';
import Flex from '@zohodesk/layout/es/Flex/Flex';
import Typography from "../../Typography/Typography";
import { isRenderable } from '@zohodesk/utils/es/renderNode';
import renderNode from '@zohodesk/utils/es/renderNode';
import propTypes from "./props/propTypes";
import defaultProps from "./props/defaultProps";
import { DUMMY_OBJECT } from '@zohodesk/dotkit/es/utils/constants';
import { ICON_PLACEMENT, LOADER_PLACEMENT, STATUS, TYPOGRAPHY_SIZE_MAP, VARIANT } from "./constants";
import Loader from "../shared/Loader/Loader";
import SuccessTick from "../shared/SuccessTick/SuccessTick";
import cssJSLogic from "./css/cssJSLogic";
const getTypographySize = size => TYPOGRAPHY_SIZE_MAP[size] || '13';
const Button = /*#__PURE__*/forwardRef(function Button(props, ref) {
const {
palette,
bgAppearance,
borderAppearance,
variant,
status,
loaderPlacement,
size,
iconName,
iconSize,
iconPlacement,
renderIcon,
renderBefore,
renderAfter,
renderLoader,
renderSuccess,
children,
type,
onClick,
isDisabled,
isReadOnly,
isSelected,
shape,
paletteShade,
disabledAppearance,
title,
customProps,
customAttributes,
a11yAttributes,
customId,
testId
} = props;
const isLoading = status === STATUS.LOADING;
const isSuccess = status === STATUS.SUCCESS;
const isDisabledState = isDisabled || isLoading;
const isInteractionDisabled = isDisabledState || isReadOnly;
const overlayActive = (isLoading || isSuccess) && loaderPlacement === LOADER_PLACEMENT.OVERLAY;
const {
text: contentProps = DUMMY_OBJECT,
icon: iconProps = DUMMY_OBJECT
} = customProps;
const iconTagAttributes = useMemo(() => ({ ...(iconProps.tagAttributes || DUMMY_OBJECT),
'data-test-id': testId ? `${testId}_icon` : undefined
}), [iconProps.tagAttributes, testId]);
const classes = useMemo(() => cssJSLogic({
props
}), [palette, bgAppearance, borderAppearance, paletteShade, size, variant, status, isDisabled, isReadOnly, isSelected, shape, loaderPlacement, disabledAppearance, props.customClass]);
const {
loaderOverlayClass,
successOverlayClass,
contentWrapperClass,
textClassName,
buttonClassName,
iconClassName
} = classes;
const showIcon = variant !== VARIANT.TEXT && (renderIcon || iconName);
const _handleClick = event => {
if (isInteractionDisabled) {
return;
}
onClick(event);
};
const _renderLoader = () => {
if (!isLoading) {
return null;
}
if (isRenderable(renderLoader)) {
return renderNode(renderLoader, {
status
});
}
const loaderClassName = loaderPlacement === LOADER_PLACEMENT.OVERLAY ? loaderOverlayClass : '';
return /*#__PURE__*/React.createElement(Flex, {
$ui_displayMode: "flex",
$ui_alignItems: "center",
$ui_justifyContent: "center",
$ui_className: loaderClassName,
testId: testId ? `${testId}_loader` : undefined
}, /*#__PURE__*/React.createElement(Loader, null));
};
const _renderSuccess = () => {
if (!isSuccess) {
return null;
}
if (isRenderable(renderSuccess)) {
return renderNode(renderSuccess, {
status
});
}
const successClassName = loaderPlacement === LOADER_PLACEMENT.OVERLAY ? successOverlayClass : '';
return /*#__PURE__*/React.createElement(Flex, {
$ui_displayMode: "flex",
$ui_alignItems: "center",
$ui_justifyContent: "center",
$ui_className: successClassName,
testId: testId ? `${testId}_success` : undefined
}, /*#__PURE__*/React.createElement(SuccessTick, null));
};
const _renderIconNode = () => {
if (!showIcon) {
return null;
}
if (isRenderable(renderIcon)) {
return renderNode(renderIcon);
}
return /*#__PURE__*/React.createElement(Icon, _extends({}, iconProps, {
iconClass: iconClassName,
name: iconName,
size: iconSize,
tagAttributes: iconTagAttributes,
dataId: testId ? `${testId}_icon` : undefined
}));
};
const _renderBeforeNode = () => {
if (!isRenderable(renderBefore)) {
return null;
}
return renderNode(renderBefore, props);
};
const _renderAfterNode = () => {
if (!isRenderable(renderAfter)) {
return null;
}
return renderNode(renderAfter, props);
};
const _renderContent = () => {
const shouldShowText = variant !== VARIANT.ICON && children !== undefined && children !== null;
const showLoaderStart = isLoading && loaderPlacement === LOADER_PLACEMENT.START;
const showLoaderAfter = isLoading && loaderPlacement === LOADER_PLACEMENT.END;
const showSuccessStart = isSuccess && loaderPlacement === LOADER_PLACEMENT.START;
const showSuccessAfter = isSuccess && loaderPlacement === LOADER_PLACEMENT.END;
return /*#__PURE__*/React.createElement(Flex, {
$ui_displayMode: "flex",
$ui_direction: "row",
$flag_shrink: true,
$ui_alignItems: "center",
$ui_justifyContent: "center",
$ui_className: contentWrapperClass
}, showLoaderStart ? _renderLoader() : null, showSuccessStart ? _renderSuccess() : null, _renderBeforeNode(), iconPlacement === ICON_PLACEMENT.LEFT ? _renderIconNode() : null, shouldShowText ? /*#__PURE__*/React.createElement(Typography, _extends({}, contentProps, {
$ui_className: textClassName,
$ui_size: getTypographySize(size),
$flag_dotted: variant !== VARIANT.ICON
}), children) : null, iconPlacement === ICON_PLACEMENT.RIGHT ? _renderIconNode() : null, _renderAfterNode(), showLoaderAfter ? _renderLoader() : null, showSuccessAfter ? _renderSuccess() : null);
};
const containerAttributes = { ...customAttributes,
'data-id': customId,
'data-test-id': testId,
'data-title': title
};
return /*#__PURE__*/React.createElement("button", _extends({}, containerAttributes, a11yAttributes, {
ref: ref,
type: type,
className: buttonClassName,
"aria-busy": isLoading,
"aria-disabled": isDisabledState,
"aria-readonly": isReadOnly,
"aria-pressed": isSelected,
onClick: _handleClick
}), _renderContent(), overlayActive ? isLoading ? _renderLoader() : _renderSuccess() : null);
});
Button.propTypes = propTypes;
Button.defaultProps = defaultProps;
Button.displayName = 'Button';
export default withComponentRegistrar( /*#__PURE__*/memo(Button), {
name: 'ZDC_V1_Button'
});