col.tsx 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. import React from 'react';
  2. import PropTypes from 'prop-types';
  3. import { RowContext } from './row';
  4. import classnames from 'classnames';
  5. import { cssClasses } from '@douyinfe/semi-foundation/grid/constants';
  6. const objectOrNumber = PropTypes.oneOfType([PropTypes.object, PropTypes.number]);
  7. export interface ColSize {
  8. span?: number;
  9. order?: number;
  10. offset?: number;
  11. push?: number;
  12. pull?: number;
  13. }
  14. export interface ColProps {
  15. span?: number;
  16. order?: number;
  17. offset?: number;
  18. push?: number;
  19. pull?: number;
  20. className?: string;
  21. prefixCls?: string;
  22. style?: React.CSSProperties;
  23. children?: React.ReactNode;
  24. xs?: number | ColSize;
  25. sm?: number | ColSize;
  26. md?: number | ColSize;
  27. lg?: number | ColSize;
  28. xl?: number | ColSize;
  29. xxl?: number | ColSize;
  30. }
  31. class Col extends React.Component<ColProps> {
  32. static contextType = RowContext;
  33. static propTypes = {
  34. span: PropTypes.number,
  35. order: PropTypes.number,
  36. offset: PropTypes.number,
  37. push: PropTypes.number,
  38. pull: PropTypes.number,
  39. className: PropTypes.string,
  40. children: PropTypes.node,
  41. xs: objectOrNumber,
  42. sm: objectOrNumber,
  43. md: objectOrNumber,
  44. lg: objectOrNumber,
  45. xl: objectOrNumber,
  46. xxl: objectOrNumber,
  47. prefixCls: PropTypes.string,
  48. };
  49. static defaultProps = {
  50. prefixCls: cssClasses.PREFIX,
  51. };
  52. render() {
  53. const { props } = this;
  54. const { prefixCls, span, order, offset, push, pull, className, children, ...others } = props;
  55. let sizeClassObj = {};
  56. const prefix = `${prefixCls}-col`;
  57. ['xs', 'sm', 'md', 'lg', 'xl', 'xxl'].forEach(size => {
  58. let sizeProps: ColSize = {};
  59. if (typeof props[size] === 'number') {
  60. sizeProps.span = props[size];
  61. } else if (typeof props[size] === 'object') {
  62. sizeProps = props[size] || {};
  63. }
  64. delete others[size];
  65. sizeClassObj = {
  66. ...sizeClassObj,
  67. [`${prefix}-${size}-${sizeProps.span}`]: sizeProps.span !== undefined,
  68. [`${prefix}-${size}-order-${sizeProps.order}`]: sizeProps.order || sizeProps.order === 0,
  69. [`${prefix}-${size}-offset-${sizeProps.offset}`]: sizeProps.offset || sizeProps.offset === 0,
  70. [`${prefix}-${size}-push-${sizeProps.push}`]: sizeProps.push || sizeProps.push === 0,
  71. [`${prefix}-${size}-pull-${sizeProps.pull}`]: sizeProps.pull || sizeProps.pull === 0,
  72. };
  73. });
  74. const classes = classnames(
  75. prefix,
  76. {
  77. [`${prefix}-${span}`]: span !== undefined,
  78. [`${prefix}-order-${order}`]: order,
  79. [`${prefix}-offset-${offset}`]: offset,
  80. [`${prefix}-push-${push}`]: push,
  81. [`${prefix}-pull-${pull}`]: pull,
  82. },
  83. className,
  84. sizeClassObj
  85. );
  86. let { style } = others;
  87. let gutters;
  88. try {
  89. gutters = this.context.gutters;
  90. } catch (error) {
  91. throw new Error('please make sure <Col> inside <Row>');
  92. }
  93. style = {
  94. ...(gutters[0] > 0 ?
  95. {
  96. paddingLeft: gutters[0] / 2,
  97. paddingRight: gutters[0] / 2,
  98. } :
  99. {}),
  100. ...(gutters[1] > 0 ?
  101. {
  102. paddingTop: gutters[1] / 2,
  103. paddingBottom: gutters[1] / 2,
  104. } :
  105. {}),
  106. ...style,
  107. };
  108. return (
  109. <div {...others} style={style} className={classes}>
  110. {children}
  111. </div>
  112. );
  113. }
  114. }
  115. export default Col;