index.tsx 3.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. import React, { PureComponent, ReactNode, CSSProperties } from 'react';
  2. import cls from 'classnames';
  3. import PropTypes from 'prop-types';
  4. import { strings, cssClasses } from '@douyinfe/semi-foundation/space/constants';
  5. import '@douyinfe/semi-foundation/space/space.scss';
  6. import { isString, isArray, isNumber } from 'lodash';
  7. import { flatten } from './utils';
  8. const prefixCls = cssClasses.PREFIX;
  9. export type Align = 'start' | 'center' | 'end' | 'baseline';
  10. export type Spacing = 'loose' | 'medium' | 'tight' | number;
  11. export type SpaceProps = {
  12. wrap?: boolean;
  13. align?: Align;
  14. vertical?: boolean;
  15. spacing?: Spacing | Spacing[];
  16. children?: ReactNode;
  17. style?: CSSProperties;
  18. className?: string;
  19. };
  20. class Space extends PureComponent<SpaceProps> {
  21. static propTypes = {
  22. wrap: PropTypes.bool,
  23. align: PropTypes.oneOf(strings.ALIGN_SET),
  24. vertical: PropTypes.bool,
  25. spacing: PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.array]),
  26. children: PropTypes.node,
  27. style: PropTypes.object,
  28. className: PropTypes.string
  29. };
  30. static defaultProps = {
  31. vertical: false,
  32. wrap: false,
  33. spacing: 'tight',
  34. align: 'center'
  35. };
  36. render(): ReactNode {
  37. const {
  38. children = null,
  39. style,
  40. className,
  41. spacing,
  42. wrap,
  43. align,
  44. vertical
  45. } = this.props;
  46. const isWrap = wrap && vertical ? false : wrap;
  47. const realStyle = { ...style };
  48. let spacingHorizontalType = '';
  49. let spacingVerticalType = '';
  50. if (isString(spacing)) {
  51. spacingHorizontalType = spacing;
  52. spacingVerticalType = spacing;
  53. } else if (isNumber(spacing)) {
  54. realStyle.rowGap = spacing;
  55. realStyle.columnGap = spacing;
  56. } else if (isArray(spacing)) {
  57. if (isString(spacing[0])) {
  58. spacingHorizontalType = spacing[0];
  59. } else if (isNumber(spacing[0])) {
  60. realStyle.columnGap = `${spacing[0]}px`;
  61. }
  62. if (isString(spacing[1])) {
  63. spacingVerticalType = spacing[1];
  64. } else if (isNumber(spacing[1])) {
  65. realStyle.rowGap = `${spacing[1]}px`;
  66. }
  67. }
  68. const classNames = cls(prefixCls, className, {
  69. [`${prefixCls}-align-${align}`]: align,
  70. [`${prefixCls}-vertical`]: vertical,
  71. [`${prefixCls}-horizontal`]: !vertical,
  72. [`${prefixCls}-wrap`]: isWrap,
  73. [`${prefixCls}-tight-horizontal`]: spacingHorizontalType === strings.SPACING_TIGHT,
  74. [`${prefixCls}-tight-vertical`]: spacingVerticalType === strings.SPACING_TIGHT,
  75. [`${prefixCls}-medium-horizontal`]: spacingHorizontalType === strings.SPACING_MEDIUM,
  76. [`${prefixCls}-medium-vertical`]: spacingVerticalType === strings.SPACING_MEDIUM,
  77. [`${prefixCls}-loose-horizontal`]: spacingHorizontalType === strings.SPACING_LOOSE,
  78. [`${prefixCls}-loose-vertical`]: spacingVerticalType === strings.SPACING_LOOSE,
  79. });
  80. const childrenNodes = flatten(children);
  81. return (
  82. <div className={classNames} style={realStyle}>
  83. {childrenNodes}
  84. </div>
  85. );
  86. }
  87. }
  88. export default Space;