testokur/testokur-ui

View on GitHub
src/components/Button/component.tsx

Summary

Maintainability
C
7 hrs
Test Coverage
import * as React from 'react';
import { isUndefined, isDefined } from 'testokur-utils';
import { Sizes, SpacingsAfter, Testable } from '../../modules';
import { Types } from './const';
import { StyledButton, StyledButtonContent, IconContainer, StyledButtonContentChildren, StyledButtonProps } from './styled';
import { Loading, LoadingTypes } from '../Loading';

type Props = Testable &
StyledButtonProps &
React.ButtonHTMLAttributes<HTMLButtonElement> & {
  loading?: boolean;
  icon?: JSX.Element;
  iconLeft?: JSX.Element;
  iconRight?: JSX.Element;
  ariaExpanded?: boolean;
  ariaControls?: string;
};

const component = (props: Props): JSX.Element => {
  const {
    onClick,
    loading,
    iconLeft,
    iconRight,
    disabled,
    children,
    size,
    icon,
    type,
    buttonType,
    bordered,
    fullWidth,
    title,
    spaceAfter,
    tabIndex,
    ariaControls,
    ariaExpanded,
    role,
    circled,
    width,
    dataTestId,
  } = props;

  const hasLeftIcon = isDefined(iconLeft) || isDefined(icon);
  const hasRightIcon = isDefined(iconRight) || isDefined(icon);
  const sizeIcon = size === Sizes.Small ? Sizes.Small : Sizes.Medium;
  const onlyIcon = (isDefined(iconLeft) && isUndefined(children)) ?? false;
  const isDisabled = (loading || disabled) ?? false;

  return (
    <StyledButton
      onClick={onClick}
      hasRightIcon={hasRightIcon}
      hasLeftIcon={hasLeftIcon}
      bordered={bordered ?? false}
      fullWidth={fullWidth ?? false}
      width={width}
      role={role}
      circled={circled}
      tabIndex={tabIndex}
      aria-controls={ariaControls}
      aria-expanded={ariaExpanded}
      aria-label={title}
      spaceAfter={spaceAfter ?? SpacingsAfter.None}
      title={title}
      buttonType={buttonType}
      size={size}
      onlyIcon={onlyIcon}
      disabled={isDisabled}
      type={type}
      data-testid={dataTestId}
    >
      {loading ? <Loading type={LoadingTypes.ButtonLoader} /> : <></>}
      <StyledButtonContent loading={loading}>
        {iconLeft && (
          <IconContainer bordered={bordered} onlyIcon={onlyIcon} size={sizeIcon} type={buttonType}>
            {iconLeft}
          </IconContainer>
        )}
        {isUndefined(children) ? <></> : <StyledButtonContentChildren>{children}</StyledButtonContentChildren>}
        {iconRight && (
          <IconContainer bordered={bordered} onlyIcon={onlyIcon} size={sizeIcon} type={buttonType}>
            {iconRight}
          </IconContainer>
        )}
      </StyledButtonContent>
    </StyledButton>
  );
};

component.defaultProps = {
  size: Sizes.Medium,
  buttonType: Types.Primary,
} as Props;

component.displayName = 'Button';

export default component;