dce-reactkit 3.5.8 → 3.5.10

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.8",
3
+ "version": "3.5.10",
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
@@ -128,10 +132,10 @@ type State = {
128
132
 
129
133
  // Types of actions
130
134
  enum ActionType {
131
- // Identify that the user is now scrolled to the bottom
132
- NowScrolledToBottom = 'NowScrolledToBottom',
133
- // Identify that new content appeared at the bottom but is not visible
134
- NewContentAtBottom = 'NewContentAtBottom',
135
+ // Hide the "jump to bottom" button
136
+ HideJumpToBottomButton = 'HideJumpToBottomButton',
137
+ // Show the "jump to bottom" button
138
+ ShowJumpToBottomButton = 'ShowJumpToBottomButton',
135
139
  }
136
140
 
137
141
  // Action definitions
@@ -139,8 +143,8 @@ type Action = (
139
143
  | {
140
144
  // Action type
141
145
  type: (
142
- | ActionType.NowScrolledToBottom
143
- | ActionType.NewContentAtBottom
146
+ | ActionType.HideJumpToBottomButton
147
+ | ActionType.ShowJumpToBottomButton
144
148
  ),
145
149
  }
146
150
  );
@@ -153,17 +157,15 @@ type Action = (
153
157
  */
154
158
  const reducer = (state: State, action: Action): State => {
155
159
  switch (action.type) {
156
- case ActionType.NowScrolledToBottom: {
160
+ case ActionType.HideJumpToBottomButton: {
157
161
  return {
158
162
  ...state,
159
- // Hide the "jump to bottom" button
160
163
  jumpToBottomButtonVisible: false,
161
164
  };
162
165
  }
163
- case ActionType.NewContentAtBottom: {
166
+ case ActionType.ShowJumpToBottomButton: {
164
167
  return {
165
168
  ...state,
166
- // Show the "jump to bottom" button
167
169
  jumpToBottomButtonVisible: true,
168
170
  };
169
171
  }
@@ -189,6 +191,8 @@ const AutoscrollToBottomContainer: React.FC<Props> = (props) => {
189
191
  itemsName,
190
192
  items,
191
193
  jumpToBottomButtonVariant = Variant.Danger,
194
+ messageBeforeItems,
195
+ messageAfterItems,
192
196
  } = props;
193
197
 
194
198
  /* -------------- State ------------- */
@@ -235,6 +239,8 @@ const AutoscrollToBottomContainer: React.FC<Props> = (props) => {
235
239
  // Get info about container
236
240
  const {
237
241
  scrollTop,
242
+ scrollHeight,
243
+ clientHeight,
238
244
  } = container.current;
239
245
 
240
246
  // Distance to bottom
@@ -242,7 +248,9 @@ const AutoscrollToBottomContainer: React.FC<Props> = (props) => {
242
248
  getComputedStyle(document.documentElement).fontSize,
243
249
  10,
244
250
  );
245
- const distanceToBottomRems = Math.abs(scrollTop / rootFontSizePx);
251
+ const distanceToBottomRems = Math.abs(
252
+ (scrollTop + clientHeight - scrollHeight) / rootFontSizePx,
253
+ );
246
254
 
247
255
  // Figure out if we're scrolled to the bottom
248
256
  return (distanceToBottomRems < SCROLLED_TO_BOTTOM_THRESHOLD_REMS);
@@ -260,11 +268,11 @@ const AutoscrollToBottomContainer: React.FC<Props> = (props) => {
260
268
 
261
269
  // Update state
262
270
  dispatch({
263
- type: ActionType.NowScrolledToBottom,
271
+ type: ActionType.HideJumpToBottomButton,
264
272
  });
265
273
 
266
274
  // Scroll to bottom
267
- container.current.scrollTop = 0;
275
+ container.current.scrollTop = container.current.scrollHeight;
268
276
  };
269
277
 
270
278
  /*----------------------------------------*/
@@ -281,13 +289,10 @@ const AutoscrollToBottomContainer: React.FC<Props> = (props) => {
281
289
  return;
282
290
  }
283
291
 
284
- // Check if now scrolled to bottom
285
- const nowScrolledToBottom = isScrolledToBottom();
286
-
287
- // Remember if now no longer scrolled to bottom
288
- if (nowScrolledToBottom) {
292
+ // If scrolled to bottom, hide the button
293
+ if (isScrolledToBottom()) {
289
294
  dispatch({
290
- type: ActionType.NowScrolledToBottom,
295
+ type: ActionType.HideJumpToBottomButton,
291
296
  });
292
297
  }
293
298
  };
@@ -318,8 +323,10 @@ const AutoscrollToBottomContainer: React.FC<Props> = (props) => {
318
323
  const currentItemIds = getItemIds(items);
319
324
 
320
325
  // Check if new content appeared at bottom
321
- const newContentAtBottom = (
326
+ const newContentAppeared = (
322
327
  currentItemIds.length > 0
328
+ && lastItemIds.current
329
+ && lastItemIds.current.length > 0
323
330
  && (
324
331
  currentItemIds[currentItemIds.length - 1]
325
332
  !== lastItemIds.current[lastItemIds.current.length - 1]
@@ -327,7 +334,7 @@ const AutoscrollToBottomContainer: React.FC<Props> = (props) => {
327
334
  );
328
335
 
329
336
  // Do nothing if no new content
330
- if (!newContentAtBottom) {
337
+ if (!newContentAppeared) {
331
338
  return;
332
339
  }
333
340
 
@@ -338,7 +345,7 @@ const AutoscrollToBottomContainer: React.FC<Props> = (props) => {
338
345
  } else {
339
346
  // Not scrolled to bottom. Show "jump to bottom" button.
340
347
  dispatch({
341
- type: ActionType.NewContentAtBottom,
348
+ type: ActionType.ShowJumpToBottomButton,
342
349
  });
343
350
  }
344
351
 
@@ -401,6 +408,9 @@ const AutoscrollToBottomContainer: React.FC<Props> = (props) => {
401
408
  onScroll={handleScroll}
402
409
  ref={container}
403
410
  >
411
+ {/* Message before items */}
412
+ {messageBeforeItems}
413
+
404
414
  {/* Items */}
405
415
  {
406
416
  items
@@ -416,6 +426,9 @@ const AutoscrollToBottomContainer: React.FC<Props> = (props) => {
416
426
  );
417
427
  })
418
428
  }
429
+
430
+ {/* Message after items */}
431
+ {messageAfterItems}
419
432
  </div>
420
433
  </div>
421
434
  );