col.tsx 3.9 KB

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