virtual-scroller 1.14.0 → 1.15.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (235) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/README.md +403 -254
  3. package/bundle/index-dom-bypass.html +197 -0
  4. package/bundle/index-dom-grid.html +203 -0
  5. package/bundle/index-dom-scrollableContainer.html +214 -0
  6. package/bundle/index-dom-tbody-scrollableContainer.html +81 -0
  7. package/bundle/index-dom-tbody.html +65 -0
  8. package/bundle/index-dom.html +114 -84
  9. package/bundle/index-react-bypass.html +194 -0
  10. package/bundle/{index-bypass.html → index-react-grid.html} +122 -120
  11. package/bundle/index-react-hook.html +209 -0
  12. package/bundle/index-react-scrollableContainer.html +207 -0
  13. package/bundle/index-react-strictMode.html +193 -0
  14. package/bundle/index-react-tbody-scrollableContainer.html +94 -0
  15. package/bundle/index-react-tbody.html +78 -0
  16. package/bundle/{messages.js → items.js} +1 -1
  17. package/bundle/lib/babel.min.js +25 -0
  18. package/bundle/lib/prop-types.min.js +1 -0
  19. package/bundle/lib/react-dom.development.js +29924 -0
  20. package/bundle/lib/react-dom.production.min.js +267 -0
  21. package/bundle/lib/react.development.js +3343 -0
  22. package/bundle/lib/react.production.min.js +31 -0
  23. package/bundle/style.base.css +33 -0
  24. package/{website/style.css → bundle/style.list.css} +10 -43
  25. package/bundle/style.list.grid.css +23 -0
  26. package/bundle/virtual-scroller-dom.js +1 -1
  27. package/bundle/virtual-scroller-dom.js.map +1 -1
  28. package/bundle/virtual-scroller-react.js +1 -1
  29. package/bundle/virtual-scroller-react.js.map +1 -1
  30. package/bundle/virtual-scroller.js +1 -1
  31. package/bundle/virtual-scroller.js.map +1 -1
  32. package/commonjs/BeforeResize.js +1 -2
  33. package/commonjs/BeforeResize.js.map +1 -1
  34. package/commonjs/DOM/VirtualScroller.js +7 -13
  35. package/commonjs/DOM/VirtualScroller.js.map +1 -1
  36. package/commonjs/DOM/tbody.js +6 -6
  37. package/commonjs/DOM/tbody.js.map +1 -1
  38. package/commonjs/ItemHeights.js +10 -13
  39. package/commonjs/ItemHeights.js.map +1 -1
  40. package/commonjs/Layout.defaults.js +21 -0
  41. package/commonjs/Layout.defaults.js.map +1 -0
  42. package/commonjs/Layout.js +75 -64
  43. package/commonjs/Layout.js.map +1 -1
  44. package/commonjs/Layout.test.js +8 -4
  45. package/commonjs/Layout.test.js.map +1 -1
  46. package/commonjs/VirtualScroller.constructor.js +38 -4
  47. package/commonjs/VirtualScroller.constructor.js.map +1 -1
  48. package/commonjs/VirtualScroller.items.js +50 -4
  49. package/commonjs/VirtualScroller.items.js.map +1 -1
  50. package/commonjs/VirtualScroller.js +23 -14
  51. package/commonjs/VirtualScroller.js.map +1 -1
  52. package/commonjs/VirtualScroller.layout.js +40 -29
  53. package/commonjs/VirtualScroller.layout.js.map +1 -1
  54. package/commonjs/VirtualScroller.onContainerResize.js +1 -2
  55. package/commonjs/VirtualScroller.onContainerResize.js.map +1 -1
  56. package/commonjs/VirtualScroller.state.js +10 -9
  57. package/commonjs/VirtualScroller.state.js.map +1 -1
  58. package/commonjs/VirtualScroller.verticalSpacing.js +39 -6
  59. package/commonjs/VirtualScroller.verticalSpacing.js.map +1 -1
  60. package/commonjs/react/VirtualScroller.js +124 -131
  61. package/commonjs/react/VirtualScroller.js.map +1 -1
  62. package/commonjs/react/useClassName.js +2 -2
  63. package/commonjs/react/useClassName.js.map +1 -1
  64. package/commonjs/react/useCreateVirtualScroller.js +64 -0
  65. package/commonjs/react/useCreateVirtualScroller.js.map +1 -0
  66. package/commonjs/react/useInstanceMethods.js +4 -4
  67. package/commonjs/react/useInstanceMethods.js.map +1 -1
  68. package/commonjs/react/useItemKeys.js +28 -5
  69. package/commonjs/react/useItemKeys.js.map +1 -1
  70. package/commonjs/react/useMergeRefs.js +52 -0
  71. package/commonjs/react/useMergeRefs.js.map +1 -0
  72. package/commonjs/react/useOnItemHeightDidChange.js +28 -12
  73. package/commonjs/react/useOnItemHeightDidChange.js.map +1 -1
  74. package/commonjs/react/useSetItemState.js +31 -12
  75. package/commonjs/react/useSetItemState.js.map +1 -1
  76. package/commonjs/react/{useVirtualScrollerStartStop.js → useStartStopVirtualScroller.js} +1 -1
  77. package/commonjs/react/{useVirtualScrollerStartStop.js.map → useStartStopVirtualScroller.js.map} +1 -1
  78. package/commonjs/react/useState.js +9 -9
  79. package/commonjs/react/useState.js.map +1 -1
  80. package/commonjs/react/{useStateNoStaleBug.js → useStateWithRepeatableRead.js} +3 -3
  81. package/commonjs/react/useStateWithRepeatableRead.js.map +1 -0
  82. package/commonjs/react/useStyle.js +28 -4
  83. package/commonjs/react/useStyle.js.map +1 -1
  84. package/commonjs/react/useValidateTableBodyItemsContainer.js +24 -0
  85. package/commonjs/react/useValidateTableBodyItemsContainer.js.map +1 -0
  86. package/commonjs/react/useVirtualScroller.js +142 -42
  87. package/commonjs/react/useVirtualScroller.js.map +1 -1
  88. package/commonjs/test/ItemsContainer.js +10 -10
  89. package/commonjs/test/ItemsContainer.js.map +1 -1
  90. package/commonjs/test/VirtualScroller.js +25 -10
  91. package/commonjs/test/VirtualScroller.js.map +1 -1
  92. package/dom/index.d.ts +6 -5
  93. package/index.d.ts +19 -8
  94. package/modules/BeforeResize.js +1 -2
  95. package/modules/BeforeResize.js.map +1 -1
  96. package/modules/DOM/VirtualScroller.js +7 -13
  97. package/modules/DOM/VirtualScroller.js.map +1 -1
  98. package/modules/DOM/tbody.js +4 -4
  99. package/modules/DOM/tbody.js.map +1 -1
  100. package/modules/ItemHeights.js +11 -14
  101. package/modules/ItemHeights.js.map +1 -1
  102. package/modules/Layout.defaults.js +11 -0
  103. package/modules/Layout.defaults.js.map +1 -0
  104. package/modules/Layout.js +74 -64
  105. package/modules/Layout.js.map +1 -1
  106. package/modules/Layout.test.js +8 -4
  107. package/modules/Layout.test.js.map +1 -1
  108. package/modules/VirtualScroller.constructor.js +37 -4
  109. package/modules/VirtualScroller.constructor.js.map +1 -1
  110. package/modules/VirtualScroller.items.js +51 -5
  111. package/modules/VirtualScroller.items.js.map +1 -1
  112. package/modules/VirtualScroller.js +23 -14
  113. package/modules/VirtualScroller.js.map +1 -1
  114. package/modules/VirtualScroller.layout.js +40 -29
  115. package/modules/VirtualScroller.layout.js.map +1 -1
  116. package/modules/VirtualScroller.onContainerResize.js +1 -2
  117. package/modules/VirtualScroller.onContainerResize.js.map +1 -1
  118. package/modules/VirtualScroller.state.js +10 -9
  119. package/modules/VirtualScroller.state.js.map +1 -1
  120. package/modules/VirtualScroller.verticalSpacing.js +38 -6
  121. package/modules/VirtualScroller.verticalSpacing.js.map +1 -1
  122. package/modules/react/VirtualScroller.js +122 -124
  123. package/modules/react/VirtualScroller.js.map +1 -1
  124. package/modules/react/useClassName.js +3 -3
  125. package/modules/react/useClassName.js.map +1 -1
  126. package/modules/react/useCreateVirtualScroller.js +53 -0
  127. package/modules/react/useCreateVirtualScroller.js.map +1 -0
  128. package/modules/react/useInstanceMethods.js +4 -4
  129. package/modules/react/useInstanceMethods.js.map +1 -1
  130. package/modules/react/useItemKeys.js +28 -5
  131. package/modules/react/useItemKeys.js.map +1 -1
  132. package/modules/react/useMergeRefs.js +44 -0
  133. package/modules/react/useMergeRefs.js.map +1 -0
  134. package/modules/react/useOnItemHeightDidChange.js +28 -12
  135. package/modules/react/useOnItemHeightDidChange.js.map +1 -1
  136. package/modules/react/useSetItemState.js +31 -12
  137. package/modules/react/useSetItemState.js.map +1 -1
  138. package/modules/react/{useVirtualScrollerStartStop.js → useStartStopVirtualScroller.js} +1 -1
  139. package/modules/react/{useVirtualScrollerStartStop.js.map → useStartStopVirtualScroller.js.map} +1 -1
  140. package/modules/react/useState.js +9 -9
  141. package/modules/react/useState.js.map +1 -1
  142. package/modules/react/{useStateNoStaleBug.js → useStateWithRepeatableRead.js} +2 -2
  143. package/modules/react/useStateWithRepeatableRead.js.map +1 -0
  144. package/modules/react/useStyle.js +27 -4
  145. package/modules/react/useStyle.js.map +1 -1
  146. package/modules/react/useValidateTableBodyItemsContainer.js +16 -0
  147. package/modules/react/useValidateTableBodyItemsContainer.js.map +1 -0
  148. package/modules/react/useVirtualScroller.js +136 -42
  149. package/modules/react/useVirtualScroller.js.map +1 -1
  150. package/modules/test/ItemsContainer.js +10 -10
  151. package/modules/test/ItemsContainer.js.map +1 -1
  152. package/modules/test/VirtualScroller.js +25 -10
  153. package/modules/test/VirtualScroller.js.map +1 -1
  154. package/package.json +4 -1
  155. package/react/as.d.ts +42 -0
  156. package/react/index.cjs +2 -1
  157. package/react/index.d.ts +248 -63
  158. package/react/index.js +1 -0
  159. package/rollup.config.mjs +15 -1
  160. package/source/BeforeResize.js +1 -2
  161. package/source/DOM/VirtualScroller.js +7 -13
  162. package/source/DOM/tbody.js +5 -5
  163. package/source/ItemHeights.js +11 -12
  164. package/source/Layout.defaults.js +8 -0
  165. package/source/Layout.js +66 -53
  166. package/source/Layout.test.js +7 -2
  167. package/source/VirtualScroller.constructor.js +27 -4
  168. package/source/VirtualScroller.items.js +47 -2
  169. package/source/VirtualScroller.js +23 -14
  170. package/source/VirtualScroller.layout.js +41 -28
  171. package/source/VirtualScroller.onContainerResize.js +1 -2
  172. package/source/VirtualScroller.state.js +10 -11
  173. package/source/VirtualScroller.verticalSpacing.js +32 -6
  174. package/source/react/VirtualScroller.js +135 -133
  175. package/source/react/useClassName.js +3 -3
  176. package/source/react/useCreateVirtualScroller.js +65 -0
  177. package/source/react/useInstanceMethods.js +12 -4
  178. package/source/react/useItemKeys.js +22 -4
  179. package/source/react/useMergeRefs.js +45 -0
  180. package/source/react/useOnItemHeightDidChange.js +29 -10
  181. package/source/react/useSetItemState.js +32 -10
  182. package/source/react/useState.js +6 -6
  183. package/source/react/{useStateNoStaleBug.js → useStateWithRepeatableRead.js} +1 -1
  184. package/source/react/useStyle.js +18 -2
  185. package/source/react/useValidateTableBodyItemsContainer.js +16 -0
  186. package/source/react/useVirtualScroller.js +155 -47
  187. package/source/test/ItemsContainer.js +10 -10
  188. package/source/test/VirtualScroller.js +16 -10
  189. package/website/index-dom-bypass.html +197 -0
  190. package/website/index-dom-grid.html +203 -0
  191. package/website/index-dom-scrollableContainer.html +214 -0
  192. package/website/index-dom-tbody-scrollableContainer.html +81 -0
  193. package/website/index-dom-tbody.html +65 -0
  194. package/website/index-dom.html +116 -84
  195. package/website/index-react-bypass.html +194 -0
  196. package/website/index-react-grid.html +197 -0
  197. package/website/index-react-hook.html +209 -0
  198. package/website/index-react-scrollableContainer.html +207 -0
  199. package/website/index-react-strictMode.html +193 -0
  200. package/website/index-react-tbody-scrollableContainer.html +94 -0
  201. package/website/index-react-tbody.html +78 -0
  202. package/website/index-react.html +193 -0
  203. package/website/index.html +120 -111
  204. package/website/{messages.js → items.js} +1 -1
  205. package/website/lib/babel.min.js +25 -0
  206. package/website/lib/prop-types.min.js +1 -0
  207. package/website/lib/react-dom.development.js +29924 -0
  208. package/website/lib/react-dom.production.min.js +267 -0
  209. package/website/lib/react.development.js +3343 -0
  210. package/website/lib/react.production.min.js +31 -0
  211. package/website/style.base.css +33 -0
  212. package/website/style.list.css +92 -0
  213. package/website/style.list.grid.css +23 -0
  214. package/bundle/index-grid.html +0 -216
  215. package/bundle/index-scrollableContainer.html +0 -208
  216. package/bundle/index-tbody-scrollableContainer.html +0 -70
  217. package/bundle/index-tbody.html +0 -57
  218. package/bundle/on-scroll-to-dom.js +0 -2
  219. package/bundle/on-scroll-to-dom.js.map +0 -1
  220. package/bundle/on-scroll-to-react.js +0 -2
  221. package/bundle/on-scroll-to-react.js.map +0 -1
  222. package/bundle/on-scroll-to.js +0 -2
  223. package/bundle/on-scroll-to.js.map +0 -1
  224. package/commonjs/react/useStateNoStaleBug.js.map +0 -1
  225. package/modules/react/useStateNoStaleBug.js.map +0 -1
  226. package/website/index-bypass.html +0 -185
  227. package/website/index-grid.html +0 -216
  228. package/website/index-scrollableContainer.html +0 -208
  229. package/website/index-tbody-scrollableContainer.html +0 -70
  230. package/website/index-tbody.html +0 -57
  231. package/website/lib/on-scroll-to-dom.js +0 -2
  232. package/website/lib/on-scroll-to-dom.js.map +0 -1
  233. package/website/lib/on-scroll-to-react.js +0 -2
  234. package/website/lib/on-scroll-to-react.js.map +0 -1
  235. /package/source/react/{useVirtualScrollerStartStop.js → useStartStopVirtualScroller.js} +0 -0
@@ -6,132 +6,146 @@
6
6
  <!-- Fix document width for mobile devices. -->
7
7
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
8
8
 
9
- <title>React VirtualScroller Demo</title>
9
+ <title>VirtualScroller (React)</title>
10
10
 
11
- <script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
12
- <script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
13
- <script crossorigin src="https://cdnjs.cloudflare.com/ajax/libs/prop-types/15.7.2/prop-types.min.js"></script>
14
- <script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
11
+ <script src="./lib/react.development.js"></script>
12
+ <script src="./lib/react-dom.development.js"></script>
13
+ <script src="./lib/prop-types.min.js"></script>
14
+ <script src="./lib/babel.min.js"></script>
15
15
 
16
16
  <script src="./virtual-scroller-react.js"></script>
17
- <script src="./lib/on-scroll-to-react.js"></script>
18
- <script src="./messages.js"></script>
17
+ <script src="./items.js"></script>
19
18
 
20
- <link rel="stylesheet" href="./style.css"/>
19
+ <link rel="stylesheet" href="./style.base.css"/>
20
+ <link rel="stylesheet" href="./style.list.css"/>
21
21
  </head>
22
22
 
23
23
  <body>
24
24
  <!-- http://tholman.com/github-corners/ -->
25
- <a title="Go to GitLab repo" href="https://gitlab.com/catamphetamine/virtual-scroller" class="github-corner" aria-label="View source on GitLab"><svg width="80" height="80" viewBox="0 0 250 250" style="fill:#151513; color:#fff; position: absolute; top: 0; border: 0; right: 0;" aria-hidden="true"><path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path><path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path><path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path></svg></a><style>.github-corner:hover .octo-arm{animation:octocat-wave 560ms ease-in-out}@keyframes octocat-wave{0%,100%{transform:rotate(0)}20%,60%{transform:rotate(-25deg)}40%,80%{transform:rotate(10deg)}}@media (max-width:500px){.github-corner:hover .octo-arm{animation:none}.github-corner .octo-arm{animation:octocat-wave 560ms ease-in-out}}</style>
25
+ <a title="Go to GitHub repo" href="https://gitlab.com/catamphetamine/virtual-scroller" class="github-corner" aria-label="View source on GitHub"><svg width="80" height="80" viewBox="0 0 250 250" style="fill:#151513; color:#fff; position: absolute; top: 0; border: 0; right: 0;" aria-hidden="true"><path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path><path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path><path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path></svg></a><style>.github-corner:hover .octo-arm{animation:octocat-wave 560ms ease-in-out}@keyframes octocat-wave{0%,100%{transform:rotate(0)}20%,60%{transform:rotate(-25deg)}40%,80%{transform:rotate(10deg)}}@media (max-width:500px){.github-corner:hover .octo-arm{animation:none}.github-corner .octo-arm{animation:octocat-wave 560ms ease-in-out}}</style>
26
26
 
27
27
  <div id="root"></div>
28
28
 
29
29
  <script>
30
30
  // Enable debug output to console.
31
31
  window.VirtualScrollerDebug = true
32
- // Whether "dynamically loaded list" mode is enabled.
33
- window.dynamic = new URL(window.location).searchParams.get('dynamic')
32
+ // Pass `?pagination=✓` URL query parameter to enable pagination.
33
+ window.PAGINATION = Boolean(new URL(window.location).searchParams.get('pagination'))
34
34
  </script>
35
35
 
36
36
  <script type="text/babel">
37
- const BATCH_SIZE = 6
38
-
39
- class FeedMessages extends React.Component {
40
- constructor(props) {
41
- super(props)
42
- const { messages } = this.props
43
- if (window.dynamic) {
44
- const fromIndex = Math.floor(messages.length / 2 - BATCH_SIZE / 2)
45
- const toIndex = fromIndex + BATCH_SIZE - 1
46
- this.state = {
47
- fromIndex,
48
- toIndex,
49
- messages: messages.slice(fromIndex, toIndex + 1)
50
- }
51
- } else {
52
- this.state = {
53
- fromIndex: 0,
54
- toIndex: messages.length,
55
- messages
56
- }
57
- }
58
- }
37
+ const BATCH_SIZE = 6
38
+ const COLUMNS_COUNT = 1
59
39
 
60
- onShowPrevious = () => {
61
- const { messages } = this.props
62
- let { fromIndex } = this.state
63
- const { toIndex } = this.state
64
- fromIndex = Math.max(fromIndex - BATCH_SIZE, 0)
65
- this.setState({
40
+ function getColumnsCount(container) {
41
+ return 1
42
+ }
43
+
44
+ function getInitialState(items) {
45
+ if (window.PAGINATION) {
46
+ const fromIndex = Math.floor((items.length - BATCH_SIZE) / 2 / COLUMNS_COUNT) * COLUMNS_COUNT
47
+ const toIndex = fromIndex + BATCH_SIZE - 1
48
+ return {
66
49
  fromIndex,
67
- messages: messages.slice(fromIndex, toIndex + 1)
68
- })
50
+ toIndex,
51
+ items: items.slice(fromIndex, toIndex + 1)
52
+ }
53
+ } else {
54
+ return {
55
+ fromIndex: 0,
56
+ toIndex: items.length,
57
+ items: items
58
+ }
69
59
  }
60
+ }
70
61
 
71
- onShowNext = () => {
72
- const { messages } = this.props
73
- const { fromIndex } = this.state
74
- let { toIndex } = this.state
75
- toIndex = Math.min(toIndex + BATCH_SIZE, messages.length - 1)
76
- this.setState({
77
- toIndex,
78
- messages: messages.slice(fromIndex, toIndex + 1)
79
- })
62
+ function onShowPrevious(items, getState, setState) {
63
+ let { fromIndex } = getState()
64
+ const { toIndex } = getState()
65
+ fromIndex = Math.max(fromIndex - BATCH_SIZE, 0)
66
+ setState({
67
+ ...getState(),
68
+ fromIndex,
69
+ items: items.slice(fromIndex, toIndex + 1)
70
+ })
71
+ }
72
+
73
+ function onShowNext(items, getState, setState) {
74
+ const { fromIndex } = getState()
75
+ let { toIndex } = getState()
76
+ toIndex = Math.min(toIndex + BATCH_SIZE, items.length - 1)
77
+ setState({
78
+ ...getState(),
79
+ toIndex,
80
+ items: items.slice(fromIndex, toIndex + 1)
81
+ })
82
+ }
83
+
84
+ function VirtualScrollerDemo() {
85
+ const [state, setState] = React.useState(getInitialState(ITEMS))
86
+
87
+ const getState = () => state
88
+
89
+ const onShowPrevious_ = () => {
90
+ onShowPrevious(ITEMS, getState, setState)
80
91
  }
81
92
 
82
- render() {
83
- const {
84
- fromIndex,
85
- toIndex,
86
- messages
87
- } = this.state
88
- return (
89
- <React.Fragment>
90
- {window.dynamic && fromIndex > 0 &&
91
- <button
92
- type="button"
93
- onClick={this.onShowPrevious}
94
- className="load-items-button">
95
- Show previous
96
- </button>
97
- }
98
- <VirtualScroller
99
- id="messages"
100
- items={messages}
101
- itemComponent={Message}
102
- preserveScrollPositionOnPrependItems/>
103
- {window.dynamic && toIndex < this.props.messages.length - 1 &&
104
- <button
105
- type="button"
106
- onClick={this.onShowNext}
107
- className="load-items-button">
108
- Show next
109
- </button>
110
- }
111
- </React.Fragment>
112
- )
93
+ const onShowNext_ = () => {
94
+ onShowNext(ITEMS, getState, setState)
113
95
  }
96
+
97
+ const {
98
+ fromIndex,
99
+ toIndex,
100
+ items
101
+ } = state
102
+
103
+ return (
104
+ <React.Fragment>
105
+ {window.PAGINATION && fromIndex > 0 &&
106
+ <button
107
+ type="button"
108
+ onClick={onShowPrevious_}
109
+ className="load-items-button">
110
+ Show previous
111
+ </button>
112
+ }
113
+ <VirtualScroller
114
+ id="list"
115
+ items={items}
116
+ itemComponent={Item}
117
+ preserveScrollPositionOnPrependItems
118
+ getColumnsCount={getColumnsCount}
119
+ />
120
+ {window.PAGINATION && toIndex < ITEMS.length - 1 &&
121
+ <button
122
+ type="button"
123
+ onClick={onShowNext_}
124
+ className="load-items-button">
125
+ Show next
126
+ </button>
127
+ }
128
+ </React.Fragment>
129
+ )
114
130
  }
115
131
 
116
- const message = PropTypes.shape({
132
+ const item = PropTypes.shape({
117
133
  username: PropTypes.string.isRequired,
118
134
  date: PropTypes.instanceOf(Date).isRequired,
119
135
  text: PropTypes.string.isRequired
120
136
  })
121
137
 
122
- FeedMessages.propTypes = {
123
- messages: PropTypes.arrayOf(message).isRequired
124
- }
138
+ function Item(props) {
139
+ const { children: item } = props
125
140
 
126
- function Message(props) {
127
- const { item: message } = props
128
141
  const {
129
142
  username,
130
143
  date,
131
144
  text
132
- } = message
145
+ } = item
146
+
133
147
  return (
134
- <article className="feed-message">
148
+ <article className="list-item">
135
149
  <a target="_blank" href={`https://twitter.com/${username}`}>
136
150
  @{username}
137
151
  </a>
@@ -145,26 +159,23 @@
145
159
  )
146
160
  }
147
161
 
148
- Message.propTypes = {
149
- item: message.isRequired
162
+ Item.propTypes = {
163
+ children: item.isRequired
150
164
  }
151
165
 
152
- class Feed extends React.Component {
153
- render() {
154
- return (
155
- <section className="container">
156
- <h1>
157
- <TwitterLogo/>
158
- Latest Tweets on #politics
159
- </h1>
160
- <FeedMessages
161
- messages={messages}/>
162
- <footer>
163
- © Twitter Inc., 2019
164
- </footer>
165
- </section>
166
- )
167
- }
166
+ function Demo() {
167
+ return (
168
+ <section className="container">
169
+ <h1>
170
+ <TwitterLogo/>
171
+ Latest Tweets on #politics
172
+ </h1>
173
+ <VirtualScrollerDemo/>
174
+ <footer>
175
+ © Twitter Inc., 2019
176
+ </footer>
177
+ </section>
178
+ )
168
179
  }
169
180
 
170
181
  function TwitterLogo() {
@@ -175,10 +186,8 @@
175
186
  )
176
187
  }
177
188
 
178
- ReactDOM.render(
179
- <Feed/>,
180
- document.getElementById('root')
181
- )
189
+ const root = ReactDOM.createRoot(document.getElementById('root'))
190
+ root.render(<Demo/>)
182
191
  </script>
183
192
  </body>
184
193
  </html>
@@ -1,4 +1,4 @@
1
- window.messages = [
1
+ window.ITEMS = [
2
2
  {
3
3
  username: 'realdonaldtrump',
4
4
  date: new Date(2019, 4, 10),