react-virtuoso 2.2.2 → 2.2.6-beta.0
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.
- package/dist/List.d.ts +52 -250
- package/dist/__examples.cc6a8f9f.js +171789 -0
- package/dist/__examples.cc6a8f9f.js.map +1 -0
- package/dist/__examples.html +27 -0
- package/dist/__examples.js +392 -0
- package/dist/__examples.js.map +1 -0
- package/dist/align-to-bottom.7fcd2087.js +401 -0
- package/dist/align-to-bottom.7fcd2087.js.map +1 -0
- package/dist/alignToBottomSystem.d.ts +5 -25
- package/dist/auto-prepend-items.bd7e9b90.js +468 -0
- package/dist/auto-prepend-items.bd7e9b90.js.map +1 -0
- package/dist/benchmark.66d31485.js +366 -0
- package/dist/benchmark.66d31485.js.map +1 -0
- package/dist/chat.d4f93b8b.js +570 -0
- package/dist/chat.d4f93b8b.js.map +1 -0
- package/dist/custom-components.5aeaa7ef.js +407 -0
- package/dist/custom-components.5aeaa7ef.js.map +1 -0
- package/dist/custom-scroller.b0240d14.js +385 -0
- package/dist/custom-scroller.b0240d14.js.map +1 -0
- package/dist/data.26707046.js +391 -0
- package/dist/data.26707046.js.map +1 -0
- package/dist/decrease-items.e2211e50.js +385 -0
- package/dist/decrease-items.e2211e50.js.map +1 -0
- package/dist/default-item-height.b77ada36.js +360 -0
- package/dist/default-item-height.b77ada36.js.map +1 -0
- package/dist/empty-placeholder.00607a6e.js +390 -0
- package/dist/empty-placeholder.00607a6e.js.map +1 -0
- package/dist/end-reached.8531e5b1.js +404 -0
- package/dist/end-reached.8531e5b1.js.map +1 -0
- package/dist/endless-scrolling.bc4101f0.js +410 -0
- package/dist/endless-scrolling.bc4101f0.js.map +1 -0
- package/dist/expandable-cards.5439f51b.js +427 -0
- package/dist/expandable-cards.5439f51b.js.map +1 -0
- package/dist/follow-output.4e36fca8.js +430 -0
- package/dist/follow-output.4e36fca8.js.map +1 -0
- package/dist/followOutputSystem.d.ts +5 -25
- package/dist/grid-optimize-rendering.b49e36f5.js +452 -0
- package/dist/grid-optimize-rendering.b49e36f5.js.map +1 -0
- package/dist/grid.d5d77b6a.js +449 -0
- package/dist/grid.d5d77b6a.js.map +1 -0
- package/dist/grouped-endless-scrolling.24985a0f.js +506 -0
- package/dist/grouped-endless-scrolling.24985a0f.js.map +1 -0
- package/dist/grouped-load-more.bce8f6e4.js +505 -0
- package/dist/grouped-load-more.bce8f6e4.js.map +1 -0
- package/dist/grouped-topmost-item.34960f5e.js +366 -0
- package/dist/grouped-topmost-item.34960f5e.js.map +1 -0
- package/dist/grouped.a2908632.js +365 -0
- package/dist/grouped.a2908632.js.map +1 -0
- package/dist/header-footer.49733d45.js +376 -0
- package/dist/header-footer.49733d45.js.map +1 -0
- package/dist/hello.54765c26.js +360 -0
- package/dist/hello.54765c26.js.map +1 -0
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.m.js +1 -1
- package/dist/index.m.js.map +1 -1
- package/dist/initial-from-zero.22ad1626.js +400 -0
- package/dist/initial-from-zero.22ad1626.js.map +1 -0
- package/dist/initial-scroll-top.90db1920.js +361 -0
- package/dist/initial-scroll-top.90db1920.js.map +1 -0
- package/dist/initial-topmost-item-default-height.43a95247.js +362 -0
- package/dist/initial-topmost-item-default-height.43a95247.js.map +1 -0
- package/dist/initial-topmost-item.61c0e169.js +361 -0
- package/dist/initial-topmost-item.61c0e169.js.map +1 -0
- package/dist/initialItemCountSystem.d.ts +5 -25
- package/dist/initialScrollTopSystem.d.ts +5 -25
- package/dist/initialTopMostItemIndexSystem.d.ts +3 -25
- package/dist/listStateSystem.d.ts +5 -25
- package/dist/listSystem.d.ts +52 -250
- package/dist/long-last-item.b56ff89c.js +361 -0
- package/dist/long-last-item.b56ff89c.js.map +1 -0
- package/dist/prepend-items.f2bda34b.js +393 -0
- package/dist/prepend-items.f2bda34b.js.map +1 -0
- package/dist/prepend-last-tall-item.168a9e65.js +380 -0
- package/dist/prepend-last-tall-item.168a9e65.js.map +1 -0
- package/dist/react-beautiful-dnd-window-scroller.0a227511.js +485 -0
- package/dist/react-beautiful-dnd-window-scroller.0a227511.js.map +1 -0
- package/dist/react-beautiful-dnd.817e9251.js +482 -0
- package/dist/react-beautiful-dnd.817e9251.js.map +1 -0
- package/dist/rerender.ddd61b7c.js +400 -0
- package/dist/rerender.ddd61b7c.js.map +1 -0
- package/dist/resize-loop.309b1dac.js +388 -0
- package/dist/resize-loop.309b1dac.js.map +1 -0
- package/dist/resizing-items.c09b5e1b.js +394 -0
- package/dist/resizing-items.c09b5e1b.js.map +1 -0
- package/dist/scroll-into-view.39b77fe9.js +408 -0
- package/dist/scroll-into-view.39b77fe9.js.map +1 -0
- package/dist/scroll-seek-placeholder.69fb85c6.js +384 -0
- package/dist/scroll-seek-placeholder.69fb85c6.js.map +1 -0
- package/dist/scroll-to-index.e72249cf.js +417 -0
- package/dist/scroll-to-index.e72249cf.js.map +1 -0
- package/dist/scrollIntoViewSystem.d.ts +7 -25
- package/dist/scrollToIndexSystem.d.ts +1 -0
- package/dist/ssr.8f31b042.js +359 -0
- package/dist/ssr.8f31b042.js.map +1 -0
- package/dist/start-reached.2990ece7.js +424 -0
- package/dist/start-reached.2990ece7.js.map +1 -0
- package/dist/tall-item-reverse-scrolling.58bcd140.js +363 -0
- package/dist/tall-item-reverse-scrolling.58bcd140.js.map +1 -0
- package/dist/test-case-446.dce9595c.js +428 -0
- package/dist/test-case-446.dce9595c.js.map +1 -0
- package/dist/test-case-460.6d75ad1f.js +452 -0
- package/dist/test-case-460.6d75ad1f.js.map +1 -0
- package/dist/test-case-463.525f34ba.js +375 -0
- package/dist/test-case-463.525f34ba.js.map +1 -0
- package/dist/toggle-display-grouped.4f4ae058.js +389 -0
- package/dist/toggle-display-grouped.4f4ae058.js.map +1 -0
- package/dist/top-items.f724bf61.js +358 -0
- package/dist/top-items.f724bf61.js.map +1 -0
- package/dist/topItemCountSystem.d.ts +5 -25
- package/dist/totalListHeightSystem.d.ts +5 -25
- package/dist/upward-scroll.d49e0815.js +362 -0
- package/dist/upward-scroll.d49e0815.js.map +1 -0
- package/dist/upwardScrollFixSystem.d.ts +5 -25
- package/dist/window-grid.b22094fd.js +439 -0
- package/dist/window-grid.b22094fd.js.map +1 -0
- package/dist/window-scroller.a979c6d6.js +368 -0
- package/dist/window-scroller.a979c6d6.js.map +1 -0
- package/package.json +6 -6
|
@@ -0,0 +1,570 @@
|
|
|
1
|
+
// modules are defined as an array
|
|
2
|
+
// [ module function, map of requires ]
|
|
3
|
+
//
|
|
4
|
+
// map of requires is short require name -> numeric require
|
|
5
|
+
//
|
|
6
|
+
// anything defined in a previous bundle is accessed via the
|
|
7
|
+
// orig method which is the require for previous bundles
|
|
8
|
+
parcelRequire = (function (modules, cache, entry, globalName) {
|
|
9
|
+
// Save the require from previous bundle to this closure if any
|
|
10
|
+
var previousRequire = typeof parcelRequire === 'function' && parcelRequire;
|
|
11
|
+
var nodeRequire = typeof require === 'function' && require;
|
|
12
|
+
|
|
13
|
+
function newRequire(name, jumped) {
|
|
14
|
+
if (!cache[name]) {
|
|
15
|
+
if (!modules[name]) {
|
|
16
|
+
// if we cannot find the module within our internal map or
|
|
17
|
+
// cache jump to the current global require ie. the last bundle
|
|
18
|
+
// that was added to the page.
|
|
19
|
+
var currentRequire = typeof parcelRequire === 'function' && parcelRequire;
|
|
20
|
+
if (!jumped && currentRequire) {
|
|
21
|
+
return currentRequire(name, true);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// If there are other bundles on this page the require from the
|
|
25
|
+
// previous one is saved to 'previousRequire'. Repeat this as
|
|
26
|
+
// many times as there are bundles until the module is found or
|
|
27
|
+
// we exhaust the require chain.
|
|
28
|
+
if (previousRequire) {
|
|
29
|
+
return previousRequire(name, true);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Try the node require function if it exists.
|
|
33
|
+
if (nodeRequire && typeof name === 'string') {
|
|
34
|
+
return nodeRequire(name);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
var err = new Error('Cannot find module \'' + name + '\'');
|
|
38
|
+
err.code = 'MODULE_NOT_FOUND';
|
|
39
|
+
throw err;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
localRequire.resolve = resolve;
|
|
43
|
+
localRequire.cache = {};
|
|
44
|
+
|
|
45
|
+
var module = cache[name] = new newRequire.Module(name);
|
|
46
|
+
|
|
47
|
+
modules[name][0].call(module.exports, localRequire, module, module.exports, this);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return cache[name].exports;
|
|
51
|
+
|
|
52
|
+
function localRequire(x){
|
|
53
|
+
return newRequire(localRequire.resolve(x));
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function resolve(x){
|
|
57
|
+
return modules[name][1][x] || x;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function Module(moduleName) {
|
|
62
|
+
this.id = moduleName;
|
|
63
|
+
this.bundle = newRequire;
|
|
64
|
+
this.exports = {};
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
newRequire.isParcelRequire = true;
|
|
68
|
+
newRequire.Module = Module;
|
|
69
|
+
newRequire.modules = modules;
|
|
70
|
+
newRequire.cache = cache;
|
|
71
|
+
newRequire.parent = previousRequire;
|
|
72
|
+
newRequire.register = function (id, exports) {
|
|
73
|
+
modules[id] = [function (require, module) {
|
|
74
|
+
module.exports = exports;
|
|
75
|
+
}, {}];
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
var error;
|
|
79
|
+
for (var i = 0; i < entry.length; i++) {
|
|
80
|
+
try {
|
|
81
|
+
newRequire(entry[i]);
|
|
82
|
+
} catch (e) {
|
|
83
|
+
// Save first error but execute all entries
|
|
84
|
+
if (!error) {
|
|
85
|
+
error = e;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (entry.length) {
|
|
91
|
+
// Expose entry point to Node, AMD or browser globals
|
|
92
|
+
// Based on https://github.com/ForbesLindesay/umd/blob/master/template.js
|
|
93
|
+
var mainExports = newRequire(entry[entry.length - 1]);
|
|
94
|
+
|
|
95
|
+
// CommonJS
|
|
96
|
+
if (typeof exports === "object" && typeof module !== "undefined") {
|
|
97
|
+
module.exports = mainExports;
|
|
98
|
+
|
|
99
|
+
// RequireJS
|
|
100
|
+
} else if (typeof define === "function" && define.amd) {
|
|
101
|
+
define(function () {
|
|
102
|
+
return mainExports;
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
// <script>
|
|
106
|
+
} else if (globalName) {
|
|
107
|
+
this[globalName] = mainExports;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Override the current require with this new one
|
|
112
|
+
parcelRequire = newRequire;
|
|
113
|
+
|
|
114
|
+
if (error) {
|
|
115
|
+
// throw error from earlier, _after updating parcelRequire_
|
|
116
|
+
throw error;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
return newRequire;
|
|
120
|
+
})({"chat.tsx":[function(require,module,exports) {
|
|
121
|
+
"use strict";
|
|
122
|
+
|
|
123
|
+
Object.defineProperty(exports, "__esModule", {
|
|
124
|
+
value: true
|
|
125
|
+
});
|
|
126
|
+
exports.default = App;
|
|
127
|
+
|
|
128
|
+
var React = _interopRequireWildcard(require("react"));
|
|
129
|
+
|
|
130
|
+
var _styled = _interopRequireDefault(require("@emotion/styled"));
|
|
131
|
+
|
|
132
|
+
var _src = require("../src/");
|
|
133
|
+
|
|
134
|
+
var _faker = _interopRequireDefault(require("faker"));
|
|
135
|
+
|
|
136
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
137
|
+
|
|
138
|
+
function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
|
|
139
|
+
|
|
140
|
+
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
141
|
+
|
|
142
|
+
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
|
|
143
|
+
|
|
144
|
+
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
145
|
+
|
|
146
|
+
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter); }
|
|
147
|
+
|
|
148
|
+
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
|
|
149
|
+
|
|
150
|
+
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
|
151
|
+
|
|
152
|
+
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
153
|
+
|
|
154
|
+
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
155
|
+
|
|
156
|
+
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
|
|
157
|
+
|
|
158
|
+
function _iterableToArrayLimit(arr, i) { if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return; var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
|
|
159
|
+
|
|
160
|
+
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
161
|
+
|
|
162
|
+
function _templateObject4() {
|
|
163
|
+
var data = _taggedTemplateLiteral(["\n display: flex;\n justify-content: space-between;\n width: 100%;\n height: 100%;\n margin-top: 12px;\n"]);
|
|
164
|
+
|
|
165
|
+
_templateObject4 = function _templateObject4() {
|
|
166
|
+
return data;
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
return data;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
function _templateObject3() {
|
|
173
|
+
var data = _taggedTemplateLiteral(["\n padding: 12px 24px;\n"]);
|
|
174
|
+
|
|
175
|
+
_templateObject3 = function _templateObject3() {
|
|
176
|
+
return data;
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
return data;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
function _templateObject2() {
|
|
183
|
+
var data = _taggedTemplateLiteral(["\n background: ", ";\n color: white;\n width: 60%;\n padding: 12px;\n border-radius: 4px;\n word-break: break-word;\n"]);
|
|
184
|
+
|
|
185
|
+
_templateObject2 = function _templateObject2() {
|
|
186
|
+
return data;
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
return data;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
function _templateObject() {
|
|
193
|
+
var data = _taggedTemplateLiteral(["\n display: flex;\n justify-content: ", ";\n width: 100%;\n padding: 12px 0;\n"]);
|
|
194
|
+
|
|
195
|
+
_templateObject = function _templateObject() {
|
|
196
|
+
return data;
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
return data;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
function _taggedTemplateLiteral(strings, raw) { if (!raw) { raw = strings.slice(0); } return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); }
|
|
203
|
+
|
|
204
|
+
var BubbleWrap = _styled.default.div(_templateObject(), function (_ref) {
|
|
205
|
+
var fromUser = _ref.fromUser;
|
|
206
|
+
return fromUser && 'flex-end';
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
var Content = _styled.default.div(_templateObject2(), function (_ref2) {
|
|
210
|
+
var fromUser = _ref2.fromUser;
|
|
211
|
+
return fromUser ? 'orange' : 'red';
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
function Bubble(_ref3) {
|
|
215
|
+
var text = _ref3.text,
|
|
216
|
+
fromUser = _ref3.fromUser,
|
|
217
|
+
className = _ref3.className;
|
|
218
|
+
return React.createElement(BubbleWrap, {
|
|
219
|
+
fromUser: fromUser,
|
|
220
|
+
className: className
|
|
221
|
+
}, React.createElement(Content, {
|
|
222
|
+
fromUser: fromUser
|
|
223
|
+
}, text));
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
var Root = _styled.default.div(_templateObject3());
|
|
227
|
+
|
|
228
|
+
var TextWrapper = _styled.default.div(_templateObject4());
|
|
229
|
+
|
|
230
|
+
function ChatList(_ref4) {
|
|
231
|
+
var userId = _ref4.userId,
|
|
232
|
+
_ref4$messages = _ref4.messages,
|
|
233
|
+
messages = _ref4$messages === void 0 ? [] : _ref4$messages,
|
|
234
|
+
onSend = _ref4.onSend,
|
|
235
|
+
onReceive = _ref4.onReceive,
|
|
236
|
+
placeholder = _ref4.placeholder;
|
|
237
|
+
|
|
238
|
+
var _useState = (0, React.useState)(''),
|
|
239
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
240
|
+
newMessage = _useState2[0],
|
|
241
|
+
setNewMessage = _useState2[1];
|
|
242
|
+
|
|
243
|
+
var ref = (0, React.useRef)(null);
|
|
244
|
+
var isMyOwnMessage = (0, React.useRef)(false);
|
|
245
|
+
|
|
246
|
+
var onSendMessage = function onSendMessage() {
|
|
247
|
+
isMyOwnMessage.current = true;
|
|
248
|
+
onSend(newMessage);
|
|
249
|
+
setNewMessage('');
|
|
250
|
+
};
|
|
251
|
+
|
|
252
|
+
var onReceiveMessage = function onReceiveMessage() {
|
|
253
|
+
isMyOwnMessage.current = false;
|
|
254
|
+
onReceive();
|
|
255
|
+
};
|
|
256
|
+
|
|
257
|
+
var row = React.useMemo(function () {
|
|
258
|
+
return function (i, _ref5) {
|
|
259
|
+
var message = _ref5.message,
|
|
260
|
+
id = _ref5.id;
|
|
261
|
+
var fromUser = id === userId;
|
|
262
|
+
return React.createElement(Bubble, {
|
|
263
|
+
key: i,
|
|
264
|
+
fromUser: fromUser,
|
|
265
|
+
text: message
|
|
266
|
+
});
|
|
267
|
+
};
|
|
268
|
+
}, [userId]);
|
|
269
|
+
return React.createElement(Root, {
|
|
270
|
+
style: {
|
|
271
|
+
flex: 1,
|
|
272
|
+
display: 'flex',
|
|
273
|
+
flexDirection: 'column',
|
|
274
|
+
border: '1px solid red'
|
|
275
|
+
}
|
|
276
|
+
}, React.createElement(_src.Virtuoso, {
|
|
277
|
+
ref: ref,
|
|
278
|
+
style: {
|
|
279
|
+
flex: 1
|
|
280
|
+
},
|
|
281
|
+
initialTopMostItemIndex: messages.length - 1,
|
|
282
|
+
followOutput: function followOutput(isAtBottom) {
|
|
283
|
+
if (isMyOwnMessage.current) {
|
|
284
|
+
// if the user has scrolled away and sends a message, bring him to the bottom instantly
|
|
285
|
+
return isAtBottom ? 'smooth' : 'auto';
|
|
286
|
+
} else {
|
|
287
|
+
// a message from another user has been received - don't pull to bottom unless already there
|
|
288
|
+
return isAtBottom ? 'smooth' : false;
|
|
289
|
+
}
|
|
290
|
+
},
|
|
291
|
+
itemContent: row,
|
|
292
|
+
data: messages
|
|
293
|
+
}), React.createElement(TextWrapper, {
|
|
294
|
+
style: {
|
|
295
|
+
flex: 0,
|
|
296
|
+
minHeight: 30
|
|
297
|
+
}
|
|
298
|
+
}, React.createElement("form", {
|
|
299
|
+
onSubmit: function onSubmit(e) {
|
|
300
|
+
e.preventDefault();
|
|
301
|
+
onSendMessage();
|
|
302
|
+
}
|
|
303
|
+
}, React.createElement("input", {
|
|
304
|
+
type: "text",
|
|
305
|
+
value: newMessage,
|
|
306
|
+
onChange: function onChange(e) {
|
|
307
|
+
return setNewMessage(e.target.value);
|
|
308
|
+
},
|
|
309
|
+
placeholder: placeholder
|
|
310
|
+
}), React.createElement("button", {
|
|
311
|
+
type: "submit"
|
|
312
|
+
}, "send"), " |", React.createElement("button", {
|
|
313
|
+
type: "button",
|
|
314
|
+
onClick: onReceiveMessage
|
|
315
|
+
}, "receive"))));
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
var data = Array.from({
|
|
319
|
+
length: 130
|
|
320
|
+
}, function (_) {
|
|
321
|
+
return {
|
|
322
|
+
id: _faker.default.random.number({
|
|
323
|
+
min: 1,
|
|
324
|
+
max: 2
|
|
325
|
+
}).toString(),
|
|
326
|
+
message: _faker.default.lorem.sentences()
|
|
327
|
+
};
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
function App() {
|
|
331
|
+
var _React$useState = React.useState(data),
|
|
332
|
+
_React$useState2 = _slicedToArray(_React$useState, 2),
|
|
333
|
+
messages = _React$useState2[0],
|
|
334
|
+
setMessages = _React$useState2[1];
|
|
335
|
+
|
|
336
|
+
var userId = '1';
|
|
337
|
+
return React.createElement("div", {
|
|
338
|
+
style: {
|
|
339
|
+
height: '500px',
|
|
340
|
+
display: 'flex',
|
|
341
|
+
flexDirection: 'column'
|
|
342
|
+
}
|
|
343
|
+
}, React.createElement(ChatList, {
|
|
344
|
+
messages: messages,
|
|
345
|
+
userId: "1",
|
|
346
|
+
placeholder: "Say hi!",
|
|
347
|
+
onSend: function onSend(message) {
|
|
348
|
+
return setMessages(function (x) {
|
|
349
|
+
return [].concat(_toConsumableArray(x), [{
|
|
350
|
+
id: userId,
|
|
351
|
+
message: message
|
|
352
|
+
}]);
|
|
353
|
+
});
|
|
354
|
+
},
|
|
355
|
+
onReceive: function onReceive() {
|
|
356
|
+
setMessages(function (x) {
|
|
357
|
+
return [].concat(_toConsumableArray(x), [{
|
|
358
|
+
id: '2',
|
|
359
|
+
message: _faker.default.lorem.sentences()
|
|
360
|
+
}]);
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
}));
|
|
364
|
+
}
|
|
365
|
+
},{"react":"../node_modules/react/index.js","@emotion/styled":"../node_modules/@emotion/styled/dist/styled.browser.esm.js","../src/":"../src/index.tsx","faker":"../node_modules/faker/index.js"}],"../node_modules/parcel-bundler/src/builtins/hmr-runtime.js":[function(require,module,exports) {
|
|
366
|
+
var global = arguments[3];
|
|
367
|
+
var OVERLAY_ID = '__parcel__error__overlay__';
|
|
368
|
+
var OldModule = module.bundle.Module;
|
|
369
|
+
|
|
370
|
+
function Module(moduleName) {
|
|
371
|
+
OldModule.call(this, moduleName);
|
|
372
|
+
this.hot = {
|
|
373
|
+
data: module.bundle.hotData,
|
|
374
|
+
_acceptCallbacks: [],
|
|
375
|
+
_disposeCallbacks: [],
|
|
376
|
+
accept: function (fn) {
|
|
377
|
+
this._acceptCallbacks.push(fn || function () {});
|
|
378
|
+
},
|
|
379
|
+
dispose: function (fn) {
|
|
380
|
+
this._disposeCallbacks.push(fn);
|
|
381
|
+
}
|
|
382
|
+
};
|
|
383
|
+
module.bundle.hotData = null;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
module.bundle.Module = Module;
|
|
387
|
+
var checkedAssets, assetsToAccept;
|
|
388
|
+
var parent = module.bundle.parent;
|
|
389
|
+
|
|
390
|
+
if ((!parent || !parent.isParcelRequire) && typeof WebSocket !== 'undefined') {
|
|
391
|
+
var hostname = "" || location.hostname;
|
|
392
|
+
var protocol = location.protocol === 'https:' ? 'wss' : 'ws';
|
|
393
|
+
var ws = new WebSocket(protocol + '://' + hostname + ':' + "61208" + '/');
|
|
394
|
+
|
|
395
|
+
ws.onmessage = function (event) {
|
|
396
|
+
checkedAssets = {};
|
|
397
|
+
assetsToAccept = [];
|
|
398
|
+
var data = JSON.parse(event.data);
|
|
399
|
+
|
|
400
|
+
if (data.type === 'update') {
|
|
401
|
+
var handled = false;
|
|
402
|
+
data.assets.forEach(function (asset) {
|
|
403
|
+
if (!asset.isNew) {
|
|
404
|
+
var didAccept = hmrAcceptCheck(global.parcelRequire, asset.id);
|
|
405
|
+
|
|
406
|
+
if (didAccept) {
|
|
407
|
+
handled = true;
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
}); // Enable HMR for CSS by default.
|
|
411
|
+
|
|
412
|
+
handled = handled || data.assets.every(function (asset) {
|
|
413
|
+
return asset.type === 'css' && asset.generated.js;
|
|
414
|
+
});
|
|
415
|
+
|
|
416
|
+
if (handled) {
|
|
417
|
+
console.clear();
|
|
418
|
+
data.assets.forEach(function (asset) {
|
|
419
|
+
hmrApply(global.parcelRequire, asset);
|
|
420
|
+
});
|
|
421
|
+
assetsToAccept.forEach(function (v) {
|
|
422
|
+
hmrAcceptRun(v[0], v[1]);
|
|
423
|
+
});
|
|
424
|
+
} else if (location.reload) {
|
|
425
|
+
// `location` global exists in a web worker context but lacks `.reload()` function.
|
|
426
|
+
location.reload();
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
if (data.type === 'reload') {
|
|
431
|
+
ws.close();
|
|
432
|
+
|
|
433
|
+
ws.onclose = function () {
|
|
434
|
+
location.reload();
|
|
435
|
+
};
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
if (data.type === 'error-resolved') {
|
|
439
|
+
console.log('[parcel] ✨ Error resolved');
|
|
440
|
+
removeErrorOverlay();
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
if (data.type === 'error') {
|
|
444
|
+
console.error('[parcel] 🚨 ' + data.error.message + '\n' + data.error.stack);
|
|
445
|
+
removeErrorOverlay();
|
|
446
|
+
var overlay = createErrorOverlay(data);
|
|
447
|
+
document.body.appendChild(overlay);
|
|
448
|
+
}
|
|
449
|
+
};
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
function removeErrorOverlay() {
|
|
453
|
+
var overlay = document.getElementById(OVERLAY_ID);
|
|
454
|
+
|
|
455
|
+
if (overlay) {
|
|
456
|
+
overlay.remove();
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
function createErrorOverlay(data) {
|
|
461
|
+
var overlay = document.createElement('div');
|
|
462
|
+
overlay.id = OVERLAY_ID; // html encode message and stack trace
|
|
463
|
+
|
|
464
|
+
var message = document.createElement('div');
|
|
465
|
+
var stackTrace = document.createElement('pre');
|
|
466
|
+
message.innerText = data.error.message;
|
|
467
|
+
stackTrace.innerText = data.error.stack;
|
|
468
|
+
overlay.innerHTML = '<div style="background: black; font-size: 16px; color: white; position: fixed; height: 100%; width: 100%; top: 0px; left: 0px; padding: 30px; opacity: 0.85; font-family: Menlo, Consolas, monospace; z-index: 9999;">' + '<span style="background: red; padding: 2px 4px; border-radius: 2px;">ERROR</span>' + '<span style="top: 2px; margin-left: 5px; position: relative;">🚨</span>' + '<div style="font-size: 18px; font-weight: bold; margin-top: 20px;">' + message.innerHTML + '</div>' + '<pre>' + stackTrace.innerHTML + '</pre>' + '</div>';
|
|
469
|
+
return overlay;
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
function getParents(bundle, id) {
|
|
473
|
+
var modules = bundle.modules;
|
|
474
|
+
|
|
475
|
+
if (!modules) {
|
|
476
|
+
return [];
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
var parents = [];
|
|
480
|
+
var k, d, dep;
|
|
481
|
+
|
|
482
|
+
for (k in modules) {
|
|
483
|
+
for (d in modules[k][1]) {
|
|
484
|
+
dep = modules[k][1][d];
|
|
485
|
+
|
|
486
|
+
if (dep === id || Array.isArray(dep) && dep[dep.length - 1] === id) {
|
|
487
|
+
parents.push(k);
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
if (bundle.parent) {
|
|
493
|
+
parents = parents.concat(getParents(bundle.parent, id));
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
return parents;
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
function hmrApply(bundle, asset) {
|
|
500
|
+
var modules = bundle.modules;
|
|
501
|
+
|
|
502
|
+
if (!modules) {
|
|
503
|
+
return;
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
if (modules[asset.id] || !bundle.parent) {
|
|
507
|
+
var fn = new Function('require', 'module', 'exports', asset.generated.js);
|
|
508
|
+
asset.isNew = !modules[asset.id];
|
|
509
|
+
modules[asset.id] = [fn, asset.deps];
|
|
510
|
+
} else if (bundle.parent) {
|
|
511
|
+
hmrApply(bundle.parent, asset);
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
function hmrAcceptCheck(bundle, id) {
|
|
516
|
+
var modules = bundle.modules;
|
|
517
|
+
|
|
518
|
+
if (!modules) {
|
|
519
|
+
return;
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
if (!modules[id] && bundle.parent) {
|
|
523
|
+
return hmrAcceptCheck(bundle.parent, id);
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
if (checkedAssets[id]) {
|
|
527
|
+
return;
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
checkedAssets[id] = true;
|
|
531
|
+
var cached = bundle.cache[id];
|
|
532
|
+
assetsToAccept.push([bundle, id]);
|
|
533
|
+
|
|
534
|
+
if (cached && cached.hot && cached.hot._acceptCallbacks.length) {
|
|
535
|
+
return true;
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
return getParents(global.parcelRequire, id).some(function (id) {
|
|
539
|
+
return hmrAcceptCheck(global.parcelRequire, id);
|
|
540
|
+
});
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
function hmrAcceptRun(bundle, id) {
|
|
544
|
+
var cached = bundle.cache[id];
|
|
545
|
+
bundle.hotData = {};
|
|
546
|
+
|
|
547
|
+
if (cached) {
|
|
548
|
+
cached.hot.data = bundle.hotData;
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
if (cached && cached.hot && cached.hot._disposeCallbacks.length) {
|
|
552
|
+
cached.hot._disposeCallbacks.forEach(function (cb) {
|
|
553
|
+
cb(bundle.hotData);
|
|
554
|
+
});
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
delete bundle.cache[id];
|
|
558
|
+
bundle(id);
|
|
559
|
+
cached = bundle.cache[id];
|
|
560
|
+
|
|
561
|
+
if (cached && cached.hot && cached.hot._acceptCallbacks.length) {
|
|
562
|
+
cached.hot._acceptCallbacks.forEach(function (cb) {
|
|
563
|
+
cb();
|
|
564
|
+
});
|
|
565
|
+
|
|
566
|
+
return true;
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
},{}]},{},["../node_modules/parcel-bundler/src/builtins/hmr-runtime.js"], null)
|
|
570
|
+
//# sourceMappingURL=/chat.d4f93b8b.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["chat.tsx"],"names":[],"mappings":"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","file":"chat.d4f93b8b.js","sourceRoot":"../e2e","sourcesContent":["import { useRef, useState } from 'react'\nimport * as React from 'react'\nimport styled from '@emotion/styled'\nimport { Virtuoso } from '../src/'\nimport faker from 'faker'\n\ninterface BubbleProps {\n text: string\n fromUser?: boolean\n className?: string\n}\n\nconst BubbleWrap = styled.div<{ fromUser?: boolean }>`\n display: flex;\n justify-content: ${({ fromUser }) => fromUser && 'flex-end'};\n width: 100%;\n padding: 12px 0;\n`\n\nconst Content = styled.div<{ fromUser?: boolean }>`\n background: ${({ fromUser }) => (fromUser ? 'orange' : 'red')};\n color: white;\n width: 60%;\n padding: 12px;\n border-radius: 4px;\n word-break: break-word;\n`\n\nfunction Bubble({ text, fromUser, className }: BubbleProps) {\n return (\n <BubbleWrap fromUser={fromUser} className={className}>\n <Content fromUser={fromUser}>{text}</Content>\n </BubbleWrap>\n )\n}\n\ninterface ChatListProps {\n messages: { id: string; message: string }[]\n userId: string\n onSend: (message: string) => void\n onReceive: () => void\n height?: number\n placeholder?: string\n}\n\nconst Root = styled.div<{ fromUser?: boolean }>`\n padding: 12px 24px;\n`\n\nconst TextWrapper = styled.div`\n display: flex;\n justify-content: space-between;\n width: 100%;\n height: 100%;\n margin-top: 12px;\n`\n\nfunction ChatList({ userId, messages = [], onSend, onReceive, placeholder }: ChatListProps) {\n const [newMessage, setNewMessage] = useState('')\n const ref = useRef(null)\n const isMyOwnMessage = useRef(false)\n const onSendMessage = () => {\n isMyOwnMessage.current = true\n onSend(newMessage)\n setNewMessage('')\n }\n\n const onReceiveMessage = () => {\n isMyOwnMessage.current = false\n onReceive()\n }\n\n const row = React.useMemo(\n () => (i: number, { message, id }: { message: string; id: string }) => {\n const fromUser = id === userId\n return <Bubble key={i} fromUser={fromUser} text={message} />\n },\n [userId]\n )\n\n return (\n <Root\n style={{\n flex: 1,\n display: 'flex',\n flexDirection: 'column',\n border: '1px solid red',\n }}\n >\n <Virtuoso\n ref={ref}\n style={{ flex: 1 }}\n initialTopMostItemIndex={messages.length - 1}\n followOutput={(isAtBottom) => {\n if (isMyOwnMessage.current) {\n // if the user has scrolled away and sends a message, bring him to the bottom instantly\n return isAtBottom ? 'smooth' : 'auto'\n } else {\n // a message from another user has been received - don't pull to bottom unless already there\n return isAtBottom ? 'smooth' : false\n }\n }}\n itemContent={row}\n data={messages}\n />\n <TextWrapper style={{ flex: 0, minHeight: 30 }}>\n <form\n onSubmit={(e) => {\n e.preventDefault()\n onSendMessage()\n }}\n >\n <input\n type=\"text\"\n value={newMessage}\n onChange={(e) => setNewMessage((e.target as HTMLInputElement).value)}\n placeholder={placeholder}\n />\n <button type=\"submit\">send</button> |\n <button type=\"button\" onClick={onReceiveMessage}>\n receive\n </button>\n </form>\n </TextWrapper>\n </Root>\n )\n}\n\nconst data = Array.from({ length: 130 }, (_) => ({\n id: faker.random.number({ min: 1, max: 2 }).toString(),\n message: faker.lorem.sentences(),\n}))\n\nexport default function App() {\n const [messages, setMessages] = React.useState(data)\n const userId = '1'\n return (\n <div\n style={{\n height: '500px',\n display: 'flex',\n flexDirection: 'column',\n }}\n >\n <ChatList\n messages={messages}\n userId=\"1\"\n placeholder=\"Say hi!\"\n onSend={(message) => setMessages((x) => [...x, { id: userId, message }])}\n onReceive={() => {\n setMessages((x) => [...x, { id: '2', message: faker.lorem.sentences() }])\n }}\n />\n </div>\n )\n}\n"]}
|