dce-reactkit 3.5.7 → 3.5.9
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/cjs/index.js +29 -57
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/index.js +29 -57
- package/dist/esm/index.js.map +1 -1
- package/package.json +1 -1
- package/src/components/AutoscrollToBottomContainer.tsx +31 -58
package/package.json
CHANGED
|
@@ -58,17 +58,11 @@ const style = `
|
|
|
58
58
|
|
|
59
59
|
.AutoscrollToBottomContainer-scrollable-container {
|
|
60
60
|
/* Take up max 100% height, don't take it up if not needed */
|
|
61
|
-
/* (so column-reverse layout doesn't start at the bottom) */
|
|
62
61
|
max-height: 100%;
|
|
63
62
|
overflow-y: auto;
|
|
64
63
|
|
|
65
64
|
/* Allow children to position */
|
|
66
65
|
position: relative;
|
|
67
|
-
|
|
68
|
-
/* Reverse order of children so scroll starts at bottom */
|
|
69
|
-
/* (but children will have to be rendered in reverse order) */
|
|
70
|
-
display: flex;
|
|
71
|
-
flex-direction: column-reverse;
|
|
72
66
|
}
|
|
73
67
|
|
|
74
68
|
.AutoscrollToBottomContainer-jump-to-bottom-container {
|
|
@@ -101,7 +95,7 @@ const style = `
|
|
|
101
95
|
|
|
102
96
|
// Scrolled to bottom threshold
|
|
103
97
|
// (how close you have to be to the bottom for it to count as the bottom)
|
|
104
|
-
const SCROLLED_TO_BOTTOM_THRESHOLD_REMS =
|
|
98
|
+
const SCROLLED_TO_BOTTOM_THRESHOLD_REMS = 1.5;
|
|
105
99
|
|
|
106
100
|
/*------------------------------------------------------------------------*/
|
|
107
101
|
/* -------------------------- Static Functions -------------------------- */
|
|
@@ -126,8 +120,6 @@ const getItemIds = (items: AutoScrollItem[]): (string | number)[] => {
|
|
|
126
120
|
/* -------- State Definition -------- */
|
|
127
121
|
|
|
128
122
|
type State = {
|
|
129
|
-
// If true, the user was scrolled to the bottom after last update
|
|
130
|
-
wasScrolledToBottom: boolean,
|
|
131
123
|
// If true, the "jump to bottom" button is visible
|
|
132
124
|
jumpToBottomButtonVisible: boolean,
|
|
133
125
|
};
|
|
@@ -136,12 +128,10 @@ type State = {
|
|
|
136
128
|
|
|
137
129
|
// Types of actions
|
|
138
130
|
enum ActionType {
|
|
139
|
-
//
|
|
140
|
-
|
|
141
|
-
//
|
|
142
|
-
|
|
143
|
-
// Identify that new content appeared at the bottom but is not visible
|
|
144
|
-
NewContentAtBottom = 'NewContentAtBottom',
|
|
131
|
+
// Hide the "jump to bottom" button
|
|
132
|
+
HideJumpToBottomButton = 'HideJumpToBottomButton',
|
|
133
|
+
// Show the "jump to bottom" button
|
|
134
|
+
ShowJumpToBottomButton = 'ShowJumpToBottomButton',
|
|
145
135
|
}
|
|
146
136
|
|
|
147
137
|
// Action definitions
|
|
@@ -149,9 +139,8 @@ type Action = (
|
|
|
149
139
|
| {
|
|
150
140
|
// Action type
|
|
151
141
|
type: (
|
|
152
|
-
| ActionType.
|
|
153
|
-
| ActionType.
|
|
154
|
-
| ActionType.NewContentAtBottom
|
|
142
|
+
| ActionType.HideJumpToBottomButton
|
|
143
|
+
| ActionType.ShowJumpToBottomButton
|
|
155
144
|
),
|
|
156
145
|
}
|
|
157
146
|
);
|
|
@@ -164,28 +153,15 @@ type Action = (
|
|
|
164
153
|
*/
|
|
165
154
|
const reducer = (state: State, action: Action): State => {
|
|
166
155
|
switch (action.type) {
|
|
167
|
-
case ActionType.
|
|
156
|
+
case ActionType.HideJumpToBottomButton: {
|
|
168
157
|
return {
|
|
169
158
|
...state,
|
|
170
|
-
// Store the event
|
|
171
|
-
wasScrolledToBottom: true,
|
|
172
|
-
// Hide the "jump to bottom" button
|
|
173
159
|
jumpToBottomButtonVisible: false,
|
|
174
160
|
};
|
|
175
161
|
}
|
|
176
|
-
case ActionType.
|
|
177
|
-
return {
|
|
178
|
-
...state,
|
|
179
|
-
// Store the event
|
|
180
|
-
wasScrolledToBottom: false,
|
|
181
|
-
};
|
|
182
|
-
}
|
|
183
|
-
case ActionType.NewContentAtBottom: {
|
|
162
|
+
case ActionType.ShowJumpToBottomButton: {
|
|
184
163
|
return {
|
|
185
164
|
...state,
|
|
186
|
-
// Store the event
|
|
187
|
-
wasScrolledToBottom: false,
|
|
188
|
-
// Show the "jump to bottom" button
|
|
189
165
|
jumpToBottomButtonVisible: true,
|
|
190
166
|
};
|
|
191
167
|
}
|
|
@@ -217,7 +193,6 @@ const AutoscrollToBottomContainer: React.FC<Props> = (props) => {
|
|
|
217
193
|
|
|
218
194
|
// Initial state
|
|
219
195
|
const initialState: State = {
|
|
220
|
-
wasScrolledToBottom: true,
|
|
221
196
|
jumpToBottomButtonVisible: false,
|
|
222
197
|
};
|
|
223
198
|
|
|
@@ -226,7 +201,6 @@ const AutoscrollToBottomContainer: React.FC<Props> = (props) => {
|
|
|
226
201
|
|
|
227
202
|
// Destructure common state
|
|
228
203
|
const {
|
|
229
|
-
wasScrolledToBottom,
|
|
230
204
|
jumpToBottomButtonVisible,
|
|
231
205
|
} = state;
|
|
232
206
|
|
|
@@ -235,6 +209,7 @@ const AutoscrollToBottomContainer: React.FC<Props> = (props) => {
|
|
|
235
209
|
// Initialize refs
|
|
236
210
|
const lastItemIds = useRef<(string | number)[]>([]);
|
|
237
211
|
const container = useRef<HTMLDivElement | null>(null);
|
|
212
|
+
const wasScrolledToBottomBeforeItemsUpdate = useRef<boolean>(true);
|
|
238
213
|
|
|
239
214
|
/*------------------------------------------------------------------------*/
|
|
240
215
|
/* ------------------------- Component Functions ------------------------ */
|
|
@@ -258,6 +233,8 @@ const AutoscrollToBottomContainer: React.FC<Props> = (props) => {
|
|
|
258
233
|
// Get info about container
|
|
259
234
|
const {
|
|
260
235
|
scrollTop,
|
|
236
|
+
scrollHeight,
|
|
237
|
+
clientHeight,
|
|
261
238
|
} = container.current;
|
|
262
239
|
|
|
263
240
|
// Distance to bottom
|
|
@@ -265,7 +242,9 @@ const AutoscrollToBottomContainer: React.FC<Props> = (props) => {
|
|
|
265
242
|
getComputedStyle(document.documentElement).fontSize,
|
|
266
243
|
10,
|
|
267
244
|
);
|
|
268
|
-
const distanceToBottomRems = Math.abs(
|
|
245
|
+
const distanceToBottomRems = Math.abs(
|
|
246
|
+
(scrollTop + clientHeight - scrollHeight) / rootFontSizePx,
|
|
247
|
+
);
|
|
269
248
|
|
|
270
249
|
// Figure out if we're scrolled to the bottom
|
|
271
250
|
return (distanceToBottomRems < SCROLLED_TO_BOTTOM_THRESHOLD_REMS);
|
|
@@ -283,11 +262,11 @@ const AutoscrollToBottomContainer: React.FC<Props> = (props) => {
|
|
|
283
262
|
|
|
284
263
|
// Update state
|
|
285
264
|
dispatch({
|
|
286
|
-
type: ActionType.
|
|
265
|
+
type: ActionType.HideJumpToBottomButton,
|
|
287
266
|
});
|
|
288
267
|
|
|
289
268
|
// Scroll to bottom
|
|
290
|
-
container.current.scrollTop =
|
|
269
|
+
container.current.scrollTop = container.current.scrollHeight;
|
|
291
270
|
};
|
|
292
271
|
|
|
293
272
|
/*----------------------------------------*/
|
|
@@ -304,17 +283,10 @@ const AutoscrollToBottomContainer: React.FC<Props> = (props) => {
|
|
|
304
283
|
return;
|
|
305
284
|
}
|
|
306
285
|
|
|
307
|
-
//
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
// Remember if now no longer scrolled to bottom
|
|
311
|
-
if (nowScrolledToBottom) {
|
|
312
|
-
dispatch({
|
|
313
|
-
type: ActionType.NowScrolledToBottom,
|
|
314
|
-
});
|
|
315
|
-
} else {
|
|
286
|
+
// If scrolled to bottom, hide the button
|
|
287
|
+
if (isScrolledToBottom()) {
|
|
316
288
|
dispatch({
|
|
317
|
-
type: ActionType.
|
|
289
|
+
type: ActionType.HideJumpToBottomButton,
|
|
318
290
|
});
|
|
319
291
|
}
|
|
320
292
|
};
|
|
@@ -336,7 +308,7 @@ const AutoscrollToBottomContainer: React.FC<Props> = (props) => {
|
|
|
336
308
|
);
|
|
337
309
|
|
|
338
310
|
/**
|
|
339
|
-
* Update (also called on mount)
|
|
311
|
+
* Update (also called on mount): autoscroll
|
|
340
312
|
* @author Gabe Abrams
|
|
341
313
|
*/
|
|
342
314
|
useEffect(
|
|
@@ -345,7 +317,7 @@ const AutoscrollToBottomContainer: React.FC<Props> = (props) => {
|
|
|
345
317
|
const currentItemIds = getItemIds(items);
|
|
346
318
|
|
|
347
319
|
// Check if new content appeared at bottom
|
|
348
|
-
const
|
|
320
|
+
const newContentAppeared = (
|
|
349
321
|
currentItemIds.length > 0
|
|
350
322
|
&& (
|
|
351
323
|
currentItemIds[currentItemIds.length - 1]
|
|
@@ -354,23 +326,28 @@ const AutoscrollToBottomContainer: React.FC<Props> = (props) => {
|
|
|
354
326
|
);
|
|
355
327
|
|
|
356
328
|
// Do nothing if no new content
|
|
357
|
-
if (!
|
|
329
|
+
if (!newContentAppeared) {
|
|
358
330
|
return;
|
|
359
331
|
}
|
|
360
332
|
|
|
361
333
|
// Check if used to be scrolled to the bottom
|
|
362
|
-
if (
|
|
334
|
+
if (wasScrolledToBottomBeforeItemsUpdate.current) {
|
|
363
335
|
// Was scrolled to the bottom! Autoscroll.
|
|
364
336
|
scrollToBottom();
|
|
365
337
|
} else {
|
|
366
338
|
// Not scrolled to bottom. Show "jump to bottom" button.
|
|
367
339
|
dispatch({
|
|
368
|
-
type: ActionType.
|
|
340
|
+
type: ActionType.ShowJumpToBottomButton,
|
|
369
341
|
});
|
|
370
342
|
}
|
|
371
343
|
|
|
372
344
|
// Update last item ids
|
|
373
345
|
lastItemIds.current = currentItemIds;
|
|
346
|
+
|
|
347
|
+
// Remember if we were scrolled to the bottom before the update
|
|
348
|
+
return () => {
|
|
349
|
+
wasScrolledToBottomBeforeItemsUpdate.current = isScrolledToBottom();
|
|
350
|
+
};
|
|
374
351
|
},
|
|
375
352
|
[items],
|
|
376
353
|
);
|
|
@@ -420,9 +397,7 @@ const AutoscrollToBottomContainer: React.FC<Props> = (props) => {
|
|
|
420
397
|
{/* Scrollable Item Container */}
|
|
421
398
|
<div
|
|
422
399
|
className="AutoscrollToBottomContainer-scrollable-container"
|
|
423
|
-
onScroll={
|
|
424
|
-
handleScroll();
|
|
425
|
-
}}
|
|
400
|
+
onScroll={handleScroll}
|
|
426
401
|
ref={container}
|
|
427
402
|
>
|
|
428
403
|
{/* Items */}
|
|
@@ -439,8 +414,6 @@ const AutoscrollToBottomContainer: React.FC<Props> = (props) => {
|
|
|
439
414
|
</div>
|
|
440
415
|
);
|
|
441
416
|
})
|
|
442
|
-
// Reverse order because flex column is reverse
|
|
443
|
-
.reverse()
|
|
444
417
|
}
|
|
445
418
|
</div>
|
|
446
419
|
</div>
|