index.tsx 3.5 KB

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