dce-reactkit 4.2.4-beta.heat-seek.1 → 4.2.6
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 +259 -115
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/types/components/ProgressBar.d.ts +22 -0
- package/dist/cjs/types/helpers/getTimestampFromTimeInfoInET.d.ts +1 -1
- package/dist/cjs/types/index.d.ts +2 -1
- package/dist/cjs/types/types/ProgressBarSize.d.ts +10 -0
- package/dist/esm/index.js +259 -116
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/types/components/ProgressBar.d.ts +22 -0
- package/dist/esm/types/helpers/getTimestampFromTimeInfoInET.d.ts +1 -1
- package/dist/esm/types/index.d.ts +2 -1
- package/dist/esm/types/types/ProgressBarSize.d.ts +10 -0
- package/dist/index.d.ts +78 -48
- package/package.json +1 -1
- package/src/components/ProgressBar.tsx +347 -0
- package/src/helpers/getTimestampFromTimeInfoInET.ts +17 -119
- package/src/index.ts +2 -0
- package/src/types/ProgressBarSize.ts +11 -0
|
@@ -0,0 +1,347 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Customizable Progress Bar component using Bootstrap styles
|
|
3
|
+
* @author Allison Zhang
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// Import React
|
|
7
|
+
import React from 'react';
|
|
8
|
+
|
|
9
|
+
// Import types
|
|
10
|
+
import Variant from '../types/Variant';
|
|
11
|
+
import ProgressBarSize from '../types/ProgressBarSize';
|
|
12
|
+
|
|
13
|
+
/*------------------------------------------------------------------------*/
|
|
14
|
+
/* -------------------------------- Types ------------------------------- */
|
|
15
|
+
/*------------------------------------------------------------------------*/
|
|
16
|
+
|
|
17
|
+
// Props definition
|
|
18
|
+
type Props = (
|
|
19
|
+
& (
|
|
20
|
+
// Percent
|
|
21
|
+
| {
|
|
22
|
+
// Percentage progress (0-100)
|
|
23
|
+
percentProgress: number,
|
|
24
|
+
// Num decimal places to show (default 0)
|
|
25
|
+
numDecimalPlaces?: number,
|
|
26
|
+
}
|
|
27
|
+
// Items
|
|
28
|
+
| {
|
|
29
|
+
// Current progress (number of items completed)
|
|
30
|
+
numComplete: number,
|
|
31
|
+
// Maximum progress (total number of items)
|
|
32
|
+
total: number,
|
|
33
|
+
}
|
|
34
|
+
)
|
|
35
|
+
& {
|
|
36
|
+
// Whether to show striped effect (default false)
|
|
37
|
+
striped?: boolean,
|
|
38
|
+
// Variant of the progress bar (default warning)
|
|
39
|
+
variant?: Variant,
|
|
40
|
+
// Background variants (default secondary subtle)
|
|
41
|
+
bgVariant?: Variant,
|
|
42
|
+
// Hide outline (default false)
|
|
43
|
+
showOutline?: boolean,
|
|
44
|
+
// Size of the progress bar (default md)
|
|
45
|
+
size?: ProgressBarSize,
|
|
46
|
+
}
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
// Progress status definition
|
|
50
|
+
type ProgressStatus = (
|
|
51
|
+
| {
|
|
52
|
+
// usePercent true
|
|
53
|
+
usePercent: true,
|
|
54
|
+
// Percentage progress (0-100)
|
|
55
|
+
percentProgress: number,
|
|
56
|
+
// Num decimal places to show (default 0)
|
|
57
|
+
numDecimalPlaces?: number,
|
|
58
|
+
}
|
|
59
|
+
// Items
|
|
60
|
+
| {
|
|
61
|
+
// usePercent false
|
|
62
|
+
usePercent: false,
|
|
63
|
+
// Current progress (number of items completed)
|
|
64
|
+
numComplete: number,
|
|
65
|
+
// Maximum progress (total number of items)
|
|
66
|
+
total: number,
|
|
67
|
+
}
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
/*------------------------------------------------------------------------*/
|
|
71
|
+
/* ------------------------------ Constants ----------------------------- */
|
|
72
|
+
/*------------------------------------------------------------------------*/
|
|
73
|
+
|
|
74
|
+
// Multiplier for calculating width of number of items
|
|
75
|
+
const ITEM_WIDTH_MULTIPLIER = 1.3;
|
|
76
|
+
|
|
77
|
+
// Constant for percent width
|
|
78
|
+
const PERCENT_WIDTH = 3;
|
|
79
|
+
|
|
80
|
+
// Constant for item width
|
|
81
|
+
const ITEM_WIDTH = 2;
|
|
82
|
+
|
|
83
|
+
/*------------------------------------------------------------------------*/
|
|
84
|
+
/* -------------------------------- Style ------------------------------- */
|
|
85
|
+
/*------------------------------------------------------------------------*/
|
|
86
|
+
|
|
87
|
+
// Base styles
|
|
88
|
+
let style = `
|
|
89
|
+
.ProgressBar-number-of,
|
|
90
|
+
.ProgressBar-percent {
|
|
91
|
+
flex: 0 0 auto;
|
|
92
|
+
white-space: nowrap;
|
|
93
|
+
padding-right: 0.5em;
|
|
94
|
+
padding-left: 0.25em;
|
|
95
|
+
text-align: right;
|
|
96
|
+
transition: width .25s ease;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.ProgressBar-background {
|
|
100
|
+
overflow: hidden;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.ProgressBar-bar {
|
|
104
|
+
transition: width 1s ease;
|
|
105
|
+
overflow: hidden;
|
|
106
|
+
}
|
|
107
|
+
`;
|
|
108
|
+
|
|
109
|
+
/*------------------------------------------------------------------------*/
|
|
110
|
+
/* ------------------------------ Component ----------------------------- */
|
|
111
|
+
/*------------------------------------------------------------------------*/
|
|
112
|
+
|
|
113
|
+
const ProgressBar: React.FC<Props> = (props) => {
|
|
114
|
+
/*------------------------------------------------------------------------*/
|
|
115
|
+
/* -------------------------------- Setup ------------------------------- */
|
|
116
|
+
/*------------------------------------------------------------------------*/
|
|
117
|
+
|
|
118
|
+
/* -------------- Props ------------- */
|
|
119
|
+
|
|
120
|
+
// Destructure props
|
|
121
|
+
const {
|
|
122
|
+
striped,
|
|
123
|
+
variant = Variant.Warning,
|
|
124
|
+
bgVariant = Variant.Secondary,
|
|
125
|
+
showOutline,
|
|
126
|
+
size = ProgressBarSize.Medium,
|
|
127
|
+
} = props;
|
|
128
|
+
|
|
129
|
+
/* -------------- Status ------------- */
|
|
130
|
+
|
|
131
|
+
// Determine progress status
|
|
132
|
+
let status: ProgressStatus;
|
|
133
|
+
|
|
134
|
+
// Check whether to use percent or items
|
|
135
|
+
if ('percentProgress' in props) {
|
|
136
|
+
// Percent
|
|
137
|
+
const {
|
|
138
|
+
percentProgress,
|
|
139
|
+
numDecimalPlaces,
|
|
140
|
+
} = props;
|
|
141
|
+
status = {
|
|
142
|
+
usePercent: true,
|
|
143
|
+
percentProgress,
|
|
144
|
+
numDecimalPlaces,
|
|
145
|
+
};
|
|
146
|
+
} else {
|
|
147
|
+
// Items
|
|
148
|
+
const {
|
|
149
|
+
numComplete,
|
|
150
|
+
total,
|
|
151
|
+
} = props;
|
|
152
|
+
status = {
|
|
153
|
+
usePercent: false,
|
|
154
|
+
numComplete,
|
|
155
|
+
total,
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/*------------------------------------------------------------------------*/
|
|
160
|
+
/* ------------------------------- Render ------------------------------- */
|
|
161
|
+
/*------------------------------------------------------------------------*/
|
|
162
|
+
|
|
163
|
+
/*----------------------------------------*/
|
|
164
|
+
/* ---------------- Sizes --------------- */
|
|
165
|
+
/*----------------------------------------*/
|
|
166
|
+
|
|
167
|
+
// Size styles
|
|
168
|
+
switch (size) {
|
|
169
|
+
case ProgressBarSize.Small:
|
|
170
|
+
// Small size
|
|
171
|
+
style += `
|
|
172
|
+
.ProgressBar-container .ProgressBar-number-of, .ProgressBar-container .ProgressBar-percent {
|
|
173
|
+
font-size: 1em;
|
|
174
|
+
}
|
|
175
|
+
.ProgressBar-container .ProgressBar-background {
|
|
176
|
+
height: 1.5em;
|
|
177
|
+
border-radius: 0.5em;
|
|
178
|
+
}
|
|
179
|
+
.ProgressBar-container .ProgressBar-bar {
|
|
180
|
+
height: 1.5em;
|
|
181
|
+
border-radius: 0.5em;
|
|
182
|
+
}
|
|
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
|
+
`;
|
|
192
|
+
break;
|
|
193
|
+
case ProgressBarSize.Medium:
|
|
194
|
+
// Medium size
|
|
195
|
+
style += `
|
|
196
|
+
.ProgressBar-container .ProgressBar-number-of, .ProgressBar-container .ProgressBar-percent {
|
|
197
|
+
font-size: 1.5em;
|
|
198
|
+
}
|
|
199
|
+
.ProgressBar-container .ProgressBar-background {
|
|
200
|
+
height: 2em;
|
|
201
|
+
border-radius: 0.7em;
|
|
202
|
+
}
|
|
203
|
+
.ProgressBar-container .ProgressBar-bar {
|
|
204
|
+
height: 2em;
|
|
205
|
+
border-radius: 0.7em;
|
|
206
|
+
}
|
|
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
|
+
`;
|
|
240
|
+
break;
|
|
241
|
+
default:
|
|
242
|
+
break;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// Get the width of the outline based on size
|
|
246
|
+
const outlineWidth = (() => {
|
|
247
|
+
switch (size) {
|
|
248
|
+
case ProgressBarSize.Small: return '0.05em';
|
|
249
|
+
case ProgressBarSize.Medium: return '0.08em';
|
|
250
|
+
case ProgressBarSize.Large: return '0.1em';
|
|
251
|
+
default: return '0.05em';
|
|
252
|
+
}
|
|
253
|
+
})();
|
|
254
|
+
|
|
255
|
+
/*----------------------------------------*/
|
|
256
|
+
/* --------------- Stripes -------------- */
|
|
257
|
+
/*----------------------------------------*/
|
|
258
|
+
|
|
259
|
+
// Stripes style
|
|
260
|
+
const stripesStyle = `
|
|
261
|
+
.ProgressBar-stripes {
|
|
262
|
+
background-image: linear-gradient(315deg, #ffffff 25%, #000000 25%, #000000 50%, #ffffff 50%, #ffffff 75%, #000000 75%, #000000 100%);
|
|
263
|
+
background-size: 6em 6em;
|
|
264
|
+
animation: ProgressBar-stripe-animation 2.5s linear infinite;
|
|
265
|
+
opacity: 0.09;
|
|
266
|
+
}
|
|
267
|
+
@keyframes ProgressBar-stripe-animation {
|
|
268
|
+
0% {
|
|
269
|
+
background-position: -6em 0;
|
|
270
|
+
}
|
|
271
|
+
100% {
|
|
272
|
+
background-position: 0 0;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
`;
|
|
276
|
+
|
|
277
|
+
// 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
|
+
|
|
289
|
+
</div>
|
|
290
|
+
</div>
|
|
291
|
+
);
|
|
292
|
+
|
|
293
|
+
/*----------------------------------------*/
|
|
294
|
+
/* --------------- Main UI -------------- */
|
|
295
|
+
/*----------------------------------------*/
|
|
296
|
+
|
|
297
|
+
// Render the progress bar
|
|
298
|
+
return (
|
|
299
|
+
<div className="ProgressBar-container d-flex align-items-center">
|
|
300
|
+
{/* Style */}
|
|
301
|
+
<style>{style}</style>
|
|
302
|
+
{/* Use items */}
|
|
303
|
+
{!status.usePercent && status.numComplete && (
|
|
304
|
+
<span
|
|
305
|
+
className="ProgressBar-number-of pe-2 align-self-center"
|
|
306
|
+
>
|
|
307
|
+
{status.numComplete}
|
|
308
|
+
of
|
|
309
|
+
{status.total}
|
|
310
|
+
</span>
|
|
311
|
+
)}
|
|
312
|
+
{/* Use percentage */}
|
|
313
|
+
{status.usePercent && status.percentProgress && (
|
|
314
|
+
<span
|
|
315
|
+
className="ProgressBar-percent pe-2 align-self-center"
|
|
316
|
+
>
|
|
317
|
+
{status.percentProgress.toFixed(status?.numDecimalPlaces ?? 0)}
|
|
318
|
+
%
|
|
319
|
+
</span>
|
|
320
|
+
)}
|
|
321
|
+
<div
|
|
322
|
+
className={`ProgressBar-background bg-${bgVariant} w-100`}
|
|
323
|
+
style={{
|
|
324
|
+
boxShadow: `0 0 0 ${outlineWidth} ${showOutline ? '#000' : '#DEE2E6'}`,
|
|
325
|
+
}}
|
|
326
|
+
aria-valuenow={status.usePercent ? status.percentProgress : status.numComplete}
|
|
327
|
+
aria-valuemin={0}
|
|
328
|
+
aria-valuemax={status.usePercent ? 100 : status.total}
|
|
329
|
+
>
|
|
330
|
+
<div
|
|
331
|
+
className={
|
|
332
|
+
`ProgressBar-bar bg-${variant} text-start position-relative`
|
|
333
|
+
}
|
|
334
|
+
style={{
|
|
335
|
+
width: `${(status.usePercent ? status.percentProgress : (status.numComplete / status.total) * 100)}%`,
|
|
336
|
+
overflow: 'hidden',
|
|
337
|
+
}}
|
|
338
|
+
>
|
|
339
|
+
{striped && stripes}
|
|
340
|
+
|
|
341
|
+
</div>
|
|
342
|
+
</div>
|
|
343
|
+
</div>
|
|
344
|
+
);
|
|
345
|
+
};
|
|
346
|
+
|
|
347
|
+
export default ProgressBar;
|
|
@@ -6,78 +6,6 @@ import ReactKitErrorCode from '../types/ReactKitErrorCode';
|
|
|
6
6
|
import getTimeInfoInET from './getTimeInfoInET';
|
|
7
7
|
import padZerosLeft from './padZerosLeft';
|
|
8
8
|
|
|
9
|
-
/*----------------------------------------*/
|
|
10
|
-
/* --------------- Helpers -------------- */
|
|
11
|
-
/*----------------------------------------*/
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Check if a timestamp is valid
|
|
15
|
-
* @param opts object containing all arguments
|
|
16
|
-
* @param opts.timestamp Timestamp in milliseconds since epoch
|
|
17
|
-
* @param opts.expectedYear Expected year
|
|
18
|
-
* @param opts.expectedMonth Expected month
|
|
19
|
-
* @param opts.expectedDay Expected day
|
|
20
|
-
* @param opts.expectedHour Expected hour
|
|
21
|
-
* @param opts.expectedMinute Expected minute
|
|
22
|
-
* @returns 1 if the timestamp needs to be increased, -1 if it needs to be decreased, 0 if it is valid
|
|
23
|
-
*/
|
|
24
|
-
const checkTimestamp = (
|
|
25
|
-
opts: {
|
|
26
|
-
timestamp: number,
|
|
27
|
-
expectedYear: number,
|
|
28
|
-
expectedMonth: number,
|
|
29
|
-
expectedDay: number,
|
|
30
|
-
expectedHour: number,
|
|
31
|
-
expectedMinute: number,
|
|
32
|
-
},
|
|
33
|
-
): number => {
|
|
34
|
-
const {
|
|
35
|
-
timestamp,
|
|
36
|
-
expectedYear,
|
|
37
|
-
expectedMonth,
|
|
38
|
-
expectedDay,
|
|
39
|
-
expectedHour,
|
|
40
|
-
expectedMinute,
|
|
41
|
-
} = opts;
|
|
42
|
-
|
|
43
|
-
const timeInfoInET = getTimeInfoInET(timestamp);
|
|
44
|
-
if (timeInfoInET.year < expectedYear) {
|
|
45
|
-
return 1;
|
|
46
|
-
}
|
|
47
|
-
if (timeInfoInET.year > expectedYear) {
|
|
48
|
-
return -1;
|
|
49
|
-
}
|
|
50
|
-
if (timeInfoInET.month < expectedMonth) {
|
|
51
|
-
return 1;
|
|
52
|
-
}
|
|
53
|
-
if (timeInfoInET.month > expectedMonth) {
|
|
54
|
-
return -1;
|
|
55
|
-
}
|
|
56
|
-
if (timeInfoInET.day < expectedDay) {
|
|
57
|
-
return 1;
|
|
58
|
-
}
|
|
59
|
-
if (timeInfoInET.day > expectedDay) {
|
|
60
|
-
return -1;
|
|
61
|
-
}
|
|
62
|
-
if (timeInfoInET.hour < expectedHour) {
|
|
63
|
-
return 1;
|
|
64
|
-
}
|
|
65
|
-
if (timeInfoInET.hour > expectedHour) {
|
|
66
|
-
return -1;
|
|
67
|
-
}
|
|
68
|
-
if (timeInfoInET.minute < expectedMinute) {
|
|
69
|
-
return 1;
|
|
70
|
-
}
|
|
71
|
-
if (timeInfoInET.minute > expectedMinute) {
|
|
72
|
-
return -1;
|
|
73
|
-
}
|
|
74
|
-
return 0;
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
/*----------------------------------------*/
|
|
78
|
-
/* ---------------- Main ---------------- */
|
|
79
|
-
/*----------------------------------------*/
|
|
80
|
-
|
|
81
9
|
/**
|
|
82
10
|
* Get a timestamp (ms since epoch) from time info (year, month, day, hour, minute, etc.) in Eastern Time (ET)
|
|
83
11
|
* @author Gardenia Liu
|
|
@@ -87,7 +15,7 @@ const checkTimestamp = (
|
|
|
87
15
|
* @param opts.month Month (1-12)
|
|
88
16
|
* @param opts.day Day of the month (1-31)
|
|
89
17
|
* @param opts.hour Hour (0-23)
|
|
90
|
-
* @param opts.minute Minute (0-59)
|
|
18
|
+
* @param opts.minute Minute (0-59))
|
|
91
19
|
* @returns Timestamp in milliseconds since epoch
|
|
92
20
|
*/
|
|
93
21
|
const getTimestampFromTimeInfoInET = (
|
|
@@ -122,55 +50,25 @@ const getTimestampFromTimeInfoInET = (
|
|
|
122
50
|
|
|
123
51
|
// Build ET ISO string and convert to UTC timestamp
|
|
124
52
|
const etISOString = `${year}-${mm}-${dd}T${hh}:${min}:00${etOffset}`;
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
// Heat seek to get the right timestamp
|
|
128
|
-
const maxOffset = 24 * 60; // 24 hours in minutes
|
|
129
|
-
let currentOffset = 0; // minutes
|
|
130
|
-
const offsetIncrement = 15; // minutes
|
|
131
|
-
const offsetDirection = checkTimestamp({
|
|
132
|
-
timestamp,
|
|
133
|
-
expectedYear: year,
|
|
134
|
-
expectedMonth: month,
|
|
135
|
-
expectedDay: day,
|
|
136
|
-
expectedHour: hour,
|
|
137
|
-
expectedMinute: minute,
|
|
138
|
-
});
|
|
139
|
-
if (offsetDirection === 0) {
|
|
140
|
-
// Valid! Return the timestamp
|
|
141
|
-
return timestamp;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
// Heat seek
|
|
145
|
-
while (Math.abs(currentOffset) < maxOffset) {
|
|
146
|
-
// Update offset
|
|
147
|
-
currentOffset += (offsetDirection * offsetIncrement);
|
|
53
|
+
const timestamp = (new Date(etISOString)).getTime();
|
|
148
54
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
if (newDirection === 0) {
|
|
163
|
-
// Valid! Return the timestamp
|
|
164
|
-
return timestamp;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
// Invalid. Keep looping.
|
|
55
|
+
// Verify that the timestamp is correct
|
|
56
|
+
const timeInfoInET = getTimeInfoInET(timestamp);
|
|
57
|
+
if (
|
|
58
|
+
timeInfoInET.year !== year
|
|
59
|
+
|| timeInfoInET.month !== month
|
|
60
|
+
|| timeInfoInET.day !== day
|
|
61
|
+
|| timeInfoInET.hour !== hour
|
|
62
|
+
|| timeInfoInET.minute !== minute
|
|
63
|
+
) {
|
|
64
|
+
throw new ErrorWithCode(
|
|
65
|
+
`Timestamp mismatch: expected ${year}-${mm}-${dd} ${hh}:${min}, got ${timeInfoInET.year}-${padZerosLeft(timeInfoInET.month, 2)}-${padZerosLeft(timeInfoInET.day, 2)} ${padZerosLeft(timeInfoInET.hour, 2)}:${padZerosLeft(timeInfoInET.minute, 2)}`,
|
|
66
|
+
ReactKitErrorCode.ETTimestampInvalid,
|
|
67
|
+
);
|
|
168
68
|
}
|
|
169
69
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
ReactKitErrorCode.ETTimestampInvalid,
|
|
173
|
-
);
|
|
70
|
+
// Valid! Return the timestamp
|
|
71
|
+
return timestamp;
|
|
174
72
|
};
|
|
175
73
|
|
|
176
74
|
export default getTimestampFromTimeInfoInET;
|
package/src/index.ts
CHANGED
|
@@ -31,6 +31,7 @@ import ToggleSwitch from './components/ToggleSwitch';
|
|
|
31
31
|
import AutoscrollToBottomContainer from './components/AutoscrollToBottomContainer';
|
|
32
32
|
import MultiSwitch from './components/MultiSwitch';
|
|
33
33
|
import Dropdown from './components/Dropdown';
|
|
34
|
+
import ProgressBar from './components/ProgressBar';
|
|
34
35
|
|
|
35
36
|
// Import errors
|
|
36
37
|
import ErrorWithCode from './errors/ErrorWithCode';
|
|
@@ -156,6 +157,7 @@ export {
|
|
|
156
157
|
AutoscrollToBottomContainer,
|
|
157
158
|
MultiSwitch,
|
|
158
159
|
Dropdown,
|
|
160
|
+
ProgressBar,
|
|
159
161
|
// Global functions
|
|
160
162
|
alert,
|
|
161
163
|
prompt,
|