@wistia/ui 0.26.0-beta.f4d3df49.8d1c05a → 0.26.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
 
2
2
  /*
3
- * @license @wistia/ui v0.26.0-beta.f4d3df49.8d1c05a
3
+ * @license @wistia/ui v0.26.1
4
4
  *
5
5
  * Copyright (c) 2024-2026, Wistia, Inc. and its affiliates.
6
6
  *
@@ -8,7 +8,7 @@
8
8
  */
9
9
 
10
10
  import { Tooltip as Tooltip$1 } from "@base-ui/react/tooltip";
11
- import { Children, cloneElement, createContext, forwardRef, isValidElement, useCallback, useContext, useEffect, useId, useLayoutEffect, useMemo, useRef, useState, useTransition } from "react";
11
+ import { Children, cloneElement, createContext, forwardRef, isValidElement, useCallback, useContext, useEffect, useId, useImperativeHandle, useLayoutEffect, useMemo, useRef, useState, useTransition } from "react";
12
12
  import { createGlobalStyle, css, keyframes, styled } from "styled-components";
13
13
  import { isArray, isBoolean, isEmptyString, isFunction, isNil, isNonEmptyArray, isNonEmptyString, isNotNil, isNotUndefined, isNumber, isRecord, isString, isUndefined } from "@wistia/type-guards";
14
14
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
@@ -11444,6 +11444,711 @@ const InputClickToCopy = forwardRef(({ value, onCopy, disabled = false, ...props
11444
11444
  });
11445
11445
  InputClickToCopy.displayName = "InputClickToCopy_UI";
11446
11446
  //#endregion
11447
+ //#region src/components/InputDuration/constants.ts
11448
+ const SECONDS_PER_MINUTE = 60;
11449
+ const MINUTES_PER_HOUR = 60;
11450
+ const MAX_MINUTES_UNIT_VALUE = SECONDS_PER_MINUTE - 1;
11451
+ const SECONDS_PER_TEN_MINUTES = SECONDS_PER_MINUTE * 10;
11452
+ const SECONDS_PER_HOUR = SECONDS_PER_MINUTE * MINUTES_PER_HOUR;
11453
+ const TEN_HOURS = SECONDS_PER_HOUR * 10;
11454
+ const ONE_HUNDREDTH_OF_A_SECOND = .01;
11455
+ const MAX_TIME = TEN_HOURS - ONE_HUNDREDTH_OF_A_SECOND;
11456
+ const NUMBER_STRING_SET = new Set([
11457
+ "0",
11458
+ "1",
11459
+ "2",
11460
+ "3",
11461
+ "4",
11462
+ "5",
11463
+ "6",
11464
+ "7",
11465
+ "8",
11466
+ "9"
11467
+ ]);
11468
+ //#endregion
11469
+ //#region src/components/InputDuration/durationFormatting.ts
11470
+ const hoursFormatter = new Intl.NumberFormat("en-US", {
11471
+ maximumFractionDigits: 0,
11472
+ useGrouping: false
11473
+ });
11474
+ const minutesFormatter = new Intl.NumberFormat("en-US", {
11475
+ maximumFractionDigits: 0,
11476
+ minimumIntegerDigits: 1
11477
+ });
11478
+ const tensOfMinutesFormatter = new Intl.NumberFormat("en-US", {
11479
+ maximumFractionDigits: 0,
11480
+ minimumIntegerDigits: 2
11481
+ });
11482
+ const getSecondsFormatter = (decimalUnitLength) => {
11483
+ return new Intl.NumberFormat("en-US", {
11484
+ maximumFractionDigits: decimalUnitLength,
11485
+ minimumFractionDigits: decimalUnitLength,
11486
+ minimumIntegerDigits: 2
11487
+ });
11488
+ };
11489
+ const isValidHour = (number) => Number.isInteger(number) && number >= 0;
11490
+ const isValidMinute = (number) => Number.isInteger(number) && number >= 0 && number <= MAX_MINUTES_UNIT_VALUE;
11491
+ const isValidSecond = (number) => Number.isFinite(number) && number >= 0 && number < SECONDS_PER_MINUTE;
11492
+ const durationValueToSeconds = (formattedTimeString) => {
11493
+ const segments = formattedTimeString.split(":");
11494
+ if (segments.length <= 3) {
11495
+ const [seconds = 0, minutes = 0, hours = 0] = segments.reverse().map(Number);
11496
+ if (isValidSecond(seconds) && isValidMinute(minutes) && isValidHour(hours)) return hours * SECONDS_PER_HOUR + minutes * SECONDS_PER_MINUTE + seconds;
11497
+ }
11498
+ throw new SyntaxError(`Invalid time (${formattedTimeString})`);
11499
+ };
11500
+ const getFormattedHours = ({ hours, maxUnit }) => {
11501
+ if (maxUnit !== "hours") return null;
11502
+ return hoursFormatter.format(hours);
11503
+ };
11504
+ const getFormattedMinutes = ({ minutes, maxUnit }) => {
11505
+ if (maxUnit === "seconds") return null;
11506
+ if (maxUnit === "minutes") return minutesFormatter.format(minutes);
11507
+ return tensOfMinutesFormatter.format(minutes);
11508
+ };
11509
+ const getFormattedSeconds = ({ seconds, decimalUnitLength }) => {
11510
+ return getSecondsFormatter(decimalUnitLength).format(seconds);
11511
+ };
11512
+ const convertSecondsToHMSUnits = (durationInSeconds) => {
11513
+ const wholeSeconds = Math.trunc(durationInSeconds);
11514
+ const fractionalSeconds = durationInSeconds - wholeSeconds;
11515
+ const { hours, minutes, seconds } = buildTimeDuration(wholeSeconds * milisecondsInSecond);
11516
+ return {
11517
+ hours,
11518
+ minutes,
11519
+ seconds: seconds + fractionalSeconds
11520
+ };
11521
+ };
11522
+ const secondsToDurationValue = ({ seconds: durationInSeconds, maxUnit, decimalUnitLength }) => {
11523
+ const { hours, minutes, seconds } = convertSecondsToHMSUnits(durationInSeconds);
11524
+ return [
11525
+ getFormattedHours({
11526
+ hours,
11527
+ maxUnit
11528
+ }),
11529
+ getFormattedMinutes({
11530
+ minutes,
11531
+ maxUnit
11532
+ }),
11533
+ getFormattedSeconds({
11534
+ seconds,
11535
+ decimalUnitLength
11536
+ })
11537
+ ].filter(Boolean).join(":");
11538
+ };
11539
+ const getMaxUnit = (seconds) => {
11540
+ if (seconds >= SECONDS_PER_HOUR) return "hours";
11541
+ if (seconds >= SECONDS_PER_TEN_MINUTES) return "tens-of-minutes";
11542
+ if (seconds >= SECONDS_PER_MINUTE) return "minutes";
11543
+ return "seconds";
11544
+ };
11545
+ const clampSeconds = ({ maxSeconds, minSeconds, seconds }) => {
11546
+ return Math.min(Math.max(seconds, minSeconds), maxSeconds);
11547
+ };
11548
+ const roundSeconds = (seconds, decimalUnitLength) => {
11549
+ const multiplier = decimalUnitLength === 0 ? 1 : 100;
11550
+ return Math.round(seconds * multiplier) / multiplier;
11551
+ };
11552
+ const getDurationBounds = ({ decimalUnitLength, maxSeconds, minSeconds }) => {
11553
+ const roundedMaxSeconds = roundSeconds(maxSeconds, decimalUnitLength);
11554
+ const roundedMinSeconds = roundSeconds(minSeconds, decimalUnitLength);
11555
+ if (roundedMaxSeconds < roundedMinSeconds) return {
11556
+ maxSeconds: roundedMaxSeconds,
11557
+ minSeconds: roundedMaxSeconds
11558
+ };
11559
+ return {
11560
+ maxSeconds: roundedMaxSeconds,
11561
+ minSeconds: roundedMinSeconds
11562
+ };
11563
+ };
11564
+ //#endregion
11565
+ //#region src/components/InputDuration/durationSelection.ts
11566
+ const getEmptySelectionRanges = () => ({
11567
+ hours: {
11568
+ start: null,
11569
+ end: null
11570
+ },
11571
+ "tens-of-minutes": {
11572
+ start: null,
11573
+ end: null
11574
+ },
11575
+ minutes: {
11576
+ start: null,
11577
+ end: null
11578
+ },
11579
+ seconds: {
11580
+ start: null,
11581
+ end: null
11582
+ },
11583
+ "hundredths-of-seconds": {
11584
+ start: null,
11585
+ end: null
11586
+ }
11587
+ });
11588
+ const getSegmentRange = ({ segment, offset }) => {
11589
+ return {
11590
+ nextOffset: offset + segment.length + 1,
11591
+ range: {
11592
+ start: offset,
11593
+ end: offset + segment.length
11594
+ }
11595
+ };
11596
+ };
11597
+ const getSecondsRanges = ({ segment, offset }) => {
11598
+ const decimalSeparatorIndex = segment.indexOf(".");
11599
+ const ranges = {
11600
+ seconds: {
11601
+ start: offset,
11602
+ end: offset + (decimalSeparatorIndex === -1 ? segment.length : decimalSeparatorIndex)
11603
+ },
11604
+ "hundredths-of-seconds": {
11605
+ start: null,
11606
+ end: null
11607
+ }
11608
+ };
11609
+ if (decimalSeparatorIndex !== -1 && decimalSeparatorIndex < segment.length - 1) ranges["hundredths-of-seconds"] = {
11610
+ start: offset + decimalSeparatorIndex + 1,
11611
+ end: offset + segment.length
11612
+ };
11613
+ return ranges;
11614
+ };
11615
+ const getSelectionRanges = ({ inputValue, maxUnit }) => {
11616
+ const segments = inputValue.split(":");
11617
+ let offset = 0;
11618
+ if (maxUnit === "hours") {
11619
+ const [hours = "", minutes = "", seconds = ""] = segments;
11620
+ const hoursResult = getSegmentRange({
11621
+ segment: hours,
11622
+ offset
11623
+ });
11624
+ offset = hoursResult.nextOffset;
11625
+ const minutesResult = getSegmentRange({
11626
+ segment: minutes,
11627
+ offset
11628
+ });
11629
+ offset = minutesResult.nextOffset;
11630
+ return {
11631
+ ...getEmptySelectionRanges(),
11632
+ hours: hoursResult.range,
11633
+ "tens-of-minutes": minutesResult.range,
11634
+ ...getSecondsRanges({
11635
+ segment: seconds,
11636
+ offset
11637
+ })
11638
+ };
11639
+ }
11640
+ if (maxUnit === "tens-of-minutes") {
11641
+ const [minutes = "", seconds = ""] = segments;
11642
+ const minutesResult = getSegmentRange({
11643
+ segment: minutes,
11644
+ offset
11645
+ });
11646
+ offset = minutesResult.nextOffset;
11647
+ return {
11648
+ ...getEmptySelectionRanges(),
11649
+ "tens-of-minutes": minutesResult.range,
11650
+ ...getSecondsRanges({
11651
+ segment: seconds,
11652
+ offset
11653
+ })
11654
+ };
11655
+ }
11656
+ if (maxUnit === "minutes") {
11657
+ const [minutes = "", seconds = ""] = segments;
11658
+ const minutesResult = getSegmentRange({
11659
+ segment: minutes,
11660
+ offset
11661
+ });
11662
+ offset = minutesResult.nextOffset;
11663
+ return {
11664
+ ...getEmptySelectionRanges(),
11665
+ minutes: minutesResult.range,
11666
+ ...getSecondsRanges({
11667
+ segment: seconds,
11668
+ offset
11669
+ })
11670
+ };
11671
+ }
11672
+ const [seconds = ""] = segments;
11673
+ return {
11674
+ ...getEmptySelectionRanges(),
11675
+ ...getSecondsRanges({
11676
+ segment: seconds,
11677
+ offset
11678
+ })
11679
+ };
11680
+ };
11681
+ //#endregion
11682
+ //#region src/components/InputDuration/durationUnits.ts
11683
+ const DURATION_UNITS = new Set([
11684
+ "hours",
11685
+ "hundredths-of-seconds",
11686
+ "minutes",
11687
+ "seconds",
11688
+ "tens-of-minutes"
11689
+ ]);
11690
+ const isDurationUnit = (unit) => {
11691
+ return isNotNil(unit) && DURATION_UNITS.has(unit);
11692
+ };
11693
+ //#endregion
11694
+ //#region src/components/InputDuration/useInputDuration.ts
11695
+ const useInputDuration = ({ decimalUnitLength, maxSeconds, minSeconds, onChangeValueInSeconds, valueInSeconds }) => {
11696
+ const [inputSelection, setInputSelection] = useState(null);
11697
+ const inputRef = useRef(null);
11698
+ const anyKeyIsDownRef = useRef(false);
11699
+ const selectedUnitRef = useRef(null);
11700
+ const secondDigitMightBeTypedNext = useRef(false);
11701
+ const { maxSeconds: roundedMaxSeconds, minSeconds: roundedMinSeconds } = useMemo(() => getDurationBounds({
11702
+ decimalUnitLength,
11703
+ maxSeconds,
11704
+ minSeconds
11705
+ }), [
11706
+ decimalUnitLength,
11707
+ maxSeconds,
11708
+ minSeconds
11709
+ ]);
11710
+ const maxUnit = useMemo(() => getMaxUnit(roundedMaxSeconds), [roundedMaxSeconds]);
11711
+ const boundedValueInSeconds = useMemo(() => clampSeconds({
11712
+ maxSeconds: roundedMaxSeconds,
11713
+ minSeconds: roundedMinSeconds,
11714
+ seconds: valueInSeconds
11715
+ }), [
11716
+ roundedMaxSeconds,
11717
+ roundedMinSeconds,
11718
+ valueInSeconds
11719
+ ]);
11720
+ const inputValue = useMemo(() => secondsToDurationValue({
11721
+ decimalUnitLength,
11722
+ maxUnit,
11723
+ seconds: boundedValueInSeconds
11724
+ }), [
11725
+ boundedValueInSeconds,
11726
+ decimalUnitLength,
11727
+ maxUnit
11728
+ ]);
11729
+ const selectionRanges = useMemo(() => getSelectionRanges({
11730
+ inputValue,
11731
+ maxUnit
11732
+ }), [inputValue, maxUnit]);
11733
+ const decimalStep = decimalUnitLength === 0 ? 0 : ONE_HUNDREDTH_OF_A_SECOND;
11734
+ const maybeSetInputValueAndTriggerOnChange = useCallback((candidateInputValue) => {
11735
+ const seconds = durationValueToSeconds(candidateInputValue);
11736
+ if (seconds < roundedMinSeconds || seconds > roundedMaxSeconds) return;
11737
+ onChangeValueInSeconds(seconds);
11738
+ }, [
11739
+ onChangeValueInSeconds,
11740
+ roundedMaxSeconds,
11741
+ roundedMinSeconds
11742
+ ]);
11743
+ const selectUnit = useCallback((unit) => {
11744
+ selectedUnitRef.current = unit;
11745
+ if (unit == null) {
11746
+ setInputSelection(null);
11747
+ return;
11748
+ }
11749
+ const { start, end } = selectionRanges[unit];
11750
+ if (start == null || end == null) {
11751
+ setInputSelection(null);
11752
+ return;
11753
+ }
11754
+ inputRef.current?.setSelectionRange(start, end);
11755
+ setInputSelection({
11756
+ start,
11757
+ end
11758
+ });
11759
+ }, [selectionRanges]);
11760
+ const getFirstSelectableUnit = useCallback(() => {
11761
+ const result = Object.entries(selectionRanges).find(([, { start, end }]) => {
11762
+ return start !== null && end !== null;
11763
+ })?.[0] ?? null;
11764
+ if (!isDurationUnit(result)) return null;
11765
+ return result;
11766
+ }, [selectionRanges]);
11767
+ const selectFirstUnit = useCallback(() => {
11768
+ selectUnit(getFirstSelectableUnit());
11769
+ }, [getFirstSelectableUnit, selectUnit]);
11770
+ const getUnitForSelectionIndices = useCallback(({ selectionStart, selectionEnd }) => {
11771
+ const result = Object.entries(selectionRanges).find(([, { start, end }]) => {
11772
+ if (start === null || end === null) return false;
11773
+ return selectionStart >= start && selectionEnd <= end;
11774
+ })?.[0] ?? null;
11775
+ if (!isDurationUnit(result)) return null;
11776
+ return result;
11777
+ }, [selectionRanges]);
11778
+ const selectedUnit = useMemo(() => {
11779
+ if (inputSelection == null) return null;
11780
+ const { start: selectionStart, end: selectionEnd } = inputSelection;
11781
+ const foundUnit = getUnitForSelectionIndices({
11782
+ selectionStart,
11783
+ selectionEnd
11784
+ });
11785
+ if (!isDurationUnit(foundUnit)) return null;
11786
+ return foundUnit;
11787
+ }, [getUnitForSelectionIndices, inputSelection]);
11788
+ const selectUnitToRight = useCallback(() => {
11789
+ if (inputSelection == null) return;
11790
+ const unitToSelect = getUnitForSelectionIndices({
11791
+ selectionEnd: inputSelection.end + 1,
11792
+ selectionStart: inputSelection.end + 1
11793
+ });
11794
+ if (unitToSelect == null) return;
11795
+ selectedUnitRef.current = unitToSelect;
11796
+ requestAnimationFrame(() => {
11797
+ selectUnit(unitToSelect);
11798
+ });
11799
+ }, [
11800
+ getUnitForSelectionIndices,
11801
+ inputSelection,
11802
+ selectUnit
11803
+ ]);
11804
+ const selectUnitToLeft = useCallback(() => {
11805
+ if (inputSelection == null) return;
11806
+ const unitToSelect = getUnitForSelectionIndices({
11807
+ selectionEnd: inputSelection.start - 1,
11808
+ selectionStart: inputSelection.start - 1
11809
+ });
11810
+ if (unitToSelect == null) return;
11811
+ selectUnit(unitToSelect);
11812
+ }, [
11813
+ getUnitForSelectionIndices,
11814
+ inputSelection,
11815
+ selectUnit
11816
+ ]);
11817
+ const incrementBySeconds = useCallback((secondsToIncrementBy) => {
11818
+ const newValue = durationValueToSeconds(inputValue) + secondsToIncrementBy;
11819
+ if (newValue > roundedMaxSeconds) return;
11820
+ maybeSetInputValueAndTriggerOnChange(secondsToDurationValue({
11821
+ decimalUnitLength,
11822
+ maxUnit,
11823
+ seconds: newValue
11824
+ }));
11825
+ }, [
11826
+ decimalUnitLength,
11827
+ inputValue,
11828
+ maxUnit,
11829
+ maybeSetInputValueAndTriggerOnChange,
11830
+ roundedMaxSeconds
11831
+ ]);
11832
+ const decrementBySeconds = useCallback((secondsToDecrementBy) => {
11833
+ const newValue = durationValueToSeconds(inputValue) - secondsToDecrementBy;
11834
+ if (newValue < roundedMinSeconds) return;
11835
+ maybeSetInputValueAndTriggerOnChange(secondsToDurationValue({
11836
+ decimalUnitLength,
11837
+ maxUnit,
11838
+ seconds: newValue
11839
+ }));
11840
+ }, [
11841
+ decimalUnitLength,
11842
+ inputValue,
11843
+ maxUnit,
11844
+ maybeSetInputValueAndTriggerOnChange,
11845
+ roundedMinSeconds
11846
+ ]);
11847
+ const incrementSelectedUnit = useCallback(() => {
11848
+ if (selectedUnit == null) return;
11849
+ if (selectedUnit === "hours") {
11850
+ incrementBySeconds(SECONDS_PER_HOUR);
11851
+ return;
11852
+ }
11853
+ if (selectedUnit === "minutes" || selectedUnit === "tens-of-minutes") {
11854
+ incrementBySeconds(SECONDS_PER_MINUTE);
11855
+ return;
11856
+ }
11857
+ if (selectedUnit === "seconds") {
11858
+ incrementBySeconds(1);
11859
+ return;
11860
+ }
11861
+ incrementBySeconds(decimalStep);
11862
+ }, [
11863
+ decimalStep,
11864
+ incrementBySeconds,
11865
+ selectedUnit
11866
+ ]);
11867
+ const decrementSelectedUnit = useCallback(() => {
11868
+ if (selectedUnit == null) return;
11869
+ if (selectedUnit === "hours") {
11870
+ decrementBySeconds(SECONDS_PER_HOUR);
11871
+ return;
11872
+ }
11873
+ if (selectedUnit === "minutes" || selectedUnit === "tens-of-minutes") {
11874
+ decrementBySeconds(SECONDS_PER_MINUTE);
11875
+ return;
11876
+ }
11877
+ if (selectedUnit === "seconds") {
11878
+ decrementBySeconds(1);
11879
+ return;
11880
+ }
11881
+ decrementBySeconds(decimalStep);
11882
+ }, [
11883
+ decimalStep,
11884
+ decrementBySeconds,
11885
+ selectedUnit
11886
+ ]);
11887
+ const setSelectedUnitToZero = useCallback(() => {
11888
+ if (selectedUnit == null || inputSelection == null) return;
11889
+ const textToLeftOfSelection = inputValue.slice(0, inputSelection.start);
11890
+ const textToRightOfSelection = inputValue.slice(inputSelection.end);
11891
+ if (selectedUnit === "hours") {
11892
+ maybeSetInputValueAndTriggerOnChange(`0${textToRightOfSelection}`);
11893
+ selectUnitToRight();
11894
+ return;
11895
+ }
11896
+ if (selectedUnit === "tens-of-minutes") {
11897
+ maybeSetInputValueAndTriggerOnChange(`${textToLeftOfSelection}00${textToRightOfSelection}`);
11898
+ selectUnitToRight();
11899
+ return;
11900
+ }
11901
+ if (selectedUnit === "minutes") {
11902
+ maybeSetInputValueAndTriggerOnChange(`0${textToRightOfSelection}`);
11903
+ selectUnitToRight();
11904
+ return;
11905
+ }
11906
+ if (selectedUnit === "seconds") {
11907
+ maybeSetInputValueAndTriggerOnChange(`${textToLeftOfSelection}00${textToRightOfSelection}`);
11908
+ selectUnitToRight();
11909
+ return;
11910
+ }
11911
+ maybeSetInputValueAndTriggerOnChange(`${textToLeftOfSelection}${"0".repeat(decimalUnitLength)}`);
11912
+ selectUnitToRight();
11913
+ }, [
11914
+ decimalUnitLength,
11915
+ inputSelection,
11916
+ inputValue,
11917
+ maybeSetInputValueAndTriggerOnChange,
11918
+ selectUnitToRight,
11919
+ selectedUnit
11920
+ ]);
11921
+ const onInputSelect = useCallback((event) => {
11922
+ if (anyKeyIsDownRef.current) return;
11923
+ const { selectionStart, selectionEnd } = event.currentTarget;
11924
+ if (selectionStart === null || selectionEnd === null) return;
11925
+ selectUnit(getUnitForSelectionIndices({
11926
+ selectionStart,
11927
+ selectionEnd
11928
+ }));
11929
+ }, [getUnitForSelectionIndices, selectUnit]);
11930
+ const onFocus = useCallback(() => {
11931
+ const selectFirstUnitIfAllTextIsSelected = () => {
11932
+ const input = inputRef.current;
11933
+ if (input == null) return;
11934
+ if (input.selectionStart === 0 && input.selectionEnd === input.value.length) selectFirstUnit();
11935
+ };
11936
+ selectFirstUnitIfAllTextIsSelected();
11937
+ requestAnimationFrame(selectFirstUnitIfAllTextIsSelected);
11938
+ }, [selectFirstUnit]);
11939
+ const restoreSelectionToSelectedUnit = useCallback(() => {
11940
+ selectUnit(selectedUnitRef.current);
11941
+ }, [selectUnit]);
11942
+ useLayoutEffect(() => {
11943
+ if (inputRef.current == null || document.activeElement !== inputRef.current) return;
11944
+ selectUnit(selectedUnitRef.current);
11945
+ }, [inputValue, selectUnit]);
11946
+ const prepareForPossibleSecondDigit = useCallback(() => {
11947
+ secondDigitMightBeTypedNext.current = true;
11948
+ restoreSelectionToSelectedUnit();
11949
+ }, [restoreSelectionToSelectedUnit]);
11950
+ const onTypeNumber = useCallback((number) => {
11951
+ if (inputSelection == null) return;
11952
+ const selectedText = inputValue.slice(inputSelection.start, inputSelection.end);
11953
+ const textToLeftOfSelection = inputValue.slice(0, inputSelection.start);
11954
+ const textToRightOfSelection = inputValue.slice(inputSelection.end);
11955
+ if (selectedUnit === "hours") {
11956
+ maybeSetInputValueAndTriggerOnChange(`${number.toString()}${textToRightOfSelection}`);
11957
+ selectUnitToRight();
11958
+ return;
11959
+ }
11960
+ if (selectedUnit === "tens-of-minutes" && number >= SECONDS_PER_MINUTE / 10 && !secondDigitMightBeTypedNext.current) {
11961
+ maybeSetInputValueAndTriggerOnChange(`${textToLeftOfSelection}0${number.toString()}${textToRightOfSelection}`);
11962
+ secondDigitMightBeTypedNext.current = false;
11963
+ selectUnitToRight();
11964
+ return;
11965
+ }
11966
+ if (selectedUnit === "tens-of-minutes" && !secondDigitMightBeTypedNext.current) {
11967
+ maybeSetInputValueAndTriggerOnChange(`${textToLeftOfSelection}${number.toString()}0${textToRightOfSelection}`);
11968
+ prepareForPossibleSecondDigit();
11969
+ return;
11970
+ }
11971
+ if (selectedUnit === "tens-of-minutes" && secondDigitMightBeTypedNext.current) {
11972
+ maybeSetInputValueAndTriggerOnChange(`${textToLeftOfSelection}${selectedText[0]}${number.toString()}${textToRightOfSelection}`);
11973
+ secondDigitMightBeTypedNext.current = false;
11974
+ selectUnitToRight();
11975
+ return;
11976
+ }
11977
+ if (selectedUnit === "minutes") {
11978
+ maybeSetInputValueAndTriggerOnChange(`${number.toString()}${textToRightOfSelection}`);
11979
+ selectUnitToRight();
11980
+ return;
11981
+ }
11982
+ if (selectedUnit === "seconds" && number >= SECONDS_PER_MINUTE / 10 && !secondDigitMightBeTypedNext.current) {
11983
+ maybeSetInputValueAndTriggerOnChange(`${textToLeftOfSelection}0${number.toString()}${textToRightOfSelection}`);
11984
+ secondDigitMightBeTypedNext.current = false;
11985
+ selectUnitToRight();
11986
+ return;
11987
+ }
11988
+ if (selectedUnit === "seconds" && !secondDigitMightBeTypedNext.current) {
11989
+ maybeSetInputValueAndTriggerOnChange(`${textToLeftOfSelection}${number.toString()}0${textToRightOfSelection}`);
11990
+ prepareForPossibleSecondDigit();
11991
+ return;
11992
+ }
11993
+ if (selectedUnit === "seconds" && secondDigitMightBeTypedNext.current) {
11994
+ maybeSetInputValueAndTriggerOnChange(`${textToLeftOfSelection}${selectedText[0]}${number.toString()}${textToRightOfSelection}`);
11995
+ secondDigitMightBeTypedNext.current = false;
11996
+ selectUnitToRight();
11997
+ return;
11998
+ }
11999
+ if (selectedUnit === "hundredths-of-seconds" && !secondDigitMightBeTypedNext.current) {
12000
+ maybeSetInputValueAndTriggerOnChange(`${textToLeftOfSelection}${number.toString()}0`);
12001
+ prepareForPossibleSecondDigit();
12002
+ return;
12003
+ }
12004
+ if (selectedUnit === "hundredths-of-seconds" && secondDigitMightBeTypedNext.current) {
12005
+ maybeSetInputValueAndTriggerOnChange(`${textToLeftOfSelection}${selectedText[0]}${number.toString()}`);
12006
+ secondDigitMightBeTypedNext.current = false;
12007
+ restoreSelectionToSelectedUnit();
12008
+ }
12009
+ }, [
12010
+ inputSelection,
12011
+ inputValue,
12012
+ maybeSetInputValueAndTriggerOnChange,
12013
+ prepareForPossibleSecondDigit,
12014
+ restoreSelectionToSelectedUnit,
12015
+ selectUnitToRight,
12016
+ selectedUnit
12017
+ ]);
12018
+ return {
12019
+ inputRef,
12020
+ inputValue,
12021
+ onFocus,
12022
+ onInputSelect,
12023
+ onKeyDown: useCallback((event) => {
12024
+ anyKeyIsDownRef.current = true;
12025
+ if (inputRef.current == null || inputSelection == null) return;
12026
+ const { start: selectionStart, end: selectionEnd } = inputSelection;
12027
+ const { key } = event;
12028
+ if (key === "ArrowRight") {
12029
+ event.preventDefault();
12030
+ secondDigitMightBeTypedNext.current = false;
12031
+ selectUnitToRight();
12032
+ return;
12033
+ }
12034
+ if (key === "ArrowLeft") {
12035
+ event.preventDefault();
12036
+ secondDigitMightBeTypedNext.current = false;
12037
+ selectUnitToLeft();
12038
+ return;
12039
+ }
12040
+ if (key === "ArrowUp") {
12041
+ event.preventDefault();
12042
+ secondDigitMightBeTypedNext.current = false;
12043
+ incrementSelectedUnit();
12044
+ restoreSelectionToSelectedUnit();
12045
+ return;
12046
+ }
12047
+ if (key === "ArrowDown") {
12048
+ event.preventDefault();
12049
+ secondDigitMightBeTypedNext.current = false;
12050
+ decrementSelectedUnit();
12051
+ restoreSelectionToSelectedUnit();
12052
+ return;
12053
+ }
12054
+ if (key === "Tab" && !event.shiftKey && selectionEnd < inputRef.current.value.length) {
12055
+ event.preventDefault();
12056
+ secondDigitMightBeTypedNext.current = false;
12057
+ selectUnitToRight();
12058
+ return;
12059
+ }
12060
+ if (key === "Tab" && event.shiftKey && selectionStart > 0) {
12061
+ event.preventDefault();
12062
+ secondDigitMightBeTypedNext.current = false;
12063
+ selectUnitToLeft();
12064
+ return;
12065
+ }
12066
+ if (key === ":") {
12067
+ event.preventDefault();
12068
+ secondDigitMightBeTypedNext.current = false;
12069
+ selectUnitToRight();
12070
+ return;
12071
+ }
12072
+ if (key === "." && decimalUnitLength > 0) {
12073
+ event.preventDefault();
12074
+ secondDigitMightBeTypedNext.current = false;
12075
+ selectUnit("hundredths-of-seconds");
12076
+ return;
12077
+ }
12078
+ if (NUMBER_STRING_SET.has(key)) {
12079
+ event.preventDefault();
12080
+ onTypeNumber(Number(key));
12081
+ return;
12082
+ }
12083
+ if (key === "Backspace") {
12084
+ event.preventDefault();
12085
+ setSelectedUnitToZero();
12086
+ restoreSelectionToSelectedUnit();
12087
+ }
12088
+ }, [
12089
+ decimalUnitLength,
12090
+ decrementSelectedUnit,
12091
+ incrementSelectedUnit,
12092
+ inputSelection,
12093
+ onTypeNumber,
12094
+ restoreSelectionToSelectedUnit,
12095
+ selectUnit,
12096
+ selectUnitToLeft,
12097
+ selectUnitToRight,
12098
+ setSelectedUnitToZero
12099
+ ]),
12100
+ onKeyUp: useCallback(() => {
12101
+ anyKeyIsDownRef.current = false;
12102
+ }, [])
12103
+ };
12104
+ };
12105
+ //#endregion
12106
+ //#region src/components/InputDuration/InputDuration.tsx
12107
+ const EXTRA_INPUT_WIDTH_CH = 4;
12108
+ const getInputWidth = (inputValue) => {
12109
+ return `calc(${inputValue.length + EXTRA_INPUT_WIDTH_CH}ch + var(--wui-input-horizontal-padding) + var(--wui-input-horizontal-padding))`;
12110
+ };
12111
+ /**
12112
+ * InputDuration lets users edit a duration value using a keyboard-friendly time input.
12113
+ */
12114
+ const InputDuration = forwardRef(({ decimalUnitLength = 2, disabled = false, fullWidth = false, maxSeconds = MAX_TIME, minSeconds = 0, onChangeValueInSeconds, valueInSeconds, onFocus, style, ...props }, externalRef) => {
12115
+ const { inputRef, inputValue, onFocus: onInputFocus, onInputSelect, onKeyDown, onKeyUp } = useInputDuration({
12116
+ decimalUnitLength,
12117
+ maxSeconds,
12118
+ minSeconds,
12119
+ onChangeValueInSeconds,
12120
+ valueInSeconds
12121
+ });
12122
+ const inputWidth = fullWidth ? void 0 : getInputWidth(inputValue);
12123
+ useImperativeHandle(externalRef, () => inputRef.current);
12124
+ const handleFocus = (event) => {
12125
+ onInputFocus();
12126
+ onFocus?.(event);
12127
+ };
12128
+ return /* @__PURE__ */ jsx(Input, {
12129
+ ...props,
12130
+ ref: inputRef,
12131
+ disabled,
12132
+ fullWidth,
12133
+ inputMode: "numeric",
12134
+ monospace: true,
12135
+ onChange: () => {},
12136
+ onFocus: handleFocus,
12137
+ onKeyDown,
12138
+ onKeyUp,
12139
+ onSelect: onInputSelect,
12140
+ style: {
12141
+ width: inputWidth,
12142
+ textAlign: "right",
12143
+ caretColor: "transparent",
12144
+ ...style
12145
+ },
12146
+ type: "text",
12147
+ value: inputValue
12148
+ });
12149
+ });
12150
+ InputDuration.displayName = "InputDuration_UI";
12151
+ //#endregion
11447
12152
  //#region src/components/InputPassword/InputPassword.tsx
11448
12153
  const StyledIconButton = styled(IconButton)`
11449
12154
  /* override size for icon button since prop gets changed by Input */
@@ -15029,6 +15734,6 @@ const WistiaLogo = ({ description, height = 100, hoverColor, href, iconOnly = fa
15029
15734
  };
15030
15735
  WistiaLogo.displayName = "WistiaLogo_UI";
15031
15736
  //#endregion
15032
- export { ActionButton, Avatar, Badge, Banner, Box, Breadcrumb, Breadcrumbs, Button, ButtonGroup, Card, Center, Checkbox, CheckboxGroup, CheckboxMenuItem, ClickRegion, Collapsible, CollapsibleContent, CollapsibleTrigger, CollapsibleTriggerIcon, ColorGrid, ColorGridOption, ColorList, ColorListGroup, ColorListOption, ColorPicker, ColorPickerPopoverContent, ColorPickerSection, ColorPickerTrigger, ColorSchemeWrapper, Combobox, ComboboxOption, ContextMenu, ContrastControls, CustomizableThemeWrapper, DataCard, DataCardHoverArrow, DataCardTrend, DataCards, DataList, DataListItem, DataListItemLabel, DataListItemValue, 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, Image, ImageDimensionsValidator, Input, InputClickToCopy, 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, Slider, SplitButton, Stack, SubMenu, Switch, Table, TableBody, TableCell, TableFoot, TableHead, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Tag, Text, Thumbnail, ThumbnailBadge, ThumbnailCollage, Tooltip, UIProvider, ValueNameOrHexCode, ValueSwatch, WistiaLogo, buildTimeDuration, calculateContrast, coerceToBoolean, colorSchemeOptions, copyToClipboard, dateOnlyISOString, dateOnlyString, dateOnlyStringForSentence, dateOnlyStringNumeric, dateTime, dateTimeRounded, dateTimeString, dateTimeStringForSentence, dateTimeToDate, dateTimeToISO, dateToDateTime, dateUTCOffset, dayOfWeekString, iconSizeMap, isKeyboardKey, mediaDurationString, mergeRefs, millisecondsToDurationISOString, monthDayStringNumeric, mq, parseDateString, sessionDurationString, timeAgoString, timeOnlyString, useActiveMq, useAriaLive, useBoolean, useClipboard, useElementObserver, useFilePicker, useFocusTrap, useForceUpdate, useFormState, useImperativeFilePicker, useIsHovered, useKey, useKeyPress, useLocalStorage, useLockBodyScroll, useMq, useOnClickOutside, usePreviousValue, useToast, useWindowSize, validateWithYup };
15737
+ export { ActionButton, Avatar, Badge, Banner, Box, Breadcrumb, Breadcrumbs, Button, ButtonGroup, Card, Center, Checkbox, CheckboxGroup, CheckboxMenuItem, ClickRegion, Collapsible, CollapsibleContent, CollapsibleTrigger, CollapsibleTriggerIcon, ColorGrid, ColorGridOption, ColorList, ColorListGroup, ColorListOption, ColorPicker, ColorPickerPopoverContent, ColorPickerSection, ColorPickerTrigger, ColorSchemeWrapper, Combobox, ComboboxOption, ContextMenu, ContrastControls, CustomizableThemeWrapper, DataCard, DataCardHoverArrow, DataCardTrend, DataCards, DataList, DataListItem, DataListItemLabel, DataListItemValue, 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, 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, Slider, SplitButton, Stack, SubMenu, Switch, Table, TableBody, TableCell, TableFoot, TableHead, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Tag, Text, Thumbnail, ThumbnailBadge, ThumbnailCollage, Tooltip, UIProvider, ValueNameOrHexCode, ValueSwatch, WistiaLogo, buildTimeDuration, calculateContrast, coerceToBoolean, colorSchemeOptions, copyToClipboard, dateOnlyISOString, dateOnlyString, dateOnlyStringForSentence, dateOnlyStringNumeric, dateTime, dateTimeRounded, dateTimeString, dateTimeStringForSentence, dateTimeToDate, dateTimeToISO, dateToDateTime, dateUTCOffset, dayOfWeekString, iconSizeMap, isKeyboardKey, mediaDurationString, mergeRefs, millisecondsToDurationISOString, monthDayStringNumeric, mq, parseDateString, sessionDurationString, timeAgoString, timeOnlyString, useActiveMq, useAriaLive, useBoolean, useClipboard, useElementObserver, useFilePicker, useFocusTrap, useForceUpdate, useFormState, useImperativeFilePicker, useIsHovered, useKey, useKeyPress, useLocalStorage, useLockBodyScroll, useMq, useOnClickOutside, usePreviousValue, useToast, useWindowSize, validateWithYup };
15033
15738
 
15034
15739
  //# sourceMappingURL=index.js.map