dce-reactkit 3.5.6 → 3.5.8

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.
@@ -1,7 +1,9 @@
1
1
  /**
2
2
  * Container that automatically scrolls when new items are added,
3
3
  * lets the user scroll up to see old items, but resumes
4
- * autoscroll when the user scrolls back to the bottom
4
+ * autoscroll when the user scrolls back to the bottom.
5
+ * Note: takes up full height of parent, so parent should
6
+ * have a determined height for the scroll to work.
5
7
  * @author Gabe Abrams
6
8
  */
7
9
  import React from 'react';
@@ -15,5 +17,5 @@ type AutoScrollItem = {
15
17
  id: string | number;
16
18
  item: React.ReactNode;
17
19
  };
18
- declare const ScrollLockToBottom: React.FC<Props>;
19
- export default ScrollLockToBottom;
20
+ declare const AutoscrollToBottomContainer: React.FC<Props>;
21
+ export default AutoscrollToBottomContainer;
@@ -19,7 +19,7 @@ import CSVDownloadButton from './components/CSVDownloadButton';
19
19
  import DBEntryManagerPanel from './components/DBEntryManagerPanel';
20
20
  import Tooltip from './components/Tooltip';
21
21
  import ToggleSwitch from './components/ToggleSwitch';
22
- import ScrollLockToBottom from './components/ScrollLockToBottomContainer';
22
+ import AutoscrollToBottomContainer from './components/AutoscrollToBottomContainer';
23
23
  import ErrorWithCode from './errors/ErrorWithCode';
24
24
  import MINUTE_IN_MS from './constants/MINUTE_IN_MS';
25
25
  import HOUR_IN_MS from './constants/HOUR_IN_MS';
@@ -83,4 +83,4 @@ import PickableItem from './components/ItemPicker/types/PickableItem';
83
83
  import DBEntry from './components/DBEntryManagerPanel/types/DBEntry';
84
84
  import DBEntryField from './components/DBEntryManagerPanel/types/DBEntryField';
85
85
  import DBEntryFieldType from './components/DBEntryManagerPanel/types/DBEntryFieldType';
86
- export { AppWrapper, LoadingSpinner, ErrorBox, Modal, TabBox, RadioButton, CheckboxButton, ButtonInputGroup, SimpleDateChooser, Drawer, PopSuccessMark, PopFailureMark, PopPendingMark, CopiableBox, ItemPicker, LogReviewer, IntelliTable, CSVDownloadButton, DBEntryManagerPanel, Tooltip, ToggleSwitch, ScrollLockToBottom, alert, confirm, showFatalError, ErrorWithCode, MINUTE_IN_MS, HOUR_IN_MS, DAY_IN_MS, DynamicWord, abbreviate, avg, ceilToNumDecimals, floorToNumDecimals, forceNumIntoBounds, padDecimalZeros, padZerosLeft, roundToNumDecimals, sum, waitMs, getOrdinal, getTimeInfoInET, stubServerEndpoint, startMinWait, getHumanReadableDate, getPartOfDay, stringsToHumanReadableList, onlyKeepLetters, parallelLimit, getMonthName, genCSV, canReviewLogs, isMobileOrTablet, extractProp, compareArraysByProp, genCommaList, validateEmail, validatePhoneNumber, validateString, getLocalTimeInfo, idify, initClient, visitServerEndpoint, logClientEvent, addFatalErrorHandler, initServer, genRouteHandler, handleError, handleSuccess, initLogCollection, addDBEditorEndpoints, ModalButtonType, ModalSize, ModalType, ReactKitErrorCode, Variant, DayOfWeek, Log, LogType, LogSource, LogAction, LogBuiltInMetadata, LogMetadataType, IntelliTableColumn, PickableItem, DBEntry, DBEntryField, DBEntryFieldType, ParamType, };
86
+ export { AppWrapper, LoadingSpinner, ErrorBox, Modal, TabBox, RadioButton, CheckboxButton, ButtonInputGroup, SimpleDateChooser, Drawer, PopSuccessMark, PopFailureMark, PopPendingMark, CopiableBox, ItemPicker, LogReviewer, IntelliTable, CSVDownloadButton, DBEntryManagerPanel, Tooltip, ToggleSwitch, AutoscrollToBottomContainer, alert, confirm, showFatalError, ErrorWithCode, MINUTE_IN_MS, HOUR_IN_MS, DAY_IN_MS, DynamicWord, abbreviate, avg, ceilToNumDecimals, floorToNumDecimals, forceNumIntoBounds, padDecimalZeros, padZerosLeft, roundToNumDecimals, sum, waitMs, getOrdinal, getTimeInfoInET, stubServerEndpoint, startMinWait, getHumanReadableDate, getPartOfDay, stringsToHumanReadableList, onlyKeepLetters, parallelLimit, getMonthName, genCSV, canReviewLogs, isMobileOrTablet, extractProp, compareArraysByProp, genCommaList, validateEmail, validatePhoneNumber, validateString, getLocalTimeInfo, idify, initClient, visitServerEndpoint, logClientEvent, addFatalErrorHandler, initServer, genRouteHandler, handleError, handleSuccess, initLogCollection, addDBEditorEndpoints, ModalButtonType, ModalSize, ModalType, ReactKitErrorCode, Variant, DayOfWeek, Log, LogType, LogSource, LogAction, LogBuiltInMetadata, LogMetadataType, IntelliTableColumn, PickableItem, DBEntry, DBEntryField, DBEntryFieldType, ParamType, };
package/dist/index.d.ts CHANGED
@@ -609,7 +609,9 @@ declare const ToggleSwitch: React.FC<Props$1>;
609
609
  /**
610
610
  * Container that automatically scrolls when new items are added,
611
611
  * lets the user scroll up to see old items, but resumes
612
- * autoscroll when the user scrolls back to the bottom
612
+ * autoscroll when the user scrolls back to the bottom.
613
+ * Note: takes up full height of parent, so parent should
614
+ * have a determined height for the scroll to work.
613
615
  * @author Gabe Abrams
614
616
  */
615
617
 
@@ -622,7 +624,7 @@ type AutoScrollItem = {
622
624
  id: string | number;
623
625
  item: React.ReactNode;
624
626
  };
625
- declare const ScrollLockToBottom: React.FC<Props>;
627
+ declare const AutoscrollToBottomContainer: React.FC<Props>;
626
628
 
627
629
  /**
628
630
  * An error with a code
@@ -1410,4 +1412,4 @@ declare const LogBuiltInMetadata: {
1410
1412
  };
1411
1413
  };
1412
1414
 
1413
- export { AppWrapper, ButtonInputGroup, CSVDownloadButton, CheckboxButton, CopiableBox, DAY_IN_MS, DBEntry, DBEntryField, DBEntryFieldType, DBEntryManagerPanel, DayOfWeek, Drawer, DynamicWord, ErrorBox, ErrorWithCode, HOUR_IN_MS, IntelliTable, IntelliTableColumn, ItemPicker, LoadingSpinner, Log, LogAction, LogBuiltInMetadata, LogMetadataType, LogReviewer, LogSource, LogType, MINUTE_IN_MS, Modal, ModalButtonType, ModalSize, ModalType, ParamType, PickableItem, PopFailureMark, PopPendingMark, PopSuccessMark, RadioButton, ReactKitErrorCode, ScrollLockToBottom, SimpleDateChooser, TabBox, ToggleSwitch, Tooltip, Variant, abbreviate, addDBEditorEndpoints, addFatalErrorHandler, alert, avg, canReviewLogs, ceilToNumDecimals, compareArraysByProp, confirm, extractProp, floorToNumDecimals, forceNumIntoBounds, genCSV, genCommaList, genRouteHandler, getHumanReadableDate, getLocalTimeInfo, getMonthName, getOrdinal, getPartOfDay, getTimeInfoInET, handleError, handleSuccess, idify, initClient, initLogCollection, initServer, isMobileOrTablet, logClientEvent, onlyKeepLetters, padDecimalZeros, padZerosLeft, parallelLimit, roundToNumDecimals, showFatalError, startMinWait, stringsToHumanReadableList, stubServerEndpoint, sum, validateEmail, validatePhoneNumber, validateString, visitServerEndpoint, waitMs };
1415
+ export { AppWrapper, AutoscrollToBottomContainer, ButtonInputGroup, CSVDownloadButton, CheckboxButton, CopiableBox, DAY_IN_MS, DBEntry, DBEntryField, DBEntryFieldType, DBEntryManagerPanel, DayOfWeek, Drawer, DynamicWord, ErrorBox, ErrorWithCode, HOUR_IN_MS, IntelliTable, IntelliTableColumn, ItemPicker, LoadingSpinner, Log, LogAction, LogBuiltInMetadata, LogMetadataType, LogReviewer, LogSource, LogType, MINUTE_IN_MS, Modal, ModalButtonType, ModalSize, ModalType, ParamType, PickableItem, PopFailureMark, PopPendingMark, PopSuccessMark, RadioButton, ReactKitErrorCode, SimpleDateChooser, TabBox, ToggleSwitch, Tooltip, Variant, abbreviate, addDBEditorEndpoints, addFatalErrorHandler, alert, avg, canReviewLogs, ceilToNumDecimals, compareArraysByProp, confirm, extractProp, floorToNumDecimals, forceNumIntoBounds, genCSV, genCommaList, genRouteHandler, getHumanReadableDate, getLocalTimeInfo, getMonthName, getOrdinal, getPartOfDay, getTimeInfoInET, handleError, handleSuccess, idify, initClient, initLogCollection, initServer, isMobileOrTablet, logClientEvent, onlyKeepLetters, padDecimalZeros, padZerosLeft, parallelLimit, roundToNumDecimals, showFatalError, startMinWait, stringsToHumanReadableList, stubServerEndpoint, sum, validateEmail, validatePhoneNumber, validateString, visitServerEndpoint, waitMs };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dce-reactkit",
3
- "version": "3.5.6",
3
+ "version": "3.5.8",
4
4
  "description": "Shared components for Harvard DCE apps",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/esm/index.js",
@@ -1,7 +1,9 @@
1
1
  /**
2
2
  * Container that automatically scrolls when new items are added,
3
3
  * lets the user scroll up to see old items, but resumes
4
- * autoscroll when the user scrolls back to the bottom
4
+ * autoscroll when the user scrolls back to the bottom.
5
+ * Note: takes up full height of parent, so parent should
6
+ * have a determined height for the scroll to work.
5
7
  * @author Gabe Abrams
6
8
  */
7
9
 
@@ -48,28 +50,22 @@ type AutoScrollItem = {
48
50
  /*------------------------------------------------------------------------*/
49
51
 
50
52
  const style = `
51
- .ScrollLockToBottom-outer-container {
53
+ .AutoscrollToBottomContainer-outer-container {
52
54
  /* Take up all space */
53
55
  height: 100%;
54
56
  position: relative;
55
57
  }
56
58
 
57
- .ScrollLockToBottom-scrollable-container {
59
+ .AutoscrollToBottomContainer-scrollable-container {
58
60
  /* Take up max 100% height, don't take it up if not needed */
59
- /* (so column-reverse layout doesn't start at the bottom) */
60
61
  max-height: 100%;
61
62
  overflow-y: auto;
62
63
 
63
64
  /* Allow children to position */
64
65
  position: relative;
65
-
66
- /* Reverse order of children so scroll starts at bottom */
67
- /* (but children will have to be rendered in reverse order) */
68
- display: flex;
69
- flex-direction: column-reverse;
70
66
  }
71
67
 
72
- .ScrollLockToBottom-jump-to-bottom-container {
68
+ .AutoscrollToBottomContainer-jump-to-bottom-container {
73
69
  /* Don't take any space in parent */
74
70
  height: 0;
75
71
  overflow: visible;
@@ -86,7 +82,7 @@ const style = `
86
82
  text-align: center;
87
83
  }
88
84
 
89
- .ScrollLockToBottom-item-container {
85
+ .AutoscrollToBottomContainer-item-container {
90
86
  /* Normal Height */
91
87
  position: relative;
92
88
  z-index: 1;
@@ -99,7 +95,7 @@ const style = `
99
95
 
100
96
  // Scrolled to bottom threshold
101
97
  // (how close you have to be to the bottom for it to count as the bottom)
102
- const SCROLLED_TO_BOTTOM_THRESHOLD_REMS = 2;
98
+ const SCROLLED_TO_BOTTOM_THRESHOLD_REMS = 1.5;
103
99
 
104
100
  /*------------------------------------------------------------------------*/
105
101
  /* -------------------------- Static Functions -------------------------- */
@@ -124,8 +120,6 @@ const getItemIds = (items: AutoScrollItem[]): (string | number)[] => {
124
120
  /* -------- State Definition -------- */
125
121
 
126
122
  type State = {
127
- // If true, the user was scrolled to the bottom after last update
128
- wasScrolledToBottom: boolean,
129
123
  // If true, the "jump to bottom" button is visible
130
124
  jumpToBottomButtonVisible: boolean,
131
125
  };
@@ -136,8 +130,6 @@ type State = {
136
130
  enum ActionType {
137
131
  // Identify that the user is now scrolled to the bottom
138
132
  NowScrolledToBottom = 'NowScrolledToBottom',
139
- // Identify that the user scrolled away from the bottom
140
- NowScrolledAwayFromBottom = 'NowScrolledAwayFromBottom',
141
133
  // Identify that new content appeared at the bottom but is not visible
142
134
  NewContentAtBottom = 'NewContentAtBottom',
143
135
  }
@@ -148,7 +140,6 @@ type Action = (
148
140
  // Action type
149
141
  type: (
150
142
  | ActionType.NowScrolledToBottom
151
- | ActionType.NowScrolledAwayFromBottom
152
143
  | ActionType.NewContentAtBottom
153
144
  ),
154
145
  }
@@ -165,24 +156,13 @@ const reducer = (state: State, action: Action): State => {
165
156
  case ActionType.NowScrolledToBottom: {
166
157
  return {
167
158
  ...state,
168
- // Store the event
169
- wasScrolledToBottom: true,
170
159
  // Hide the "jump to bottom" button
171
160
  jumpToBottomButtonVisible: false,
172
161
  };
173
162
  }
174
- case ActionType.NowScrolledAwayFromBottom: {
175
- return {
176
- ...state,
177
- // Store the event
178
- wasScrolledToBottom: false,
179
- };
180
- }
181
163
  case ActionType.NewContentAtBottom: {
182
164
  return {
183
165
  ...state,
184
- // Store the event
185
- wasScrolledToBottom: false,
186
166
  // Show the "jump to bottom" button
187
167
  jumpToBottomButtonVisible: true,
188
168
  };
@@ -197,7 +177,7 @@ const reducer = (state: State, action: Action): State => {
197
177
  /* ------------------------------ Component ----------------------------- */
198
178
  /*------------------------------------------------------------------------*/
199
179
 
200
- const ScrollLockToBottom: React.FC<Props> = (props) => {
180
+ const AutoscrollToBottomContainer: React.FC<Props> = (props) => {
201
181
  /*------------------------------------------------------------------------*/
202
182
  /* -------------------------------- Setup ------------------------------- */
203
183
  /*------------------------------------------------------------------------*/
@@ -215,7 +195,6 @@ const ScrollLockToBottom: React.FC<Props> = (props) => {
215
195
 
216
196
  // Initial state
217
197
  const initialState: State = {
218
- wasScrolledToBottom: true,
219
198
  jumpToBottomButtonVisible: false,
220
199
  };
221
200
 
@@ -224,7 +203,6 @@ const ScrollLockToBottom: React.FC<Props> = (props) => {
224
203
 
225
204
  // Destructure common state
226
205
  const {
227
- wasScrolledToBottom,
228
206
  jumpToBottomButtonVisible,
229
207
  } = state;
230
208
 
@@ -233,6 +211,7 @@ const ScrollLockToBottom: React.FC<Props> = (props) => {
233
211
  // Initialize refs
234
212
  const lastItemIds = useRef<(string | number)[]>([]);
235
213
  const container = useRef<HTMLDivElement | null>(null);
214
+ const wasScrolledToBottomBeforeItemsUpdate = useRef<boolean>(true);
236
215
 
237
216
  /*------------------------------------------------------------------------*/
238
217
  /* ------------------------- Component Functions ------------------------ */
@@ -310,10 +289,6 @@ const ScrollLockToBottom: React.FC<Props> = (props) => {
310
289
  dispatch({
311
290
  type: ActionType.NowScrolledToBottom,
312
291
  });
313
- } else {
314
- dispatch({
315
- type: ActionType.NowScrolledAwayFromBottom,
316
- });
317
292
  }
318
293
  };
319
294
 
@@ -334,7 +309,7 @@ const ScrollLockToBottom: React.FC<Props> = (props) => {
334
309
  );
335
310
 
336
311
  /**
337
- * Update (also called on mount)
312
+ * Update (also called on mount): autoscroll
338
313
  * @author Gabe Abrams
339
314
  */
340
315
  useEffect(
@@ -357,7 +332,7 @@ const ScrollLockToBottom: React.FC<Props> = (props) => {
357
332
  }
358
333
 
359
334
  // Check if used to be scrolled to the bottom
360
- if (wasScrolledToBottom) {
335
+ if (wasScrolledToBottomBeforeItemsUpdate.current) {
361
336
  // Was scrolled to the bottom! Autoscroll.
362
337
  scrollToBottom();
363
338
  } else {
@@ -369,6 +344,11 @@ const ScrollLockToBottom: React.FC<Props> = (props) => {
369
344
 
370
345
  // Update last item ids
371
346
  lastItemIds.current = currentItemIds;
347
+
348
+ // Remember if we were scrolled to the bottom before the update
349
+ return () => {
350
+ wasScrolledToBottomBeforeItemsUpdate.current = isScrolledToBottom();
351
+ };
372
352
  },
373
353
  [items],
374
354
  );
@@ -385,10 +365,10 @@ const ScrollLockToBottom: React.FC<Props> = (props) => {
385
365
  let jumpToBottomButton: React.ReactNode;
386
366
  if (jumpToBottomButtonVisible) {
387
367
  jumpToBottomButton = (
388
- <div className={`ScrollLockToBottom-jump-to-bottom-container ScrollLockToBottom-for-${idify(itemsName ?? 'items')}`}>
368
+ <div className={`AutoscrollToBottomContainer-jump-to-bottom-container AutoscrollToBottomContainer-for-${idify(itemsName ?? 'items')}`}>
389
369
  <button
390
370
  type="button"
391
- className={`ScrollLockToBottom-jump-to-bottom-button ScrollLockToBottom-jump-to-bottom-button-for-${idify(itemsName ?? 'items')} btn btn-sm btn-${jumpToBottomButtonVariant} pt-0 pb-0`}
371
+ className={`AutoscrollToBottomContainer-jump-to-bottom-button AutoscrollToBottomContainer-jump-to-bottom-button-for-${idify(itemsName ?? 'items')} btn btn-sm btn-${jumpToBottomButtonVariant} pt-0 pb-0`}
392
372
  onClick={scrollToBottom}
393
373
  aria-label="scroll back to bottom and show new content"
394
374
  >
@@ -406,7 +386,7 @@ const ScrollLockToBottom: React.FC<Props> = (props) => {
406
386
 
407
387
  // Main UI
408
388
  return (
409
- <div className="ScrollLockToBottom-outer-container bg-warning">
389
+ <div className="AutoscrollToBottomContainer-outer-container">
410
390
  {/* Style */}
411
391
  <style>
412
392
  {style}
@@ -417,10 +397,8 @@ const ScrollLockToBottom: React.FC<Props> = (props) => {
417
397
 
418
398
  {/* Scrollable Item Container */}
419
399
  <div
420
- className="ScrollLockToBottom-scrollable-container"
421
- onScroll={() => {
422
- handleScroll();
423
- }}
400
+ className="AutoscrollToBottomContainer-scrollable-container"
401
+ onScroll={handleScroll}
424
402
  ref={container}
425
403
  >
426
404
  {/* Items */}
@@ -430,15 +408,13 @@ const ScrollLockToBottom: React.FC<Props> = (props) => {
430
408
  .map((item) => {
431
409
  return (
432
410
  <div
433
- className="ScrollLockToBottom-item-container"
411
+ className="AutoscrollToBottomContainer-item-container"
434
412
  key={item.id}
435
413
  >
436
414
  {item.item}
437
415
  </div>
438
416
  );
439
417
  })
440
- // Reverse order because flex column is reverse
441
- .reverse()
442
418
  }
443
419
  </div>
444
420
  </div>
@@ -450,4 +426,4 @@ const ScrollLockToBottom: React.FC<Props> = (props) => {
450
426
  /*------------------------------------------------------------------------*/
451
427
 
452
428
  // Export component
453
- export default ScrollLockToBottom;
429
+ export default AutoscrollToBottomContainer;
package/src/index.ts CHANGED
@@ -25,7 +25,7 @@ import CSVDownloadButton from './components/CSVDownloadButton';
25
25
  import DBEntryManagerPanel from './components/DBEntryManagerPanel';
26
26
  import Tooltip from './components/Tooltip';
27
27
  import ToggleSwitch from './components/ToggleSwitch';
28
- import ScrollLockToBottom from './components/ScrollLockToBottomContainer';
28
+ import AutoscrollToBottomContainer from './components/AutoscrollToBottomContainer';
29
29
 
30
30
  // Import errors
31
31
  import ErrorWithCode from './errors/ErrorWithCode';
@@ -126,7 +126,7 @@ export {
126
126
  DBEntryManagerPanel,
127
127
  Tooltip,
128
128
  ToggleSwitch,
129
- ScrollLockToBottom,
129
+ AutoscrollToBottomContainer,
130
130
  // Global functions
131
131
  alert,
132
132
  confirm,