dce-reactkit 3.5.9 → 3.5.11

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.
@@ -12,6 +12,8 @@ type Props = {
12
12
  itemsName?: string;
13
13
  items: AutoScrollItem[];
14
14
  jumpToBottomButtonVariant?: Variant;
15
+ messageBeforeItems?: React.ReactNode;
16
+ messageAfterItems?: React.ReactNode;
15
17
  };
16
18
  type AutoScrollItem = {
17
19
  id: string | number;
package/dist/index.d.ts CHANGED
@@ -619,6 +619,8 @@ type Props = {
619
619
  itemsName?: string;
620
620
  items: AutoScrollItem[];
621
621
  jumpToBottomButtonVariant?: Variant;
622
+ messageBeforeItems?: React.ReactNode;
623
+ messageAfterItems?: React.ReactNode;
622
624
  };
623
625
  type AutoScrollItem = {
624
626
  id: string | number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dce-reactkit",
3
- "version": "3.5.9",
3
+ "version": "3.5.11",
4
4
  "description": "Shared components for Harvard DCE apps",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/esm/index.js",
@@ -35,6 +35,10 @@ type Props = {
35
35
  items: AutoScrollItem[],
36
36
  // Custom variant for the "Jump to Bottom" button
37
37
  jumpToBottomButtonVariant?: Variant,
38
+ // Optional element to display before last item (but within the scrollpane)
39
+ messageBeforeItems?: React.ReactNode,
40
+ // Optional element to display after the last item (but within the scrollpane)
41
+ messageAfterItems?: React.ReactNode,
38
42
  };
39
43
 
40
44
  // AutoScrollItem definition
@@ -187,6 +191,8 @@ const AutoscrollToBottomContainer: React.FC<Props> = (props) => {
187
191
  itemsName,
188
192
  items,
189
193
  jumpToBottomButtonVariant = Variant.Danger,
194
+ messageBeforeItems,
195
+ messageAfterItems,
190
196
  } = props;
191
197
 
192
198
  /* -------------- State ------------- */
@@ -209,7 +215,7 @@ const AutoscrollToBottomContainer: React.FC<Props> = (props) => {
209
215
  // Initialize refs
210
216
  const lastItemIds = useRef<(string | number)[]>([]);
211
217
  const container = useRef<HTMLDivElement | null>(null);
212
- const wasScrolledToBottomBeforeItemsUpdate = useRef<boolean>(true);
218
+ const wasLastScrolledToBottom = useRef<boolean>(true);
213
219
 
214
220
  /*------------------------------------------------------------------------*/
215
221
  /* ------------------------- Component Functions ------------------------ */
@@ -247,7 +253,12 @@ const AutoscrollToBottomContainer: React.FC<Props> = (props) => {
247
253
  );
248
254
 
249
255
  // Figure out if we're scrolled to the bottom
250
- return (distanceToBottomRems < SCROLLED_TO_BOTTOM_THRESHOLD_REMS);
256
+ const atBottom = (distanceToBottomRems < SCROLLED_TO_BOTTOM_THRESHOLD_REMS);
257
+
258
+ // Remember if we scrolled to the bottom
259
+ wasLastScrolledToBottom.current = atBottom;
260
+
261
+ return atBottom;
251
262
  };
252
263
 
253
264
  /**
@@ -266,7 +277,13 @@ const AutoscrollToBottomContainer: React.FC<Props> = (props) => {
266
277
  });
267
278
 
268
279
  // Scroll to bottom
269
- container.current.scrollTop = container.current.scrollHeight;
280
+ container.current.scrollTop = (
281
+ container.current.scrollHeight
282
+ - container.current.clientHeight
283
+ );
284
+
285
+ // Remember that we scrolled to the bottom
286
+ wasLastScrolledToBottom.current = true;
270
287
  };
271
288
 
272
289
  /*----------------------------------------*/
@@ -283,8 +300,9 @@ const AutoscrollToBottomContainer: React.FC<Props> = (props) => {
283
300
  return;
284
301
  }
285
302
 
286
- // If scrolled to bottom, hide the button
303
+ // If scrolled to bottom, hide the button and remember position
287
304
  if (isScrolledToBottom()) {
305
+ // Hide button
288
306
  dispatch({
289
307
  type: ActionType.HideJumpToBottomButton,
290
308
  });
@@ -318,20 +336,24 @@ const AutoscrollToBottomContainer: React.FC<Props> = (props) => {
318
336
 
319
337
  // Check if new content appeared at bottom
320
338
  const newContentAppeared = (
339
+ // There are items
321
340
  currentItemIds.length > 0
322
- && (
323
- currentItemIds[currentItemIds.length - 1]
324
- !== lastItemIds.current[lastItemIds.current.length - 1]
341
+ // The last item is new
342
+ && !lastItemIds.current.includes(
343
+ currentItemIds[currentItemIds.length - 1],
325
344
  )
326
345
  );
327
346
 
347
+ // Update last item ids
348
+ lastItemIds.current = currentItemIds;
349
+
328
350
  // Do nothing if no new content
329
351
  if (!newContentAppeared) {
330
352
  return;
331
353
  }
332
354
 
333
355
  // Check if used to be scrolled to the bottom
334
- if (wasScrolledToBottomBeforeItemsUpdate.current) {
356
+ if (wasLastScrolledToBottom.current) {
335
357
  // Was scrolled to the bottom! Autoscroll.
336
358
  scrollToBottom();
337
359
  } else {
@@ -340,14 +362,6 @@ const AutoscrollToBottomContainer: React.FC<Props> = (props) => {
340
362
  type: ActionType.ShowJumpToBottomButton,
341
363
  });
342
364
  }
343
-
344
- // Update last item ids
345
- lastItemIds.current = currentItemIds;
346
-
347
- // Remember if we were scrolled to the bottom before the update
348
- return () => {
349
- wasScrolledToBottomBeforeItemsUpdate.current = isScrolledToBottom();
350
- };
351
365
  },
352
366
  [items],
353
367
  );
@@ -400,6 +414,9 @@ const AutoscrollToBottomContainer: React.FC<Props> = (props) => {
400
414
  onScroll={handleScroll}
401
415
  ref={container}
402
416
  >
417
+ {/* Message before items */}
418
+ {messageBeforeItems}
419
+
403
420
  {/* Items */}
404
421
  {
405
422
  items
@@ -415,6 +432,9 @@ const AutoscrollToBottomContainer: React.FC<Props> = (props) => {
415
432
  );
416
433
  })
417
434
  }
435
+
436
+ {/* Message after items */}
437
+ {messageAfterItems}
418
438
  </div>
419
439
  </div>
420
440
  );