basicStep.tsx 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. import React from 'react';
  2. import { isFunction } from 'lodash-es';
  3. import PropTypes from 'prop-types';
  4. import classnames from 'classnames';
  5. import { stepsClasses as css } from '@douyinfe/semi-foundation/steps/constants';
  6. import { IconTickCircle, IconAlertCircle, IconAlertTriangle } from '@douyinfe/semi-icons';
  7. export type Status = 'wait' | 'process' | 'finish' | 'error' | 'warning';
  8. export type Size = 'default' | 'small';
  9. export interface BasicStepProps {
  10. description?: React.ReactNode;
  11. icon?: React.ReactNode;
  12. status?: Status;
  13. title?: React.ReactNode;
  14. className?: string;
  15. style?: React.CSSProperties;
  16. active?: boolean;
  17. prefixCls?: string;
  18. stepNumber?: string;
  19. size?: Size;
  20. done?: boolean;
  21. onChange?: () => void;
  22. onClick?: React.MouseEventHandler<HTMLDivElement>;
  23. }
  24. export enum stepSizeMapIconSize {
  25. small = 'large',
  26. default = 'extra-large'
  27. }
  28. const BasicStep = (props: BasicStepProps) => {
  29. const {
  30. prefixCls,
  31. className,
  32. size,
  33. title,
  34. description,
  35. status,
  36. style,
  37. active,
  38. done,
  39. icon,
  40. stepNumber,
  41. onClick,
  42. onChange,
  43. ...restProps
  44. } = props;
  45. const renderIcon = () => {
  46. let inner, progress;
  47. if ('icon' in props) {
  48. if (React.isValidElement(icon)) {
  49. inner = icon;
  50. }
  51. } else if ('status' in props) {
  52. switch (status) {
  53. case 'error':
  54. inner = <IconAlertCircle size={stepSizeMapIconSize[size]} />;
  55. break;
  56. case 'wait':
  57. inner = <span className={`${prefixCls}-number-icon`}>{stepNumber}</span>;
  58. break;
  59. case 'process':
  60. inner = <span className={`${prefixCls}-number-icon`}>{stepNumber}</span>;
  61. progress = true;
  62. break;
  63. case 'finish':
  64. inner = <IconTickCircle size={stepSizeMapIconSize[size]} />;
  65. break;
  66. case 'warning':
  67. inner = <IconAlertTriangle size={stepSizeMapIconSize[size]} />;
  68. break;
  69. default:
  70. inner = null;
  71. break;
  72. }
  73. }
  74. const cls = classnames({
  75. [`${prefixCls}-icon`]: true,
  76. [`${prefixCls}-custom-icon`]: 'icon' in props,
  77. [`${prefixCls}-icon-process`]: progress,
  78. });
  79. return inner ? <span className={cls}>{inner}</span> : null;
  80. };
  81. const classString = classnames(prefixCls, className, `${prefixCls}-${status}`, {
  82. [`${prefixCls}-active`]: active,
  83. [`${prefixCls}-done`]: done
  84. });
  85. const handleClick = (e: React.MouseEvent) => {
  86. if (isFunction(onClick)) {
  87. onClick(e);
  88. }
  89. onChange();
  90. };
  91. return (
  92. <div {...restProps} className={classString} style={style} onClick={e => handleClick(e)}>
  93. <div className={`${prefixCls}-container`}>
  94. <div className={`${prefixCls}-left`}>{renderIcon()}</div>
  95. <div className={`${prefixCls}-content`}>
  96. <div className={`${prefixCls}-title`}>
  97. <div className={`${prefixCls}-title-text`}>{title}</div>
  98. </div>
  99. {description && <div className={`${prefixCls}-description`}>{description}</div>}
  100. </div>
  101. </div>
  102. </div>
  103. );
  104. };
  105. BasicStep.propTypes = {
  106. prefixCls: PropTypes.string,
  107. description: PropTypes.node,
  108. icon: PropTypes.node,
  109. status: PropTypes.oneOf(['wait', 'process', 'finish', 'error', 'warning']),
  110. title: PropTypes.node,
  111. className: PropTypes.string,
  112. style: PropTypes.object,
  113. onClick: PropTypes.func,
  114. active: PropTypes.bool,
  115. done: PropTypes.bool,
  116. };
  117. BasicStep.defaultProps = {
  118. prefixCls: css.ITEM,
  119. active: false,
  120. done: false,
  121. status: 'wait',
  122. className: '',
  123. };
  124. export default BasicStep;