UNPKG

@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
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' });