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
@@ -0,0 +1,31 @@
1
+ /**
2
+ * @license React
3
+ * react.production.min.js
4
+ *
5
+ * Copyright (c) Facebook, Inc. and its affiliates.
6
+ *
7
+ * This source code is licensed under the MIT license found in the
8
+ * LICENSE file in the root directory of this source tree.
9
+ */
10
+ (function(){'use strict';(function(c,x){"object"===typeof exports&&"undefined"!==typeof module?x(exports):"function"===typeof define&&define.amd?define(["exports"],x):(c=c||self,x(c.React={}))})(this,function(c){function x(a){if(null===a||"object"!==typeof a)return null;a=V&&a[V]||a["@@iterator"];return"function"===typeof a?a:null}function w(a,b,e){this.props=a;this.context=b;this.refs=W;this.updater=e||X}function Y(){}function K(a,b,e){this.props=a;this.context=b;this.refs=W;this.updater=e||X}function Z(a,b,
11
+ e){var m,d={},c=null,h=null;if(null!=b)for(m in void 0!==b.ref&&(h=b.ref),void 0!==b.key&&(c=""+b.key),b)aa.call(b,m)&&!ba.hasOwnProperty(m)&&(d[m]=b[m]);var l=arguments.length-2;if(1===l)d.children=e;else if(1<l){for(var f=Array(l),k=0;k<l;k++)f[k]=arguments[k+2];d.children=f}if(a&&a.defaultProps)for(m in l=a.defaultProps,l)void 0===d[m]&&(d[m]=l[m]);return{$$typeof:y,type:a,key:c,ref:h,props:d,_owner:L.current}}function oa(a,b){return{$$typeof:y,type:a.type,key:b,ref:a.ref,props:a.props,_owner:a._owner}}
12
+ function M(a){return"object"===typeof a&&null!==a&&a.$$typeof===y}function pa(a){var b={"=":"=0",":":"=2"};return"$"+a.replace(/[=:]/g,function(a){return b[a]})}function N(a,b){return"object"===typeof a&&null!==a&&null!=a.key?pa(""+a.key):b.toString(36)}function B(a,b,e,m,d){var c=typeof a;if("undefined"===c||"boolean"===c)a=null;var h=!1;if(null===a)h=!0;else switch(c){case "string":case "number":h=!0;break;case "object":switch(a.$$typeof){case y:case qa:h=!0}}if(h)return h=a,d=d(h),a=""===m?"."+
13
+ N(h,0):m,ca(d)?(e="",null!=a&&(e=a.replace(da,"$&/")+"/"),B(d,b,e,"",function(a){return a})):null!=d&&(M(d)&&(d=oa(d,e+(!d.key||h&&h.key===d.key?"":(""+d.key).replace(da,"$&/")+"/")+a)),b.push(d)),1;h=0;m=""===m?".":m+":";if(ca(a))for(var l=0;l<a.length;l++){c=a[l];var f=m+N(c,l);h+=B(c,b,e,f,d)}else if(f=x(a),"function"===typeof f)for(a=f.call(a),l=0;!(c=a.next()).done;)c=c.value,f=m+N(c,l++),h+=B(c,b,e,f,d);else if("object"===c)throw b=String(a),Error("Objects are not valid as a React child (found: "+
14
+ ("[object Object]"===b?"object with keys {"+Object.keys(a).join(", ")+"}":b)+"). If you meant to render a collection of children, use an array instead.");return h}function C(a,b,e){if(null==a)return a;var c=[],d=0;B(a,c,"","",function(a){return b.call(e,a,d++)});return c}function ra(a){if(-1===a._status){var b=a._result;b=b();b.then(function(b){if(0===a._status||-1===a._status)a._status=1,a._result=b},function(b){if(0===a._status||-1===a._status)a._status=2,a._result=b});-1===a._status&&(a._status=
15
+ 0,a._result=b)}if(1===a._status)return a._result.default;throw a._result;}function O(a,b){var e=a.length;a.push(b);a:for(;0<e;){var c=e-1>>>1,d=a[c];if(0<D(d,b))a[c]=b,a[e]=d,e=c;else break a}}function p(a){return 0===a.length?null:a[0]}function E(a){if(0===a.length)return null;var b=a[0],e=a.pop();if(e!==b){a[0]=e;a:for(var c=0,d=a.length,k=d>>>1;c<k;){var h=2*(c+1)-1,l=a[h],f=h+1,g=a[f];if(0>D(l,e))f<d&&0>D(g,l)?(a[c]=g,a[f]=e,c=f):(a[c]=l,a[h]=e,c=h);else if(f<d&&0>D(g,e))a[c]=g,a[f]=e,c=f;else break a}}return b}
16
+ function D(a,b){var c=a.sortIndex-b.sortIndex;return 0!==c?c:a.id-b.id}function P(a){for(var b=p(r);null!==b;){if(null===b.callback)E(r);else if(b.startTime<=a)E(r),b.sortIndex=b.expirationTime,O(q,b);else break;b=p(r)}}function Q(a){z=!1;P(a);if(!u)if(null!==p(q))u=!0,R(S);else{var b=p(r);null!==b&&T(Q,b.startTime-a)}}function S(a,b){u=!1;z&&(z=!1,ea(A),A=-1);F=!0;var c=k;try{P(b);for(n=p(q);null!==n&&(!(n.expirationTime>b)||a&&!fa());){var m=n.callback;if("function"===typeof m){n.callback=null;
17
+ k=n.priorityLevel;var d=m(n.expirationTime<=b);b=v();"function"===typeof d?n.callback=d:n===p(q)&&E(q);P(b)}else E(q);n=p(q)}if(null!==n)var g=!0;else{var h=p(r);null!==h&&T(Q,h.startTime-b);g=!1}return g}finally{n=null,k=c,F=!1}}function fa(){return v()-ha<ia?!1:!0}function R(a){G=a;H||(H=!0,I())}function T(a,b){A=ja(function(){a(v())},b)}function ka(a){throw Error("act(...) is not supported in production builds of React.");}var y=Symbol.for("react.element"),qa=Symbol.for("react.portal"),sa=Symbol.for("react.fragment"),
18
+ ta=Symbol.for("react.strict_mode"),ua=Symbol.for("react.profiler"),va=Symbol.for("react.provider"),wa=Symbol.for("react.context"),xa=Symbol.for("react.forward_ref"),ya=Symbol.for("react.suspense"),za=Symbol.for("react.memo"),Aa=Symbol.for("react.lazy"),V=Symbol.iterator,X={isMounted:function(a){return!1},enqueueForceUpdate:function(a,b,c){},enqueueReplaceState:function(a,b,c,m){},enqueueSetState:function(a,b,c,m){}},la=Object.assign,W={};w.prototype.isReactComponent={};w.prototype.setState=function(a,
19
+ b){if("object"!==typeof a&&"function"!==typeof a&&null!=a)throw Error("setState(...): takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,a,b,"setState")};w.prototype.forceUpdate=function(a){this.updater.enqueueForceUpdate(this,a,"forceUpdate")};Y.prototype=w.prototype;var t=K.prototype=new Y;t.constructor=K;la(t,w.prototype);t.isPureReactComponent=!0;var ca=Array.isArray,aa=Object.prototype.hasOwnProperty,L={current:null},
20
+ ba={key:!0,ref:!0,__self:!0,__source:!0},da=/\/+/g,g={current:null},J={transition:null};if("object"===typeof performance&&"function"===typeof performance.now){var Ba=performance;var v=function(){return Ba.now()}}else{var ma=Date,Ca=ma.now();v=function(){return ma.now()-Ca}}var q=[],r=[],Da=1,n=null,k=3,F=!1,u=!1,z=!1,ja="function"===typeof setTimeout?setTimeout:null,ea="function"===typeof clearTimeout?clearTimeout:null,na="undefined"!==typeof setImmediate?setImmediate:null;"undefined"!==typeof navigator&&
21
+ void 0!==navigator.scheduling&&void 0!==navigator.scheduling.isInputPending&&navigator.scheduling.isInputPending.bind(navigator.scheduling);var H=!1,G=null,A=-1,ia=5,ha=-1,U=function(){if(null!==G){var a=v();ha=a;var b=!0;try{b=G(!0,a)}finally{b?I():(H=!1,G=null)}}else H=!1};if("function"===typeof na)var I=function(){na(U)};else if("undefined"!==typeof MessageChannel){t=new MessageChannel;var Ea=t.port2;t.port1.onmessage=U;I=function(){Ea.postMessage(null)}}else I=function(){ja(U,0)};t={ReactCurrentDispatcher:g,
22
+ ReactCurrentOwner:L,ReactCurrentBatchConfig:J,Scheduler:{__proto__:null,unstable_ImmediatePriority:1,unstable_UserBlockingPriority:2,unstable_NormalPriority:3,unstable_IdlePriority:5,unstable_LowPriority:4,unstable_runWithPriority:function(a,b){switch(a){case 1:case 2:case 3:case 4:case 5:break;default:a=3}var c=k;k=a;try{return b()}finally{k=c}},unstable_next:function(a){switch(k){case 1:case 2:case 3:var b=3;break;default:b=k}var c=k;k=b;try{return a()}finally{k=c}},unstable_scheduleCallback:function(a,
23
+ b,c){var e=v();"object"===typeof c&&null!==c?(c=c.delay,c="number"===typeof c&&0<c?e+c:e):c=e;switch(a){case 1:var d=-1;break;case 2:d=250;break;case 5:d=1073741823;break;case 4:d=1E4;break;default:d=5E3}d=c+d;a={id:Da++,callback:b,priorityLevel:a,startTime:c,expirationTime:d,sortIndex:-1};c>e?(a.sortIndex=c,O(r,a),null===p(q)&&a===p(r)&&(z?(ea(A),A=-1):z=!0,T(Q,c-e))):(a.sortIndex=d,O(q,a),u||F||(u=!0,R(S)));return a},unstable_cancelCallback:function(a){a.callback=null},unstable_wrapCallback:function(a){var b=
24
+ k;return function(){var c=k;k=b;try{return a.apply(this,arguments)}finally{k=c}}},unstable_getCurrentPriorityLevel:function(){return k},unstable_shouldYield:fa,unstable_requestPaint:function(){},unstable_continueExecution:function(){u||F||(u=!0,R(S))},unstable_pauseExecution:function(){},unstable_getFirstCallbackNode:function(){return p(q)},get unstable_now(){return v},unstable_forceFrameRate:function(a){0>a||125<a?console.error("forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported"):
25
+ ia=0<a?Math.floor(1E3/a):5},unstable_Profiling:null}};c.Children={map:C,forEach:function(a,b,c){C(a,function(){b.apply(this,arguments)},c)},count:function(a){var b=0;C(a,function(){b++});return b},toArray:function(a){return C(a,function(a){return a})||[]},only:function(a){if(!M(a))throw Error("React.Children.only expected to receive a single React element child.");return a}};c.Component=w;c.Fragment=sa;c.Profiler=ua;c.PureComponent=K;c.StrictMode=ta;c.Suspense=ya;c.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=
26
+ t;c.act=ka;c.cloneElement=function(a,b,c){if(null===a||void 0===a)throw Error("React.cloneElement(...): The argument must be a React element, but you passed "+a+".");var e=la({},a.props),d=a.key,k=a.ref,h=a._owner;if(null!=b){void 0!==b.ref&&(k=b.ref,h=L.current);void 0!==b.key&&(d=""+b.key);if(a.type&&a.type.defaultProps)var l=a.type.defaultProps;for(f in b)aa.call(b,f)&&!ba.hasOwnProperty(f)&&(e[f]=void 0===b[f]&&void 0!==l?l[f]:b[f])}var f=arguments.length-2;if(1===f)e.children=c;else if(1<f){l=
27
+ Array(f);for(var g=0;g<f;g++)l[g]=arguments[g+2];e.children=l}return{$$typeof:y,type:a.type,key:d,ref:k,props:e,_owner:h}};c.createContext=function(a){a={$$typeof:wa,_currentValue:a,_currentValue2:a,_threadCount:0,Provider:null,Consumer:null,_defaultValue:null,_globalName:null};a.Provider={$$typeof:va,_context:a};return a.Consumer=a};c.createElement=Z;c.createFactory=function(a){var b=Z.bind(null,a);b.type=a;return b};c.createRef=function(){return{current:null}};c.forwardRef=function(a){return{$$typeof:xa,
28
+ render:a}};c.isValidElement=M;c.lazy=function(a){return{$$typeof:Aa,_payload:{_status:-1,_result:a},_init:ra}};c.memo=function(a,b){return{$$typeof:za,type:a,compare:void 0===b?null:b}};c.startTransition=function(a,b){b=J.transition;J.transition={};try{a()}finally{J.transition=b}};c.unstable_act=ka;c.useCallback=function(a,b){return g.current.useCallback(a,b)};c.useContext=function(a){return g.current.useContext(a)};c.useDebugValue=function(a,b){};c.useDeferredValue=function(a){return g.current.useDeferredValue(a)};
29
+ c.useEffect=function(a,b){return g.current.useEffect(a,b)};c.useId=function(){return g.current.useId()};c.useImperativeHandle=function(a,b,c){return g.current.useImperativeHandle(a,b,c)};c.useInsertionEffect=function(a,b){return g.current.useInsertionEffect(a,b)};c.useLayoutEffect=function(a,b){return g.current.useLayoutEffect(a,b)};c.useMemo=function(a,b){return g.current.useMemo(a,b)};c.useReducer=function(a,b,c){return g.current.useReducer(a,b,c)};c.useRef=function(a){return g.current.useRef(a)};
30
+ c.useState=function(a){return g.current.useState(a)};c.useSyncExternalStore=function(a,b,c){return g.current.useSyncExternalStore(a,b,c)};c.useTransition=function(){return g.current.useTransition()};c.version="18.3.1"});
31
+ })();
@@ -0,0 +1,33 @@
1
+ body {
2
+ margin: 0;
3
+ font-family: sans-serif;
4
+ font-size: 20px;
5
+ color: rgb(20, 23, 26);
6
+ background-color: rgb(230, 236, 240);
7
+ }
8
+
9
+ h1 {
10
+ display: flex;
11
+ align-items: center;
12
+ margin-left: 40px;
13
+ margin-right: 40px;
14
+ font-weight: normal;
15
+ }
16
+
17
+ p {
18
+ line-height: 1.35;
19
+ }
20
+
21
+
22
+ footer {
23
+ margin-top: 40px;
24
+ margin-bottom: 30px;
25
+ text-align: center;
26
+ color: #a0a0a0;
27
+ }
28
+
29
+ .twitter-logo {
30
+ width: 28px;
31
+ height: 28px;
32
+ margin-right: 0.5em;
33
+ }
@@ -0,0 +1,92 @@
1
+ .container {
2
+ width: 100%;
3
+ max-width: 720px;
4
+ margin-left: auto;
5
+ margin-right: auto;
6
+ }
7
+
8
+ /* This `border-top` for `:first-child` didn't actually work
9
+ for restoring scroll position after prepending items via `.updateItems()`. */
10
+ /*
11
+ .list-item:first-child {
12
+ border-top: 2px solid rgb(230, 236, 240);
13
+ }
14
+ */
15
+ /* Using `border-top` on `#list` instead. */
16
+ #list {
17
+ border-top: 2px solid rgb(230, 236, 240);
18
+ }
19
+
20
+ .list-item {
21
+ padding: 40px;
22
+ border-bottom: 2px solid rgb(230, 236, 240);
23
+ background-color: white;
24
+ }
25
+
26
+ .list-item a {
27
+ font-weight: bold;
28
+ text-decoration: none;
29
+ color: rgba(29,161,242,1.00);
30
+ }
31
+
32
+ .list-item time {
33
+ color: #a0a0a0;
34
+ font-size: 85%;
35
+ }
36
+
37
+ .list-item time:before {
38
+ display: inline-block;
39
+ content: '·';
40
+ margin-left: 0.4em;
41
+ margin-right: 0.4em;
42
+ }
43
+
44
+ .list-item p {
45
+ margin-top: 20px;
46
+ margin-bottom: 0;
47
+ }
48
+
49
+ /* For testing inter-item spacing. */
50
+ /*
51
+ .list-item {
52
+ margin-top: 40px;
53
+ background: #f9f9f9;
54
+ }
55
+ .list-item:first-child {
56
+ margin-top: 0px;
57
+ }
58
+ */
59
+
60
+ .load-items-button {
61
+ /* Button style reset. */
62
+ margin: 0;
63
+ padding: 0;
64
+ white-space: nowrap;
65
+ -webkit-appearance: none;
66
+ -moz-appearance: none;
67
+ appearance: none;
68
+ border: none;
69
+ background: none;
70
+ cursor: pointer;
71
+ font-size: inherit;
72
+ font-family: inherit;
73
+ font-weight: inherit;
74
+ font-style: inherit;
75
+ -webkit-user-select: none;
76
+ -moz-user-select: none;
77
+ -ms-user-select: none;
78
+ user-select: none;
79
+ outline: none;
80
+ /* Styles. */
81
+ display: block;
82
+ width: 100%;
83
+ padding-top: 0.5em;
84
+ padding-bottom: 0.5em;
85
+ color: rgb(29, 161, 242);
86
+ }
87
+
88
+ .load-items-button:hover,
89
+ .load-items-button:focus {
90
+ /*background-color: rgb(245, 248, 250);*/
91
+ background-color: rgb(235, 241, 245);
92
+ }
@@ -0,0 +1,23 @@
1
+ .container {
2
+ max-width: 1280px;
3
+ }
4
+
5
+ #list {
6
+ display: flex;
7
+ flex-wrap: wrap;
8
+ }
9
+
10
+ .list-item {
11
+ flex-basis: 33.333333%;
12
+ box-sizing: border-box;
13
+ border: 2px solid rgb(230, 236, 240);
14
+ }
15
+
16
+ @media screen and (max-width: 1280px) {
17
+ .container {
18
+ max-width: 720px;
19
+ }
20
+ .list-item {
21
+ flex-basis: 100%;
22
+ }
23
+ }
@@ -1,216 +0,0 @@
1
- <!DOCTYPE html>
2
- <html>
3
- <head>
4
- <!-- Fix encoding. -->
5
- <meta charset="utf-8">
6
- <!-- Fix document width for mobile devices. -->
7
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
8
-
9
- <title>React VirtualScroller Demo (Grid Layout)</title>
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>
15
-
16
- <script src="./virtual-scroller-react.js"></script>
17
- <script src="./on-scroll-to-react.js"></script>
18
- <script src="./messages.js"></script>
19
-
20
- <link rel="stylesheet" href="./style.css"/>
21
-
22
- <style>
23
- #messages {
24
- display: flex;
25
- flex-wrap: wrap;
26
- }
27
- .feed-message {
28
- flex-basis: 33.333333%;
29
- box-sizing: border-box;
30
- border: 2px solid rgb(230, 236, 240);
31
- }
32
- .container {
33
- max-width: 1280px;
34
- }
35
- @media screen and (max-width: 1280px) {
36
- .container {
37
- max-width: 720px;
38
- }
39
- .feed-message {
40
- flex-basis: 100%;
41
- }
42
- }
43
- </style>
44
- </head>
45
-
46
- <body>
47
- <!-- http://tholman.com/github-corners/ -->
48
- <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>
49
-
50
- <div id="root"></div>
51
-
52
- <script>
53
- // Enable debug output to console.
54
- window.VirtualScrollerDebug = true
55
- // Whether "dynamically loaded list" mode is enabled.
56
- window.dynamic = new URL(window.location).searchParams.get('dynamic')
57
- </script>
58
-
59
- <script type="text/babel">
60
- const BATCH_SIZE = 6
61
- const COLUMNS_COUNT = 3
62
-
63
- function getColumnsCount(container) {
64
- if (container.getWidth() > 1280) {
65
- return COLUMNS_COUNT
66
- }
67
- return 1
68
- }
69
-
70
- class FeedMessages extends React.Component {
71
- constructor(props) {
72
- super(props)
73
- const { messages } = this.props
74
- if (window.dynamic) {
75
- const fromIndex = Math.floor((messages.length - BATCH_SIZE) / 2 / COLUMNS_COUNT) * COLUMNS_COUNT
76
- const toIndex = fromIndex + BATCH_SIZE - 1
77
- this.state = {
78
- fromIndex,
79
- toIndex,
80
- messages: messages.slice(fromIndex, toIndex + 1)
81
- }
82
- } else {
83
- this.state = {
84
- fromIndex: 0,
85
- toIndex: messages.length,
86
- messages
87
- }
88
- }
89
- }
90
-
91
- onShowPrevious = () => {
92
- const { messages } = this.props
93
- let { fromIndex } = this.state
94
- const { toIndex } = this.state
95
- fromIndex = Math.max(fromIndex - BATCH_SIZE, 0)
96
- this.setState({
97
- fromIndex,
98
- messages: messages.slice(fromIndex, toIndex + 1)
99
- })
100
- }
101
-
102
- onShowNext = () => {
103
- const { messages } = this.props
104
- const { fromIndex } = this.state
105
- let { toIndex } = this.state
106
- toIndex = Math.min(toIndex + BATCH_SIZE, messages.length - 1)
107
- this.setState({
108
- toIndex,
109
- messages: messages.slice(fromIndex, toIndex + 1)
110
- })
111
- }
112
-
113
- render() {
114
- const {
115
- fromIndex,
116
- toIndex,
117
- messages
118
- } = this.state
119
- return (
120
- <React.Fragment>
121
- {window.dynamic && fromIndex > 0 &&
122
- <button
123
- type="button"
124
- onClick={this.onShowPrevious}
125
- className="load-items-button">
126
- Show previous
127
- </button>
128
- }
129
- <VirtualScroller
130
- id="messages"
131
- items={messages}
132
- itemComponent={Message}
133
- preserveScrollPositionOnPrependItems
134
- getColumnsCount={getColumnsCount}/>
135
- {window.dynamic && toIndex < this.props.messages.length - 1 &&
136
- <button
137
- type="button"
138
- onClick={this.onShowNext}
139
- className="load-items-button">
140
- Show next
141
- </button>
142
- }
143
- </React.Fragment>
144
- )
145
- }
146
- }
147
-
148
- const message = PropTypes.shape({
149
- username: PropTypes.string.isRequired,
150
- date: PropTypes.instanceOf(Date).isRequired,
151
- text: PropTypes.string.isRequired
152
- })
153
-
154
- FeedMessages.propTypes = {
155
- messages: PropTypes.arrayOf(message).isRequired
156
- }
157
-
158
- function Message(props) {
159
- const { children: message } = props
160
- const {
161
- username,
162
- date,
163
- text
164
- } = message
165
- return (
166
- <article className="feed-message">
167
- <a target="_blank" href={`https://twitter.com/${username}`}>
168
- @{username}
169
- </a>
170
- <time dateTime={date.toISOString()}>
171
- {date.getMonth() + 1}/{date.getDate()}/{date.getFullYear()}
172
- </time>
173
- <p>
174
- {text}
175
- </p>
176
- </article>
177
- )
178
- }
179
-
180
- Message.propTypes = {
181
- children: message.isRequired
182
- }
183
-
184
- class Feed extends React.Component {
185
- render() {
186
- return (
187
- <section className="container">
188
- <h1>
189
- <TwitterLogo/>
190
- Latest Tweets on #politics
191
- </h1>
192
- <FeedMessages
193
- messages={messages}/>
194
- <footer>
195
- © Twitter Inc., 2019
196
- </footer>
197
- </section>
198
- )
199
- }
200
- }
201
-
202
- function TwitterLogo() {
203
- return (
204
- <svg className="twitter-logo" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128">
205
- <path fill="#00AAEC" fillRule="evenodd" d="M128 23.294a51.28 51.28 0 0 1-15.079 4.237c5.424-3.328 9.587-8.606 11.548-14.892a51.718 51.718 0 0 1-16.687 6.526c-4.778-5.231-11.608-8.498-19.166-8.498-14.493 0-26.251 12.057-26.251 26.927 0 2.111.225 4.16.676 6.133-21.824-1.126-41.17-11.835-54.131-28.145a27.422 27.422 0 0 0-3.554 13.552c0 9.338 4.636 17.581 11.683 22.412-4.297-.131-8.355-1.356-11.901-3.359v.331c0 13.051 9.053 23.937 21.074 26.403-2.201.632-4.523.948-6.92.948-1.69 0-3.343-.162-4.944-.478 3.343 10.694 13.035 18.483 24.53 18.691-8.986 7.227-20.315 11.533-32.614 11.533-2.119 0-4.215-.123-6.266-.37 11.623 7.627 25.432 12.088 40.255 12.088 48.309 0 74.717-41.026 74.717-76.612a89.39 89.39 0 0 0-.068-3.49A53.862 53.862 0 0 0 128 23.294" clipRule="evenodd"/>
206
- </svg>
207
- )
208
- }
209
-
210
- ReactDOM.render(
211
- <Feed/>,
212
- document.getElementById('root')
213
- )
214
- </script>
215
- </body>
216
- </html>
@@ -1,208 +0,0 @@
1
- <!DOCTYPE html>
2
- <html>
3
- <head>
4
- <!-- Fix encoding. -->
5
- <meta charset="utf-8">
6
- <!-- Fix document width for mobile devices. -->
7
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
8
-
9
- <title>React VirtualScroller Demo (Scrollable Container)</title>
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>
15
-
16
- <script src="./virtual-scroller-react.js"></script>
17
- <script src="./on-scroll-to-react.js"></script>
18
- <script src="./messages.js"></script>
19
-
20
- <link rel="stylesheet" href="./style.css"/>
21
- </head>
22
-
23
- <body>
24
- <!-- http://tholman.com/github-corners/ -->
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
-
27
- <div id="root"></div>
28
-
29
- <script>
30
- // Enable debug output to console.
31
- window.VirtualScrollerDebug = true
32
- // Whether "dynamically loaded list" mode is enabled.
33
- window.dynamic = new URL(window.location).searchParams.get('dynamic')
34
- </script>
35
-
36
- <script type="text/babel">
37
- const BATCH_SIZE = 6
38
-
39
- const SCROLLABLE_CONTAINER_STYLE = {
40
- marginTop: '20vh',
41
- maxHeight: '60vh',
42
- overflow: 'auto'
43
- }
44
-
45
- class FeedMessages extends React.Component {
46
- constructor(props) {
47
- super(props)
48
- const { messages } = this.props
49
- if (window.dynamic) {
50
- const fromIndex = Math.floor(messages.length / 2 - BATCH_SIZE / 2)
51
- const toIndex = fromIndex + BATCH_SIZE - 1
52
- this.state = {
53
- fromIndex,
54
- toIndex,
55
- messages: messages.slice(fromIndex, toIndex + 1)
56
- }
57
- } else {
58
- this.state = {
59
- fromIndex: 0,
60
- toIndex: messages.length,
61
- messages
62
- }
63
- }
64
- }
65
-
66
- onShowPrevious = () => {
67
- const { messages } = this.props
68
- let { fromIndex } = this.state
69
- const { toIndex } = this.state
70
- fromIndex = Math.max(fromIndex - BATCH_SIZE, 0)
71
- this.setState({
72
- fromIndex,
73
- messages: messages.slice(fromIndex, toIndex + 1)
74
- })
75
- }
76
-
77
- onShowNext = () => {
78
- const { messages } = this.props
79
- const { fromIndex } = this.state
80
- let { toIndex } = this.state
81
- toIndex = Math.min(toIndex + BATCH_SIZE, messages.length - 1)
82
- this.setState({
83
- toIndex,
84
- messages: messages.slice(fromIndex, toIndex + 1)
85
- })
86
- }
87
-
88
- getScrollableContainer = () => {
89
- return this.scrollableContainer
90
- }
91
-
92
- setScrollableContainer = (node) => {
93
- this.scrollableContainer = node
94
- }
95
-
96
- componentDidMount() {
97
- this.setState({ isMounted: true })
98
- }
99
-
100
- render() {
101
- const {
102
- fromIndex,
103
- toIndex,
104
- messages,
105
- isMounted
106
- } = this.state
107
- return (
108
- <div
109
- ref={this.setScrollableContainer}
110
- style={SCROLLABLE_CONTAINER_STYLE}>
111
- {window.dynamic && fromIndex > 0 &&
112
- <button
113
- type="button"
114
- onClick={this.onShowPrevious}
115
- className="load-items-button">
116
- Show previous
117
- </button>
118
- }
119
- {isMounted &&
120
- <VirtualScroller
121
- id="messages"
122
- items={messages}
123
- itemComponent={Message}
124
- preserveScrollPosition
125
- scrollableContainer={this.scrollableContainer}/>
126
- }
127
- {window.dynamic && toIndex < this.props.messages.length - 1 &&
128
- <button
129
- type="button"
130
- onClick={this.onShowNext}
131
- className="load-items-button">
132
- Show next
133
- </button>
134
- }
135
- </div>
136
- )
137
- }
138
- }
139
-
140
- const message = PropTypes.shape({
141
- username: PropTypes.string.isRequired,
142
- date: PropTypes.instanceOf(Date).isRequired,
143
- text: PropTypes.string.isRequired
144
- })
145
-
146
- FeedMessages.propTypes = {
147
- messages: PropTypes.arrayOf(message).isRequired
148
- }
149
-
150
- function Message(props) {
151
- const { children: message } = props
152
- const {
153
- username,
154
- date,
155
- text
156
- } = message
157
- return (
158
- <article className="feed-message">
159
- <a target="_blank" href={`https://twitter.com/${username}`}>
160
- @{username}
161
- </a>
162
- <time dateTime={date.toISOString()}>
163
- {date.getMonth() + 1}/{date.getDate()}/{date.getFullYear()}
164
- </time>
165
- <p>
166
- {text}
167
- </p>
168
- </article>
169
- )
170
- }
171
-
172
- Message.propTypes = {
173
- children: message.isRequired
174
- }
175
-
176
- class Feed extends React.Component {
177
- render() {
178
- return (
179
- <section className="container">
180
- <h1>
181
- <TwitterLogo/>
182
- Latest Tweets on #politics
183
- </h1>
184
- <FeedMessages
185
- messages={messages}/>
186
- <footer>
187
- © Twitter Inc., 2019
188
- </footer>
189
- </section>
190
- )
191
- }
192
- }
193
-
194
- function TwitterLogo() {
195
- return (
196
- <svg className="twitter-logo" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128">
197
- <path fill="#00AAEC" fillRule="evenodd" d="M128 23.294a51.28 51.28 0 0 1-15.079 4.237c5.424-3.328 9.587-8.606 11.548-14.892a51.718 51.718 0 0 1-16.687 6.526c-4.778-5.231-11.608-8.498-19.166-8.498-14.493 0-26.251 12.057-26.251 26.927 0 2.111.225 4.16.676 6.133-21.824-1.126-41.17-11.835-54.131-28.145a27.422 27.422 0 0 0-3.554 13.552c0 9.338 4.636 17.581 11.683 22.412-4.297-.131-8.355-1.356-11.901-3.359v.331c0 13.051 9.053 23.937 21.074 26.403-2.201.632-4.523.948-6.92.948-1.69 0-3.343-.162-4.944-.478 3.343 10.694 13.035 18.483 24.53 18.691-8.986 7.227-20.315 11.533-32.614 11.533-2.119 0-4.215-.123-6.266-.37 11.623 7.627 25.432 12.088 40.255 12.088 48.309 0 74.717-41.026 74.717-76.612a89.39 89.39 0 0 0-.068-3.49A53.862 53.862 0 0 0 128 23.294" clipRule="evenodd"/>
198
- </svg>
199
- )
200
- }
201
-
202
- ReactDOM.render(
203
- <Feed/>,
204
- document.getElementById('root')
205
- )
206
- </script>
207
- </body>
208
- </html>