dce-reactkit 5.0.0 → 5.0.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.
- package/dist/cjs/index.js +349 -226
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/types/components/FakeProgressBar.d.ts +27 -0
- package/dist/cjs/types/index.d.ts +2 -1
- package/dist/cjs/types/types/ProgressBarSize.d.ts +0 -1
- package/dist/esm/index.js +350 -228
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/types/components/FakeProgressBar.d.ts +27 -0
- package/dist/esm/types/index.d.ts +2 -1
- package/dist/esm/types/types/ProgressBarSize.d.ts +0 -1
- package/dist/index.d.ts +74 -50
- package/package.json +1 -1
- package/src/components/FakeProgressBar.tsx +274 -0
- package/src/components/ProgressBar.tsx +66 -76
- package/src/index.ts +2 -0
- package/src/types/ProgressBarSize.ts +0 -1
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fake progress bar that approaches completion but never fully finishes.
|
|
3
|
+
* Built on top of the existing ProgressBar component.
|
|
4
|
+
*
|
|
5
|
+
* Two phases:
|
|
6
|
+
* 1. Fast phase (0–90%): random jumps of 1–5% at randomized intervals,
|
|
7
|
+
* paced to reach ~90% in roughly estimatedTimeSec seconds.
|
|
8
|
+
* 2. Slow phase (90–99%): crawls 1% at a time with longer random delays,
|
|
9
|
+
* never reaching 100% on its own.
|
|
10
|
+
*
|
|
11
|
+
* When isFinished becomes true, the bar immediately jumps to 100%.
|
|
12
|
+
* @author Yuen Ler Chow
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
// Import React
|
|
16
|
+
import React, { useReducer, useEffect } from 'react';
|
|
17
|
+
|
|
18
|
+
// Import helpers
|
|
19
|
+
import { waitMs } from 'dce-commonkit';
|
|
20
|
+
|
|
21
|
+
// Import types
|
|
22
|
+
import Variant from '../types/Variant';
|
|
23
|
+
import ProgressBarSize from '../types/ProgressBarSize';
|
|
24
|
+
|
|
25
|
+
// Import components
|
|
26
|
+
import ProgressBar from './ProgressBar';
|
|
27
|
+
|
|
28
|
+
/*------------------------------------------------------------------------*/
|
|
29
|
+
/* ------------------------------ Constants ----------------------------- */
|
|
30
|
+
/*------------------------------------------------------------------------*/
|
|
31
|
+
|
|
32
|
+
// Percent where the bar switches from fast random jumps to a slow crawl
|
|
33
|
+
const SLOW_PHASE_START_PERCENT = 90;
|
|
34
|
+
|
|
35
|
+
// Highest percent the bar will reach on its own (before isFinished is true)
|
|
36
|
+
const MAX_UNFINISHED_PERCENT = 99;
|
|
37
|
+
|
|
38
|
+
// Average step size during the fast phase (uniform random from 1–5)
|
|
39
|
+
const AVG_FAST_PHASE_STEP = 3;
|
|
40
|
+
|
|
41
|
+
// Minimum delay (ms) between steps during the slow phase
|
|
42
|
+
const SLOW_PHASE_MIN_DELAY_MS = 2000;
|
|
43
|
+
|
|
44
|
+
// Maximum delay (ms) between steps during the slow phase
|
|
45
|
+
const SLOW_PHASE_MAX_DELAY_MS = 5000;
|
|
46
|
+
|
|
47
|
+
/*------------------------------------------------------------------------*/
|
|
48
|
+
/* -------------------------------- Types ------------------------------- */
|
|
49
|
+
/*------------------------------------------------------------------------*/
|
|
50
|
+
|
|
51
|
+
// Props definition
|
|
52
|
+
type Props = {
|
|
53
|
+
// True if the task is finished (triggers animation to 100%)
|
|
54
|
+
isFinished?: boolean,
|
|
55
|
+
// Estimated time (in seconds) to finish the task (default 8)
|
|
56
|
+
estimatedTimeSec?: number,
|
|
57
|
+
// Whether to show striped effect (default false)
|
|
58
|
+
striped?: boolean,
|
|
59
|
+
// Variant of the progress bar (default warning)
|
|
60
|
+
variant?: Variant,
|
|
61
|
+
// Background variants (default secondary subtle)
|
|
62
|
+
bgVariant?: Variant,
|
|
63
|
+
// Hide outline (default false)
|
|
64
|
+
showOutline?: boolean,
|
|
65
|
+
// Size of the progress bar (default md)
|
|
66
|
+
size?: ProgressBarSize,
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
/*------------------------------------------------------------------------*/
|
|
70
|
+
/* -------------------------------- State ------------------------------- */
|
|
71
|
+
/*------------------------------------------------------------------------*/
|
|
72
|
+
|
|
73
|
+
/* -------- State Definition -------- */
|
|
74
|
+
|
|
75
|
+
type State = {
|
|
76
|
+
// Current progress percentage (0-99)
|
|
77
|
+
progress: number,
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
/* ------------- Actions ------------ */
|
|
81
|
+
|
|
82
|
+
// Types of actions
|
|
83
|
+
enum ActionType {
|
|
84
|
+
// Advance the progress by a given step
|
|
85
|
+
Advance = 'Advance',
|
|
86
|
+
// Set progress to 100% (task complete)
|
|
87
|
+
Complete = 'Complete',
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Action definitions
|
|
91
|
+
type Action = (
|
|
92
|
+
| {
|
|
93
|
+
// Action type
|
|
94
|
+
type: ActionType.Advance,
|
|
95
|
+
// Number of percent points to advance
|
|
96
|
+
step: number,
|
|
97
|
+
}
|
|
98
|
+
| {
|
|
99
|
+
// Action type
|
|
100
|
+
type: ActionType.Complete,
|
|
101
|
+
}
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Reducer that executes actions
|
|
106
|
+
* @author Yuen Ler Chow
|
|
107
|
+
* @param state current state
|
|
108
|
+
* @param action action to execute
|
|
109
|
+
*/
|
|
110
|
+
const reducer = (state: State, action: Action): State => {
|
|
111
|
+
switch (action.type) {
|
|
112
|
+
case ActionType.Advance: {
|
|
113
|
+
return {
|
|
114
|
+
...state,
|
|
115
|
+
progress: Math.min(100, state.progress + action.step),
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
case ActionType.Complete: {
|
|
119
|
+
return {
|
|
120
|
+
...state,
|
|
121
|
+
progress: 100,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
default: {
|
|
125
|
+
return state;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
/*------------------------------------------------------------------------*/
|
|
131
|
+
/* ------------------------------ Component ----------------------------- */
|
|
132
|
+
/*------------------------------------------------------------------------*/
|
|
133
|
+
|
|
134
|
+
const FakeProgressBar: React.FC<Props> = (props) => {
|
|
135
|
+
/*------------------------------------------------------------------------*/
|
|
136
|
+
/* -------------------------------- Setup ------------------------------- */
|
|
137
|
+
/*------------------------------------------------------------------------*/
|
|
138
|
+
|
|
139
|
+
/* -------------- Props ------------- */
|
|
140
|
+
|
|
141
|
+
// Destructure props
|
|
142
|
+
const {
|
|
143
|
+
isFinished,
|
|
144
|
+
estimatedTimeSec = 8,
|
|
145
|
+
striped,
|
|
146
|
+
variant,
|
|
147
|
+
bgVariant,
|
|
148
|
+
showOutline,
|
|
149
|
+
size,
|
|
150
|
+
} = props;
|
|
151
|
+
|
|
152
|
+
/* -------------- State ------------- */
|
|
153
|
+
|
|
154
|
+
// Initial state
|
|
155
|
+
const initialState: State = {
|
|
156
|
+
progress: 0,
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
// Initialize state
|
|
160
|
+
const [state, dispatch] = useReducer(reducer, initialState);
|
|
161
|
+
|
|
162
|
+
// Destructure common state
|
|
163
|
+
const {
|
|
164
|
+
progress,
|
|
165
|
+
} = state;
|
|
166
|
+
|
|
167
|
+
// Convert estimate to milliseconds
|
|
168
|
+
const estimatedMs = estimatedTimeSec * 1000;
|
|
169
|
+
|
|
170
|
+
// Average interval between updates to reach ~90% in the estimated time
|
|
171
|
+
const avgIntervalMs = (estimatedMs / SLOW_PHASE_START_PERCENT) * AVG_FAST_PHASE_STEP;
|
|
172
|
+
|
|
173
|
+
/*------------------------------------------------------------------------*/
|
|
174
|
+
/* ------------------------- Lifecycle Functions ------------------------ */
|
|
175
|
+
/*------------------------------------------------------------------------*/
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Animate to 100% when isFinished becomes true
|
|
179
|
+
* @author Yuen Ler Chow
|
|
180
|
+
*/
|
|
181
|
+
useEffect(
|
|
182
|
+
() => {
|
|
183
|
+
if (isFinished) {
|
|
184
|
+
dispatch({
|
|
185
|
+
type: ActionType.Complete,
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
},
|
|
189
|
+
[isFinished],
|
|
190
|
+
);
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Advance the progress in two phases:
|
|
194
|
+
* 1) Random jumps up to 90%
|
|
195
|
+
* 2) Slow crawl from 90% to 99%
|
|
196
|
+
* @author Yuen Ler Chow
|
|
197
|
+
*/
|
|
198
|
+
useEffect(
|
|
199
|
+
() => {
|
|
200
|
+
// Stop if already finished or at max
|
|
201
|
+
if (isFinished || progress >= MAX_UNFINISHED_PERCENT) {
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// Determine which phase we are in
|
|
206
|
+
const inFastPhase = progress < SLOW_PHASE_START_PERCENT;
|
|
207
|
+
|
|
208
|
+
// Default values
|
|
209
|
+
let delay = avgIntervalMs;
|
|
210
|
+
let step = 1;
|
|
211
|
+
|
|
212
|
+
if (inFastPhase) {
|
|
213
|
+
// Randomize delay around the average interval for variability
|
|
214
|
+
const randomnessMultiplier = 0.5 + (Math.random());
|
|
215
|
+
delay = avgIntervalMs * randomnessMultiplier;
|
|
216
|
+
|
|
217
|
+
// Randomly move forward by 1-5%, capped at 90%
|
|
218
|
+
step = Math.min(
|
|
219
|
+
1 + Math.floor(Math.random() * 5),
|
|
220
|
+
SLOW_PHASE_START_PERCENT - progress,
|
|
221
|
+
);
|
|
222
|
+
} else {
|
|
223
|
+
// Crawl slowly 1% at a time, clamped so we don't exceed 99%
|
|
224
|
+
delay = SLOW_PHASE_MIN_DELAY_MS + (Math.random() * (SLOW_PHASE_MAX_DELAY_MS - SLOW_PHASE_MIN_DELAY_MS));
|
|
225
|
+
step = Math.min(1, MAX_UNFINISHED_PERCENT - progress);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// Track whether this effect invocation is still current
|
|
229
|
+
let cancelled = false;
|
|
230
|
+
|
|
231
|
+
// Wait then dispatch the next progress update
|
|
232
|
+
(async () => {
|
|
233
|
+
await waitMs(delay);
|
|
234
|
+
if (!cancelled) {
|
|
235
|
+
dispatch({
|
|
236
|
+
type: ActionType.Advance,
|
|
237
|
+
step,
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
})();
|
|
241
|
+
|
|
242
|
+
return () => {
|
|
243
|
+
cancelled = true;
|
|
244
|
+
};
|
|
245
|
+
},
|
|
246
|
+
[progress, avgIntervalMs, isFinished],
|
|
247
|
+
);
|
|
248
|
+
|
|
249
|
+
/*------------------------------------------------------------------------*/
|
|
250
|
+
/* ------------------------------- Render ------------------------------- */
|
|
251
|
+
/*------------------------------------------------------------------------*/
|
|
252
|
+
|
|
253
|
+
/*----------------------------------------*/
|
|
254
|
+
/* --------------- Main UI -------------- */
|
|
255
|
+
/*----------------------------------------*/
|
|
256
|
+
|
|
257
|
+
return (
|
|
258
|
+
<ProgressBar
|
|
259
|
+
percentProgress={progress}
|
|
260
|
+
striped={striped}
|
|
261
|
+
variant={variant}
|
|
262
|
+
bgVariant={bgVariant}
|
|
263
|
+
showOutline={showOutline}
|
|
264
|
+
size={size}
|
|
265
|
+
/>
|
|
266
|
+
);
|
|
267
|
+
};
|
|
268
|
+
|
|
269
|
+
/*------------------------------------------------------------------------*/
|
|
270
|
+
/* ------------------------------- Wrap Up ------------------------------ */
|
|
271
|
+
/*------------------------------------------------------------------------*/
|
|
272
|
+
|
|
273
|
+
// Export component
|
|
274
|
+
export default FakeProgressBar;
|
|
@@ -10,6 +10,12 @@ import React from 'react';
|
|
|
10
10
|
import Variant from '../types/Variant';
|
|
11
11
|
import ProgressBarSize from '../types/ProgressBarSize';
|
|
12
12
|
|
|
13
|
+
// Import helpers
|
|
14
|
+
import {
|
|
15
|
+
roundToNumDecimals,
|
|
16
|
+
padDecimalZeros,
|
|
17
|
+
} from 'dce-commonkit';
|
|
18
|
+
|
|
13
19
|
/*------------------------------------------------------------------------*/
|
|
14
20
|
/* -------------------------------- Types ------------------------------- */
|
|
15
21
|
/*------------------------------------------------------------------------*/
|
|
@@ -75,7 +81,7 @@ type ProgressStatus = (
|
|
|
75
81
|
const ITEM_WIDTH_MULTIPLIER = 1.3;
|
|
76
82
|
|
|
77
83
|
// Constant for percent width
|
|
78
|
-
const PERCENT_WIDTH =
|
|
84
|
+
const PERCENT_WIDTH = 2.7;
|
|
79
85
|
|
|
80
86
|
// Constant for item width
|
|
81
87
|
const ITEM_WIDTH = 2;
|
|
@@ -88,11 +94,9 @@ const ITEM_WIDTH = 2;
|
|
|
88
94
|
let style = `
|
|
89
95
|
.ProgressBar-number-of,
|
|
90
96
|
.ProgressBar-percent {
|
|
91
|
-
flex: 0 0 auto;
|
|
92
97
|
white-space: nowrap;
|
|
93
|
-
padding-right: 0.
|
|
94
|
-
|
|
95
|
-
text-align: right;
|
|
98
|
+
padding-right: 0.3em;
|
|
99
|
+
text-align: left;
|
|
96
100
|
transition: width .25s ease;
|
|
97
101
|
}
|
|
98
102
|
|
|
@@ -164,10 +168,20 @@ const ProgressBar: React.FC<Props> = (props) => {
|
|
|
164
168
|
/* ---------------- Sizes --------------- */
|
|
165
169
|
/*----------------------------------------*/
|
|
166
170
|
|
|
171
|
+
// Add dynamic general style
|
|
172
|
+
style += `
|
|
173
|
+
.ProgressBar-percent {
|
|
174
|
+
min-width: ${(status.usePercent ? status.numDecimalPlaces ?? 0 : 0) + PERCENT_WIDTH}em;
|
|
175
|
+
}
|
|
176
|
+
.ProgressBar-number-of {
|
|
177
|
+
min-width: ${((!status.usePercent ? String(status.total ?? 0).length || 1 : 0) * ITEM_WIDTH_MULTIPLIER) + ITEM_WIDTH}em;
|
|
178
|
+
}
|
|
179
|
+
`;
|
|
180
|
+
|
|
167
181
|
// Size styles
|
|
168
182
|
switch (size) {
|
|
169
|
-
case ProgressBarSize.
|
|
170
|
-
//
|
|
183
|
+
case ProgressBarSize.Medium:
|
|
184
|
+
// Medium size
|
|
171
185
|
style += `
|
|
172
186
|
.ProgressBar-container .ProgressBar-number-of, .ProgressBar-container .ProgressBar-percent {
|
|
173
187
|
font-size: 1em;
|
|
@@ -180,18 +194,10 @@ const ProgressBar: React.FC<Props> = (props) => {
|
|
|
180
194
|
height: 1.5em;
|
|
181
195
|
border-radius: 0.5em;
|
|
182
196
|
}
|
|
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
197
|
`;
|
|
192
198
|
break;
|
|
193
|
-
case ProgressBarSize.
|
|
194
|
-
//
|
|
199
|
+
case ProgressBarSize.Large:
|
|
200
|
+
// Large size
|
|
195
201
|
style += `
|
|
196
202
|
.ProgressBar-container .ProgressBar-number-of, .ProgressBar-container .ProgressBar-percent {
|
|
197
203
|
font-size: 1.5em;
|
|
@@ -204,38 +210,6 @@ const ProgressBar: React.FC<Props> = (props) => {
|
|
|
204
210
|
height: 2em;
|
|
205
211
|
border-radius: 0.7em;
|
|
206
212
|
}
|
|
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
213
|
`;
|
|
240
214
|
break;
|
|
241
215
|
default:
|
|
@@ -245,9 +219,8 @@ const ProgressBar: React.FC<Props> = (props) => {
|
|
|
245
219
|
// Get the width of the outline based on size
|
|
246
220
|
const outlineWidth = (() => {
|
|
247
221
|
switch (size) {
|
|
248
|
-
case ProgressBarSize.
|
|
249
|
-
case ProgressBarSize.
|
|
250
|
-
case ProgressBarSize.Large: return '0.1em';
|
|
222
|
+
case ProgressBarSize.Medium: return '0.05em';
|
|
223
|
+
case ProgressBarSize.Large: return '0.08em';
|
|
251
224
|
default: return '0.05em';
|
|
252
225
|
}
|
|
253
226
|
})();
|
|
@@ -275,25 +248,38 @@ const ProgressBar: React.FC<Props> = (props) => {
|
|
|
275
248
|
`;
|
|
276
249
|
|
|
277
250
|
// Stripes for striped effect
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
<div
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
251
|
+
let stripes: React.ReactNode = null;
|
|
252
|
+
if (striped) {
|
|
253
|
+
stripes = (
|
|
254
|
+
<div>
|
|
255
|
+
<style>{stripesStyle}</style>
|
|
256
|
+
<div
|
|
257
|
+
className="ProgressBar-stripes position-absolute"
|
|
258
|
+
style={{
|
|
259
|
+
width: '200%',
|
|
260
|
+
height: '100%',
|
|
261
|
+
}}
|
|
262
|
+
>
|
|
263
|
+
|
|
264
|
+
</div>
|
|
289
265
|
</div>
|
|
290
|
-
|
|
291
|
-
|
|
266
|
+
);
|
|
267
|
+
}
|
|
292
268
|
|
|
293
269
|
/*----------------------------------------*/
|
|
294
270
|
/* --------------- Main UI -------------- */
|
|
295
271
|
/*----------------------------------------*/
|
|
296
272
|
|
|
273
|
+
// Calculate the width of the progress bar
|
|
274
|
+
let progressBarWidthPercent = 0;
|
|
275
|
+
if (status.usePercent) {
|
|
276
|
+
// Use percent progress directly
|
|
277
|
+
progressBarWidthPercent = status.percentProgress;
|
|
278
|
+
} else if (status.total > 0) {
|
|
279
|
+
// Calculate percent progress from items
|
|
280
|
+
progressBarWidthPercent = (status.numComplete / status.total) * 100;
|
|
281
|
+
}
|
|
282
|
+
|
|
297
283
|
// Render the progress bar
|
|
298
284
|
return (
|
|
299
285
|
<div className="ProgressBar-container d-flex align-items-center">
|
|
@@ -301,25 +287,27 @@ const ProgressBar: React.FC<Props> = (props) => {
|
|
|
301
287
|
<style>{style}</style>
|
|
302
288
|
{/* Use items */}
|
|
303
289
|
{!status.usePercent && status.numComplete && (
|
|
304
|
-
<span
|
|
305
|
-
className="ProgressBar-number-of pe-2 align-self-center"
|
|
306
|
-
>
|
|
290
|
+
<span className="ProgressBar-number-of">
|
|
307
291
|
{status.numComplete}
|
|
308
292
|
of
|
|
309
293
|
{status.total}
|
|
310
294
|
</span>
|
|
311
295
|
)}
|
|
312
296
|
{/* Use percentage */}
|
|
313
|
-
{status.usePercent &&
|
|
314
|
-
<span
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
297
|
+
{status.usePercent && (
|
|
298
|
+
<span className="ProgressBar-percent">
|
|
299
|
+
{
|
|
300
|
+
padDecimalZeros(
|
|
301
|
+
roundToNumDecimals(status.percentProgress ?? 0, status?.numDecimalPlaces ?? 0),
|
|
302
|
+
status?.numDecimalPlaces ?? 0,
|
|
303
|
+
)
|
|
304
|
+
}
|
|
318
305
|
%
|
|
319
306
|
</span>
|
|
320
307
|
)}
|
|
308
|
+
{/* Progress Bar Filled Area */}
|
|
321
309
|
<div
|
|
322
|
-
className={`ProgressBar-background bg-${bgVariant}
|
|
310
|
+
className={`ProgressBar-background bg-${bgVariant} flex-grow-1`}
|
|
323
311
|
style={{
|
|
324
312
|
boxShadow: `0 0 0 ${outlineWidth} ${showOutline ? '#000' : '#DEE2E6'}`,
|
|
325
313
|
}}
|
|
@@ -332,11 +320,13 @@ const ProgressBar: React.FC<Props> = (props) => {
|
|
|
332
320
|
`ProgressBar-bar bg-${variant} text-start position-relative`
|
|
333
321
|
}
|
|
334
322
|
style={{
|
|
335
|
-
width: `${
|
|
323
|
+
width: `${progressBarWidthPercent}%`,
|
|
336
324
|
overflow: 'hidden',
|
|
337
325
|
}}
|
|
338
326
|
>
|
|
339
|
-
{
|
|
327
|
+
{/* Show Strips (if they exist) */}
|
|
328
|
+
{stripes}
|
|
329
|
+
{/* Space so the bar has some content */}
|
|
340
330
|
|
|
341
331
|
</div>
|
|
342
332
|
</div>
|
package/src/index.ts
CHANGED
|
@@ -103,6 +103,7 @@ import AutoscrollToBottomContainer from './components/AutoscrollToBottomContaine
|
|
|
103
103
|
import MultiSwitch from './components/MultiSwitch';
|
|
104
104
|
import Dropdown from './components/Dropdown';
|
|
105
105
|
import ProgressBar from './components/ProgressBar';
|
|
106
|
+
import FakeProgressBar from './components/FakeProgressBar';
|
|
106
107
|
|
|
107
108
|
// Import dynamic constants
|
|
108
109
|
import DynamicWord from './dynamicConstants/DynamicWord';
|
|
@@ -163,6 +164,7 @@ export {
|
|
|
163
164
|
MultiSwitch,
|
|
164
165
|
Dropdown,
|
|
165
166
|
ProgressBar,
|
|
167
|
+
FakeProgressBar,
|
|
166
168
|
// Global functions
|
|
167
169
|
alert,
|
|
168
170
|
prompt,
|