dce-reactkit 5.0.7 → 5.0.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 +319 -16
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/types/helpers/useBackButton.d.ts +20 -0
- package/dist/cjs/types/helpers/visitServerEndpoint.d.ts +5 -0
- package/dist/cjs/types/index.d.ts +4 -1
- package/dist/cjs/types/types/BackButtonController.d.ts +40 -0
- package/dist/cjs/types/types/BackState.d.ts +11 -0
- package/dist/esm/index.js +317 -17
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/types/helpers/useBackButton.d.ts +20 -0
- package/dist/esm/types/helpers/visitServerEndpoint.d.ts +5 -0
- package/dist/esm/types/index.d.ts +4 -1
- package/dist/esm/types/types/BackButtonController.d.ts +40 -0
- package/dist/esm/types/types/BackState.d.ts +11 -0
- package/dist/index.d.ts +75 -1
- package/package.json +1 -1
- package/src/components/ItemPicker/NestableItemList.tsx +44 -42
- package/src/components/Tooltip.tsx +17 -0
- package/src/helpers/useBackButton.tsx +352 -0
- package/src/helpers/visitServerEndpoint.tsx +5 -0
- package/src/index.ts +7 -0
- package/src/types/BackButtonController.ts +43 -0
- package/src/types/BackState.ts +15 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import BackButtonController from '../types/BackButtonController';
|
|
2
|
+
/**
|
|
3
|
+
* Controller for driving back navigation from anywhere in the app. Requires
|
|
4
|
+
* useBackButton to have been called in the top-level app
|
|
5
|
+
* @author Yuen Ler Chow
|
|
6
|
+
*/
|
|
7
|
+
export declare const backButtonController: BackButtonController;
|
|
8
|
+
/**
|
|
9
|
+
* Hook that makes the browser's back button navigate within the app instead of
|
|
10
|
+
* leaving it. Call this once in your top-level app, then use
|
|
11
|
+
* backButtonController to enter subpanels and describe their state.
|
|
12
|
+
*
|
|
13
|
+
* Assumes a single level of navigation: one home screen plus subpanels that the
|
|
14
|
+
* user returns home from.
|
|
15
|
+
* @author Yuen Ler Chow
|
|
16
|
+
* @param handleGoHomeFunc handler that performs the app state changes required
|
|
17
|
+
* to return to the home screen
|
|
18
|
+
*/
|
|
19
|
+
declare const useBackButton: (handleGoHomeFunc: () => void) => void;
|
|
20
|
+
export default useBackButton;
|
|
@@ -22,6 +22,8 @@ export declare const _setStubResponse: (opts: {
|
|
|
22
22
|
* @param opts.path - the path of the server endpoint
|
|
23
23
|
* @param [opts.method=GET] - the method of the endpoint
|
|
24
24
|
* @param [opts.params] - query/body parameters to include
|
|
25
|
+
* @param [opts.headers] - custom headers to include; values must already be
|
|
26
|
+
* string to avoid issue with header serialization
|
|
25
27
|
* @returns response from server
|
|
26
28
|
*/
|
|
27
29
|
declare const visitServerEndpoint: (opts: {
|
|
@@ -30,5 +32,8 @@ declare const visitServerEndpoint: (opts: {
|
|
|
30
32
|
params?: {
|
|
31
33
|
[x: string]: any;
|
|
32
34
|
} | undefined;
|
|
35
|
+
headers?: {
|
|
36
|
+
[x: string]: string;
|
|
37
|
+
} | undefined;
|
|
33
38
|
}) => Promise<any>;
|
|
34
39
|
export default visitServerEndpoint;
|
|
@@ -37,6 +37,7 @@ import isMobileOrTablet from './helpers/isMobileOrTablet';
|
|
|
37
37
|
import makeLinksClickable from './helpers/makeLinksClickable';
|
|
38
38
|
import combineClassNames from './helpers/combineClassNames';
|
|
39
39
|
import useForceRender from './helpers/useForceRender';
|
|
40
|
+
import useBackButton, { backButtonController } from './helpers/useBackButton';
|
|
40
41
|
import isSelectAdmin from './helpers/isSelectAdmin';
|
|
41
42
|
import ModalButtonType from './types/ModalButtonType';
|
|
42
43
|
import ModalSize from './types/ModalSize';
|
|
@@ -45,8 +46,10 @@ import Variant from './types/Variant';
|
|
|
45
46
|
import IntelliTableColumn from './types/IntelliTableColumn';
|
|
46
47
|
import DropdownItemType from './types/DropdownItemType';
|
|
47
48
|
import ProgressBarSize from './types/ProgressBarSize';
|
|
49
|
+
import BackState from './types/BackState';
|
|
50
|
+
import BackButtonController from './types/BackButtonController';
|
|
48
51
|
import PickableItem from './components/ItemPicker/types/PickableItem';
|
|
49
52
|
import DBEntry from './components/DBEntryManagerPanel/types/DBEntry';
|
|
50
53
|
import DBEntryField from './components/DBEntryManagerPanel/types/DBEntryField';
|
|
51
54
|
import DBEntryFieldType from './components/DBEntryManagerPanel/types/DBEntryFieldType';
|
|
52
|
-
export { AppWrapper, LoadingSpinner, ErrorBox, Modal, TabBox, RadioButton, CheckboxButton, ButtonInputGroup, SimpleDateChooser, SimpleMonthChooser, SimpleTimeChooser, Drawer, PopSuccessMark, PopFailureMark, PopPendingMark, CopiableBox, ItemPicker, LogReviewer, IntelliTable, CSVDownloadButton, DBEntryManagerPanel, Tooltip, ToggleSwitch, AutoscrollToBottomContainer, MultiSwitch, Dropdown, ProgressBar, FakeProgressBar, alert, prompt, confirm, showFatalError, DynamicWord, stubServerEndpoint, canReviewLogs, isMobileOrTablet, makeLinksClickable, isSelectAdmin, initClient, visitServerEndpoint, logClientEvent, addFatalErrorHandler, leaveToURL, combineClassNames, useForceRender, setClientEventMetadataPopulator, ModalButtonType, ModalSize, ModalType, Variant, IntelliTableColumn, DropdownItemType, LogReviewerFilterState, ProgressBarSize, PickableItem, DBEntry, DBEntryField, DBEntryFieldType, ErrorWithCode, MINUTE_IN_MS, HOUR_IN_MS, DAY_IN_MS, LOG_REVIEW_ROUTE_PATH_PREFIX, LOG_ROUTE_PATH, LOG_REVIEW_STATUS_ROUTE, LOG_REVIEW_GET_LOGS_ROUTE, SELECT_ADMIN_CHECK_ROUTE, abbreviate, avg, ceilToNumDecimals, floorToNumDecimals, forceNumIntoBounds, padDecimalZeros, padZerosLeft, roundToNumDecimals, sum, waitMs, getOrdinal, getTimeInfoInET, getMondayOfTimestamp, startMinWait, getHumanReadableDate, getPartOfDay, stringsToHumanReadableList, onlyKeepLetters, parallelLimit, getMonthName, genCSV, extractProp, compareArraysByProp, getLocalTimeInfo, genCommaList, validateEmail, validatePhoneNumber, validateString, idify, prefixWithAOrAn, everyAsync, filterAsync, forEachAsync, mapAsync, someAsync, capitalize, shuffleArray, getWordCount, cloneDeep, getTimestampFromTimeInfoInET, spaceAtCapitals, ParamType, DayOfWeek, Log, LogType, LogSource, LogAction, LogBuiltInMetadata, LogMetadataType, LogFunction, LogTypeSpecificInfo, LogMainInfo, LogSourceSpecificInfo, LogLevel, CommonKitErrorCode, };
|
|
55
|
+
export { AppWrapper, LoadingSpinner, ErrorBox, Modal, TabBox, RadioButton, CheckboxButton, ButtonInputGroup, SimpleDateChooser, SimpleMonthChooser, SimpleTimeChooser, Drawer, PopSuccessMark, PopFailureMark, PopPendingMark, CopiableBox, ItemPicker, LogReviewer, IntelliTable, CSVDownloadButton, DBEntryManagerPanel, Tooltip, ToggleSwitch, AutoscrollToBottomContainer, MultiSwitch, Dropdown, ProgressBar, FakeProgressBar, alert, prompt, confirm, showFatalError, DynamicWord, stubServerEndpoint, canReviewLogs, isMobileOrTablet, makeLinksClickable, isSelectAdmin, initClient, visitServerEndpoint, logClientEvent, addFatalErrorHandler, leaveToURL, combineClassNames, useForceRender, useBackButton, backButtonController, setClientEventMetadataPopulator, ModalButtonType, ModalSize, ModalType, Variant, IntelliTableColumn, DropdownItemType, LogReviewerFilterState, ProgressBarSize, BackState, BackButtonController, PickableItem, DBEntry, DBEntryField, DBEntryFieldType, ErrorWithCode, MINUTE_IN_MS, HOUR_IN_MS, DAY_IN_MS, LOG_REVIEW_ROUTE_PATH_PREFIX, LOG_ROUTE_PATH, LOG_REVIEW_STATUS_ROUTE, LOG_REVIEW_GET_LOGS_ROUTE, SELECT_ADMIN_CHECK_ROUTE, abbreviate, avg, ceilToNumDecimals, floorToNumDecimals, forceNumIntoBounds, padDecimalZeros, padZerosLeft, roundToNumDecimals, sum, waitMs, getOrdinal, getTimeInfoInET, getMondayOfTimestamp, startMinWait, getHumanReadableDate, getPartOfDay, stringsToHumanReadableList, onlyKeepLetters, parallelLimit, getMonthName, genCSV, extractProp, compareArraysByProp, getLocalTimeInfo, genCommaList, validateEmail, validatePhoneNumber, validateString, idify, prefixWithAOrAn, everyAsync, filterAsync, forEachAsync, mapAsync, someAsync, capitalize, shuffleArray, getWordCount, cloneDeep, getTimestampFromTimeInfoInET, spaceAtCapitals, ParamType, DayOfWeek, Log, LogType, LogSource, LogAction, LogBuiltInMetadata, LogMetadataType, LogFunction, LogTypeSpecificInfo, LogMainInfo, LogSourceSpecificInfo, LogLevel, CommonKitErrorCode, };
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import BackState from './BackState';
|
|
2
|
+
/**
|
|
3
|
+
* Controller for the back button, used to drive back navigation from anywhere
|
|
4
|
+
* in the app. Pass this to subpanels so they can describe their state and
|
|
5
|
+
* send the user home.
|
|
6
|
+
* @author Yuen Ler Chow
|
|
7
|
+
*/
|
|
8
|
+
type BackButtonController = {
|
|
9
|
+
/**
|
|
10
|
+
* Call this when the user navigates to a child of the home screen (something
|
|
11
|
+
* they can come back from)
|
|
12
|
+
*/
|
|
13
|
+
onSubpanelEntered: () => void;
|
|
14
|
+
/**
|
|
15
|
+
* Send the user back to the home screen
|
|
16
|
+
* @param [force] if true, go home immediately without checking the subpanel
|
|
17
|
+
* state (no confirmation, not blocked). If falsy, nothing happens when
|
|
18
|
+
* blocked and confirmation is required when there are unsaved changes
|
|
19
|
+
*/
|
|
20
|
+
goHome: (force?: boolean) => Promise<void>;
|
|
21
|
+
/**
|
|
22
|
+
* Set the state of the current subpanel, which determines what happens when
|
|
23
|
+
* the user tries to go back
|
|
24
|
+
* @param newSubpanelState the new state of the subpanel
|
|
25
|
+
*/
|
|
26
|
+
setSubpanelState: (newSubpanelState: BackState) => void;
|
|
27
|
+
/**
|
|
28
|
+
* Set the confirmation message shown if the user tries to go back while there
|
|
29
|
+
* are unsaved changes (cleared upon returning to the home screen)
|
|
30
|
+
* @param message the message to show
|
|
31
|
+
*/
|
|
32
|
+
setCustomUnsavedChangesMessage: (message: string) => void;
|
|
33
|
+
/**
|
|
34
|
+
* Set the message shown if the user tries to go back while blocked (cleared
|
|
35
|
+
* upon returning to the home screen)
|
|
36
|
+
* @param message the message to show
|
|
37
|
+
*/
|
|
38
|
+
setCustomBlockedMessage: (message: string) => void;
|
|
39
|
+
};
|
|
40
|
+
export default BackButtonController;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* State of the current subpanel, determining what happens when the user tries
|
|
3
|
+
* to go back to the home screen
|
|
4
|
+
* @author Yuen Ler Chow
|
|
5
|
+
*/
|
|
6
|
+
declare enum BackState {
|
|
7
|
+
Normal = "Normal",
|
|
8
|
+
UnsavedChanges = "UnsavedChanges",
|
|
9
|
+
Blocked = "Blocked"
|
|
10
|
+
}
|
|
11
|
+
export default BackState;
|
package/dist/index.d.ts
CHANGED
|
@@ -865,6 +865,8 @@ declare const initClient: (opts: ({
|
|
|
865
865
|
* @param opts.path - the path of the server endpoint
|
|
866
866
|
* @param [opts.method=GET] - the method of the endpoint
|
|
867
867
|
* @param [opts.params] - query/body parameters to include
|
|
868
|
+
* @param [opts.headers] - custom headers to include; values must already be
|
|
869
|
+
* string to avoid issue with header serialization
|
|
868
870
|
* @returns response from server
|
|
869
871
|
*/
|
|
870
872
|
declare const visitServerEndpoint: (opts: {
|
|
@@ -873,6 +875,9 @@ declare const visitServerEndpoint: (opts: {
|
|
|
873
875
|
params?: {
|
|
874
876
|
[x: string]: any;
|
|
875
877
|
} | undefined;
|
|
878
|
+
headers?: {
|
|
879
|
+
[x: string]: string;
|
|
880
|
+
} | undefined;
|
|
876
881
|
}) => Promise<any>;
|
|
877
882
|
|
|
878
883
|
/**
|
|
@@ -962,6 +967,75 @@ declare const combineClassNames: (classNames: (string | undefined | null | false
|
|
|
962
967
|
*/
|
|
963
968
|
declare const useForceRender: (useReducer: any) => () => void;
|
|
964
969
|
|
|
970
|
+
/**
|
|
971
|
+
* State of the current subpanel, determining what happens when the user tries
|
|
972
|
+
* to go back to the home screen
|
|
973
|
+
* @author Yuen Ler Chow
|
|
974
|
+
*/
|
|
975
|
+
declare enum BackState {
|
|
976
|
+
Normal = "Normal",
|
|
977
|
+
UnsavedChanges = "UnsavedChanges",
|
|
978
|
+
Blocked = "Blocked"
|
|
979
|
+
}
|
|
980
|
+
|
|
981
|
+
/**
|
|
982
|
+
* Controller for the back button, used to drive back navigation from anywhere
|
|
983
|
+
* in the app. Pass this to subpanels so they can describe their state and
|
|
984
|
+
* send the user home.
|
|
985
|
+
* @author Yuen Ler Chow
|
|
986
|
+
*/
|
|
987
|
+
type BackButtonController = {
|
|
988
|
+
/**
|
|
989
|
+
* Call this when the user navigates to a child of the home screen (something
|
|
990
|
+
* they can come back from)
|
|
991
|
+
*/
|
|
992
|
+
onSubpanelEntered: () => void;
|
|
993
|
+
/**
|
|
994
|
+
* Send the user back to the home screen
|
|
995
|
+
* @param [force] if true, go home immediately without checking the subpanel
|
|
996
|
+
* state (no confirmation, not blocked). If falsy, nothing happens when
|
|
997
|
+
* blocked and confirmation is required when there are unsaved changes
|
|
998
|
+
*/
|
|
999
|
+
goHome: (force?: boolean) => Promise<void>;
|
|
1000
|
+
/**
|
|
1001
|
+
* Set the state of the current subpanel, which determines what happens when
|
|
1002
|
+
* the user tries to go back
|
|
1003
|
+
* @param newSubpanelState the new state of the subpanel
|
|
1004
|
+
*/
|
|
1005
|
+
setSubpanelState: (newSubpanelState: BackState) => void;
|
|
1006
|
+
/**
|
|
1007
|
+
* Set the confirmation message shown if the user tries to go back while there
|
|
1008
|
+
* are unsaved changes (cleared upon returning to the home screen)
|
|
1009
|
+
* @param message the message to show
|
|
1010
|
+
*/
|
|
1011
|
+
setCustomUnsavedChangesMessage: (message: string) => void;
|
|
1012
|
+
/**
|
|
1013
|
+
* Set the message shown if the user tries to go back while blocked (cleared
|
|
1014
|
+
* upon returning to the home screen)
|
|
1015
|
+
* @param message the message to show
|
|
1016
|
+
*/
|
|
1017
|
+
setCustomBlockedMessage: (message: string) => void;
|
|
1018
|
+
};
|
|
1019
|
+
|
|
1020
|
+
/**
|
|
1021
|
+
* Controller for driving back navigation from anywhere in the app. Requires
|
|
1022
|
+
* useBackButton to have been called in the top-level app
|
|
1023
|
+
* @author Yuen Ler Chow
|
|
1024
|
+
*/
|
|
1025
|
+
declare const backButtonController: BackButtonController;
|
|
1026
|
+
/**
|
|
1027
|
+
* Hook that makes the browser's back button navigate within the app instead of
|
|
1028
|
+
* leaving it. Call this once in your top-level app, then use
|
|
1029
|
+
* backButtonController to enter subpanels and describe their state.
|
|
1030
|
+
*
|
|
1031
|
+
* Assumes a single level of navigation: one home screen plus subpanels that the
|
|
1032
|
+
* user returns home from.
|
|
1033
|
+
* @author Yuen Ler Chow
|
|
1034
|
+
* @param handleGoHomeFunc handler that performs the app state changes required
|
|
1035
|
+
* to return to the home screen
|
|
1036
|
+
*/
|
|
1037
|
+
declare const useBackButton: (handleGoHomeFunc: () => void) => void;
|
|
1038
|
+
|
|
965
1039
|
/**
|
|
966
1040
|
* Checks if the current user is a select admin
|
|
967
1041
|
* @author Gardenia Liu
|
|
@@ -969,4 +1043,4 @@ declare const useForceRender: (useReducer: any) => () => void;
|
|
|
969
1043
|
*/
|
|
970
1044
|
declare const isSelectAdmin: () => Promise<boolean>;
|
|
971
1045
|
|
|
972
|
-
export { AppWrapper, AutoscrollToBottomContainer, ButtonInputGroup, CSVDownloadButton, CheckboxButton, CopiableBox, DBEntry, DBEntryField, DBEntryFieldType, DBEntryManagerPanel, Drawer, Dropdown, DropdownItemType, DynamicWord, ErrorBox, FakeProgressBar, IntelliTable, IntelliTableColumn, ItemPicker, LoadingSpinner, LogReviewer, Modal, ModalButtonType, ModalSize, ModalType, MultiSwitch, PickableItem, PopFailureMark, PopPendingMark, PopSuccessMark, ProgressBar, ProgressBarSize, RadioButton, SimpleDateChooser, SimpleMonthChooser, SimpleTimeChooser, TabBox, ToggleSwitch, Tooltip, Variant, addFatalErrorHandler, alert, canReviewLogs, combineClassNames, confirm, initClient, isMobileOrTablet, isSelectAdmin, leaveToURL, logClientEvent, makeLinksClickable, prompt, setClientEventMetadataPopulator, showFatalError, stubServerEndpoint, useForceRender, visitServerEndpoint };
|
|
1046
|
+
export { AppWrapper, AutoscrollToBottomContainer, BackButtonController, BackState, ButtonInputGroup, CSVDownloadButton, CheckboxButton, CopiableBox, DBEntry, DBEntryField, DBEntryFieldType, DBEntryManagerPanel, Drawer, Dropdown, DropdownItemType, DynamicWord, ErrorBox, FakeProgressBar, IntelliTable, IntelliTableColumn, ItemPicker, LoadingSpinner, LogReviewer, Modal, ModalButtonType, ModalSize, ModalType, MultiSwitch, PickableItem, PopFailureMark, PopPendingMark, PopSuccessMark, ProgressBar, ProgressBarSize, RadioButton, SimpleDateChooser, SimpleMonthChooser, SimpleTimeChooser, TabBox, ToggleSwitch, Tooltip, Variant, addFatalErrorHandler, alert, backButtonController, canReviewLogs, combineClassNames, confirm, initClient, isMobileOrTablet, isSelectAdmin, leaveToURL, logClientEvent, makeLinksClickable, prompt, setClientEventMetadataPopulator, showFatalError, stubServerEndpoint, useBackButton, useForceRender, visitServerEndpoint };
|
package/package.json
CHANGED
|
@@ -258,48 +258,50 @@ const NestableItemList: React.FC<Props> = (props) => {
|
|
|
258
258
|
|
|
259
259
|
return (
|
|
260
260
|
<div key={item.id}>
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
<
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
261
|
+
<div className="NestableItemList-item d-flex align-items-center">
|
|
262
|
+
{/* Dropdown Button */}
|
|
263
|
+
<span
|
|
264
|
+
className="NestableItemList-dropdown-button-container"
|
|
265
|
+
style={{
|
|
266
|
+
minWidth: '2rem',
|
|
267
|
+
}}
|
|
268
|
+
>
|
|
269
|
+
{item.isGroup && (
|
|
270
|
+
<button
|
|
271
|
+
className={`NestableItemList-dropdown-button NestableItemList-dropdown-button-${item.id}`}
|
|
272
|
+
style={{
|
|
273
|
+
border: 0,
|
|
274
|
+
backgroundColor: 'transparent',
|
|
275
|
+
}}
|
|
276
|
+
type="button"
|
|
277
|
+
onClick={() => {
|
|
278
|
+
dispatch({
|
|
279
|
+
type: ActionType.ToggleChild,
|
|
280
|
+
id: item.id,
|
|
281
|
+
});
|
|
282
|
+
}}
|
|
283
|
+
aria-label={`${childExpanded[item.id] ? 'Hide' : 'Show'} items in ${accessibleName}`}
|
|
284
|
+
>
|
|
285
|
+
<FontAwesomeIcon
|
|
286
|
+
icon={childExpanded[item.id] ? faChevronDown : faChevronRight}
|
|
287
|
+
/>
|
|
288
|
+
</button>
|
|
289
|
+
)}
|
|
290
|
+
</span>
|
|
291
|
+
|
|
292
|
+
{/* Checkbox and Text (optionally wrapped in a tooltip) */}
|
|
293
|
+
{
|
|
294
|
+
item.tooltip
|
|
295
|
+
? (
|
|
296
|
+
<Tooltip text={item.tooltip}>
|
|
297
|
+
<span className="d-inline-block">
|
|
298
|
+
{checkbox}
|
|
299
|
+
</span>
|
|
300
|
+
</Tooltip>
|
|
301
|
+
)
|
|
302
|
+
: checkbox
|
|
303
|
+
}
|
|
304
|
+
</div>
|
|
303
305
|
|
|
304
306
|
{/* Children */}
|
|
305
307
|
{(item.isGroup && childExpanded[item.id]) && (
|
|
@@ -63,6 +63,14 @@ const Tooltip: React.FC<Props> = (props) => {
|
|
|
63
63
|
// Import bootstrap tooltip
|
|
64
64
|
const BSTooltip = (await import('bootstrap')).Tooltip;
|
|
65
65
|
|
|
66
|
+
// The child may have unmounted while the dynamic import above was
|
|
67
|
+
// resolving (React nulls the ref on unmount). Constructing a
|
|
68
|
+
// Bootstrap tooltip with a null element causes an error,
|
|
69
|
+
// so bail out instead
|
|
70
|
+
if (!childRef.current) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
|
|
66
74
|
// Initialize
|
|
67
75
|
t = new BSTooltip(
|
|
68
76
|
childRef.current,
|
|
@@ -78,6 +86,15 @@ const Tooltip: React.FC<Props> = (props) => {
|
|
|
78
86
|
return () => {
|
|
79
87
|
if (t) {
|
|
80
88
|
t.dispose();
|
|
89
|
+
// Bootstrap's hide() queues a transition-end callback that can
|
|
90
|
+
// fire AFTER dispose and touch the (now null) trigger map and
|
|
91
|
+
// element (twbs/bootstrap issue #37474). Point those private
|
|
92
|
+
// fields at harmless stand-ins so the late callback is a no-op
|
|
93
|
+
// instead of a crash.
|
|
94
|
+
/* eslint-disable no-underscore-dangle */
|
|
95
|
+
t._activeTrigger = {};
|
|
96
|
+
t._element = document.createElement('noscript');
|
|
97
|
+
/* eslint-enable no-underscore-dangle */
|
|
81
98
|
}
|
|
82
99
|
};
|
|
83
100
|
},
|