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.
- package/dist/cjs/index.js +24 -44
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/types/components/{ScrollLockToBottomContainer.d.ts → AutoscrollToBottomContainer.d.ts} +5 -3
- package/dist/cjs/types/index.d.ts +2 -2
- package/dist/esm/index.js +24 -44
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/types/components/{ScrollLockToBottomContainer.d.ts → AutoscrollToBottomContainer.d.ts} +5 -3
- package/dist/esm/types/index.d.ts +2 -2
- package/dist/index.d.ts +5 -3
- package/package.json +1 -1
- package/src/components/{ScrollLockToBottomContainer.tsx → AutoscrollToBottomContainer.tsx} +24 -48
- package/src/index.ts +2 -2
|
@@ -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
|
|
19
|
-
export default
|
|
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
|
|
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,
|
|
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
|
|
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,
|
|
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,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
|
-
.
|
|
53
|
+
.AutoscrollToBottomContainer-outer-container {
|
|
52
54
|
/* Take up all space */
|
|
53
55
|
height: 100%;
|
|
54
56
|
position: relative;
|
|
55
57
|
}
|
|
56
58
|
|
|
57
|
-
.
|
|
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
|
-
.
|
|
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
|
-
.
|
|
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 =
|
|
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
|
|
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 (
|
|
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={`
|
|
368
|
+
<div className={`AutoscrollToBottomContainer-jump-to-bottom-container AutoscrollToBottomContainer-for-${idify(itemsName ?? 'items')}`}>
|
|
389
369
|
<button
|
|
390
370
|
type="button"
|
|
391
|
-
className={`
|
|
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="
|
|
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="
|
|
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="
|
|
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
|
|
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
|
|
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
|
-
|
|
129
|
+
AutoscrollToBottomContainer,
|
|
130
130
|
// Global functions
|
|
131
131
|
alert,
|
|
132
132
|
confirm,
|