dce-reactkit 3.7.3 → 3.7.5
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 +159 -3
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/types/components/Modal.d.ts +1 -0
- package/dist/cjs/types/components/Shimmer.d.ts +13 -0
- package/dist/cjs/types/helpers/asyncArrayFunctions/everyAsync.d.ts +13 -0
- package/dist/cjs/types/helpers/asyncArrayFunctions/everyAsync.test.d.ts +1 -0
- package/dist/cjs/types/helpers/asyncArrayFunctions/filterAsync.d.ts +13 -0
- package/dist/cjs/types/helpers/asyncArrayFunctions/filterAsync.test.d.ts +1 -0
- package/dist/cjs/types/helpers/asyncArrayFunctions/forEachAsync.d.ts +10 -0
- package/dist/cjs/types/helpers/asyncArrayFunctions/forEachAsync.test.d.ts +1 -0
- package/dist/cjs/types/helpers/asyncArrayFunctions/mapAsync.d.ts +11 -0
- package/dist/cjs/types/helpers/asyncArrayFunctions/mapAsync.test.d.ts +1 -0
- package/dist/cjs/types/helpers/asyncArrayFunctions/someAsync.d.ts +13 -0
- package/dist/cjs/types/helpers/asyncArrayFunctions/someAsync.test.d.ts +1 -0
- package/dist/cjs/types/index.d.ts +6 -1
- package/dist/esm/index.js +155 -4
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/types/components/Modal.d.ts +1 -0
- package/dist/esm/types/components/Shimmer.d.ts +13 -0
- package/dist/esm/types/helpers/asyncArrayFunctions/everyAsync.d.ts +13 -0
- package/dist/esm/types/helpers/asyncArrayFunctions/everyAsync.test.d.ts +1 -0
- package/dist/esm/types/helpers/asyncArrayFunctions/filterAsync.d.ts +13 -0
- package/dist/esm/types/helpers/asyncArrayFunctions/filterAsync.test.d.ts +1 -0
- package/dist/esm/types/helpers/asyncArrayFunctions/forEachAsync.d.ts +10 -0
- package/dist/esm/types/helpers/asyncArrayFunctions/forEachAsync.test.d.ts +1 -0
- package/dist/esm/types/helpers/asyncArrayFunctions/mapAsync.d.ts +11 -0
- package/dist/esm/types/helpers/asyncArrayFunctions/mapAsync.test.d.ts +1 -0
- package/dist/esm/types/helpers/asyncArrayFunctions/someAsync.d.ts +13 -0
- package/dist/esm/types/helpers/asyncArrayFunctions/someAsync.test.d.ts +1 -0
- package/dist/esm/types/index.d.ts +6 -1
- package/dist/index.d.ts +62 -1
- package/package.json +1 -1
- package/src/components/CopiableBox.tsx +1 -1
- package/src/components/Modal.tsx +4 -1
- package/src/components/Shimmer.tsx +153 -0
- package/src/helpers/asyncArrayFunctions/everyAsync.test.ts +114 -0
- package/src/helpers/asyncArrayFunctions/everyAsync.ts +51 -0
- package/src/helpers/asyncArrayFunctions/filterAsync.test.ts +126 -0
- package/src/helpers/asyncArrayFunctions/filterAsync.ts +50 -0
- package/src/helpers/asyncArrayFunctions/forEachAsync.test.ts +136 -0
- package/src/helpers/asyncArrayFunctions/forEachAsync.ts +40 -0
- package/src/helpers/asyncArrayFunctions/mapAsync.test.ts +125 -0
- package/src/helpers/asyncArrayFunctions/mapAsync.ts +46 -0
- package/src/helpers/asyncArrayFunctions/someAsync.test.ts +92 -0
- package/src/helpers/asyncArrayFunctions/someAsync.ts +49 -0
- package/src/index.ts +10 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A shimmer effect to add to the background of an element. The parent of this element
|
|
3
|
+
* will automatically have its overflow hidden
|
|
4
|
+
* @author Alessandra De Lucas
|
|
5
|
+
* @author Gabe Abrams
|
|
6
|
+
*/
|
|
7
|
+
import React from 'react';
|
|
8
|
+
type Props = {
|
|
9
|
+
durationSec?: number;
|
|
10
|
+
numShimmers?: number;
|
|
11
|
+
};
|
|
12
|
+
declare const Shimmer: React.FC<Props>;
|
|
13
|
+
export default Shimmer;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Run the operator function on each item in the array, returning true if
|
|
3
|
+
* the operator function returns true for every item in the array
|
|
4
|
+
* @author Gabe Abrams
|
|
5
|
+
* @param operatorFunction the operator function to apply. If it returns true
|
|
6
|
+
* for every item, this function will return true
|
|
7
|
+
* @returns true if the operator function returns true for every item in the array
|
|
8
|
+
*/
|
|
9
|
+
declare const everyAsync: <T>(array: T[], operatorFunction: (item: T, index: number, opts: {
|
|
10
|
+
breakNow: () => void;
|
|
11
|
+
array: T[];
|
|
12
|
+
}) => Promise<any>) => Promise<boolean>;
|
|
13
|
+
export default everyAsync;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Run the operator function on each item in the array, returning a new array
|
|
3
|
+
* that only contains the items that pass the filter
|
|
4
|
+
* @author Gabe Abrams
|
|
5
|
+
* @param operatorFunction the operator function to apply. If it returns true
|
|
6
|
+
* for an item, the item will be included in the returned array
|
|
7
|
+
* @returns the filtered array
|
|
8
|
+
*/
|
|
9
|
+
declare const filterAsync: <T>(array: T[], operatorFunction: (item: T, index: number, opts: {
|
|
10
|
+
breakNow: () => void;
|
|
11
|
+
array: T[];
|
|
12
|
+
}) => Promise<any>) => Promise<T[]>;
|
|
13
|
+
export default filterAsync;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Run the operator function on each item in the array
|
|
3
|
+
* @author Gabe Abrams
|
|
4
|
+
* @param operatorFunction the operator function to apply
|
|
5
|
+
*/
|
|
6
|
+
declare const forEachAsync: <T>(array: T[], operatorFunction: (item: T, index: number, opts: {
|
|
7
|
+
breakNow: () => void;
|
|
8
|
+
array: T[];
|
|
9
|
+
}) => void) => Promise<void>;
|
|
10
|
+
export default forEachAsync;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Run the operator function on each item in the array, collecting all results
|
|
3
|
+
* @author Gabe Abrams
|
|
4
|
+
* @param operatorFunction the operator function to apply
|
|
5
|
+
* @returns the array of results
|
|
6
|
+
*/
|
|
7
|
+
declare const mapAsync: <T, U>(array: T[], operatorFunction: (item: T, index: number, opts: {
|
|
8
|
+
breakNow: () => void;
|
|
9
|
+
array: T[];
|
|
10
|
+
}) => Promise<U>) => Promise<U[]>;
|
|
11
|
+
export default mapAsync;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Run the operator function on each item in the array, returning true if
|
|
3
|
+
* the operator function returns true for any item in the array
|
|
4
|
+
* @author Gabe Abrams
|
|
5
|
+
* @param operatorFunction the operator function to apply. If it returns true
|
|
6
|
+
* for any item, this function will return true
|
|
7
|
+
* @returns true if the operator function returns true for any item in the array
|
|
8
|
+
*/
|
|
9
|
+
declare const someAsync: <T>(array: T[], operatorFunction: (item: T, index: number, opts: {
|
|
10
|
+
breakNow: () => void;
|
|
11
|
+
array: T[];
|
|
12
|
+
}) => Promise<any>) => Promise<boolean>;
|
|
13
|
+
export default someAsync;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -70,6 +70,11 @@ import makeLinksClickable from './helpers/makeLinksClickable';
|
|
|
70
70
|
import combineClassNames from './helpers/combineClassNames';
|
|
71
71
|
import prefixWithAOrAn from './helpers/prefixWithAOrAn';
|
|
72
72
|
import useForceRender from './helpers/useForceRender';
|
|
73
|
+
import everyAsync from './helpers/asyncArrayFunctions/everyAsync';
|
|
74
|
+
import filterAsync from './helpers/asyncArrayFunctions/filterAsync';
|
|
75
|
+
import forEachAsync from './helpers/asyncArrayFunctions/forEachAsync';
|
|
76
|
+
import mapAsync from './helpers/asyncArrayFunctions/mapAsync';
|
|
77
|
+
import someAsync from './helpers/asyncArrayFunctions/someAsync';
|
|
73
78
|
import ModalButtonType from './types/ModalButtonType';
|
|
74
79
|
import ModalSize from './types/ModalSize';
|
|
75
80
|
import ModalType from './types/ModalType';
|
|
@@ -89,4 +94,4 @@ import PickableItem from './components/ItemPicker/types/PickableItem';
|
|
|
89
94
|
import DBEntry from './components/DBEntryManagerPanel/types/DBEntry';
|
|
90
95
|
import DBEntryField from './components/DBEntryManagerPanel/types/DBEntryField';
|
|
91
96
|
import DBEntryFieldType from './components/DBEntryManagerPanel/types/DBEntryFieldType';
|
|
92
|
-
export { AppWrapper, LoadingSpinner, ErrorBox, Modal, TabBox, RadioButton, CheckboxButton, ButtonInputGroup, SimpleDateChooser, Drawer, PopSuccessMark, PopFailureMark, PopPendingMark, CopiableBox, ItemPicker, LogReviewer, IntelliTable, CSVDownloadButton, DBEntryManagerPanel, Tooltip, ToggleSwitch, AutoscrollToBottomContainer, MultiSwitch, 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, makeLinksClickable, prefixWithAOrAn, initClient, visitServerEndpoint, logClientEvent, addFatalErrorHandler, leaveToURL, combineClassNames, useForceRender, setClientEventMetadataPopulator, initServer, genRouteHandler, handleError, handleSuccess, initLogCollection, addDBEditorEndpoints, ModalButtonType, ModalSize, ModalType, ReactKitErrorCode, Variant, DayOfWeek, Log, LogType, LogSource, LogAction, LogBuiltInMetadata, LogMetadataType, LogFunction, IntelliTableColumn, PickableItem, DBEntry, DBEntryField, DBEntryFieldType, ParamType, };
|
|
97
|
+
export { AppWrapper, LoadingSpinner, ErrorBox, Modal, TabBox, RadioButton, CheckboxButton, ButtonInputGroup, SimpleDateChooser, Drawer, PopSuccessMark, PopFailureMark, PopPendingMark, CopiableBox, ItemPicker, LogReviewer, IntelliTable, CSVDownloadButton, DBEntryManagerPanel, Tooltip, ToggleSwitch, AutoscrollToBottomContainer, MultiSwitch, 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, makeLinksClickable, prefixWithAOrAn, everyAsync, filterAsync, forEachAsync, mapAsync, someAsync, initClient, visitServerEndpoint, logClientEvent, addFatalErrorHandler, leaveToURL, combineClassNames, useForceRender, setClientEventMetadataPopulator, initServer, genRouteHandler, handleError, handleSuccess, initLogCollection, addDBEditorEndpoints, ModalButtonType, ModalSize, ModalType, ReactKitErrorCode, Variant, DayOfWeek, Log, LogType, LogSource, LogAction, LogBuiltInMetadata, LogMetadataType, LogFunction, IntelliTableColumn, PickableItem, DBEntry, DBEntryField, DBEntryFieldType, ParamType, };
|
package/dist/index.d.ts
CHANGED
|
@@ -153,6 +153,7 @@ type Props$j = {
|
|
|
153
153
|
children?: React.ReactNode;
|
|
154
154
|
onClose?: (type: ModalButtonType) => void;
|
|
155
155
|
dontAllowBackdropExit?: boolean;
|
|
156
|
+
dontShowXButton?: boolean;
|
|
156
157
|
okayLabel?: string;
|
|
157
158
|
okayVariant?: Variant;
|
|
158
159
|
cancelLabel?: string;
|
|
@@ -1465,6 +1466,66 @@ declare const prefixWithAOrAn: (text: string, capitalize?: boolean) => string;
|
|
|
1465
1466
|
*/
|
|
1466
1467
|
declare const useForceRender: (useReducer: any) => () => void;
|
|
1467
1468
|
|
|
1469
|
+
/**
|
|
1470
|
+
* Run the operator function on each item in the array, returning true if
|
|
1471
|
+
* the operator function returns true for every item in the array
|
|
1472
|
+
* @author Gabe Abrams
|
|
1473
|
+
* @param operatorFunction the operator function to apply. If it returns true
|
|
1474
|
+
* for every item, this function will return true
|
|
1475
|
+
* @returns true if the operator function returns true for every item in the array
|
|
1476
|
+
*/
|
|
1477
|
+
declare const everyAsync: <T>(array: T[], operatorFunction: (item: T, index: number, opts: {
|
|
1478
|
+
breakNow: () => void;
|
|
1479
|
+
array: T[];
|
|
1480
|
+
}) => Promise<any>) => Promise<boolean>;
|
|
1481
|
+
|
|
1482
|
+
/**
|
|
1483
|
+
* Run the operator function on each item in the array, returning a new array
|
|
1484
|
+
* that only contains the items that pass the filter
|
|
1485
|
+
* @author Gabe Abrams
|
|
1486
|
+
* @param operatorFunction the operator function to apply. If it returns true
|
|
1487
|
+
* for an item, the item will be included in the returned array
|
|
1488
|
+
* @returns the filtered array
|
|
1489
|
+
*/
|
|
1490
|
+
declare const filterAsync: <T>(array: T[], operatorFunction: (item: T, index: number, opts: {
|
|
1491
|
+
breakNow: () => void;
|
|
1492
|
+
array: T[];
|
|
1493
|
+
}) => Promise<any>) => Promise<T[]>;
|
|
1494
|
+
|
|
1495
|
+
/**
|
|
1496
|
+
* Run the operator function on each item in the array
|
|
1497
|
+
* @author Gabe Abrams
|
|
1498
|
+
* @param operatorFunction the operator function to apply
|
|
1499
|
+
*/
|
|
1500
|
+
declare const forEachAsync: <T>(array: T[], operatorFunction: (item: T, index: number, opts: {
|
|
1501
|
+
breakNow: () => void;
|
|
1502
|
+
array: T[];
|
|
1503
|
+
}) => void) => Promise<void>;
|
|
1504
|
+
|
|
1505
|
+
/**
|
|
1506
|
+
* Run the operator function on each item in the array, collecting all results
|
|
1507
|
+
* @author Gabe Abrams
|
|
1508
|
+
* @param operatorFunction the operator function to apply
|
|
1509
|
+
* @returns the array of results
|
|
1510
|
+
*/
|
|
1511
|
+
declare const mapAsync: <T, U>(array: T[], operatorFunction: (item: T, index: number, opts: {
|
|
1512
|
+
breakNow: () => void;
|
|
1513
|
+
array: T[];
|
|
1514
|
+
}) => Promise<U>) => Promise<U[]>;
|
|
1515
|
+
|
|
1516
|
+
/**
|
|
1517
|
+
* Run the operator function on each item in the array, returning true if
|
|
1518
|
+
* the operator function returns true for any item in the array
|
|
1519
|
+
* @author Gabe Abrams
|
|
1520
|
+
* @param operatorFunction the operator function to apply. If it returns true
|
|
1521
|
+
* for any item, this function will return true
|
|
1522
|
+
* @returns true if the operator function returns true for any item in the array
|
|
1523
|
+
*/
|
|
1524
|
+
declare const someAsync: <T>(array: T[], operatorFunction: (item: T, index: number, opts: {
|
|
1525
|
+
breakNow: () => void;
|
|
1526
|
+
array: T[];
|
|
1527
|
+
}) => Promise<any>) => Promise<boolean>;
|
|
1528
|
+
|
|
1468
1529
|
/**
|
|
1469
1530
|
* List of error codes built into the react kit
|
|
1470
1531
|
* @author Gabe Abrams
|
|
@@ -1515,4 +1576,4 @@ declare const LogBuiltInMetadata: {
|
|
|
1515
1576
|
};
|
|
1516
1577
|
};
|
|
1517
1578
|
|
|
1518
|
-
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, LogFunction, LogMetadataType, LogReviewer, LogSource, LogType, MINUTE_IN_MS, Modal, ModalButtonType, ModalSize, ModalType, MultiSwitch, ParamType, PickableItem, PopFailureMark, PopPendingMark, PopSuccessMark, RadioButton, ReactKitErrorCode, SimpleDateChooser, TabBox, ToggleSwitch, Tooltip, Variant, abbreviate, addDBEditorEndpoints, addFatalErrorHandler, alert, avg, canReviewLogs, ceilToNumDecimals, combineClassNames, compareArraysByProp, confirm, extractProp, floorToNumDecimals, forceNumIntoBounds, genCSV, genCommaList, genRouteHandler, getHumanReadableDate, getLocalTimeInfo, getMonthName, getOrdinal, getPartOfDay, getTimeInfoInET, handleError, handleSuccess, idify, initClient, initLogCollection, initServer, isMobileOrTablet, leaveToURL, logClientEvent, makeLinksClickable, onlyKeepLetters, padDecimalZeros, padZerosLeft, parallelLimit, prefixWithAOrAn, roundToNumDecimals, setClientEventMetadataPopulator, showFatalError, startMinWait, stringsToHumanReadableList, stubServerEndpoint, sum, useForceRender, validateEmail, validatePhoneNumber, validateString, visitServerEndpoint, waitMs };
|
|
1579
|
+
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, LogFunction, LogMetadataType, LogReviewer, LogSource, LogType, MINUTE_IN_MS, Modal, ModalButtonType, ModalSize, ModalType, MultiSwitch, ParamType, PickableItem, PopFailureMark, PopPendingMark, PopSuccessMark, RadioButton, ReactKitErrorCode, SimpleDateChooser, TabBox, ToggleSwitch, Tooltip, Variant, abbreviate, addDBEditorEndpoints, addFatalErrorHandler, alert, avg, canReviewLogs, ceilToNumDecimals, combineClassNames, compareArraysByProp, confirm, everyAsync, extractProp, filterAsync, floorToNumDecimals, forEachAsync, forceNumIntoBounds, genCSV, genCommaList, genRouteHandler, getHumanReadableDate, getLocalTimeInfo, getMonthName, getOrdinal, getPartOfDay, getTimeInfoInET, handleError, handleSuccess, idify, initClient, initLogCollection, initServer, isMobileOrTablet, leaveToURL, logClientEvent, makeLinksClickable, mapAsync, onlyKeepLetters, padDecimalZeros, padZerosLeft, parallelLimit, prefixWithAOrAn, roundToNumDecimals, setClientEventMetadataPopulator, showFatalError, someAsync, startMinWait, stringsToHumanReadableList, stubServerEndpoint, sum, useForceRender, validateEmail, validatePhoneNumber, validateString, visitServerEndpoint, waitMs };
|
package/package.json
CHANGED
package/src/components/Modal.tsx
CHANGED
|
@@ -222,6 +222,8 @@ type Props = {
|
|
|
222
222
|
onClose?: (type: ModalButtonType) => void,
|
|
223
223
|
// If true, don't allow the user to click the backdrop to exit
|
|
224
224
|
dontAllowBackdropExit?: boolean,
|
|
225
|
+
// If true, don't show the "X" close button
|
|
226
|
+
dontShowXButton?: boolean,
|
|
225
227
|
// Custom label for "okay" button
|
|
226
228
|
okayLabel?: string,
|
|
227
229
|
// Custom variant for "okay" button
|
|
@@ -284,6 +286,7 @@ const Modal: React.FC<Props> = (props) => {
|
|
|
284
286
|
children,
|
|
285
287
|
onClose,
|
|
286
288
|
dontAllowBackdropExit,
|
|
289
|
+
dontShowXButton,
|
|
287
290
|
onTopOfOtherModals,
|
|
288
291
|
} = props;
|
|
289
292
|
|
|
@@ -496,7 +499,7 @@ const Modal: React.FC<Props> = (props) => {
|
|
|
496
499
|
{title}
|
|
497
500
|
</h5>
|
|
498
501
|
|
|
499
|
-
{onClose && (
|
|
502
|
+
{(onClose && !dontShowXButton) && (
|
|
500
503
|
<button
|
|
501
504
|
type="button"
|
|
502
505
|
className="Modal-x-button btn-close"
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A shimmer effect to add to the background of an element. The parent of this element
|
|
3
|
+
* will automatically have its overflow hidden
|
|
4
|
+
* @author Alessandra De Lucas
|
|
5
|
+
* @author Gabe Abrams
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
// Import React
|
|
9
|
+
import React, { useRef, useEffect } from 'react';
|
|
10
|
+
|
|
11
|
+
// Import helpers
|
|
12
|
+
import waitMs from '../helpers/waitMs';
|
|
13
|
+
|
|
14
|
+
/*------------------------------------------------------------------------*/
|
|
15
|
+
/* -------------------------------- Types ------------------------------- */
|
|
16
|
+
/*------------------------------------------------------------------------*/
|
|
17
|
+
|
|
18
|
+
// Props definition
|
|
19
|
+
type Props = {
|
|
20
|
+
// The duration in seconds of the shimmer animation
|
|
21
|
+
durationSec?: number,
|
|
22
|
+
// The number of iterations of the shimmer animation
|
|
23
|
+
numShimmers?: number,
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
/*------------------------------------------------------------------------*/
|
|
27
|
+
/* ------------------------------ Component ----------------------------- */
|
|
28
|
+
/*------------------------------------------------------------------------*/
|
|
29
|
+
|
|
30
|
+
const Shimmer: React.FC<Props> = (props) => {
|
|
31
|
+
/*------------------------------------------------------------------------*/
|
|
32
|
+
/* -------------------------------- Setup ------------------------------- */
|
|
33
|
+
/*------------------------------------------------------------------------*/
|
|
34
|
+
|
|
35
|
+
/* -------------- Props ------------- */
|
|
36
|
+
|
|
37
|
+
// Destructure all props
|
|
38
|
+
const {
|
|
39
|
+
durationSec = 2,
|
|
40
|
+
numShimmers,
|
|
41
|
+
} = props;
|
|
42
|
+
|
|
43
|
+
const numShimmerIterations: string = (
|
|
44
|
+
numShimmers
|
|
45
|
+
? String(numShimmers)
|
|
46
|
+
: 'infinite'
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
/* --------------- Refs ------------- */
|
|
50
|
+
|
|
51
|
+
// Ref for the shimmer container
|
|
52
|
+
const containerRef = useRef<HTMLDivElement>(null);
|
|
53
|
+
|
|
54
|
+
/*------------------------------------------------------------------------*/
|
|
55
|
+
/* -------------------------------- Style ------------------------------- */
|
|
56
|
+
/*------------------------------------------------------------------------*/
|
|
57
|
+
|
|
58
|
+
// Style
|
|
59
|
+
const style = `
|
|
60
|
+
.Shimmer-container {
|
|
61
|
+
display: inline-block;
|
|
62
|
+
position: absolute;
|
|
63
|
+
left: 0;
|
|
64
|
+
top: 0;
|
|
65
|
+
width: 100%;
|
|
66
|
+
height: 0;
|
|
67
|
+
overflow: visible;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.Shimmer-shine {
|
|
71
|
+
display: inline-block;
|
|
72
|
+
position: absolute;
|
|
73
|
+
width: 100%;
|
|
74
|
+
height: 100vh;
|
|
75
|
+
|
|
76
|
+
background: linear-gradient(to right, rgba(255, 255, 255, 0), rgba(255, 255, 255, 0.5), rgba(255, 255, 255, 0));
|
|
77
|
+
|
|
78
|
+
animation-name: Shimmer-slide-animation;
|
|
79
|
+
animation-duration: ${durationSec}s;
|
|
80
|
+
animation-iteration-count: ${numShimmerIterations};
|
|
81
|
+
animation-timing-function: ease-in-out;
|
|
82
|
+
animation-fill-mode: both;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
@keyframes Shimmer-slide-animation {
|
|
86
|
+
0% {
|
|
87
|
+
transform: translateX(-100%);
|
|
88
|
+
}
|
|
89
|
+
100% {
|
|
90
|
+
transform: translateX(100%);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
`;
|
|
94
|
+
|
|
95
|
+
/*------------------------------------------------------------------------*/
|
|
96
|
+
/* ------------------------- Lifecycle Functions ------------------------ */
|
|
97
|
+
/*------------------------------------------------------------------------*/
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Mount: force parent to have its overflow hidden
|
|
101
|
+
* @author Gabe Abrams
|
|
102
|
+
*/
|
|
103
|
+
useEffect(
|
|
104
|
+
() => {
|
|
105
|
+
(async () => {
|
|
106
|
+
// Wait for the container to exist
|
|
107
|
+
while (!containerRef.current) {
|
|
108
|
+
await waitMs(20);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Find the parent
|
|
112
|
+
const parent = containerRef.current.parentElement;
|
|
113
|
+
if (!parent) {
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Force the parent's overflow to be hidden
|
|
118
|
+
parent.style.overflow = 'hidden';
|
|
119
|
+
})();
|
|
120
|
+
},
|
|
121
|
+
[],
|
|
122
|
+
);
|
|
123
|
+
|
|
124
|
+
/*------------------------------------------------------------------------*/
|
|
125
|
+
/* ------------------------------- Render ------------------------------- */
|
|
126
|
+
/*------------------------------------------------------------------------*/
|
|
127
|
+
|
|
128
|
+
/*----------------------------------------*/
|
|
129
|
+
/* --------------- Main UI -------------- */
|
|
130
|
+
/*----------------------------------------*/
|
|
131
|
+
|
|
132
|
+
return (
|
|
133
|
+
<div
|
|
134
|
+
className="Shimmer-container"
|
|
135
|
+
ref={containerRef}
|
|
136
|
+
>
|
|
137
|
+
{/* Style */}
|
|
138
|
+
<style>
|
|
139
|
+
{style}
|
|
140
|
+
</style>
|
|
141
|
+
|
|
142
|
+
{/* Moving shimmer */}
|
|
143
|
+
<div className="Shimmer-shine" />
|
|
144
|
+
</div>
|
|
145
|
+
);
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
/*------------------------------------------------------------------------*/
|
|
149
|
+
/* ------------------------------- Wrap Up ------------------------------ */
|
|
150
|
+
/*------------------------------------------------------------------------*/
|
|
151
|
+
|
|
152
|
+
// Export component
|
|
153
|
+
export default Shimmer;
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
// Import item to test
|
|
2
|
+
import everyAsync from './everyAsync';
|
|
3
|
+
|
|
4
|
+
describe('everyAsync', () => {
|
|
5
|
+
it('returns true for an empty array', async () => {
|
|
6
|
+
const result = await everyAsync(
|
|
7
|
+
[],
|
|
8
|
+
async () => {
|
|
9
|
+
return true;
|
|
10
|
+
},
|
|
11
|
+
);
|
|
12
|
+
expect(result).toBe(true);
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it('returns true if the operator function returns true for every item in the array', async () => {
|
|
16
|
+
const result = await everyAsync(
|
|
17
|
+
[1, 2, 3],
|
|
18
|
+
async (item) => {
|
|
19
|
+
return item > 0;
|
|
20
|
+
},
|
|
21
|
+
);
|
|
22
|
+
expect(result).toBe(true);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it('returns false if the operator function returns false for any item in the array', async () => {
|
|
26
|
+
const result = await everyAsync(
|
|
27
|
+
[1, 2, 3],
|
|
28
|
+
async (item) => {
|
|
29
|
+
return item > 1;
|
|
30
|
+
},
|
|
31
|
+
);
|
|
32
|
+
expect(result).toBe(false);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it('passes the index as the second argument to the operator function', async () => {
|
|
36
|
+
const result = await everyAsync(
|
|
37
|
+
[1, 2, 3],
|
|
38
|
+
async (item, index) => {
|
|
39
|
+
return index === item - 1;
|
|
40
|
+
},
|
|
41
|
+
);
|
|
42
|
+
expect(result).toBe(true);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it('passes an object with a breakNow function and the array as the third argument to the operator function', async () => {
|
|
46
|
+
const result = await everyAsync(
|
|
47
|
+
[1, 2, 3],
|
|
48
|
+
async (item, index, { breakNow }) => {
|
|
49
|
+
if (item === 2) {
|
|
50
|
+
breakNow();
|
|
51
|
+
}
|
|
52
|
+
return true;
|
|
53
|
+
},
|
|
54
|
+
);
|
|
55
|
+
expect(result).toBe(false);
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it('stops iterating if the operator function calls the breakNow function', async () => {
|
|
59
|
+
const mockOperatorFunction = jest.fn(async (item, index, { breakNow }) => {
|
|
60
|
+
if (item === 2) {
|
|
61
|
+
breakNow();
|
|
62
|
+
}
|
|
63
|
+
return true;
|
|
64
|
+
});
|
|
65
|
+
const result = await everyAsync(
|
|
66
|
+
[1, 2, 3],
|
|
67
|
+
mockOperatorFunction,
|
|
68
|
+
);
|
|
69
|
+
expect(result).toBe(false);
|
|
70
|
+
expect(mockOperatorFunction).toHaveBeenCalledTimes(2);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it('handles an operator function that returns a promise that resolves to true', async () => {
|
|
74
|
+
const result = await everyAsync(
|
|
75
|
+
[1, 2, 3],
|
|
76
|
+
async (item) => {
|
|
77
|
+
return Promise.resolve(item > 0);
|
|
78
|
+
},
|
|
79
|
+
);
|
|
80
|
+
expect(result).toBe(true);
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it('handles an operator function that returns a promise that resolves to false', async () => {
|
|
84
|
+
const result = await everyAsync(
|
|
85
|
+
[1, 2, 3],
|
|
86
|
+
async (item) => {
|
|
87
|
+
return Promise.resolve(item > 1);
|
|
88
|
+
},
|
|
89
|
+
);
|
|
90
|
+
expect(result).toBe(false);
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
it('handles an operator function that throws an error', async () => {
|
|
94
|
+
const mockOperatorFunction = jest.fn(async (item) => {
|
|
95
|
+
if (item === 2) {
|
|
96
|
+
throw new Error('Test error');
|
|
97
|
+
}
|
|
98
|
+
return true;
|
|
99
|
+
});
|
|
100
|
+
let error: any = null;
|
|
101
|
+
let result: boolean | null = null;
|
|
102
|
+
try {
|
|
103
|
+
result = await everyAsync(
|
|
104
|
+
[1, 2, 3],
|
|
105
|
+
mockOperatorFunction,
|
|
106
|
+
);
|
|
107
|
+
} catch (err) {
|
|
108
|
+
error = err;
|
|
109
|
+
}
|
|
110
|
+
expect(result).toBe(null);
|
|
111
|
+
expect(error).not.toBe(null);
|
|
112
|
+
expect(mockOperatorFunction).toHaveBeenCalledTimes(2);
|
|
113
|
+
});
|
|
114
|
+
});
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Run the operator function on each item in the array, returning true if
|
|
3
|
+
* the operator function returns true for every item in the array
|
|
4
|
+
* @author Gabe Abrams
|
|
5
|
+
* @param operatorFunction the operator function to apply. If it returns true
|
|
6
|
+
* for every item, this function will return true
|
|
7
|
+
* @returns true if the operator function returns true for every item in the array
|
|
8
|
+
*/
|
|
9
|
+
const everyAsync = async <T>(
|
|
10
|
+
array: T[],
|
|
11
|
+
operatorFunction: (
|
|
12
|
+
item: T,
|
|
13
|
+
index: number,
|
|
14
|
+
opts: {
|
|
15
|
+
breakNow: () => void,
|
|
16
|
+
array: Array<T>,
|
|
17
|
+
},
|
|
18
|
+
) => Promise<any>,
|
|
19
|
+
): Promise<boolean> => {
|
|
20
|
+
// Create break logic
|
|
21
|
+
let done = false;
|
|
22
|
+
/**
|
|
23
|
+
* Break the loop (checking stops here)
|
|
24
|
+
* @author Gabe Abrams
|
|
25
|
+
*/
|
|
26
|
+
const breakNow = () => {
|
|
27
|
+
done = true;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
// Loop through each item, checking
|
|
31
|
+
for (let i = 0; i < array.length && !done; i++) {
|
|
32
|
+
const passed = await operatorFunction(
|
|
33
|
+
array[i],
|
|
34
|
+
i,
|
|
35
|
+
{
|
|
36
|
+
breakNow,
|
|
37
|
+
array,
|
|
38
|
+
},
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
// Check if this one failed or if loop was broken
|
|
42
|
+
if (!passed || done) {
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Return true because none returned false
|
|
48
|
+
return true;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export default everyAsync;
|