dce-reactkit 4.3.3 → 4.3.5-beta-progress-size.2

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.
@@ -3,7 +3,6 @@
3
3
  * @author Allison Zhang
4
4
  */
5
5
  declare enum ProgressBarSize {
6
- Small = "Small",
7
6
  Medium = "Medium",
8
7
  Large = "Large"
9
8
  }
package/dist/index.d.ts CHANGED
@@ -778,7 +778,6 @@ declare const Dropdown: React$1.FC<Props$1>;
778
778
  * @author Allison Zhang
779
779
  */
780
780
  declare enum ProgressBarSize {
781
- Small = "Small",
782
781
  Medium = "Medium",
783
782
  Large = "Large"
784
783
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dce-reactkit",
3
- "version": "4.3.3",
3
+ "version": "4.3.5-beta-progress-size.2",
4
4
  "description": "Shared components for Harvard DCE apps",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/esm/index.js",
@@ -9,6 +9,8 @@ import React from 'react';
9
9
  // Import types
10
10
  import Variant from '../types/Variant';
11
11
  import ProgressBarSize from '../types/ProgressBarSize';
12
+ import roundToNumDecimals from '../helpers/roundToNumDecimals';
13
+ import padDecimalZeros from '../helpers/padDecimalZeros';
12
14
 
13
15
  /*------------------------------------------------------------------------*/
14
16
  /* -------------------------------- Types ------------------------------- */
@@ -75,7 +77,7 @@ type ProgressStatus = (
75
77
  const ITEM_WIDTH_MULTIPLIER = 1.3;
76
78
 
77
79
  // Constant for percent width
78
- const PERCENT_WIDTH = 3;
80
+ const PERCENT_WIDTH = 2.7;
79
81
 
80
82
  // Constant for item width
81
83
  const ITEM_WIDTH = 2;
@@ -88,11 +90,9 @@ const ITEM_WIDTH = 2;
88
90
  let style = `
89
91
  .ProgressBar-number-of,
90
92
  .ProgressBar-percent {
91
- flex: 0 0 auto;
92
93
  white-space: nowrap;
93
- padding-right: 0.5em;
94
- padding-left: 0.25em;
95
- text-align: right;
94
+ padding-right: 0.3em;
95
+ text-align: left;
96
96
  transition: width .25s ease;
97
97
  }
98
98
 
@@ -164,10 +164,20 @@ const ProgressBar: React.FC<Props> = (props) => {
164
164
  /* ---------------- Sizes --------------- */
165
165
  /*----------------------------------------*/
166
166
 
167
+ // Add dynamic general style
168
+ style += `
169
+ .ProgressBar-percent {
170
+ min-width: ${(status.usePercent ? status.numDecimalPlaces ?? 0 : 0) + PERCENT_WIDTH}em;
171
+ }
172
+ .ProgressBar-number-of {
173
+ min-width: ${((!status.usePercent ? String(status.total ?? 0).length || 1 : 0) * ITEM_WIDTH_MULTIPLIER) + ITEM_WIDTH}em;
174
+ }
175
+ `;
176
+
167
177
  // Size styles
168
178
  switch (size) {
169
- case ProgressBarSize.Small:
170
- // Small size
179
+ case ProgressBarSize.Medium:
180
+ // Medium size
171
181
  style += `
172
182
  .ProgressBar-container .ProgressBar-number-of, .ProgressBar-container .ProgressBar-percent {
173
183
  font-size: 1em;
@@ -180,18 +190,10 @@ const ProgressBar: React.FC<Props> = (props) => {
180
190
  height: 1.5em;
181
191
  border-radius: 0.5em;
182
192
  }
183
- .ProgressBar-percent {
184
- min-width: ${((status.usePercent ? status.numDecimalPlaces ?? 0 : 0) * 1) + PERCENT_WIDTH}em;
185
- max-width: ${((status.usePercent ? status.numDecimalPlaces ?? 0 : 0) * 1) + PERCENT_WIDTH}em;
186
- }
187
- .ProgressBar-number-of {
188
- min-width: ${((!status.usePercent ? status.total?.toString().length || 1 : 0) * ITEM_WIDTH_MULTIPLIER) + ITEM_WIDTH}em;
189
- max-width: ${((!status.usePercent ? status.total?.toString().length || 1 : 0) * ITEM_WIDTH_MULTIPLIER) + ITEM_WIDTH}em;
190
- }
191
193
  `;
192
194
  break;
193
- case ProgressBarSize.Medium:
194
- // Medium size
195
+ case ProgressBarSize.Large:
196
+ // Large size
195
197
  style += `
196
198
  .ProgressBar-container .ProgressBar-number-of, .ProgressBar-container .ProgressBar-percent {
197
199
  font-size: 1.5em;
@@ -204,38 +206,6 @@ const ProgressBar: React.FC<Props> = (props) => {
204
206
  height: 2em;
205
207
  border-radius: 0.7em;
206
208
  }
207
- .ProgressBar-percent {
208
- min-width: ${((status.usePercent ? status.numDecimalPlaces ?? 0 : 0) * 1) + PERCENT_WIDTH}em;
209
- max-width: ${((status.usePercent ? status.numDecimalPlaces ?? 0 : 0) * 1) + PERCENT_WIDTH}em;
210
- }
211
- .ProgressBar-number-of {
212
- min-width: ${((!status.usePercent ? status.total?.toString().length || 1 : 0) * ITEM_WIDTH_MULTIPLIER) + ITEM_WIDTH}em;
213
- max-width: ${((!status.usePercent ? status.total?.toString().length || 1 : 0) * ITEM_WIDTH_MULTIPLIER) + ITEM_WIDTH}em;
214
- }
215
- `;
216
- break;
217
- case ProgressBarSize.Large:
218
- // Large size
219
- style += `
220
- .ProgressBar-container .ProgressBar-number-of, .ProgressBar-container .ProgressBar-percent {
221
- font-size: 2em;
222
- }
223
- .ProgressBar-container .ProgressBar-background {
224
- height: 3em;
225
- border-radius: 1em;
226
- }
227
- .ProgressBar-container .ProgressBar-bar {
228
- height: 3em;
229
- border-radius: 1em;
230
- }
231
- .ProgressBar-percent {
232
- min-width: ${((status.usePercent ? status.numDecimalPlaces ?? 0 : 0) * 1) + PERCENT_WIDTH}em;
233
- max-width: ${((status.usePercent ? status.numDecimalPlaces ?? 0 : 0) * 1) + PERCENT_WIDTH}em;
234
- }
235
- .ProgressBar-number-of {
236
- min-width: ${((!status.usePercent ? status.total?.toString().length || 1 : 0) * ITEM_WIDTH_MULTIPLIER) + ITEM_WIDTH}em;
237
- max-width: ${((!status.usePercent ? status.total?.toString().length || 1 : 0) * ITEM_WIDTH_MULTIPLIER) + ITEM_WIDTH}em;
238
- }
239
209
  `;
240
210
  break;
241
211
  default:
@@ -245,9 +215,8 @@ const ProgressBar: React.FC<Props> = (props) => {
245
215
  // Get the width of the outline based on size
246
216
  const outlineWidth = (() => {
247
217
  switch (size) {
248
- case ProgressBarSize.Small: return '0.05em';
249
- case ProgressBarSize.Medium: return '0.08em';
250
- case ProgressBarSize.Large: return '0.1em';
218
+ case ProgressBarSize.Medium: return '0.05em';
219
+ case ProgressBarSize.Large: return '0.08em';
251
220
  default: return '0.05em';
252
221
  }
253
222
  })();
@@ -275,25 +244,38 @@ const ProgressBar: React.FC<Props> = (props) => {
275
244
  `;
276
245
 
277
246
  // Stripes for striped effect
278
- const stripes: React.ReactNode = (
279
- <div>
280
- <style>{stripesStyle}</style>
281
- <div
282
- className="ProgressBar-stripes position-absolute "
283
- style={{
284
- width: '200%',
285
- height: '100%',
286
- }}
287
- >
288
- &nbsp;
247
+ let stripes: React.ReactNode = null;
248
+ if (striped) {
249
+ stripes = (
250
+ <div>
251
+ <style>{stripesStyle}</style>
252
+ <div
253
+ className="ProgressBar-stripes position-absolute"
254
+ style={{
255
+ width: '200%',
256
+ height: '100%',
257
+ }}
258
+ >
259
+ &nbsp;
260
+ </div>
289
261
  </div>
290
- </div>
291
- );
262
+ );
263
+ }
292
264
 
293
265
  /*----------------------------------------*/
294
266
  /* --------------- Main UI -------------- */
295
267
  /*----------------------------------------*/
296
268
 
269
+ // Calculate the width of the progress bar
270
+ let progressBarWidthPercent = 0;
271
+ if (status.usePercent) {
272
+ // Use percent progress directly
273
+ progressBarWidthPercent = status.percentProgress;
274
+ } else if (status.total > 0) {
275
+ // Calculate percent progress from items
276
+ progressBarWidthPercent = (status.numComplete / status.total) * 100;
277
+ }
278
+
297
279
  // Render the progress bar
298
280
  return (
299
281
  <div className="ProgressBar-container d-flex align-items-center">
@@ -301,9 +283,7 @@ const ProgressBar: React.FC<Props> = (props) => {
301
283
  <style>{style}</style>
302
284
  {/* Use items */}
303
285
  {!status.usePercent && status.numComplete && (
304
- <span
305
- className="ProgressBar-number-of pe-2 align-self-center"
306
- >
286
+ <span className="ProgressBar-number-of">
307
287
  {status.numComplete}
308
288
  &nbsp;of&nbsp;
309
289
  {status.total}
@@ -311,15 +291,19 @@ const ProgressBar: React.FC<Props> = (props) => {
311
291
  )}
312
292
  {/* Use percentage */}
313
293
  {status.usePercent && status.percentProgress && (
314
- <span
315
- className="ProgressBar-percent pe-2 align-self-center"
316
- >
317
- {status.percentProgress.toFixed(status?.numDecimalPlaces ?? 0)}
294
+ <span className="ProgressBar-percent">
295
+ {
296
+ padDecimalZeros(
297
+ roundToNumDecimals(status.percentProgress, status?.numDecimalPlaces ?? 0),
298
+ status?.numDecimalPlaces ?? 0,
299
+ )
300
+ }
318
301
  %
319
302
  </span>
320
303
  )}
304
+ {/* Progress Bar Filled Area */}
321
305
  <div
322
- className={`ProgressBar-background bg-${bgVariant} w-100`}
306
+ className={`ProgressBar-background bg-${bgVariant} flex-grow-1`}
323
307
  style={{
324
308
  boxShadow: `0 0 0 ${outlineWidth} ${showOutline ? '#000' : '#DEE2E6'}`,
325
309
  }}
@@ -332,11 +316,13 @@ const ProgressBar: React.FC<Props> = (props) => {
332
316
  `ProgressBar-bar bg-${variant} text-start position-relative`
333
317
  }
334
318
  style={{
335
- width: `${(status.usePercent ? status.percentProgress : (status.numComplete / status.total) * 100)}%`,
319
+ width: `${progressBarWidthPercent}%`,
336
320
  overflow: 'hidden',
337
321
  }}
338
322
  >
339
- {striped && stripes}
323
+ {/* Show Strips (if they exist) */}
324
+ {stripes}
325
+ {/* Space so the bar has some content */}
340
326
  &nbsp;
341
327
  </div>
342
328
  </div>
@@ -14,8 +14,10 @@ const parallelLimit = async (
14
14
  ): Promise<any[]> => {
15
15
  const results: any[] = [];
16
16
 
17
+ let exited = false;
18
+
17
19
  // Wait until finished with all tasks
18
- await new Promise<void>((resolve) => {
20
+ await new Promise<void>((resolve, reject) => {
19
21
  /* ------------- Helpers ------------ */
20
22
 
21
23
  let nextTaskIndex = 0;
@@ -33,23 +35,34 @@ const parallelLimit = async (
33
35
  return;
34
36
  }
35
37
 
36
- // Execute task
37
- const result = await taskFunction();
38
+ try {
39
+ // Execute task
40
+ const result = await taskFunction();
38
41
 
39
- // Add results
40
- results[taskIndex] = result;
42
+ // Add results
43
+ results[taskIndex] = result;
41
44
 
42
- // Tally and finish
43
- if (++numFinishedTasks === taskFunctions.length) {
44
- return resolve();
45
- }
45
+ // Tally and finish
46
+ if (++numFinishedTasks === taskFunctions.length) {
47
+ exited = true;
48
+ return resolve();
49
+ }
46
50
 
47
- // Not finished! Start another task
48
- startTask();
51
+ if (!exited) {
52
+ // Not finished! Start another task
53
+ startTask();
54
+ }
55
+ } catch (err) {
56
+ // Reject only once
57
+ if (!exited) {
58
+ exited = true;
59
+ return reject(err);
60
+ }
61
+ }
49
62
  };
50
63
 
51
64
  /* ----------- Start Tasks ---------- */
52
-
65
+
53
66
  // If no limit, start all tasks. At least start 1 task
54
67
  const numTasks = Math.max((limit || taskFunctions.length), 1);
55
68
  for (let i = 0; i < numTasks; i++) {
@@ -3,7 +3,6 @@
3
3
  * @author Allison Zhang
4
4
  */
5
5
  enum ProgressBarSize {
6
- Small = 'Small',
7
6
  Medium = 'Medium',
8
7
  Large = 'Large',
9
8
  }