@wistia/ui 3.5.1-beta.53aa0f7d.0398e32 → 3.5.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/CHANGELOG.md +2618 -0
- package/dist/index.d.ts +316 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +712 -15
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
|
|
2
2
|
/*
|
|
3
|
-
* @license @wistia/ui v3.5.
|
|
3
|
+
* @license @wistia/ui v3.5.2
|
|
4
4
|
*
|
|
5
5
|
* Copyright (c) 2024-2026, Wistia, Inc. and its affiliates.
|
|
6
6
|
*
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
import { Tooltip as Tooltip$1 } from "@base-ui/react/tooltip";
|
|
11
11
|
import { Children, Fragment, cloneElement, createContext, forwardRef, isValidElement, useCallback, useContext, useEffect, useId, useImperativeHandle, useLayoutEffect, useMemo, useRef, useState, useSyncExternalStore, useTransition } from "react";
|
|
12
12
|
import { createGlobalStyle, css, keyframes, styled } from "styled-components";
|
|
13
|
-
import {
|
|
13
|
+
import { isArray, isBoolean, isDate, isEmptyString, isFunction, isNil, isNonEmptyArray, isNonEmptyString, isNotNil, isNotUndefined, isNumber, isRecord, isString, isUndefined, noOpFn } from "@wistia/utils";
|
|
14
14
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
15
15
|
import { Toaster, toast } from "sonner";
|
|
16
16
|
import { getValueAndUnit } from "polished";
|
|
@@ -127,6 +127,12 @@ const globalStyleAdjustmentsCss = css`
|
|
|
127
127
|
}
|
|
128
128
|
}
|
|
129
129
|
|
|
130
|
+
input,
|
|
131
|
+
textarea,
|
|
132
|
+
[contenteditable] {
|
|
133
|
+
text-wrap: wrap;
|
|
134
|
+
}
|
|
135
|
+
|
|
130
136
|
/* Remove default margin in favour of better control in authored CSS */
|
|
131
137
|
body,
|
|
132
138
|
h1,
|
|
@@ -365,6 +371,19 @@ const UIProvider = ({ children, id, gatedIcon = "sparkle" }) => {
|
|
|
365
371
|
});
|
|
366
372
|
};
|
|
367
373
|
//#endregion
|
|
374
|
+
//#region src/helpers/coerceToBoolean/coerceToBoolean.ts
|
|
375
|
+
/**
|
|
376
|
+
* Converts a boolean string value `value` into a boolean. If passed
|
|
377
|
+
* something other than 'true' or 'false' will coerce value to boolean.
|
|
378
|
+
*
|
|
379
|
+
* @param {*} value - a value of any type
|
|
380
|
+
* @returns {boolean} - that value as a boolean
|
|
381
|
+
*/
|
|
382
|
+
const coerceToBoolean = (value) => {
|
|
383
|
+
if (value === "true" || value === "false") return value === "true";
|
|
384
|
+
return Boolean(value);
|
|
385
|
+
};
|
|
386
|
+
//#endregion
|
|
368
387
|
//#region src/helpers/copyToClipboard/copyToClipboard.ts
|
|
369
388
|
/**
|
|
370
389
|
* Copies a string to user's clipboard for easy pasting in another location
|
|
@@ -380,6 +399,673 @@ const copyToClipboard = async (textToCopy) => {
|
|
|
380
399
|
});
|
|
381
400
|
};
|
|
382
401
|
//#endregion
|
|
402
|
+
//#region src/helpers/dateTime/constants.ts
|
|
403
|
+
const defaultLocales = ["en-US"];
|
|
404
|
+
const defaultTimeZone = Intl.DateTimeFormat().resolvedOptions().timeZone || "UTC";
|
|
405
|
+
const milisecondsInSecond = 1e3;
|
|
406
|
+
const millisecondsInDay = 86400 * milisecondsInSecond;
|
|
407
|
+
//#endregion
|
|
408
|
+
//#region src/helpers/dateTime/buildTimeDuration.ts
|
|
409
|
+
/**
|
|
410
|
+
* Returns an object representing the duration in seconds, minutes and hours.
|
|
411
|
+
*
|
|
412
|
+
* @param {number} numberOfMilliseconds - number of milliseconds
|
|
413
|
+
* @returns {TimeDuration} -
|
|
414
|
+
*/
|
|
415
|
+
const buildTimeDuration = (numberOfMilliseconds) => {
|
|
416
|
+
const numberOfSeconds = Math.floor(numberOfMilliseconds / milisecondsInSecond);
|
|
417
|
+
const numberOfMinutes = Math.floor(numberOfSeconds / 60);
|
|
418
|
+
const numberOfHours = Math.floor(numberOfMinutes / 60);
|
|
419
|
+
return {
|
|
420
|
+
seconds: numberOfSeconds - numberOfMinutes * 60,
|
|
421
|
+
minutes: numberOfMinutes - numberOfHours * 60,
|
|
422
|
+
hours: numberOfHours
|
|
423
|
+
};
|
|
424
|
+
};
|
|
425
|
+
//#endregion
|
|
426
|
+
//#region src/helpers/dateTime/isInvalidDate.ts
|
|
427
|
+
/**
|
|
428
|
+
* @param {*} date - a Date object - could be unknown though
|
|
429
|
+
* @returns {boolean} - whether it's a valid date
|
|
430
|
+
*/
|
|
431
|
+
const isInvalidDate = (date) => {
|
|
432
|
+
if (!isDate(date)) return true;
|
|
433
|
+
const time = date.getTime();
|
|
434
|
+
return time === 0 || Number.isNaN(time);
|
|
435
|
+
};
|
|
436
|
+
//#endregion
|
|
437
|
+
//#region src/helpers/dateTime/dateOnlyISOString.ts
|
|
438
|
+
/**
|
|
439
|
+
* Converts a Date object into a date only string formatted to ISO8601.
|
|
440
|
+
*
|
|
441
|
+
* e.g. 2021-06-03
|
|
442
|
+
* @param {*} date a Date object you want to convert into a string - gracefully handles any input
|
|
443
|
+
* @param {object} options -
|
|
444
|
+
* @param {string} options.timeZone - the timezone you want date displayed in, defaults to current users time zone
|
|
445
|
+
* @returns {string} a formatted date string
|
|
446
|
+
*/
|
|
447
|
+
const dateOnlyISOString = (date, { timeZone = defaultTimeZone } = {}) => {
|
|
448
|
+
if (!isDate(date) || isInvalidDate(date)) return "";
|
|
449
|
+
try {
|
|
450
|
+
const partsAsObject = new Intl.DateTimeFormat(defaultLocales, {
|
|
451
|
+
year: "numeric",
|
|
452
|
+
month: "2-digit",
|
|
453
|
+
day: "2-digit",
|
|
454
|
+
timeZone
|
|
455
|
+
}).formatToParts(date).reduce((map, obj) => {
|
|
456
|
+
map[obj.type] = obj.value;
|
|
457
|
+
return map;
|
|
458
|
+
}, {});
|
|
459
|
+
return `${partsAsObject.year}-${partsAsObject.month}-${partsAsObject.day}`;
|
|
460
|
+
} catch (error) {
|
|
461
|
+
console.error(error);
|
|
462
|
+
return "";
|
|
463
|
+
}
|
|
464
|
+
};
|
|
465
|
+
//#endregion
|
|
466
|
+
//#region src/helpers/dateTime/dateOnlyString.ts
|
|
467
|
+
/**
|
|
468
|
+
* Converts a Date object into a date only string.
|
|
469
|
+
*
|
|
470
|
+
* e.g. Jun 3, 2021 or Jun 3 if `omitYear` is true.
|
|
471
|
+
*
|
|
472
|
+
* @param {*} date a Date object you want to convert into a string - gracefully handles any input
|
|
473
|
+
* @param {object} options -
|
|
474
|
+
* @param {string} options.timeZone - the timezone you want date displayed in, defaults to current user's time zone
|
|
475
|
+
* @param {boolean} options.omitYear - if true, display the date without the year
|
|
476
|
+
* @returns {string} a formatted date string
|
|
477
|
+
*/
|
|
478
|
+
const dateOnlyString = (date, { timeZone = defaultTimeZone, omitYear = false } = {}) => {
|
|
479
|
+
if (!isDate(date) || isInvalidDate(date)) return "";
|
|
480
|
+
const formatOptions = omitYear ? {
|
|
481
|
+
month: "short",
|
|
482
|
+
day: "numeric",
|
|
483
|
+
timeZone
|
|
484
|
+
} : {
|
|
485
|
+
dateStyle: "medium",
|
|
486
|
+
timeZone
|
|
487
|
+
};
|
|
488
|
+
try {
|
|
489
|
+
return new Intl.DateTimeFormat(defaultLocales, formatOptions).format(date);
|
|
490
|
+
} catch (error) {
|
|
491
|
+
console.error(error);
|
|
492
|
+
return "";
|
|
493
|
+
}
|
|
494
|
+
};
|
|
495
|
+
//#endregion
|
|
496
|
+
//#region src/helpers/dateTime/dateOnlyStringForSentence.ts
|
|
497
|
+
/**
|
|
498
|
+
* Converts a Date object into a date only string
|
|
499
|
+
* for use in a sentence.
|
|
500
|
+
*
|
|
501
|
+
* e.g. June 3, 2021
|
|
502
|
+
*
|
|
503
|
+
* @param {*} date - a Date object you want to convert into a string - gracefully handles any value
|
|
504
|
+
* @param {object} options -
|
|
505
|
+
* @param {string} options.timeZone - the timezone you want date displayed in, defaults to current users time zone
|
|
506
|
+
* @returns {string} a formatted date string
|
|
507
|
+
*/
|
|
508
|
+
const dateOnlyStringForSentence = (date, { timeZone = defaultTimeZone } = {}) => {
|
|
509
|
+
if (!isDate(date) || isInvalidDate(date)) return "";
|
|
510
|
+
try {
|
|
511
|
+
return new Intl.DateTimeFormat(defaultLocales, {
|
|
512
|
+
dateStyle: "long",
|
|
513
|
+
timeZone
|
|
514
|
+
}).format(date);
|
|
515
|
+
} catch (error) {
|
|
516
|
+
console.error(error);
|
|
517
|
+
return "";
|
|
518
|
+
}
|
|
519
|
+
};
|
|
520
|
+
//#endregion
|
|
521
|
+
//#region src/helpers/dateTime/dateOnlyStringNumeric.ts
|
|
522
|
+
/**
|
|
523
|
+
* Converts a Date object into a date only string formatted numerically.
|
|
524
|
+
*
|
|
525
|
+
* e.g. 06/03/2021
|
|
526
|
+
* @param {*} date a Date object you want to convert into a string - gracefully handles any input
|
|
527
|
+
* @param {object} options -
|
|
528
|
+
* @param {string} options.timeZone - the timezone you want date displayed in, defaults to current users time zone
|
|
529
|
+
* @returns {string} a formatted date string
|
|
530
|
+
*/
|
|
531
|
+
const dateOnlyStringNumeric = (date, { timeZone = defaultTimeZone } = {}) => {
|
|
532
|
+
if (!isDate(date) || isInvalidDate(date)) return "";
|
|
533
|
+
try {
|
|
534
|
+
return new Intl.DateTimeFormat(defaultLocales, {
|
|
535
|
+
year: "numeric",
|
|
536
|
+
month: "2-digit",
|
|
537
|
+
day: "2-digit",
|
|
538
|
+
timeZone
|
|
539
|
+
}).format(date);
|
|
540
|
+
} catch (error) {
|
|
541
|
+
console.error(error);
|
|
542
|
+
return "";
|
|
543
|
+
}
|
|
544
|
+
};
|
|
545
|
+
//#endregion
|
|
546
|
+
//#region src/helpers/dateTime/dateTimeToDate.ts
|
|
547
|
+
/**
|
|
548
|
+
* @param {Partial<WistiaDateTimeObject> | null} dateTime - a dateTime object
|
|
549
|
+
* @returns {Date | null} - the converted date or null if anything is missing
|
|
550
|
+
*/
|
|
551
|
+
const dateTimeToDate = (dateTime) => {
|
|
552
|
+
const { year, month, dayOfMonth, hours, minutes } = dateTime ?? {};
|
|
553
|
+
if (year !== void 0 && month !== void 0 && dayOfMonth !== void 0) return new Date(year, month, dayOfMonth, hours ?? 0, minutes ?? 0);
|
|
554
|
+
return null;
|
|
555
|
+
};
|
|
556
|
+
//#endregion
|
|
557
|
+
//#region src/helpers/dateTime/dateTimeToISO.ts
|
|
558
|
+
/**
|
|
559
|
+
* @param {Partial<WistiaDateTimeObject>} dateTime - a dateTime object
|
|
560
|
+
* @returns {string | null} - string with the ISO-8601 string or null
|
|
561
|
+
*/
|
|
562
|
+
const dateTimeToISO = (dateTime) => dateTimeToDate(dateTime)?.toISOString() ?? null;
|
|
563
|
+
//#endregion
|
|
564
|
+
//#region src/helpers/dateTime/dateToDateTime.ts
|
|
565
|
+
/**
|
|
566
|
+
* @typedef {Object} WistiaDateTimeObject
|
|
567
|
+
* @property {number} minutes - number of minutes
|
|
568
|
+
* @property {number} hours - number of hours
|
|
569
|
+
* @property {number} dayOfMonth - day of the month
|
|
570
|
+
* @property {number} year - year
|
|
571
|
+
* @property {number} month - month
|
|
572
|
+
*/
|
|
573
|
+
/**
|
|
574
|
+
* @param {Date | null | undefined} date - a Date object
|
|
575
|
+
* @returns {WistiaDateTimeObject | null} - replaceMe
|
|
576
|
+
*/
|
|
577
|
+
const dateToDateTime = (date) => {
|
|
578
|
+
if (!isDate(date)) return null;
|
|
579
|
+
return {
|
|
580
|
+
year: date.getFullYear(),
|
|
581
|
+
month: date.getMonth(),
|
|
582
|
+
dayOfMonth: date.getDate(),
|
|
583
|
+
hours: date.getHours(),
|
|
584
|
+
minutes: date.getMinutes()
|
|
585
|
+
};
|
|
586
|
+
};
|
|
587
|
+
//#endregion
|
|
588
|
+
//#region src/helpers/dateTime/dateTimeRounded.ts
|
|
589
|
+
/**
|
|
590
|
+
* @param {Date} dateTime - a dateTime object
|
|
591
|
+
* @param {boolean} toISOString - whether the return value should be an ISO string
|
|
592
|
+
* @returns {string | Date | null} - string or date depending on if toIsoString is true or false. Could be null if there's an error.
|
|
593
|
+
*/
|
|
594
|
+
const dateTimeRounded = (dateTime, toISOString = true) => {
|
|
595
|
+
const first30Min = dateTime.getMinutes() <= 30;
|
|
596
|
+
const hours = first30Min ? dateTime.getHours() : dateTime.getHours() + 1;
|
|
597
|
+
const minutes = first30Min ? 30 : 0;
|
|
598
|
+
const dateWithTime = {
|
|
599
|
+
...dateToDateTime(dateTime),
|
|
600
|
+
hours,
|
|
601
|
+
minutes
|
|
602
|
+
};
|
|
603
|
+
if (toISOString) return dateTimeToISO(dateWithTime);
|
|
604
|
+
return dateTimeToDate(dateWithTime);
|
|
605
|
+
};
|
|
606
|
+
//#endregion
|
|
607
|
+
//#region src/helpers/dateTime/dateTimeString.ts
|
|
608
|
+
/**
|
|
609
|
+
* Converts a Date object into a date and time string.
|
|
610
|
+
*
|
|
611
|
+
* e.g. Jun 3, 2021, 11:52 AM
|
|
612
|
+
*
|
|
613
|
+
* NOTE: you should probably use timeAgoString when trying to display
|
|
614
|
+
* an updated/created timestamp.
|
|
615
|
+
*
|
|
616
|
+
* @param {*} date - a Date object you want to convert into a string - gracefully handles any value
|
|
617
|
+
* @param {object} options -
|
|
618
|
+
* @param {string} options.timeZone - the timezone you want date displayed in, defaults to current users time zone
|
|
619
|
+
* @returns {string} a formatted date string
|
|
620
|
+
*/
|
|
621
|
+
const dateTimeString = (date, { timeZone = defaultTimeZone, omitYear = false } = {}) => {
|
|
622
|
+
if (isNil(date)) return "";
|
|
623
|
+
const formattedDate = new Date(date);
|
|
624
|
+
if (isInvalidDate(formattedDate)) return "";
|
|
625
|
+
try {
|
|
626
|
+
const baseOptions = {
|
|
627
|
+
month: "short",
|
|
628
|
+
day: "numeric",
|
|
629
|
+
hour: "numeric",
|
|
630
|
+
minute: "2-digit",
|
|
631
|
+
timeZone
|
|
632
|
+
};
|
|
633
|
+
const options = omitYear ? baseOptions : {
|
|
634
|
+
...baseOptions,
|
|
635
|
+
year: "numeric"
|
|
636
|
+
};
|
|
637
|
+
return formattedDate.toLocaleDateString(defaultLocales, options);
|
|
638
|
+
} catch (error) {
|
|
639
|
+
console.error(error);
|
|
640
|
+
return "";
|
|
641
|
+
}
|
|
642
|
+
};
|
|
643
|
+
//#endregion
|
|
644
|
+
//#region src/helpers/dateTime/dateTimeStringForSentence.ts
|
|
645
|
+
/**
|
|
646
|
+
* Converts a Date object into a date and time string
|
|
647
|
+
* for use in a sentence.
|
|
648
|
+
*
|
|
649
|
+
* e.g. June 3, 2021, 11:52 AM
|
|
650
|
+
*
|
|
651
|
+
* NOTE: you should probably use timeAgoString when trying to display
|
|
652
|
+
* an updated/created timestamp.
|
|
653
|
+
*
|
|
654
|
+
* @param {*} date - a Date object you want to convert into a string - gracefully handles any value
|
|
655
|
+
* @param {object} options -
|
|
656
|
+
* @param {string} options.timeZone - the timezone you want date displayed in, defaults to current users time zone
|
|
657
|
+
* @returns {string} a formatted date string
|
|
658
|
+
*/
|
|
659
|
+
const dateTimeStringForSentence = (date, { timeZone = defaultTimeZone } = {}) => {
|
|
660
|
+
if (!isDate(date) || isInvalidDate(date)) return "";
|
|
661
|
+
try {
|
|
662
|
+
const { year, month, day, hour, minute, dayPeriod } = new Intl.DateTimeFormat(defaultLocales, {
|
|
663
|
+
month: "long",
|
|
664
|
+
day: "numeric",
|
|
665
|
+
year: "numeric",
|
|
666
|
+
hour: "numeric",
|
|
667
|
+
minute: "2-digit",
|
|
668
|
+
timeZone
|
|
669
|
+
}).formatToParts(date).reduce((acc, part) => {
|
|
670
|
+
if (part.type !== "literal") acc[part.type] = part.value;
|
|
671
|
+
return acc;
|
|
672
|
+
}, {});
|
|
673
|
+
return `${month} ${day}, ${year}, ${hour}:${minute} ${dayPeriod}`;
|
|
674
|
+
} catch (error) {
|
|
675
|
+
console.error(error);
|
|
676
|
+
return "";
|
|
677
|
+
}
|
|
678
|
+
};
|
|
679
|
+
//#endregion
|
|
680
|
+
//#region src/helpers/dateTime/dateUTCOffset.ts
|
|
681
|
+
/**
|
|
682
|
+
* Given a date, shows the UTC offset.
|
|
683
|
+
* @param {Date} date a Date object for calculating offset.
|
|
684
|
+
* @returns {string} - string representing the UTC offset
|
|
685
|
+
*/
|
|
686
|
+
const dateUTCOffset = (date) => {
|
|
687
|
+
const offsetInHours = date.getTimezoneOffset() / 60 * -1;
|
|
688
|
+
const hours = Math.round(offsetInHours);
|
|
689
|
+
const minutes = (offsetInHours - hours) * 60;
|
|
690
|
+
return `${hours >= 0 ? "+" : ""}${`${hours}`.padStart(2, "0")}:${`${minutes}`.padStart(2, "0")}`;
|
|
691
|
+
};
|
|
692
|
+
//#endregion
|
|
693
|
+
//#region src/helpers/dateTime/dayOfWeekString.ts
|
|
694
|
+
/**
|
|
695
|
+
* Converts a Date object into a month and day string formatted numerically.
|
|
696
|
+
*
|
|
697
|
+
* e.g. Thursday
|
|
698
|
+
* @param {Date} date a Date object you want to convert into a string
|
|
699
|
+
* @param {object} options -
|
|
700
|
+
* @param {string} options.timeZone - the timezone you want date displayed in, defaults to current users time zone
|
|
701
|
+
* @returns {string} a formatted date string
|
|
702
|
+
*/
|
|
703
|
+
const dayOfWeekString = (date, { timeZone = defaultTimeZone } = {}) => {
|
|
704
|
+
if (date === null) return "";
|
|
705
|
+
try {
|
|
706
|
+
return new Intl.DateTimeFormat(defaultLocales, {
|
|
707
|
+
weekday: "long",
|
|
708
|
+
timeZone
|
|
709
|
+
}).format(date);
|
|
710
|
+
} catch (error) {
|
|
711
|
+
console.error(error);
|
|
712
|
+
return "";
|
|
713
|
+
}
|
|
714
|
+
};
|
|
715
|
+
//#endregion
|
|
716
|
+
//#region src/helpers/dateTime/padTimeInteger.ts
|
|
717
|
+
/**
|
|
718
|
+
* @param {number} num - pads integer with leading zero
|
|
719
|
+
* @returns {string} - integer with padding as string
|
|
720
|
+
*/
|
|
721
|
+
const padTimeInteger = (num) => num.toString().padStart(2, "0");
|
|
722
|
+
//#endregion
|
|
723
|
+
//#region src/helpers/dateTime/mediaDurationString.ts
|
|
724
|
+
/**
|
|
725
|
+
* A string representation of a duration for a media. Assumes most medias
|
|
726
|
+
* are under an hour so only shows hours if media is over hour.
|
|
727
|
+
*
|
|
728
|
+
* @param {number} numberOfMilliseconds - number of milliseconds
|
|
729
|
+
* @returns {string} - a string representation for duration
|
|
730
|
+
*/
|
|
731
|
+
const mediaDurationString = (numberOfMilliseconds) => {
|
|
732
|
+
const { hours, minutes, seconds } = buildTimeDuration(numberOfMilliseconds);
|
|
733
|
+
if (hours < 1) return `${minutes}:${padTimeInteger(seconds)}`;
|
|
734
|
+
return `${hours}:${padTimeInteger(minutes)}:${padTimeInteger(seconds)}`;
|
|
735
|
+
};
|
|
736
|
+
//#endregion
|
|
737
|
+
//#region src/helpers/dateTime/millisecondsToDurationISOString.ts
|
|
738
|
+
/**
|
|
739
|
+
* Given number of miliseconds, returns the iso8601 string rounded down from
|
|
740
|
+
* number of seconds. Mainly copied from https://github.com/wistia/player-modern/blob/master/src/utilities/iso8601Helper.js#L54
|
|
741
|
+
* but modified to support milliseconds
|
|
742
|
+
*
|
|
743
|
+
* @param {number} numberOfMilliseconds - number of milliseconds
|
|
744
|
+
* @returns {string} an iso8601 string format of duration
|
|
745
|
+
*/
|
|
746
|
+
const millisecondsToDurationISOString = (numberOfMilliseconds) => {
|
|
747
|
+
const { seconds, minutes, hours } = buildTimeDuration(numberOfMilliseconds);
|
|
748
|
+
let string = "PT";
|
|
749
|
+
if (hours) string += `${hours}H`;
|
|
750
|
+
if (minutes) string += `${minutes}M`;
|
|
751
|
+
if (seconds) string += `${seconds}S`;
|
|
752
|
+
if (!(seconds || minutes || hours)) string += "0S";
|
|
753
|
+
return string;
|
|
754
|
+
};
|
|
755
|
+
//#endregion
|
|
756
|
+
//#region src/helpers/dateTime/monthDayStringNumeric.ts
|
|
757
|
+
/**
|
|
758
|
+
* Converts a Date object into a month and day string formatted numerically.
|
|
759
|
+
*
|
|
760
|
+
* e.g. 06/03/2021
|
|
761
|
+
* @param {*} date a Date object you want to convert into a string - gracefully handles any value
|
|
762
|
+
* @param {object} options -
|
|
763
|
+
* @param {string} options.timeZone - the timezone you want date displayed in, defaults to current users time zone
|
|
764
|
+
* @returns {string} a formatted date string
|
|
765
|
+
*/
|
|
766
|
+
const monthDayStringNumeric = (date, { timeZone = defaultTimeZone } = {}) => {
|
|
767
|
+
if (!isDate(date) || isInvalidDate(date)) return "";
|
|
768
|
+
try {
|
|
769
|
+
return new Intl.DateTimeFormat(defaultLocales, {
|
|
770
|
+
month: "2-digit",
|
|
771
|
+
day: "2-digit",
|
|
772
|
+
timeZone
|
|
773
|
+
}).format(date);
|
|
774
|
+
} catch (error) {
|
|
775
|
+
console.error(error);
|
|
776
|
+
return "";
|
|
777
|
+
}
|
|
778
|
+
};
|
|
779
|
+
//#endregion
|
|
780
|
+
//#region src/helpers/dateTime/parseDateString.ts
|
|
781
|
+
const MONTH_NAMES = [
|
|
782
|
+
"January",
|
|
783
|
+
"February",
|
|
784
|
+
"March",
|
|
785
|
+
"April",
|
|
786
|
+
"May",
|
|
787
|
+
"June",
|
|
788
|
+
"July",
|
|
789
|
+
"August",
|
|
790
|
+
"September",
|
|
791
|
+
"October",
|
|
792
|
+
"November",
|
|
793
|
+
"December"
|
|
794
|
+
];
|
|
795
|
+
const MONTH_ABBREVIATIONS = MONTH_NAMES.map((name) => name.slice(0, 3));
|
|
796
|
+
const startOfDay = (date) => {
|
|
797
|
+
const result = new Date(date);
|
|
798
|
+
result.setHours(0, 0, 0, 0);
|
|
799
|
+
return result;
|
|
800
|
+
};
|
|
801
|
+
const startOfToday = () => startOfDay(/* @__PURE__ */ new Date());
|
|
802
|
+
const startOfTomorrow = () => {
|
|
803
|
+
const tomorrow = startOfToday();
|
|
804
|
+
tomorrow.setDate(tomorrow.getDate() + 1);
|
|
805
|
+
return tomorrow;
|
|
806
|
+
};
|
|
807
|
+
const monthIndexIn = (names, value) => names.findIndex((name) => name.toLowerCase() === value.toLowerCase());
|
|
808
|
+
const toNumberOrUndefined = (value) => value === void 0 ? void 0 : Number(value);
|
|
809
|
+
const DATE_PATTERNS = [
|
|
810
|
+
{
|
|
811
|
+
regex: new RegExp(`^(${MONTH_ABBREVIATIONS.join("|")}) (\\d{1,2})(?:, (\\d{1,4}))?$`, "i"),
|
|
812
|
+
toParts: ([, month, day, year]) => ({
|
|
813
|
+
monthIndex: monthIndexIn(MONTH_ABBREVIATIONS, month ?? ""),
|
|
814
|
+
day: Number(day),
|
|
815
|
+
year: toNumberOrUndefined(year)
|
|
816
|
+
})
|
|
817
|
+
},
|
|
818
|
+
{
|
|
819
|
+
regex: new RegExp(`^(${MONTH_NAMES.join("|")}) (\\d{1,2})(?:, (\\d{1,4}))?$`, "i"),
|
|
820
|
+
toParts: ([, month, day, year]) => ({
|
|
821
|
+
monthIndex: monthIndexIn(MONTH_NAMES, month ?? ""),
|
|
822
|
+
day: Number(day),
|
|
823
|
+
year: toNumberOrUndefined(year)
|
|
824
|
+
})
|
|
825
|
+
},
|
|
826
|
+
{
|
|
827
|
+
regex: /^(\d{1,2})\/(\d{1,2})(?:\/(\d{1,4}))?$/,
|
|
828
|
+
toParts: ([, month, day, year]) => ({
|
|
829
|
+
monthIndex: Number(month) - 1,
|
|
830
|
+
day: Number(day),
|
|
831
|
+
year: toNumberOrUndefined(year)
|
|
832
|
+
})
|
|
833
|
+
},
|
|
834
|
+
{
|
|
835
|
+
regex: /^(\d{1,2})-(\d{1,2})(?:-(\d{1,4}))?$/,
|
|
836
|
+
toParts: ([, month, day, year]) => ({
|
|
837
|
+
monthIndex: Number(month) - 1,
|
|
838
|
+
day: Number(day),
|
|
839
|
+
year: toNumberOrUndefined(year)
|
|
840
|
+
})
|
|
841
|
+
},
|
|
842
|
+
{
|
|
843
|
+
regex: /^(\d{1,4})-(\d{1,2})-(\d{1,2})$/,
|
|
844
|
+
toParts: ([, year, month, day]) => ({
|
|
845
|
+
monthIndex: Number(month) - 1,
|
|
846
|
+
day: Number(day),
|
|
847
|
+
year: Number(year)
|
|
848
|
+
})
|
|
849
|
+
}
|
|
850
|
+
];
|
|
851
|
+
const toValidDate = ({ monthIndex, day, year }, referenceDate) => {
|
|
852
|
+
if (year === 0) return null;
|
|
853
|
+
const resolvedYear = year ?? referenceDate.getFullYear();
|
|
854
|
+
const date = new Date(referenceDate.getFullYear(), 0, 1);
|
|
855
|
+
date.setFullYear(resolvedYear, monthIndex, day);
|
|
856
|
+
return date.getFullYear() === resolvedYear && date.getMonth() === monthIndex && date.getDate() === day ? date : null;
|
|
857
|
+
};
|
|
858
|
+
const parseDateString = (str) => {
|
|
859
|
+
const trimmed = str.trim();
|
|
860
|
+
if (!trimmed) return null;
|
|
861
|
+
const lower = trimmed.toLowerCase();
|
|
862
|
+
if (lower === "today") return startOfToday();
|
|
863
|
+
if (lower === "tomorrow") return startOfTomorrow();
|
|
864
|
+
const monthIndex = MONTH_NAMES.findIndex((name) => name.toLowerCase().startsWith(lower));
|
|
865
|
+
if (monthIndex !== -1) {
|
|
866
|
+
const today = startOfToday();
|
|
867
|
+
let date = new Date(today.getFullYear(), monthIndex, 1);
|
|
868
|
+
if (date.getTime() < Date.now()) date = new Date(today.getFullYear() + 1, monthIndex, 1);
|
|
869
|
+
return date;
|
|
870
|
+
}
|
|
871
|
+
const referenceDate = /* @__PURE__ */ new Date();
|
|
872
|
+
for (const { regex, toParts } of DATE_PATTERNS) {
|
|
873
|
+
const match = trimmed.match(regex);
|
|
874
|
+
if (match) {
|
|
875
|
+
const parsed = toValidDate(toParts(match), referenceDate);
|
|
876
|
+
if (parsed !== null) return parsed;
|
|
877
|
+
}
|
|
878
|
+
}
|
|
879
|
+
const native = new Date(trimmed);
|
|
880
|
+
if (!Number.isNaN(native.getTime())) return startOfDay(native);
|
|
881
|
+
return null;
|
|
882
|
+
};
|
|
883
|
+
//#endregion
|
|
884
|
+
//#region src/helpers/dateTime/sessionDurationString.ts
|
|
885
|
+
/**
|
|
886
|
+
* A string representation of a duration for a user session. Assumes that
|
|
887
|
+
* sessions may or may not be more than an hour. To prevent confusion all
|
|
888
|
+
* times show hours, even those that are less than an hour.
|
|
889
|
+
*
|
|
890
|
+
* @param {number} numberOfMilliseconds - number of milliseconds
|
|
891
|
+
* @returns {string} - a string representation of duration
|
|
892
|
+
*/
|
|
893
|
+
const sessionDurationString = (numberOfMilliseconds) => {
|
|
894
|
+
const { hours, minutes, seconds } = buildTimeDuration(numberOfMilliseconds);
|
|
895
|
+
return `${hours}:${padTimeInteger(minutes)}:${padTimeInteger(seconds)}`;
|
|
896
|
+
};
|
|
897
|
+
//#endregion
|
|
898
|
+
//#region src/helpers/dateTime/getLocalDateParts.ts
|
|
899
|
+
/**
|
|
900
|
+
* Get local year, month, day parts from a Date using Intl.DateTimeFormat.
|
|
901
|
+
* This ignores the time of day (hours, minutes, etc.).
|
|
902
|
+
*
|
|
903
|
+
* @param {Date} date
|
|
904
|
+
* @returns {{ year: number, month: number, day: number }}
|
|
905
|
+
*/
|
|
906
|
+
const getLocalDateParts = (date) => {
|
|
907
|
+
const parts = new Intl.DateTimeFormat(defaultLocales, {
|
|
908
|
+
year: "numeric",
|
|
909
|
+
month: "numeric",
|
|
910
|
+
day: "numeric",
|
|
911
|
+
timeZone: defaultTimeZone
|
|
912
|
+
}).formatToParts(date);
|
|
913
|
+
const yearPart = parts.find((part) => part.type === "year");
|
|
914
|
+
const monthPart = parts.find((part) => part.type === "month");
|
|
915
|
+
const dayPart = parts.find((part) => part.type === "day");
|
|
916
|
+
if (isNil(yearPart) || isNil(monthPart) || isNil(dayPart)) throw new Error("Failed to parse date parts");
|
|
917
|
+
return {
|
|
918
|
+
year: Math.trunc(Number(yearPart.value)),
|
|
919
|
+
month: Math.trunc(Number(monthPart.value)),
|
|
920
|
+
day: Math.trunc(Number(dayPart.value))
|
|
921
|
+
};
|
|
922
|
+
};
|
|
923
|
+
//#endregion
|
|
924
|
+
//#region src/helpers/dateTime/differenceInCalendarDays.ts
|
|
925
|
+
/**
|
|
926
|
+
* Returns the difference in calendar days between two dates in local time,
|
|
927
|
+
* ignoring the time of day.
|
|
928
|
+
*
|
|
929
|
+
* @param {Date|number} dateLeft - The later date (or timestamp).
|
|
930
|
+
* @param {Date|number} dateRight - The earlier date (or timestamp).
|
|
931
|
+
* @returns {number} - Number of calendar days (can be negative).
|
|
932
|
+
*/
|
|
933
|
+
const differenceInCalendarDays = (dateLeft, dateRight) => {
|
|
934
|
+
const leftDate = isDate(dateLeft) ? dateLeft : new Date(dateLeft);
|
|
935
|
+
const rightDate = isDate(dateRight) ? dateRight : new Date(dateRight);
|
|
936
|
+
if (Number.isNaN(leftDate.getTime()) || Number.isNaN(rightDate.getTime())) return NaN;
|
|
937
|
+
const { year: y1, month: m1, day: d1 } = getLocalDateParts(leftDate);
|
|
938
|
+
const { year: y2, month: m2, day: d2 } = getLocalDateParts(rightDate);
|
|
939
|
+
const msDiff = new Date(y1, m1 - 1, d1).getTime() - new Date(y2, m2 - 1, d2).getTime();
|
|
940
|
+
return Math.round(msDiff / millisecondsInDay);
|
|
941
|
+
};
|
|
942
|
+
//#endregion
|
|
943
|
+
//#region src/helpers/dateTime/timeAgoString.ts
|
|
944
|
+
/**
|
|
945
|
+
* Shows time ago relative to current time.
|
|
946
|
+
*
|
|
947
|
+
* examples:
|
|
948
|
+
*
|
|
949
|
+
* < 1 minute ago
|
|
950
|
+
*
|
|
951
|
+
* 33 minutes ago
|
|
952
|
+
*
|
|
953
|
+
* Today, 3:30 PM
|
|
954
|
+
*
|
|
955
|
+
* Yesterday, 6:22 AM
|
|
956
|
+
*
|
|
957
|
+
* Nov 11, 11:32 AM
|
|
958
|
+
*
|
|
959
|
+
* Feb 23, 2020, 1:55 PM
|
|
960
|
+
*
|
|
961
|
+
* or when `includeTime` is false:
|
|
962
|
+
*
|
|
963
|
+
* Today
|
|
964
|
+
*
|
|
965
|
+
* Yesterday
|
|
966
|
+
*
|
|
967
|
+
* on Thursday
|
|
968
|
+
*
|
|
969
|
+
* Nov 11
|
|
970
|
+
*
|
|
971
|
+
* Feb 23, 2020
|
|
972
|
+
*
|
|
973
|
+
* NOTE: timeAgoString doesn't support multiple time zones since doing so would
|
|
974
|
+
* complicate calculations for whether to use "Today" or "Yesterday".
|
|
975
|
+
* @param {Date} date - the date relative to now
|
|
976
|
+
* @param {object} options -
|
|
977
|
+
* @param {Date} options.nowAnchor - The date used to calculate relative to now. Defaults to current date but can be overwritten for tests.
|
|
978
|
+
* @param {boolean} options.includeTime - Whether to include the time in the output. Defaults to true.
|
|
979
|
+
* @returns {string} - a string representation of the date.
|
|
980
|
+
*/
|
|
981
|
+
const timeAgoString = (date, { nowAnchor = /* @__PURE__ */ new Date(), includeTime = true } = {}) => {
|
|
982
|
+
if (isInvalidDate(date)) return "";
|
|
983
|
+
const minutesAgo = (nowAnchor.valueOf() - date.valueOf()) / (60 * milisecondsInSecond);
|
|
984
|
+
const minutesAgoRounded = Math.round(minutesAgo);
|
|
985
|
+
const differenceInDays = differenceInCalendarDays(nowAnchor, date);
|
|
986
|
+
const isSameYear = date.getFullYear() === nowAnchor.getFullYear();
|
|
987
|
+
if (minutesAgo < 0) return dateTimeString(date);
|
|
988
|
+
if (minutesAgo < 1) return "< 1 minute ago";
|
|
989
|
+
if (minutesAgoRounded < 2) return "1 minute ago";
|
|
990
|
+
if (minutesAgoRounded <= 60) return `${minutesAgoRounded} minutes ago`;
|
|
991
|
+
if (differenceInDays === 0) return includeTime ? `Today, ${Intl.DateTimeFormat(defaultLocales, {
|
|
992
|
+
hour: "numeric",
|
|
993
|
+
minute: "2-digit"
|
|
994
|
+
}).format(date)}` : "Today";
|
|
995
|
+
if (differenceInDays === 1) return includeTime ? `Yesterday, ${Intl.DateTimeFormat(defaultLocales, {
|
|
996
|
+
hour: "numeric",
|
|
997
|
+
minute: "2-digit"
|
|
998
|
+
}).format(date)}` : "Yesterday";
|
|
999
|
+
if (differenceInDays < 7 && !includeTime) return `on ${dayOfWeekString(date)}`;
|
|
1000
|
+
return includeTime ? dateTimeString(date, { omitYear: isSameYear }) : dateOnlyString(date, { omitYear: false });
|
|
1001
|
+
};
|
|
1002
|
+
//#endregion
|
|
1003
|
+
//#region src/helpers/dateTime/timeOnlyString.ts
|
|
1004
|
+
/**
|
|
1005
|
+
* Converts a Date object into a time only string.
|
|
1006
|
+
*
|
|
1007
|
+
* e.g. 7:30 AM
|
|
1008
|
+
* @param {*} date a Date object you want to convert into a string - gracefully handles any value
|
|
1009
|
+
* @param {object} options -
|
|
1010
|
+
* @param {string} options.timeZone - the timezone you want date displayed in, defaults to current users time zone
|
|
1011
|
+
* @returns {string} a formatted date string
|
|
1012
|
+
*/
|
|
1013
|
+
const timeOnlyString = (date, { timeZone = defaultTimeZone } = {}) => {
|
|
1014
|
+
if (!isDate(date) || isInvalidDate(date)) return "";
|
|
1015
|
+
try {
|
|
1016
|
+
return new Intl.DateTimeFormat(defaultLocales, {
|
|
1017
|
+
timeStyle: "short",
|
|
1018
|
+
timeZone
|
|
1019
|
+
}).format(date);
|
|
1020
|
+
} catch (error) {
|
|
1021
|
+
console.error(error);
|
|
1022
|
+
return "";
|
|
1023
|
+
}
|
|
1024
|
+
};
|
|
1025
|
+
//#endregion
|
|
1026
|
+
//#region src/helpers/dateTime/index.ts
|
|
1027
|
+
const dateTime = {
|
|
1028
|
+
buildTimeDuration,
|
|
1029
|
+
dateOnlyISOString,
|
|
1030
|
+
dateOnlyString,
|
|
1031
|
+
dateOnlyStringForSentence,
|
|
1032
|
+
dateOnlyStringNumeric,
|
|
1033
|
+
dateTimeRounded,
|
|
1034
|
+
dateTimeString,
|
|
1035
|
+
dateTimeStringForSentence,
|
|
1036
|
+
dateTimeToDate,
|
|
1037
|
+
dateTimeToISO,
|
|
1038
|
+
dateToDateTime,
|
|
1039
|
+
dateUTCOffset,
|
|
1040
|
+
dayOfWeekString,
|
|
1041
|
+
mediaDurationString,
|
|
1042
|
+
millisecondsToDurationISOString,
|
|
1043
|
+
monthDayStringNumeric,
|
|
1044
|
+
parseDateString,
|
|
1045
|
+
sessionDurationString,
|
|
1046
|
+
timeAgoString,
|
|
1047
|
+
timeOnlyString
|
|
1048
|
+
};
|
|
1049
|
+
//#endregion
|
|
1050
|
+
//#region src/helpers/isUrl/isUrl.ts
|
|
1051
|
+
/**
|
|
1052
|
+
* Loosely validates a URL string
|
|
1053
|
+
*
|
|
1054
|
+
* @param {*} str - a string to validate - could be an unknown type
|
|
1055
|
+
* @return {boolean} - whether string appears to be a url
|
|
1056
|
+
*/
|
|
1057
|
+
const isUrl = (str) => {
|
|
1058
|
+
const protocolAndDomain = /^(?:\w+:)?\/\/(\S+)$/;
|
|
1059
|
+
const localhostDomain = /^localhost[:?\d]*(?:[^:?\d]\S*)?$/;
|
|
1060
|
+
const nonLocalhostDomain = /^[^\s.]+\.\S{2,}$/;
|
|
1061
|
+
if (!isString(str)) return false;
|
|
1062
|
+
const match = protocolAndDomain.exec(str);
|
|
1063
|
+
if (!match) return false;
|
|
1064
|
+
const remaining = match[1];
|
|
1065
|
+
if (remaining === void 0 || !remaining) return false;
|
|
1066
|
+
return localhostDomain.test(remaining) || nonLocalhostDomain.test(remaining);
|
|
1067
|
+
};
|
|
1068
|
+
//#endregion
|
|
383
1069
|
//#region src/helpers/getBackgroundGradient/getBackgroundGradient.ts
|
|
384
1070
|
const gradients = {
|
|
385
1071
|
defaultDarkOne: css`
|
|
@@ -581,6 +1267,15 @@ const mq = {
|
|
|
581
1267
|
xlAndDown
|
|
582
1268
|
};
|
|
583
1269
|
//#endregion
|
|
1270
|
+
//#region src/helpers/stripExtension/stripExtension.ts
|
|
1271
|
+
/**
|
|
1272
|
+
* Removes file extension from string
|
|
1273
|
+
*
|
|
1274
|
+
* @param {string} str - string to have file extension removed from
|
|
1275
|
+
* @returns {string} - string with file extension removed
|
|
1276
|
+
*/
|
|
1277
|
+
const stripExtension = (str) => (str || "").replace(/\.[^/.]{1,4}$/, "");
|
|
1278
|
+
//#endregion
|
|
584
1279
|
//#region src/hooks/useAriaLive/useAriaLive.tsx
|
|
585
1280
|
const useAriaLive = () => {
|
|
586
1281
|
const context = useContext(AriaLiveContext);
|
|
@@ -13914,7 +14609,9 @@ const InputClickToCopy = ({ value, onCopy, disabled = false, ref, ...props }) =>
|
|
|
13914
14609
|
};
|
|
13915
14610
|
//#endregion
|
|
13916
14611
|
//#region src/components/InputDuration/constants.ts
|
|
13917
|
-
const
|
|
14612
|
+
const SECONDS_PER_MINUTE = 60;
|
|
14613
|
+
const MAX_MINUTES_UNIT_VALUE = 59;
|
|
14614
|
+
const SECONDS_PER_TEN_MINUTES = 600;
|
|
13918
14615
|
const SECONDS_PER_HOUR = 3600;
|
|
13919
14616
|
const ONE_HUNDREDTH_OF_A_SECOND = .01;
|
|
13920
14617
|
const MAX_TIME = 35999.99;
|
|
@@ -13952,13 +14649,13 @@ const getSecondsFormatter = (decimalUnitLength) => {
|
|
|
13952
14649
|
});
|
|
13953
14650
|
};
|
|
13954
14651
|
const isValidHour = (number) => Number.isInteger(number) && number >= 0;
|
|
13955
|
-
const isValidMinute = (number) => Number.isInteger(number) && number >= 0 && number <=
|
|
13956
|
-
const isValidSecond = (number) => Number.isFinite(number) && number >= 0 && number <
|
|
14652
|
+
const isValidMinute = (number) => Number.isInteger(number) && number >= 0 && number <= MAX_MINUTES_UNIT_VALUE;
|
|
14653
|
+
const isValidSecond = (number) => Number.isFinite(number) && number >= 0 && number < SECONDS_PER_MINUTE;
|
|
13957
14654
|
const durationValueToSeconds = (formattedTimeString) => {
|
|
13958
14655
|
const segments = formattedTimeString.split(":");
|
|
13959
14656
|
if (segments.length <= 3) {
|
|
13960
14657
|
const [seconds = 0, minutes = 0, hours = 0] = segments.toReversed().map(Number);
|
|
13961
|
-
if (isValidSecond(seconds) && isValidMinute(minutes) && isValidHour(hours)) return hours * SECONDS_PER_HOUR + minutes *
|
|
14658
|
+
if (isValidSecond(seconds) && isValidMinute(minutes) && isValidHour(hours)) return hours * SECONDS_PER_HOUR + minutes * SECONDS_PER_MINUTE + seconds;
|
|
13962
14659
|
}
|
|
13963
14660
|
throw new SyntaxError(`Invalid time (${formattedTimeString})`);
|
|
13964
14661
|
};
|
|
@@ -13977,7 +14674,7 @@ const getFormattedSeconds = ({ seconds, decimalUnitLength }) => {
|
|
|
13977
14674
|
const convertSecondsToHMSUnits = (durationInSeconds) => {
|
|
13978
14675
|
const wholeSeconds = Math.trunc(durationInSeconds);
|
|
13979
14676
|
const fractionalSeconds = durationInSeconds - wholeSeconds;
|
|
13980
|
-
const { hours, minutes, seconds } = buildTimeDuration(wholeSeconds *
|
|
14677
|
+
const { hours, minutes, seconds } = buildTimeDuration(wholeSeconds * milisecondsInSecond);
|
|
13981
14678
|
return {
|
|
13982
14679
|
hours,
|
|
13983
14680
|
minutes,
|
|
@@ -14002,9 +14699,9 @@ const secondsToDurationValue = ({ seconds: durationInSeconds, maxUnit, decimalUn
|
|
|
14002
14699
|
].filter(Boolean).join(":");
|
|
14003
14700
|
};
|
|
14004
14701
|
const getMaxUnit = (seconds) => {
|
|
14005
|
-
if (seconds >=
|
|
14006
|
-
if (seconds >=
|
|
14007
|
-
if (seconds >=
|
|
14702
|
+
if (seconds >= SECONDS_PER_HOUR) return "hours";
|
|
14703
|
+
if (seconds >= SECONDS_PER_TEN_MINUTES) return "tens-of-minutes";
|
|
14704
|
+
if (seconds >= SECONDS_PER_MINUTE) return "minutes";
|
|
14008
14705
|
return "seconds";
|
|
14009
14706
|
};
|
|
14010
14707
|
const clampSeconds = ({ maxSeconds, minSeconds, seconds }) => {
|
|
@@ -14316,7 +15013,7 @@ const useInputDuration = ({ decimalUnitLength, maxSeconds, minSeconds, onChangeV
|
|
|
14316
15013
|
return;
|
|
14317
15014
|
}
|
|
14318
15015
|
if (selectedUnit === "minutes" || selectedUnit === "tens-of-minutes") {
|
|
14319
|
-
incrementBySeconds(
|
|
15016
|
+
incrementBySeconds(SECONDS_PER_MINUTE);
|
|
14320
15017
|
return;
|
|
14321
15018
|
}
|
|
14322
15019
|
if (selectedUnit === "seconds") {
|
|
@@ -14336,7 +15033,7 @@ const useInputDuration = ({ decimalUnitLength, maxSeconds, minSeconds, onChangeV
|
|
|
14336
15033
|
return;
|
|
14337
15034
|
}
|
|
14338
15035
|
if (selectedUnit === "minutes" || selectedUnit === "tens-of-minutes") {
|
|
14339
|
-
decrementBySeconds(
|
|
15036
|
+
decrementBySeconds(SECONDS_PER_MINUTE);
|
|
14340
15037
|
return;
|
|
14341
15038
|
}
|
|
14342
15039
|
if (selectedUnit === "seconds") {
|
|
@@ -14423,7 +15120,7 @@ const useInputDuration = ({ decimalUnitLength, maxSeconds, minSeconds, onChangeV
|
|
|
14423
15120
|
selectUnitToRight();
|
|
14424
15121
|
return;
|
|
14425
15122
|
}
|
|
14426
|
-
if (selectedUnit === "tens-of-minutes" && number >=
|
|
15123
|
+
if (selectedUnit === "tens-of-minutes" && number >= SECONDS_PER_MINUTE / 10 && !secondDigitMightBeTypedNext.current) {
|
|
14427
15124
|
maybeSetInputValueAndTriggerOnChange(`${textToLeftOfSelection}0${number.toString()}${textToRightOfSelection}`);
|
|
14428
15125
|
secondDigitMightBeTypedNext.current = false;
|
|
14429
15126
|
selectUnitToRight();
|
|
@@ -14445,7 +15142,7 @@ const useInputDuration = ({ decimalUnitLength, maxSeconds, minSeconds, onChangeV
|
|
|
14445
15142
|
selectUnitToRight();
|
|
14446
15143
|
return;
|
|
14447
15144
|
}
|
|
14448
|
-
if (selectedUnit === "seconds" && number >=
|
|
15145
|
+
if (selectedUnit === "seconds" && number >= SECONDS_PER_MINUTE / 10 && !secondDigitMightBeTypedNext.current) {
|
|
14449
15146
|
maybeSetInputValueAndTriggerOnChange(`${textToLeftOfSelection}0${number.toString()}${textToRightOfSelection}`);
|
|
14450
15147
|
secondDigitMightBeTypedNext.current = false;
|
|
14451
15148
|
selectUnitToRight();
|
|
@@ -17484,6 +18181,6 @@ const WistiaLogo = ({ description, height = 100, hoverColor, href, iconOnly = fa
|
|
|
17484
18181
|
};
|
|
17485
18182
|
WistiaLogo.displayName = "WistiaLogo_UI";
|
|
17486
18183
|
//#endregion
|
|
17487
|
-
export { ActionButton, Avatar, Badge, Banner, Box, Breadcrumb, Breadcrumbs, Button, ButtonGroup, Card, Center, Checkbox, CheckboxCard, CheckboxGroup, CheckboxMenuItem, ClickRegion, Collapsible, CollapsibleContent, CollapsibleTrigger, CollapsibleTriggerIcon, ColorGrid, ColorGridOption, ColorList, ColorListGroup, ColorListOption, ColorPicker, ColorPickerPopoverContent, ColorPickerSection, ColorPickerTrigger, ColorSchemeWrapper, Combobox, ComboboxOption, ContextMenu, ContrastControls, ContrastEnforcerSwitch, ContrastIndicator, ContrastPreview, CustomizableThemeWrapper, DOCUMENT_COLOR_MODE_ATTRIBUTE, DataCard, DataCardHoverArrow, DataCardTrend, DataCards, DataList, DataListItem, DataListItemLabel, DataListItemValue, DatePicker, Dimmer, Divider, EditableHeading, EditableText, EditableTextCancelButton, EditableTextContext, EditableTextDisplay, EditableTextInput, EditableTextLabel, EditableTextRoot, EditableTextSubmitButton, EditableTextTrigger, Ellipsis, FeatureCard, FeatureCardImage, FileAmountLimitValidator, FileSizeValidator, FileTypeValidator, FilterMenu, FilterMenuItem, Form, FormErrorSummary, FormField, FormGroup, Grid, Heading, HexColorInput, HueSlider, Icon, IconButton, IconChip, Image, ImageDimensionsValidator, Input, InputClickToCopy, InputDuration, InputPassword, KeyboardShortcut, Label, Link, List, ListItem, Mark, Markdown, Menu, MenuItem, MenuItemDescription, MenuItemLabel, MenuLabel, MenuRadioGroup, Meter, Modal, ModalCallout, ModalCallouts, PersistentFileAmountLimitValidator, Popover, PopoverAnchor, PopoverArrow, PopoverClose, PopoverCloseButton, PopoverContent, PopoverPortal, PopoverRoot, PopoverTrigger, PreviewCard, ProgressBar, Radio, RadioCard, RadioCardImage, RadioGroup, RadioMenuItem, SaturationAndValuePicker, ScreenReaderOnly, ScrollArea, SegmentedControl, SegmentedControlItem, Select, SelectOption, SelectOptionGroup, Sidebar, SidebarButton, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupLabel, SidebarHeader, SidebarSearchInput, SidebarTitle, Slider, SplitButton, Stack, SubMenu, Switch, Table, TableBody, TableCell, TableFoot, TableHead, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Tag, Text, Thumbnail, ThumbnailBadge, ThumbnailCollage, TileButton, Tooltip, UIProvider, ValueNameOrHexCode, ValueSwatch, WistiaLogo, calculateContrast, colorModeOptions, colorSchemeOptions, copyToClipboard, documentColorModeOptions, getBackgroundGradient, getDocumentColorMode, getSemiRandomBackgroundGradient, iconSizeMap, isKeyboardKey, mergeRefs, mq, setDocumentColorMode, useActiveMq, useAriaLive, useBoolean, useClipboard, useDocumentColorMode, useElementObserver, useFilePicker, useFocusTrap, useForceUpdate, useFormState, useImperativeFilePicker, useIsHovered, useKey, useKeyPress, useLocalStorage, useLockBodyScroll, useMq, useOnClickOutside, usePreviousValue, useToast, useWindowSize, validateWithYup };
|
|
18184
|
+
export { ActionButton, Avatar, Badge, Banner, Box, Breadcrumb, Breadcrumbs, Button, ButtonGroup, Card, Center, Checkbox, CheckboxCard, CheckboxGroup, CheckboxMenuItem, ClickRegion, Collapsible, CollapsibleContent, CollapsibleTrigger, CollapsibleTriggerIcon, ColorGrid, ColorGridOption, ColorList, ColorListGroup, ColorListOption, ColorPicker, ColorPickerPopoverContent, ColorPickerSection, ColorPickerTrigger, ColorSchemeWrapper, Combobox, ComboboxOption, ContextMenu, ContrastControls, ContrastEnforcerSwitch, ContrastIndicator, ContrastPreview, CustomizableThemeWrapper, DOCUMENT_COLOR_MODE_ATTRIBUTE, DataCard, DataCardHoverArrow, DataCardTrend, DataCards, DataList, DataListItem, DataListItemLabel, DataListItemValue, DatePicker, Dimmer, Divider, EditableHeading, EditableText, EditableTextCancelButton, EditableTextContext, EditableTextDisplay, EditableTextInput, EditableTextLabel, EditableTextRoot, EditableTextSubmitButton, EditableTextTrigger, Ellipsis, FeatureCard, FeatureCardImage, FileAmountLimitValidator, FileSizeValidator, FileTypeValidator, FilterMenu, FilterMenuItem, Form, FormErrorSummary, FormField, FormGroup, Grid, Heading, HexColorInput, HueSlider, Icon, IconButton, IconChip, Image, ImageDimensionsValidator, Input, InputClickToCopy, InputDuration, InputPassword, KeyboardShortcut, Label, Link, List, ListItem, Mark, Markdown, Menu, MenuItem, MenuItemDescription, MenuItemLabel, MenuLabel, MenuRadioGroup, Meter, Modal, ModalCallout, ModalCallouts, PersistentFileAmountLimitValidator, Popover, PopoverAnchor, PopoverArrow, PopoverClose, PopoverCloseButton, PopoverContent, PopoverPortal, PopoverRoot, PopoverTrigger, PreviewCard, ProgressBar, Radio, RadioCard, RadioCardImage, RadioGroup, RadioMenuItem, SaturationAndValuePicker, ScreenReaderOnly, ScrollArea, SegmentedControl, SegmentedControlItem, Select, SelectOption, SelectOptionGroup, Sidebar, SidebarButton, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupLabel, SidebarHeader, SidebarSearchInput, SidebarTitle, Slider, SplitButton, Stack, SubMenu, Switch, Table, TableBody, TableCell, TableFoot, TableHead, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Tag, Text, Thumbnail, ThumbnailBadge, ThumbnailCollage, TileButton, Tooltip, UIProvider, ValueNameOrHexCode, ValueSwatch, WistiaLogo, buildTimeDuration, calculateContrast, coerceToBoolean, colorModeOptions, colorSchemeOptions, copyToClipboard, dateOnlyISOString, dateOnlyString, dateOnlyStringForSentence, dateOnlyStringNumeric, dateTime, dateTimeRounded, dateTimeString, dateTimeStringForSentence, dateTimeToDate, dateTimeToISO, dateToDateTime, dateUTCOffset, dayOfWeekString, documentColorModeOptions, getBackgroundGradient, getDocumentColorMode, getSemiRandomBackgroundGradient, iconSizeMap, isKeyboardKey, isUrl, mediaDurationString, mergeRefs, millisecondsToDurationISOString, monthDayStringNumeric, mq, parseDateString, sessionDurationString, setDocumentColorMode, stripExtension, timeAgoString, timeOnlyString, useActiveMq, useAriaLive, useBoolean, useClipboard, useDocumentColorMode, useElementObserver, useFilePicker, useFocusTrap, useForceUpdate, useFormState, useImperativeFilePicker, useIsHovered, useKey, useKeyPress, useLocalStorage, useLockBodyScroll, useMq, useOnClickOutside, usePreviousValue, useToast, useWindowSize, validateWithYup };
|
|
17488
18185
|
|
|
17489
18186
|
//# sourceMappingURL=index.js.map
|