col.tsx 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  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, RowContextType } 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. context: RowContextType;
  56. render() {
  57. const { props } = this;
  58. const { prefixCls, span, order, offset, push, pull, className, children, ...others } = props;
  59. let sizeClassObj = {};
  60. const prefix = `${prefixCls}-col`;
  61. ['xs', 'sm', 'md', 'lg', 'xl', 'xxl'].forEach(size => {
  62. let sizeProps: ColSize = {};
  63. if (typeof props[size] === 'number') {
  64. sizeProps.span = props[size];
  65. } else if (typeof props[size] === 'object') {
  66. sizeProps = props[size] || {};
  67. }
  68. delete others[size];
  69. sizeClassObj = {
  70. ...sizeClassObj,
  71. [`${prefix}-${size}-${sizeProps.span}`]: sizeProps.span !== undefined,
  72. [`${prefix}-${size}-order-${sizeProps.order}`]: sizeProps.order || sizeProps.order === 0,
  73. [`${prefix}-${size}-offset-${sizeProps.offset}`]: sizeProps.offset || sizeProps.offset === 0,
  74. [`${prefix}-${size}-push-${sizeProps.push}`]: sizeProps.push || sizeProps.push === 0,
  75. [`${prefix}-${size}-pull-${sizeProps.pull}`]: sizeProps.pull || sizeProps.pull === 0,
  76. };
  77. });
  78. const classes = classnames(
  79. prefix,
  80. {
  81. [`${prefix}-${span}`]: span !== undefined,
  82. [`${prefix}-order-${order}`]: order,
  83. [`${prefix}-offset-${offset}`]: offset,
  84. [`${prefix}-push-${push}`]: push,
  85. [`${prefix}-pull-${pull}`]: pull,
  86. },
  87. className,
  88. sizeClassObj
  89. );
  90. let { style } = others;
  91. let gutters;
  92. try {
  93. gutters = this.context.gutters;
  94. } catch (error) {
  95. throw new Error('please make sure <Col> inside <Row>');
  96. }
  97. style = {
  98. ...(gutters[0] > 0 ?
  99. {
  100. paddingLeft: gutters[0] / 2,
  101. paddingRight: gutters[0] / 2,
  102. } :
  103. {}),
  104. ...(gutters[1] > 0 ?
  105. {
  106. paddingTop: gutters[1] / 2,
  107. paddingBottom: gutters[1] / 2,
  108. } :
  109. {}),
  110. ...style,
  111. };
  112. return (
  113. <div {...others} style={style} className={classes} x-semi-prop="children">
  114. {children}
  115. </div>
  116. );
  117. }
  118. }
  119. export default Col;