Advertisement
Guest User

Untitled

a guest
Sep 20th, 2019
108
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.24 KB | None | 0 0
  1. import React from 'react'
  2. import cx from 'classnames'
  3. import arrowRight from 'assets/images/arrow_right.svg'
  4. import CheckboxFilled from 'assets/images/checkbox_filled.svg'
  5. import CheckboxIndeterminate from 'assets/images/checkbox_indeterminate.svg'
  6. import CheckboxOutline from 'assets/images/checkbox_outline.svg'
  7. import styles from './TreeSelector.module.scss'
  8.  
  9. export class TreeSelector extends React.Component {
  10. constructor() {
  11. super()
  12. this.state = {
  13. expanded: [],
  14. selected: [],
  15. }
  16. }
  17.  
  18. getProductSkus = id => {
  19. const [product] = this.props.products.filter(product => product.id === id)
  20. return product.skus
  21. }
  22.  
  23. handleParentCheckbox = id => {
  24. const { selected } = this.state
  25. const skus = this.getProductSkus(id)
  26. const varientsSelected = []
  27.  
  28. skus.forEach(sku => {
  29. if (selected.includes(sku.id)) {
  30. varientsSelected.push(sku.id)
  31. }
  32. })
  33.  
  34. if (varientsSelected.length !== 0) {
  35. const checkboxIcon =
  36. varientsSelected.length === skus.length
  37. ? CheckboxFilled
  38. : CheckboxIndeterminate
  39. return checkboxIcon
  40. }
  41. return CheckboxOutline
  42. }
  43.  
  44. handleToggleExpandView = id => {
  45. const { expanded } = this.state
  46. if (expanded.includes(id)) {
  47. this.setState({ expanded: expanded.filter(item => item !== id) })
  48. } else {
  49. expanded.push(id)
  50. this.setState({ expanded })
  51. }
  52. }
  53.  
  54. handleParentSelection = id => {
  55. const { selected } = this.state
  56. const skus = this.getProductSkus(id)
  57. const varientsSelected = []
  58. const skusIds = []
  59. skus.forEach(({ id: skuId }) => {
  60. skusIds.push(skuId)
  61. if (selected.includes(skuId)) {
  62. varientsSelected.push(skuId)
  63. }
  64. })
  65.  
  66. this.setState({ selected: varientsSelected.length === 0 ? skusIds : [] })
  67. }
  68.  
  69. handleChildSelection = id => {
  70. const { selected } = this.state
  71. if (selected.includes(id)) {
  72. this.setState({ selected: selected.filter(item => item !== id) })
  73. } else {
  74. selected.push(id)
  75. this.setState({ selected })
  76. }
  77. }
  78.  
  79. renderCheckbox = (id, hasChildren) => {
  80. let checkboxIcon = CheckboxOutline
  81. if (hasChildren) {
  82. checkboxIcon = this.handleParentCheckbox(id)
  83. } else {
  84. checkboxIcon = this.state.selected.includes(id)
  85. ? CheckboxFilled
  86. : CheckboxOutline
  87. }
  88.  
  89. return (
  90. <span
  91. className={styles.checkbox}
  92. style={{ backgroundImage: `url(${checkboxIcon})` }}
  93. alt="selection"
  94. />
  95. )
  96. }
  97.  
  98. renderItem = ({
  99. id,
  100. images: [image],
  101. name,
  102. skus,
  103. productName,
  104. className,
  105. handleSelection,
  106. }) => {
  107. const { expanded } = this.state
  108. const hasChildren = skus && skus.length > 0
  109. const isExpanded = expanded.includes(id)
  110.  
  111. return (
  112. <>
  113. <div key={id} className={cx(styles.node, className)}>
  114. {hasChildren && (
  115. <button
  116. className="btn-reset"
  117. onClick={() => this.handleToggleExpandView(id)}
  118. >
  119. <img
  120. src={arrowRight}
  121. alt="arrow"
  122. className={cx(styles.arrow, isExpanded && styles.expanded)}
  123. />
  124. </button>
  125. )}
  126.  
  127. <button
  128. className={cx('btn-reset')}
  129. onClick={() => handleSelection(id)}
  130. >
  131. {this.renderCheckbox(id, hasChildren)}
  132. </button>
  133. <div
  134. className={styles.details}
  135. onClick={() => this.handleToggleExpandView(id)}
  136. >
  137. <img src={image.url} alt={name} className={styles.image} />
  138. <span>
  139. {productName && `${productName}: `}
  140. {name}
  141. </span>
  142. </div>
  143. </div>
  144.  
  145. {hasChildren &&
  146. isExpanded &&
  147. skus.map(sku =>
  148. this.renderItem({
  149. ...sku,
  150. productName: name,
  151. className: styles.child,
  152. handleSelection: this.handleChildSelection,
  153. })
  154. )}
  155. </>
  156. )
  157. }
  158.  
  159. render() {
  160. return (
  161. <section className={styles.container}>
  162. {this.props.products.map(product =>
  163. this.renderItem({
  164. ...product,
  165. handleSelection: this.handleParentSelection,
  166. })
  167. )}
  168. </section>
  169. )
  170. }
  171. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement