dce-reactkit 3.0.35 → 3.0.38

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/index.d.ts CHANGED
@@ -7,7 +7,7 @@ import React from 'react';
7
7
  * @author Gabe Abrams
8
8
  */
9
9
 
10
- declare type Props$8 = {
10
+ declare type Props$9 = {
11
11
  children: React.ReactNode;
12
12
  sendRequest: SendRequestFunction;
13
13
  dark?: boolean;
@@ -52,7 +52,7 @@ declare const confirm: (title: string, text: string) => Promise<boolean>;
52
52
  * @param [errorTitle] title of the error box
53
53
  */
54
54
  declare const showFatalError: (error: any, errorTitle?: string) => undefined;
55
- declare const AppWrapper: React.FC<Props$8>;
55
+ declare const AppWrapper: React.FC<Props$9>;
56
56
 
57
57
  /**
58
58
  * Loading spinner/indicator
@@ -65,12 +65,12 @@ declare const LoadingSpinner: () => JSX.Element;
65
65
  * @author Gabe Abrams
66
66
  */
67
67
 
68
- declare type Props$7 = {
68
+ declare type Props$8 = {
69
69
  error: any;
70
70
  title?: string;
71
71
  onClose?: () => void;
72
72
  };
73
- declare const ErrorBox: React.FC<Props$7>;
73
+ declare const ErrorBox: React.FC<Props$8>;
74
74
 
75
75
  /**
76
76
  * Bootstrap variants
@@ -136,7 +136,7 @@ declare enum ModalType {
136
136
  * @author Gabe Abrams
137
137
  */
138
138
 
139
- declare type Props$6 = {
139
+ declare type Props$7 = {
140
140
  type?: ModalType;
141
141
  size?: ModalSize;
142
142
  title?: React.ReactNode;
@@ -165,26 +165,26 @@ declare type Props$6 = {
165
165
  confirmVariant?: Variant;
166
166
  onTopOfOtherModals?: boolean;
167
167
  };
168
- declare const Modal: React.FC<Props$6>;
168
+ declare const Modal: React.FC<Props$7>;
169
169
 
170
170
  /**
171
171
  * A box with a tab on the top that holds buttons and other content
172
172
  * @author Gabe Abrams
173
173
  */
174
174
 
175
- declare type Props$5 = {
175
+ declare type Props$6 = {
176
176
  title: React.ReactNode;
177
177
  children: React.ReactNode;
178
178
  noBottomPadding?: boolean;
179
179
  };
180
- declare const TabBox: React.FC<Props$5>;
180
+ declare const TabBox: React.FC<Props$6>;
181
181
 
182
182
  /**
183
183
  * A radio selection button
184
184
  * @author Gabe Abrams
185
185
  */
186
186
 
187
- declare type Props$4 = {
187
+ declare type Props$5 = {
188
188
  text: string;
189
189
  onSelected: () => void;
190
190
  ariaLabel: string;
@@ -196,14 +196,14 @@ declare type Props$4 = {
196
196
  unselectedVariant?: Variant;
197
197
  small?: boolean;
198
198
  };
199
- declare const RadioButton: React.FC<Props$4>;
199
+ declare const RadioButton: React.FC<Props$5>;
200
200
 
201
201
  /**
202
202
  * A checkbox button
203
203
  * @author Gabe Abrams
204
204
  */
205
205
 
206
- declare type Props$3 = {
206
+ declare type Props$4 = {
207
207
  text: string;
208
208
  onChanged: (checked: boolean) => void;
209
209
  ariaLabel: string;
@@ -215,26 +215,26 @@ declare type Props$3 = {
215
215
  uncheckedVariant?: Variant;
216
216
  small?: boolean;
217
217
  };
218
- declare const CheckboxButton: React.FC<Props$3>;
218
+ declare const CheckboxButton: React.FC<Props$4>;
219
219
 
220
220
  /**
221
221
  * Input group with a title and space for buttons
222
222
  * @author Gabe Abrams
223
223
  */
224
224
 
225
- declare type Props$2 = {
225
+ declare type Props$3 = {
226
226
  label: string;
227
227
  minLabelWidth?: string;
228
228
  children: React.ReactNode;
229
229
  };
230
- declare const ButtonInputGroup: React.FC<Props$2>;
230
+ declare const ButtonInputGroup: React.FC<Props$3>;
231
231
 
232
232
  /**
233
233
  * A very simple, lightweight date chooser
234
234
  * @author Gabe Abrams
235
235
  */
236
236
 
237
- declare type Props$1 = {
237
+ declare type Props$2 = {
238
238
  ariaLabel: string;
239
239
  name: string;
240
240
  month: number;
@@ -249,17 +249,29 @@ declare type Props$1 = {
249
249
  onChange: (month: number, day: number, year: number) => void;
250
250
  numMonthsToShow?: number;
251
251
  };
252
- declare const SimpleDateChooser: React.FC<Props$1>;
252
+ declare const SimpleDateChooser: React.FC<Props$2>;
253
253
 
254
254
  /**
255
255
  * Drawer container
256
256
  * @author Gabe Abrams
257
257
  */
258
258
 
259
- declare type Props = {
259
+ declare type Props$1 = {
260
260
  children: React.ReactNode;
261
261
  };
262
- declare const Drawer: React.FC<Props>;
262
+ declare const Drawer: React.FC<Props$1>;
263
+
264
+ /**
265
+ * Success checkmark that pops into view
266
+ * @author Gabe Abrams
267
+ */
268
+
269
+ declare type Props = {
270
+ sizeRem?: number;
271
+ circleVariant?: string;
272
+ checkVariant?: string;
273
+ };
274
+ declare const PopSuccessMark: React.FC<Props>;
263
275
 
264
276
  /**
265
277
  * An error with a code
@@ -523,6 +535,15 @@ declare const stubServerEndpoint: (opts: {
523
535
  errorCode?: string | undefined;
524
536
  }) => void;
525
537
 
538
+ /**
539
+ * Start a dynamic wait, call the function once the operation has completed and
540
+ * the dynamic wait will continue waiting for the rest of the minimum time
541
+ * @author Gabe Abrams
542
+ * @param minWaitMs the minimum number of ms to wait
543
+ * @returns async function to call to finish the wait
544
+ */
545
+ declare const startMinWait: (minWaitMs: number) => () => Promise<void>;
546
+
526
547
  /**
527
548
  * List of error codes built into the react kit
528
549
  * @author Gabe Abrams
@@ -540,4 +561,4 @@ declare enum ReactKitErrorCode {
540
561
  NotAdmin = "DRK10"
541
562
  }
542
563
 
543
- export { AppWrapper, ButtonInputGroup, CheckboxButton, DAY_IN_MS, Drawer, ErrorBox, ErrorWithCode, HOUR_IN_MS, LoadingSpinner, MINUTE_IN_MS, Modal, ModalButtonType, ModalSize, ModalType, ParamType, RadioButton, ReactKitErrorCode, SimpleDateChooser, TabBox, Variant, abbreviate, alert, avg, ceilToNumDecimals, confirm, floorToNumDecimals, forceNumIntoBounds, genRouteHandler, getOrdinal, getTimeInfoInET, handleError, handleSuccess, initServer, padDecimalZeros, padZerosLeft, roundToNumDecimals, showFatalError, stubServerEndpoint, sum, visitServerEndpoint, waitMs };
564
+ export { AppWrapper, ButtonInputGroup, CheckboxButton, DAY_IN_MS, Drawer, ErrorBox, ErrorWithCode, HOUR_IN_MS, LoadingSpinner, MINUTE_IN_MS, Modal, ModalButtonType, ModalSize, ModalType, ParamType, PopSuccessMark, RadioButton, ReactKitErrorCode, SimpleDateChooser, TabBox, Variant, abbreviate, alert, avg, ceilToNumDecimals, confirm, floorToNumDecimals, forceNumIntoBounds, genRouteHandler, getOrdinal, getTimeInfoInET, handleError, handleSuccess, initServer, padDecimalZeros, padZerosLeft, roundToNumDecimals, showFatalError, startMinWait, stubServerEndpoint, sum, visitServerEndpoint, waitMs };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dce-reactkit",
3
- "version": "3.0.35",
3
+ "version": "3.0.38",
4
4
  "description": "Shared components for Harvard DCE apps",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/esm/index.js",
@@ -23,7 +23,7 @@
23
23
  "@fortawesome/free-solid-svg-icons": "^6.1.1",
24
24
  "@fortawesome/react-fontawesome": "^0.1.18",
25
25
  "bootstrap": "^5.1.3",
26
- "react": "^17.0.1"
26
+ "react": "^17.x.x"
27
27
  },
28
28
  "devDependencies": {
29
29
  "@rollup/plugin-commonjs": "^22.0.0",
@@ -0,0 +1,172 @@
1
+ /**
2
+ * Success checkmark that pops into view
3
+ * @author Gabe Abrams
4
+ */
5
+
6
+ // Import React
7
+ import React from 'react';
8
+
9
+ /*------------------------------------------------------------------------*/
10
+ /* Types */
11
+ /*------------------------------------------------------------------------*/
12
+
13
+ // Props definition
14
+ type Props = {
15
+ // Size of checkmark in rem
16
+ sizeRem?: number,
17
+ // Bootstrap variant of circle
18
+ circleVariant?: string,
19
+ // Bootstrap variant of checkmark
20
+ checkVariant?: string,
21
+ };
22
+
23
+ /*------------------------------------------------------------------------*/
24
+ /* Style */
25
+ /*------------------------------------------------------------------------*/
26
+
27
+ const style = `
28
+ .PopSuccessMark-outer-container {
29
+ position: relative;
30
+ display: inline-block;
31
+ border-radius: 50%;
32
+
33
+ animation-name: PopSuccessMark-outer-container;
34
+ animation-duration: 0.8s;
35
+ animation-fill-mode: both;
36
+ animation-iteration-count: 1;
37
+ animation-timing-function: ease-out;
38
+ }
39
+ @keyframes PopSuccessMark-outer-container {
40
+ 0% {
41
+ opacity: 0;
42
+ transform: scale(1.5);
43
+ filter: saturate(0);
44
+ }
45
+ 80.7% {
46
+ opacity: 1;
47
+ transform: scale(1);
48
+ filter: saturate(0);
49
+ }
50
+ 100% {
51
+ opacity: 1;
52
+ transform: scale(1);
53
+ filter: saturate(1);
54
+ }
55
+ }
56
+
57
+ .PopSuccessMark-check-stroke-1 {
58
+ position: absolute;
59
+ left: 20%;
60
+ top: 36%;
61
+
62
+ display: inline-block;
63
+ height: 16%;
64
+ width: 35%;
65
+
66
+ transform-origin: left;
67
+
68
+ animation-name: PopSuccessMark-check-stroke-1;
69
+ animation-duration: 0.3s;
70
+ animation-delay: 0.3s;
71
+ animation-fill-mode: both;
72
+ animation-iteration-count: 1;
73
+ animation-timing-function: ease-in;
74
+ }
75
+ @keyframes PopSuccessMark-check-stroke-1 {
76
+ 0% {
77
+ transform: rotate(45deg) scaleX(0);
78
+ }
79
+ 100% {
80
+ transform: rotate(45deg) scaleX(1);
81
+ }
82
+ }
83
+
84
+
85
+ .PopSuccessMark-check-stroke-2 {
86
+ position: absolute;
87
+ left: 35%;
88
+ top: 63%;
89
+
90
+ display: inline-block;
91
+ height: 16%;
92
+ width: 60%;
93
+
94
+ transform-origin: left;
95
+
96
+ animation-name: PopSuccessMark-check-stroke-2;
97
+ animation-duration: 0.3s;
98
+ animation-delay: 0.6s;
99
+ animation-fill-mode: both;
100
+ animation-iteration-count: 1;
101
+ animation-timing-function: ease-out;
102
+ }
103
+ @keyframes PopSuccessMark-check-stroke-2 {
104
+ 0% {
105
+ transform: rotate(-40deg) scaleX(0);
106
+ }
107
+ 100% {
108
+ transform: rotate(-40deg) scaleX(1);
109
+ }
110
+ }
111
+ `;
112
+
113
+ /*------------------------------------------------------------------------*/
114
+ /* Component */
115
+ /*------------------------------------------------------------------------*/
116
+
117
+ const PopSuccessMark: React.FC<Props> = (props) => {
118
+ /*------------------------------------------------------------------------*/
119
+ /* Setup */
120
+ /*------------------------------------------------------------------------*/
121
+
122
+ /* -------------- Props ------------- */
123
+
124
+ // Destructure all props
125
+ const {
126
+ sizeRem = 3,
127
+ circleVariant = 'success',
128
+ checkVariant = 'white',
129
+ } = props;
130
+
131
+ /*------------------------------------------------------------------------*/
132
+ /* Render */
133
+ /*------------------------------------------------------------------------*/
134
+
135
+ /*----------------------------------------*/
136
+ /* Main UI */
137
+ /*----------------------------------------*/
138
+
139
+ return (
140
+ <div
141
+ className={`PopSuccessMark-outer-container bg-${circleVariant}`}
142
+ style={{
143
+ width: `${sizeRem}rem`,
144
+ height: `${sizeRem}rem`,
145
+ }}
146
+ aria-label="checkmark indicating success"
147
+ >
148
+ {/* Style */}
149
+ <style>{style}</style>
150
+ {/* Check mark */}
151
+ <div
152
+ className={`PopSuccessMark-check-stroke-1 bg-${checkVariant}`}
153
+ style={{
154
+ borderRadius: `${sizeRem / 5}rem`,
155
+ }}
156
+ />
157
+ <div
158
+ className={`PopSuccessMark-check-stroke-2 bg-${checkVariant}`}
159
+ style={{
160
+ borderRadius: `${sizeRem / 5}rem`,
161
+ }}
162
+ />
163
+ </div>
164
+ );
165
+ };
166
+
167
+ /*------------------------------------------------------------------------*/
168
+ /* Wrap Up */
169
+ /*------------------------------------------------------------------------*/
170
+
171
+ // Export component
172
+ export default PopSuccessMark;
@@ -0,0 +1,33 @@
1
+ // Import other helpers
2
+ import waitMs from './waitMs';
3
+
4
+ /**
5
+ * Start a dynamic wait, call the function once the operation has completed and
6
+ * the dynamic wait will continue waiting for the rest of the minimum time
7
+ * @author Gabe Abrams
8
+ * @param minWaitMs the minimum number of ms to wait
9
+ * @returns async function to call to finish the wait
10
+ */
11
+ const startMinWait = (minWaitMs: number): () => Promise<void> => {
12
+ const startTimestamp = Date.now();
13
+
14
+ /**
15
+ * Finish the remaining time to wait
16
+ * @author Gabe Abrams
17
+ */
18
+ return async () => {
19
+ const endTimestamp = Date.now();
20
+
21
+ // Calculate remaining time to wait
22
+ const elapsedTimeMs = (endTimestamp - startTimestamp);
23
+ const remainingTimeToWaitMs = minWaitMs - elapsedTimeMs;
24
+ if (remainingTimeToWaitMs <= 0) {
25
+ return;
26
+ }
27
+
28
+ // Perform wait
29
+ await waitMs(remainingTimeToWaitMs);
30
+ };
31
+ };
32
+
33
+ export default startMinWait;
package/src/index.ts CHANGED
@@ -9,6 +9,7 @@ import CheckboxButton from './components/CheckboxButton';
9
9
  import ButtonInputGroup from './components/ButtonInputGroup';
10
10
  import SimpleDateChooser from './components/SimpleDateChooser';
11
11
  import Drawer from './components/Drawer';
12
+ import PopSuccessMark from './components/PopSuccessMark';
12
13
 
13
14
  // Import errors
14
15
  import ErrorWithCode from './errors/ErrorWithCode';
@@ -37,6 +38,7 @@ import initServer from './server/initServer';
37
38
  import getOrdinal from './helpers/getOrdinal';
38
39
  import getTimeInfoInET from './helpers/getTimeInfoInET';
39
40
  import stubServerEndpoint from './helpers/stubServerEndpoint';
41
+ import startMinWait from './helpers/startMinWait';
40
42
 
41
43
  // Import types
42
44
  import ModalButtonType from './types/ModalButtonType';
@@ -59,6 +61,7 @@ export {
59
61
  ButtonInputGroup,
60
62
  SimpleDateChooser,
61
63
  Drawer,
64
+ PopSuccessMark,
62
65
  // Global functions
63
66
  alert,
64
67
  confirm,
@@ -83,6 +86,7 @@ export {
83
86
  getOrdinal,
84
87
  getTimeInfoInET,
85
88
  stubServerEndpoint,
89
+ startMinWait,
86
90
  // Client helpers
87
91
  visitServerEndpoint,
88
92
  // Server helpers