index.tsx 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. import React from 'react'
  2. import { Row } from 'antd'
  3. const styles = require('./EllipsisList.less')
  4. interface IEllipsisListProps {
  5. rows?: number
  6. children: JSX.Element[]
  7. }
  8. interface IEllipsisListStates {
  9. screenWidth: number
  10. withEllipsis: boolean
  11. }
  12. export class EllipsisList extends React.Component<IEllipsisListProps, IEllipsisListStates> {
  13. private container: any
  14. constructor (props) {
  15. super(props)
  16. this.state = {
  17. screenWidth: 0,
  18. withEllipsis: true
  19. }
  20. }
  21. public componentWillMount () {
  22. this.setScreenWidth()
  23. window.addEventListener('resize', this.setScreenWidth, false)
  24. }
  25. public componentWillUnmount () {
  26. window.removeEventListener('resize', this.setScreenWidth, false)
  27. }
  28. private setScreenWidth = () => {
  29. this.setState({
  30. screenWidth: document.documentElement.clientWidth
  31. })
  32. }
  33. private static layoutSetting = {
  34. xs: {
  35. minWidth: 0,
  36. cols: 1
  37. },
  38. sm: {
  39. minWidth: 768,
  40. cols: 2
  41. },
  42. md: {
  43. minWidth: 992,
  44. cols: 3
  45. },
  46. lg: {
  47. minWidth: 1200,
  48. cols: 4
  49. },
  50. xl: {
  51. minWidth: 1600,
  52. cols: 6
  53. }
  54. }
  55. private getColumns = () => {
  56. const { screenWidth } = this.state
  57. let cols = 0
  58. Object.keys(EllipsisList.layoutSetting).every((item) => {
  59. const setting = EllipsisList.layoutSetting[item]
  60. const pass = screenWidth >= setting.minWidth
  61. if (pass) { cols = setting.cols }
  62. return pass
  63. })
  64. return cols
  65. }
  66. private showAll = () => {
  67. this.setState({
  68. withEllipsis: false
  69. })
  70. }
  71. private renderEllipsis = (rowIdx: number, colIdx: number) => {
  72. const cols = this.getColumns()
  73. let style: React.CSSProperties = { }
  74. if (colIdx !== 0) {
  75. style = {
  76. bottom: `${100 / (2 * (rowIdx + 1))}%`,
  77. left: `${((2 * colIdx + 1) / (2 * cols)) * 100}%`,
  78. position: 'absolute',
  79. transform: 'translate3d(-50%, 50%, 0)'
  80. }
  81. } else {
  82. style = {
  83. display: 'flex',
  84. flexDirection: 'column',
  85. alignItems: 'center'
  86. }
  87. }
  88. return (
  89. <div style={style}>
  90. <div onClick={this.showAll} className={styles.moreList}>
  91. <div className={styles.more}/>
  92. <div className={styles.more}/>
  93. <div className={styles.more}/>
  94. </div>
  95. </div>
  96. )
  97. }
  98. public render () {
  99. const { rows, children } = this.props
  100. if (!Array.isArray(children)) { return null }
  101. const { withEllipsis } = this.state
  102. const cols = this.getColumns()
  103. let shownChildren = [...children]
  104. if (rows && withEllipsis) {
  105. shownChildren = shownChildren.slice(0, rows * cols - 1)
  106. }
  107. const rowIdx = Math.floor(shownChildren.length / cols)
  108. const colIdx = shownChildren.length % cols
  109. return (
  110. <Row
  111. gutter={20}
  112. ref={(f) => { this.container = f }}
  113. >
  114. {shownChildren}
  115. {rows && withEllipsis ? this.renderEllipsis(rowIdx, colIdx) : null}
  116. </Row>
  117. )
  118. }
  119. }
  120. export default EllipsisList