@oracle/oraclejet-preact 18.0.0 → 18.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/amd/InputDatePicker-18e2546b.js +2 -0
- package/amd/{InputDatePicker-fc39f0a6.js.map → InputDatePicker-18e2546b.js.map} +1 -1
- package/amd/ReadonlyTextFieldVariants.styles.css +20 -20
- package/amd/ReadonlyTextFieldVariants.styles2.css +20 -20
- package/amd/Theme-redwood/theme.css +142 -142
- package/amd/Theme-stable/theme.css +216 -216
- package/amd/UNSAFE_InputDateMask.js +1 -1
- package/amd/UNSAFE_InputDatePicker.js +1 -1
- package/amd/UNSAFE_InputPassword.js +1 -1
- package/amd/UNSAFE_InputSensitiveText.js +1 -1
- package/amd/UNSAFE_InputSensitiveText.js.map +1 -1
- package/amd/UNSAFE_InputText.js +1 -1
- package/amd/UNSAFE_InputTimeMask.js +1 -1
- package/amd/UNSAFE_InputTimeMask.js.map +1 -1
- package/amd/UNSAFE_LabelledLink.js +1 -1
- package/amd/UNSAFE_LabelledLink.js.map +1 -1
- package/amd/UNSAFE_NumberInputText.js +1 -1
- package/amd/UNSAFE_SelectMultiple.js +1 -1
- package/amd/UNSAFE_SelectSingle.js +1 -1
- package/amd/UNSAFE_TextArea.js +1 -1
- package/amd/UNSAFE_TextAreaAutosize.js +1 -1
- package/amd/UNSAFE_TextField/themes/redwood/ReadonlyTextFieldTheme.js +1 -1
- package/amd/UNSAFE_TextField/themes/redwood/ReadonlyTextFieldTheme.js.map +1 -1
- package/amd/UNSAFE_TextField/themes/redwood/ReadonlyTextFieldVariants.css.js +1 -1
- package/amd/UNSAFE_TextField/themes/stable/ReadonlyTextFieldTheme.js +1 -1
- package/amd/UNSAFE_TextField/themes/stable/ReadonlyTextFieldTheme.js.map +1 -1
- package/amd/UNSAFE_TextField/themes/stable/ReadonlyTextFieldVariants.css.js +1 -1
- package/amd/UNSAFE_TextField.js +1 -1
- package/cjs/ActionCard-61b21d6c.js +1 -1
- package/cjs/{BarChart-ca7f8ed5.js → BarChart-93a3813c.js} +3 -3
- package/cjs/{BarChart-ca7f8ed5.js.map → BarChart-93a3813c.js.map} +1 -1
- package/cjs/BarGroup-4a24a995.js +1 -1
- package/cjs/BaseButton-3a0bf8e4.js +2 -2
- package/cjs/BaseCardView-ade994f5.js +7 -7
- package/cjs/{BaseCardViewSelectionTest-df948f2c.js → BaseCardViewSelectionTest-c6f05079.js} +7 -7
- package/cjs/{BaseCardViewSelectionTest-df948f2c.js.map → BaseCardViewSelectionTest-c6f05079.js.map} +1 -1
- package/cjs/{useNavigationListItem-ae481fdc.js → BaseNavigationListItem-50e4c603.js} +40 -2
- package/cjs/BaseNavigationListItem-50e4c603.js.map +1 -0
- package/cjs/BaseRichSelection-e73cac1d.js +8 -8
- package/cjs/ButtonSet-90db1168.js +2 -2
- package/cjs/ButtonSetIconButton-f3b4a721.js +3 -3
- package/cjs/{Card-a6693442.js → Card-a0dadf5f.js} +2 -2
- package/cjs/{Card-a6693442.js.map → Card-a0dadf5f.js.map} +1 -1
- package/cjs/{Center-c0baccb0.js → Center-9f407cb2.js} +2 -2
- package/cjs/{Center-c0baccb0.js.map → Center-9f407cb2.js.map} +1 -1
- package/cjs/{Chart-fbbd3329.js → Chart-40d95d14.js} +10 -10
- package/cjs/{Chart-fbbd3329.js.map → Chart-40d95d14.js.map} +1 -1
- package/cjs/CheckboxControl-5beb656d.js +6 -6
- package/cjs/CheckboxRadioField-0d5c9def.js +6 -6
- package/cjs/Chip-f12bb8cd.js +1 -1
- package/cjs/ClearIcon-edcc3f6e.js +1 -1
- package/cjs/CollapseIcon-2394e7ea.js +1 -1
- package/cjs/Collapsible-41311eb0.js +2 -2
- package/cjs/{ComboChart-95863e7a.js → ComboChart-cffd0759.js} +4 -4
- package/cjs/{ComboChart-95863e7a.js.map → ComboChart-cffd0759.js.map} +1 -1
- package/cjs/CompactHelpSource-61ead0c7.js +2 -2
- package/cjs/{CompactLabelAssistance-fd841834.js → CompactLabelAssistance-ec1e72af.js} +5 -5
- package/cjs/{CompactLabelAssistance-fd841834.js.map → CompactLabelAssistance-ec1e72af.js.map} +1 -1
- package/cjs/CompactUserAssistance-391bf7ca.js +4 -4
- package/cjs/ComponentMessageContainer-24e79106.js +4 -4
- package/cjs/ConveyorBeltItem-ac146ef0.js +2 -2
- package/cjs/{DatePicker-65b047ad.js → DatePicker-d99097e4.js} +6 -6
- package/cjs/{DatePicker-65b047ad.js.map → DatePicker-d99097e4.js.map} +1 -1
- package/cjs/DatePickerHeader-0938a3aa.js +3 -3
- package/cjs/{Diagram-2e66a8cb.js → Diagram-aceccb23.js} +5 -5
- package/cjs/{Diagram-2e66a8cb.js.map → Diagram-aceccb23.js.map} +1 -1
- package/cjs/{Dialog-4160338c.js → Dialog-2219a24f.js} +8 -8
- package/cjs/{Dialog-4160338c.js.map → Dialog-2219a24f.js.map} +1 -1
- package/cjs/DirectionalCollapseArrowIcon-0cf2279a.js +1 -1
- package/cjs/DirectionalExpandArrowIcon-a362cb2f.js +1 -1
- package/cjs/{DragHandle-67b6118b.js → DragHandle-951c36ef.js} +2 -2
- package/cjs/{DragHandle-67b6118b.js.map → DragHandle-951c36ef.js.map} +1 -1
- package/cjs/{Dropdown-34b8f141.js → Dropdown-00e73e4d.js} +5 -5
- package/cjs/{Dropdown-34b8f141.js.map → Dropdown-00e73e4d.js.map} +1 -1
- package/cjs/{EnvironmentProvider-75eb79f3.js → EnvironmentProvider-bfd5febc.js} +3 -3
- package/cjs/{EnvironmentProvider-75eb79f3.js.map → EnvironmentProvider-bfd5febc.js.map} +1 -1
- package/cjs/ExpandableList-be84ca8e.js +3 -3
- package/cjs/FilePicker-f93470cf.js +2 -2
- package/cjs/{Flex-e7a85bef.js → Flex-ce16a2fa.js} +2 -2
- package/cjs/{Flex-e7a85bef.js.map → Flex-ce16a2fa.js.map} +1 -1
- package/cjs/{Floating-56621d20.js → Floating-3a80c067.js} +4 -4
- package/cjs/{Floating-56621d20.js.map → Floating-3a80c067.js.map} +1 -1
- package/cjs/FormLayout-86e60b6c.js +1 -1
- package/cjs/Gantt-7b6b99a0.js +9 -9
- package/cjs/{Grid-a7316edd.js → Grid-b8fadf4a.js} +2 -2
- package/cjs/{Grid-a7316edd.js.map → Grid-b8fadf4a.js.map} +1 -1
- package/cjs/{Gridlines-ef3af190.js → Gridlines-22c46764.js} +2 -2
- package/cjs/{Gridlines-ef3af190.js.map → Gridlines-22c46764.js.map} +1 -1
- package/cjs/GroupLoadingIndicator-5940d185.js +1 -1
- package/cjs/{HighlightText-dd11dd32.js → HighlightText-2061d12d.js} +2 -2
- package/cjs/{HighlightText-dd11dd32.js.map → HighlightText-2061d12d.js.map} +1 -1
- package/cjs/Icon-c024b93c.js +3 -3
- package/cjs/IconButton-28559efb.js +3 -3
- package/cjs/IconMenuButton-2a108d43.js +3 -3
- package/cjs/IconProgressButton-01d95e57.js +3 -3
- package/cjs/IconSwitchButton-a1016218.js +3 -3
- package/cjs/IconToggleButton-52f6f126.js +3 -3
- package/cjs/{IconUserAssistance-52208fde.js → IconUserAssistance-3faf6a09.js} +3 -3
- package/cjs/{IconUserAssistance-52208fde.js.map → IconUserAssistance-3faf6a09.js.map} +1 -1
- package/cjs/Indexer-72430806.js +4 -4
- package/cjs/InlineHelpSource-0549100d.js +1 -1
- package/cjs/InlineUserAssistance-820162f4.js +5 -5
- package/cjs/InputDateMask-a7575cef.js +7 -7
- package/cjs/{InputDatePicker-bc2c534a.js → InputDatePicker-4d36637f.js} +10 -10
- package/cjs/{InputDatePicker-bc2c534a.js.map → InputDatePicker-4d36637f.js.map} +1 -1
- package/cjs/InputPassword-eb6d227b.js +4 -4
- package/cjs/InputText-a9c423c3.js +6 -6
- package/cjs/Label-e0d15892.js +5 -5
- package/cjs/LabelValueLayout-4049c1a1.js +1 -1
- package/cjs/{Layer-0053053a.js → Layer-49394ca6.js} +3 -3
- package/cjs/{Layer-0053053a.js.map → Layer-49394ca6.js.map} +1 -1
- package/cjs/{LayerHost-a8c7f182.js → LayerHost-7182bfaf.js} +2 -2
- package/cjs/{LayerHost-a8c7f182.js.map → LayerHost-7182bfaf.js.map} +1 -1
- package/cjs/{LayerManager-2d0b83ac.js → LayerManager-db087520.js} +2 -2
- package/cjs/{LayerManager-2d0b83ac.js.map → LayerManager-db087520.js.map} +1 -1
- package/cjs/Legend-33a7824e.js +3 -3
- package/cjs/{LineAreaChart-4a54a017.js → LineAreaChart-57408e94.js} +4 -4
- package/cjs/{LineAreaChart-4a54a017.js.map → LineAreaChart-57408e94.js.map} +1 -1
- package/cjs/{LineSeries-0e984080.js → LineSeries-995be81c.js} +2 -2
- package/cjs/{LineSeries-0e984080.js.map → LineSeries-995be81c.js.map} +1 -1
- package/cjs/Link-b8435440.js +1 -1
- package/cjs/List-0dc2c4c4.js +5 -5
- package/cjs/{ListItemLayout-ec53f199.js → ListItemLayout-bc581097.js} +2 -2
- package/cjs/{ListItemLayout-ec53f199.js.map → ListItemLayout-bc581097.js.map} +1 -1
- package/cjs/ListView-17b8250d.js +3 -3
- package/cjs/{LiveRegion-567427c5.js → LiveRegion-3bc583c6.js} +2 -2
- package/cjs/{LiveRegion-567427c5.js.map → LiveRegion-3bc583c6.js.map} +1 -1
- package/cjs/{MaxLengthLiveRegion-f03f07c6.js → MaxLengthLiveRegion-5e31c44e.js} +3 -3
- package/cjs/{MaxLengthLiveRegion-f03f07c6.js.map → MaxLengthLiveRegion-5e31c44e.js.map} +1 -1
- package/cjs/Menu-658212ed.js +6 -6
- package/cjs/MenuButton-1599ce50.js +2 -2
- package/cjs/MenuItem-c459d748.js +1 -1
- package/cjs/Message-33a66325.js +2 -2
- package/cjs/{MessageLayer-f9aa9828.js → MessageLayer-fc21a223.js} +6 -6
- package/cjs/{MessageLayer-f9aa9828.js.map → MessageLayer-fc21a223.js.map} +1 -1
- package/cjs/MessageToast-0b1d66ed.js +8 -8
- package/cjs/MessagesManager-1ae749bf.js +3 -3
- package/cjs/MeterBar-0adbe81a.js +5 -5
- package/cjs/MeterCircle-97a75b35.js +5 -5
- package/cjs/{Modal-b9987f2d.js → Modal-76b3a4d9.js} +3 -3
- package/cjs/{Modal-b9987f2d.js.map → Modal-76b3a4d9.js.map} +1 -1
- package/cjs/{MonthView-9c2819f0.js → MonthView-458d3d61.js} +4 -4
- package/cjs/{MonthView-9c2819f0.js.map → MonthView-458d3d61.js.map} +1 -1
- package/cjs/{NavigationList-7495908b.js → NavigationListItem-4c4e804d.js} +23 -5
- package/cjs/NavigationListItem-4c4e804d.js.map +1 -0
- package/cjs/NumberInputText-3f25f408.js +6 -6
- package/cjs/{OverflowTabBar-e92bab53.js → OverflowTabBar-428798a0.js} +3 -3
- package/cjs/{OverflowTabBar-e92bab53.js.map → OverflowTabBar-428798a0.js.map} +1 -1
- package/cjs/{OverflowTabBarItem-5820e1fa.js → OverflowTabBarItem-3c7adb01.js} +7 -8
- package/cjs/{OverflowTabBarItem-5820e1fa.js.map → OverflowTabBarItem-3c7adb01.js.map} +1 -1
- package/cjs/PRIVATE_BaseCardView.js +22 -22
- package/cjs/PRIVATE_Chart.js +35 -35
- package/cjs/PRIVATE_CheckboxControl.js +23 -23
- package/cjs/PRIVATE_CheckboxRadioField.js +24 -24
- package/cjs/PRIVATE_ClearIcon.js +18 -18
- package/cjs/PRIVATE_DatePickerHeader.js +19 -19
- package/cjs/PRIVATE_DatePickerLayout.js +4 -4
- package/cjs/PRIVATE_EmbeddedIconButton.js +3 -3
- package/cjs/PRIVATE_FormControls.js +19 -19
- package/cjs/PRIVATE_IconSwitchButton.js +16 -16
- package/cjs/PRIVATE_Icons/CheckboxMixed.js +16 -16
- package/cjs/PRIVATE_Icons/CheckboxOff.js +16 -16
- package/cjs/PRIVATE_Icons/CheckboxOn.js +16 -16
- package/cjs/PRIVATE_Icons/DragV.js +16 -16
- package/cjs/PRIVATE_Icons/WarningS.js +16 -16
- package/cjs/PRIVATE_List.js +20 -20
- package/cjs/PRIVATE_Message.js +19 -19
- package/cjs/PRIVATE_MessageLayer.js +12 -12
- package/cjs/PRIVATE_MonthView.js +7 -7
- package/cjs/PRIVATE_MonthYearGridView.js +7 -7
- package/cjs/PRIVATE_PlotArea.js +4 -4
- package/cjs/PRIVATE_RevealToggleIcon.js +17 -17
- package/cjs/PRIVATE_RichSelectionCommon.js +25 -25
- package/cjs/PRIVATE_SelectCommon.js +28 -28
- package/cjs/PRIVATE_StyledCard.js +4 -4
- package/cjs/PRIVATE_StyledCheckbox.js +16 -16
- package/cjs/PRIVATE_Table.js +24 -24
- package/cjs/PRIVATE_ThemedIcons/CalendarIcon.js +16 -16
- package/cjs/PRIVATE_ThemedIcons/ChartMarqueeSelectIcon.js +16 -16
- package/cjs/PRIVATE_ThemedIcons/ChartPanIcon.js +16 -16
- package/cjs/PRIVATE_ThemedIcons/ChartZoomIcon.js +16 -16
- package/cjs/PRIVATE_ThemedIcons/CheckIcon.js +16 -16
- package/cjs/PRIVATE_ThemedIcons/CheckboxMixedIcon.js +16 -16
- package/cjs/PRIVATE_ThemedIcons/CheckboxOffIcon.js +16 -16
- package/cjs/PRIVATE_ThemedIcons/CheckboxOnIcon.js +16 -16
- package/cjs/PRIVATE_ThemedIcons/CloseIcon.js +16 -16
- package/cjs/PRIVATE_ThemedIcons/CollapseIcon.js +17 -17
- package/cjs/PRIVATE_ThemedIcons/CollapseUpIcon.js +16 -16
- package/cjs/PRIVATE_ThemedIcons/DecrementIcon.js +16 -16
- package/cjs/PRIVATE_ThemedIcons/DeleteIcon.js +16 -16
- package/cjs/PRIVATE_ThemedIcons/DirectionalCollapseArrowIcon.js +17 -17
- package/cjs/PRIVATE_ThemedIcons/DirectionalExpandArrowIcon.js +17 -17
- package/cjs/PRIVATE_ThemedIcons/DragHandleIcon.js +16 -16
- package/cjs/PRIVATE_ThemedIcons/DropdownArrowIcon.js +16 -16
- package/cjs/PRIVATE_ThemedIcons/ExpandIcon.js +16 -16
- package/cjs/PRIVATE_ThemedIcons/HelpIcon.js +16 -16
- package/cjs/PRIVATE_ThemedIcons/IncrementIcon.js +16 -16
- package/cjs/PRIVATE_ThemedIcons/MenuButtonDropdownIcon.js +16 -16
- package/cjs/PRIVATE_ThemedIcons/MessageConfirmationIcon.js +16 -16
- package/cjs/PRIVATE_ThemedIcons/MessageErrorIcon.js +16 -16
- package/cjs/PRIVATE_ThemedIcons/MessageInfoIcon.js +16 -16
- package/cjs/PRIVATE_ThemedIcons/MessageWarningIcon.js +16 -16
- package/cjs/PRIVATE_ThemedIcons/MinusIcon.js +16 -16
- package/cjs/PRIVATE_ThemedIcons/NavDownIcon.js +16 -16
- package/cjs/PRIVATE_ThemedIcons/OverviewHorizontalDragHandleIcon.js +16 -16
- package/cjs/PRIVATE_ThemedIcons/PlusIcon.js +16 -16
- package/cjs/PRIVATE_ThemedIcons/RadioOffIcon.js +16 -16
- package/cjs/PRIVATE_ThemedIcons/RadioOnIcon.js +16 -16
- package/cjs/PRIVATE_ThemedIcons/SortAscendingIcon.js +16 -16
- package/cjs/PRIVATE_ThemedIcons/SortDescendingIcon.js +16 -16
- package/cjs/PRIVATE_ThemedIcons/ViewHideIcon.js +16 -16
- package/cjs/PRIVATE_ThemedIcons/ViewIcon.js +16 -16
- package/cjs/PRIVATE_TimeComponent.js +18 -18
- package/cjs/PRIVATE_VisOverview.js +16 -16
- package/cjs/PRIVATE_VisTabularDatatip.js +4 -4
- package/cjs/PictoChart-292f6c54.js +6 -6
- package/cjs/PieChart-411377a1.js +6 -6
- package/cjs/{Popup-84ce41d3.js → Popup-3e6b37ba.js} +9 -9
- package/cjs/{Popup-84ce41d3.js.map → Popup-3e6b37ba.js.map} +1 -1
- package/cjs/{ProgressBar-aa9edb7a.js → ProgressBar-ee008afc.js} +3 -3
- package/cjs/{ProgressBar-aa9edb7a.js.map → ProgressBar-ee008afc.js.map} +1 -1
- package/cjs/ProgressButton-433a67b5.js +3 -3
- package/cjs/ProgressButtonLabelLayout-13908869.js +3 -3
- package/cjs/{ProgressCircle-1d9fbade.js → ProgressCircle-e91f65f3.js} +2 -2
- package/cjs/{ProgressCircle-1d9fbade.js.map → ProgressCircle-e91f65f3.js.map} +1 -1
- package/cjs/RadioItem-c6ada23a.js +6 -6
- package/cjs/RatingGauge-4f129f42.js +7 -7
- package/cjs/ReadonlyTextFieldInput-af4ddced.js +1 -1
- package/cjs/{RemovableNavigationListItem-39312f9c.js → RemovableNavigationListItem-0eea31bc.js} +4 -5
- package/cjs/{RemovableNavigationListItem-39312f9c.js.map → RemovableNavigationListItem-0eea31bc.js.map} +1 -1
- package/cjs/RemovableTabBarItem-ff408dff.js +2 -2
- package/cjs/{ReorderableTabBar-5614d872.js → ReorderableTabBar-344938e7.js} +5 -5
- package/cjs/{ReorderableTabBar-5614d872.js.map → ReorderableTabBar-344938e7.js.map} +1 -1
- package/cjs/RevealToggleIcon-2e88a00a.js +1 -1
- package/cjs/{ScatterChart-80ef4bee.js → ScatterChart-763e1f3e.js} +4 -4
- package/cjs/{ScatterChart-80ef4bee.js.map → ScatterChart-763e1f3e.js.map} +1 -1
- package/cjs/SectionalLegend-da9d7dc4.js +4 -4
- package/cjs/{SectionedContent-06dc071c.js → SectionedContent-2210037c.js} +5 -5
- package/cjs/{SectionedContent-06dc071c.js.map → SectionedContent-2210037c.js.map} +1 -1
- package/cjs/SelectMultiple-b1f05b9f.js +8 -8
- package/cjs/SelectSingle-84b0b3eb.js +7 -7
- package/cjs/{SelectionCard-67f7003e.js → SelectionCard-e26feb4d.js} +2 -2
- package/cjs/{SelectionCard-67f7003e.js.map → SelectionCard-e26feb4d.js.map} +1 -1
- package/cjs/Selector-565b3810.js +1 -1
- package/cjs/{SelectorAll-b55e1b61.js → SelectorAll-e81b943f.js} +7 -7
- package/cjs/{SelectorAll-b55e1b61.js.map → SelectorAll-e81b943f.js.map} +1 -1
- package/cjs/{Sheet-86989265.js → Sheet-73cb51b2.js} +3 -3
- package/cjs/{Sheet-86989265.js.map → Sheet-73cb51b2.js.map} +1 -1
- package/cjs/SplitMenuButton-de680884.js +2 -2
- package/cjs/{StyledCard-a0496c88.js → StyledCard-f6b7f046.js} +2 -2
- package/cjs/{StyledCard-a0496c88.js.map → StyledCard-f6b7f046.js.map} +1 -1
- package/cjs/StyledTextField-3289e35c.js +3 -3
- package/cjs/{TabBar-bcf66387.js → TabBar-bf94b95a.js} +6 -11
- package/cjs/{TabBar-bcf66387.js.map → TabBar-bf94b95a.js.map} +1 -1
- package/cjs/TabBarItem-00fcf601.js +3 -3
- package/cjs/TabBarLayout-846a4d9a.js +1 -1
- package/cjs/{TabBarMixed-ac642788.js → TabBarMixed-975141a6.js} +6 -11
- package/cjs/{TabBarMixed-ac642788.js.map → TabBarMixed-975141a6.js.map} +1 -1
- package/cjs/{TabBarMixedSeparator-0e258647.js → TabBarMixedSeparator-0f55c6f6.js} +2 -2
- package/cjs/{TabBarMixedSeparator-0e258647.js.map → TabBarMixedSeparator-0f55c6f6.js.map} +1 -1
- package/cjs/Table-90fe7ad8.js +9 -9
- package/cjs/TagCloud-ff6f5158.js +8 -8
- package/cjs/{TextArea-e7f98e9f.js → TextArea-4c8f0284.js} +27 -9
- package/{es/TextArea-64b4e972.js.map → cjs/TextArea-4c8f0284.js.map} +1 -1
- package/cjs/{TextAreaAutosize-d96c7038.js → TextAreaAutosize-466a21cc.js} +8 -8
- package/cjs/{TextAreaAutosize-d96c7038.js.map → TextAreaAutosize-466a21cc.js.map} +1 -1
- package/cjs/TextField-976ee745.js +3 -3
- package/cjs/TextFieldInput-e83921a4.js +1 -1
- package/cjs/Theme-redwood/theme.css +221 -221
- package/cjs/Theme-stable/theme.css +307 -307
- package/cjs/TimeComponentCanvas2D-952a80c3.js +5 -5
- package/cjs/Toolbar-f94296cb.js +1 -1
- package/cjs/{TruncatingBadge-efe34bb7.js → TruncatingBadge-3a82f13b.js} +4 -4
- package/cjs/{TruncatingBadge-efe34bb7.js.map → TruncatingBadge-3a82f13b.js.map} +1 -1
- package/cjs/{TruncatingText-33c06a6c.js → TruncatingText-df3db482.js} +4 -4
- package/cjs/{TruncatingText-33c06a6c.js.map → TruncatingText-df3db482.js.map} +1 -1
- package/cjs/UNSAFE_ActionCard.js +3 -3
- package/cjs/UNSAFE_BarChart/__test__/BarChart.spec.js +36 -36
- package/cjs/UNSAFE_BarChart.js +36 -36
- package/cjs/UNSAFE_BaseButton.js +3 -3
- package/cjs/UNSAFE_Button.js +3 -3
- package/cjs/UNSAFE_ButtonLayout/tests/ButtonLayout.spec.js +21 -21
- package/cjs/UNSAFE_ButtonSet.js +4 -4
- package/cjs/UNSAFE_ButtonSetButton.js +3 -3
- package/cjs/UNSAFE_ButtonSetIconButton.js +16 -16
- package/cjs/UNSAFE_ButtonSetItem.js +16 -16
- package/cjs/UNSAFE_ButtonSetMultiple.js +4 -4
- package/cjs/UNSAFE_ButtonSetSingle.js +4 -4
- package/cjs/UNSAFE_Card.js +5 -5
- package/cjs/UNSAFE_CardFlexView.js +22 -22
- package/cjs/UNSAFE_CardGridView.js +22 -22
- package/cjs/UNSAFE_Center.js +5 -5
- package/cjs/UNSAFE_ChartWithLegend.js +4 -4
- package/cjs/UNSAFE_Checkbox.js +23 -23
- package/cjs/UNSAFE_CheckboxItem.js +24 -24
- package/cjs/UNSAFE_CheckboxSet.js +23 -23
- package/cjs/UNSAFE_Chip.js +2 -2
- package/cjs/UNSAFE_Collapsible.js +18 -18
- package/cjs/UNSAFE_ComboChart.js +38 -38
- package/cjs/UNSAFE_ComponentMessage.js +19 -19
- package/cjs/UNSAFE_ConveyorBelt.js +16 -16
- package/cjs/UNSAFE_DatePicker.js +24 -24
- package/cjs/UNSAFE_Diagram.js +21 -21
- package/cjs/UNSAFE_Dialog.js +21 -21
- package/cjs/UNSAFE_DragHandle.js +18 -18
- package/cjs/UNSAFE_DrawerLayout.js +12 -12
- package/cjs/UNSAFE_DrawerPopup.js +11 -11
- package/cjs/UNSAFE_Dropdown.js +13 -13
- package/cjs/UNSAFE_Environment.js +4 -4
- package/cjs/UNSAFE_ExpandableList.js +23 -23
- package/cjs/UNSAFE_FilePicker.js +4 -4
- package/cjs/UNSAFE_Flex.js +4 -4
- package/cjs/UNSAFE_Floating.js +11 -11
- package/cjs/UNSAFE_FormLayout.js +2 -2
- package/cjs/UNSAFE_Gantt.js +23 -23
- package/cjs/UNSAFE_Grid.js +4 -4
- package/cjs/UNSAFE_HighlightText.js +4 -4
- package/cjs/UNSAFE_Icon.js +16 -16
- package/cjs/UNSAFE_IconButton.js +16 -16
- package/cjs/UNSAFE_IconMenuButton.js +21 -21
- package/cjs/UNSAFE_IconProgressButton.js +19 -19
- package/cjs/UNSAFE_IconToggleButton.js +16 -16
- package/cjs/UNSAFE_Indexer.js +6 -6
- package/cjs/UNSAFE_InputDateMask.js +24 -24
- package/cjs/UNSAFE_InputDatePicker.js +112 -112
- package/cjs/UNSAFE_InputPassword.js +23 -23
- package/cjs/UNSAFE_InputSensitiveText.js +25 -25
- package/cjs/UNSAFE_InputText.js +26 -26
- package/cjs/UNSAFE_InputTimeMask.js +24 -24
- package/cjs/UNSAFE_Label.js +23 -23
- package/cjs/UNSAFE_LabelValueLayout.js +4 -4
- package/cjs/UNSAFE_LabelledLink.js +24 -24
- package/cjs/UNSAFE_Layer.js +8 -8
- package/cjs/UNSAFE_Legend.js +24 -24
- package/cjs/UNSAFE_LineAreaChart.js +38 -38
- package/cjs/UNSAFE_Link.js +2 -2
- package/cjs/UNSAFE_ListItemLayout.js +5 -5
- package/cjs/UNSAFE_ListView.js +28 -28
- package/cjs/UNSAFE_LiveRegion.js +4 -4
- package/cjs/UNSAFE_Menu.js +23 -23
- package/cjs/UNSAFE_MenuButton.js +21 -21
- package/cjs/UNSAFE_MessageBanner.js +19 -19
- package/cjs/UNSAFE_MessageToast.js +22 -22
- package/cjs/UNSAFE_MeterBar.js +16 -16
- package/cjs/UNSAFE_MeterCircle.js +17 -17
- package/cjs/UNSAFE_Modal.js +8 -8
- package/cjs/UNSAFE_NavigationList.js +34 -36
- package/cjs/UNSAFE_NavigationList.js.map +1 -1
- package/cjs/UNSAFE_NavigationListCommon.js +70 -71
- package/cjs/UNSAFE_NavigationListCommon.js.map +1 -1
- package/cjs/UNSAFE_NumberInputText.js +25 -25
- package/cjs/UNSAFE_OverflowTabBar.js +50 -52
- package/cjs/UNSAFE_OverflowTabBar.js.map +1 -1
- package/cjs/UNSAFE_PictoChart.js +14 -14
- package/cjs/UNSAFE_PieChart/__test__/PieChart.spec.js +21 -21
- package/cjs/UNSAFE_PieChart.js +21 -21
- package/cjs/UNSAFE_Popup.js +16 -16
- package/cjs/UNSAFE_ProgressBar.js +5 -5
- package/cjs/UNSAFE_ProgressButton.js +19 -19
- package/cjs/UNSAFE_ProgressButtonLabelLayout.js +10 -10
- package/cjs/UNSAFE_ProgressCircle.js +4 -4
- package/cjs/UNSAFE_RadioItem.js +23 -23
- package/cjs/UNSAFE_RadioSet.js +23 -23
- package/cjs/UNSAFE_RatingGauge.js +17 -17
- package/cjs/UNSAFE_ReorderableTabBar.js +37 -48
- package/cjs/UNSAFE_ReorderableTabBar.js.map +1 -1
- package/cjs/UNSAFE_RichCheckboxSet.js +25 -25
- package/cjs/UNSAFE_RichRadioSet.js +25 -25
- package/cjs/UNSAFE_RichSelectionItem.js +27 -27
- package/cjs/UNSAFE_ScatterChart.js +38 -38
- package/cjs/UNSAFE_SectionalLegend.js +25 -25
- package/cjs/UNSAFE_SelectMultiple.js +30 -30
- package/cjs/UNSAFE_SelectSingle.js +30 -30
- package/cjs/UNSAFE_SelectionCard.js +5 -5
- package/cjs/UNSAFE_Selector.js +16 -16
- package/cjs/UNSAFE_SelectorAll.js +20 -20
- package/cjs/UNSAFE_Sheet/__test__/Sheet.spec.js +14 -14
- package/cjs/UNSAFE_Sheet.js +11 -11
- package/cjs/UNSAFE_SplitMenuButton.js +21 -21
- package/cjs/UNSAFE_TabBar.js +50 -52
- package/cjs/UNSAFE_TabBar.js.map +1 -1
- package/cjs/UNSAFE_TabBarCommon.js +42 -44
- package/cjs/UNSAFE_TabBarCommon.js.map +1 -1
- package/cjs/UNSAFE_TabBarMixed.js +59 -61
- package/cjs/UNSAFE_TabBarMixed.js.map +1 -1
- package/cjs/UNSAFE_TableView.js +24 -24
- package/cjs/UNSAFE_TagCloud.js +23 -23
- package/cjs/UNSAFE_TextArea.js +28 -29
- package/cjs/UNSAFE_TextArea.js.map +1 -1
- package/cjs/UNSAFE_TextAreaAutosize.js +28 -28
- package/cjs/UNSAFE_TextField.js +7 -7
- package/cjs/UNSAFE_ToggleButton.js +3 -3
- package/cjs/UNSAFE_Toolbar/tests/Toolbar.spec.js +23 -23
- package/cjs/UNSAFE_Toolbar.js +4 -4
- package/cjs/UNSAFE_Train.js +17 -17
- package/cjs/UNSAFE_TruncatingBadge.js +18 -18
- package/cjs/UNSAFE_TruncatingText.js +17 -17
- package/cjs/UNSAFE_UserAssistance.js +24 -24
- package/cjs/UNSAFE_View.js +7 -7
- package/cjs/UNSAFE_VirtualizedListView.js +20 -20
- package/cjs/UNSAFE_VisProgressiveLoader/__test__/VisProgressiveLoader.spec.js +8 -8
- package/cjs/UNSAFE_VisProgressiveLoader.js +6 -6
- package/cjs/UNSAFE_VisStatusMessage.js +6 -6
- package/cjs/UNSAFE_WindowOverlay.js +4 -4
- package/cjs/{View-5930179e.js → View-145a402d.js} +5 -5
- package/cjs/{View-5930179e.js.map → View-145a402d.js.map} +1 -1
- package/cjs/{VisNoData-5b2aa6a2.js → VisNoData-210b0385.js} +3 -3
- package/cjs/{VisNoData-5b2aa6a2.js.map → VisNoData-210b0385.js.map} +1 -1
- package/cjs/{VisProgressiveLoader-dacfe618.js → VisProgressiveLoader-5ed4eb9d.js} +3 -3
- package/cjs/{VisProgressiveLoader-dacfe618.js.map → VisProgressiveLoader-5ed4eb9d.js.map} +1 -1
- package/cjs/{VisTabularDatatip-eca8aa8f.js → VisTabularDatatip-a06f4ca3.js} +2 -2
- package/cjs/{VisTabularDatatip-eca8aa8f.js.map → VisTabularDatatip-a06f4ca3.js.map} +1 -1
- package/cjs/{WindowOverlay-06408f56.js → WindowOverlay-de3bd373.js} +2 -2
- package/cjs/{WindowOverlay-06408f56.js.map → WindowOverlay-de3bd373.js.map} +1 -1
- package/cjs/{YearsGridView-09f2f6c4.js → YearsGridView-e8d7a02c.js} +4 -4
- package/cjs/{YearsGridView-09f2f6c4.js.map → YearsGridView-e8d7a02c.js.map} +1 -1
- package/cjs/hoc/PRIVATE_withDirectionIcon.js +4 -4
- package/cjs/hoc/PRIVATE_withThemeIcon.js +3 -3
- package/cjs/hoc/UNSAFE_withThemeProps.js +3 -3
- package/cjs/hooks/PRIVATE_useChartContextMenu.js +20 -20
- package/cjs/hooks/PRIVATE_useChartDatatip.js +14 -14
- package/cjs/hooks/PRIVATE_useChartEvents.js +18 -18
- package/cjs/hooks/PRIVATE_useChartMarquee.js +18 -18
- package/cjs/hooks/PRIVATE_useCssVars.js +7 -7
- package/cjs/hooks/PRIVATE_useCurrentKey.js +4 -4
- package/cjs/hooks/PRIVATE_useDatatip.js +12 -12
- package/cjs/hooks/PRIVATE_useFloating.js +4 -4
- package/cjs/hooks/PRIVATE_useReorderable.js +5 -5
- package/cjs/hooks/PRIVATE_useRovingTabIndexContainer.js +4 -4
- package/cjs/hooks/PRIVATE_useSelection.js +4 -4
- package/cjs/hooks/PRIVATE_useTabBar.js +4 -4
- package/cjs/hooks/PRIVATE_useVisContextMenu.js +20 -20
- package/cjs/hooks/PRIVATE_useVisDragModeControls.js +18 -18
- package/cjs/hooks/PRIVATE_useVisEvents.js +4 -4
- package/cjs/hooks/PRIVATE_useVisMeterEvents.js +14 -14
- package/cjs/hooks/PRIVATE_useVisSelection.js +13 -13
- package/cjs/hooks/UNSAFE_useColorScheme.js +3 -3
- package/cjs/hooks/UNSAFE_useCurrentBgColor.js +3 -3
- package/cjs/hooks/UNSAFE_useDensity.js +3 -3
- package/cjs/hooks/UNSAFE_useOutsideClick.js +8 -8
- package/cjs/hooks/UNSAFE_usePrefixSuffix.js +4 -4
- package/cjs/hooks/UNSAFE_useScale.js +3 -3
- package/cjs/hooks/UNSAFE_useTestId.js +3 -3
- package/cjs/hooks/UNSAFE_useTheme.js +3 -3
- package/cjs/hooks/UNSAFE_useThemeInterpolations.js +6 -6
- package/cjs/hooks/UNSAFE_useTooltip.js +17 -17
- package/cjs/hooks/UNSAFE_useTranslationBundle.js +3 -3
- package/cjs/hooks/UNSAFE_useUser.js +3 -3
- package/cjs/{index-ce6f9627.js → index-8c93d858.js} +2 -2
- package/cjs/index-8c93d858.js.map +1 -0
- package/cjs/listViewSelectionTests-858bb12a.js +3 -3
- package/cjs/{render-9767e967.js → render-bc47fc7e.js} +3 -3
- package/cjs/{render-9767e967.js.map → render-bc47fc7e.js.map} +1 -1
- package/cjs/{tabbableUtils-a38b7148.js → tabbableUtils-b14a04ea.js} +3 -3
- package/cjs/{tabbableUtils-a38b7148.js.map → tabbableUtils-b14a04ea.js.map} +1 -1
- package/cjs/{testData-7439df49.js → testData-c996c33b.js} +3 -3
- package/cjs/{testData-7439df49.js.map → testData-c996c33b.js.map} +1 -1
- package/cjs/{tooltipUtils-669c2ae0.js → tooltipUtils-2228b0f7.js} +5 -5
- package/cjs/{tooltipUtils-669c2ae0.js.map → tooltipUtils-2228b0f7.js.map} +1 -1
- package/cjs/useCellNavigation-6f7cd4c8.js +1 -1
- package/cjs/useChartContextMenu-d114824a.js +2 -2
- package/cjs/{useChartDatatip-c6107d63.js → useChartDatatip-538a4577.js} +4 -4
- package/cjs/{useChartDatatip-c6107d63.js.map → useChartDatatip-538a4577.js.map} +1 -1
- package/cjs/{useColorScheme-ce2a88b1.js → useColorScheme-e6bef5a4.js} +2 -2
- package/cjs/{useColorScheme-ce2a88b1.js.map → useColorScheme-e6bef5a4.js.map} +1 -1
- package/cjs/useContextMenu-3ebf8f80.js +2 -2
- package/cjs/{useCssVars-bd95e715.js → useCssVars-9bea15a9.js} +5 -5
- package/cjs/{useCssVars-bd95e715.js.map → useCssVars-9bea15a9.js.map} +1 -1
- package/cjs/{useCurrentBgColor-6e39eb3a.js → useCurrentBgColor-6835bf45.js} +2 -2
- package/cjs/{useCurrentBgColor-6e39eb3a.js.map → useCurrentBgColor-6835bf45.js.map} +1 -1
- package/cjs/{useCurrentKey-88495da2.js → useCurrentKey-d8d41864.js} +2 -2
- package/cjs/{useCurrentKey-88495da2.js.map → useCurrentKey-d8d41864.js.map} +1 -1
- package/cjs/{useDatatip-83ab0540.js → useDatatip-1dda9a86.js} +4 -4
- package/cjs/{useDatatip-83ab0540.js.map → useDatatip-1dda9a86.js.map} +1 -1
- package/cjs/{useDensity-1f8cc921.js → useDensity-38283c57.js} +2 -2
- package/cjs/{useDensity-1f8cc921.js.map → useDensity-38283c57.js.map} +1 -1
- package/cjs/{useFloating-480d365a.js → useFloating-c9e127d3.js} +2 -2
- package/cjs/{useFloating-480d365a.js.map → useFloating-c9e127d3.js.map} +1 -1
- package/cjs/{useKeyboardEvents-5e808fe3.js → useKeyboardEvents-7ab0d8ee.js} +2 -2
- package/cjs/{useKeyboardEvents-5e808fe3.js.map → useKeyboardEvents-7ab0d8ee.js.map} +1 -1
- package/cjs/useLegendContextMenu-82be007a.js +4 -4
- package/cjs/{useMeterDatatip-641afcc6.js → useMeterDatatip-945883f5.js} +3 -3
- package/cjs/{useMeterDatatip-641afcc6.js.map → useMeterDatatip-945883f5.js.map} +1 -1
- package/cjs/{useOutsideClick-03a6c38c.js → useOutsideClick-ad999b14.js} +2 -2
- package/cjs/{useOutsideClick-03a6c38c.js.map → useOutsideClick-ad999b14.js.map} +1 -1
- package/cjs/{usePopupAnimation-2afacc4b.js → usePopupAnimation-b911e9ed.js} +2 -2
- package/cjs/{usePopupAnimation-2afacc4b.js.map → usePopupAnimation-b911e9ed.js.map} +1 -1
- package/cjs/{usePrefixSuffix-23341de3.js → usePrefixSuffix-1de3a724.js} +2 -2
- package/cjs/{usePrefixSuffix-23341de3.js.map → usePrefixSuffix-1de3a724.js.map} +1 -1
- package/cjs/{useReorderableItem-0dbb8843.js → useReorderableItem-5fc4d599.js} +3 -3
- package/cjs/{useReorderableItem-0dbb8843.js.map → useReorderableItem-5fc4d599.js.map} +1 -1
- package/cjs/{useRovingTabIndexContainer-dc12b802.js → useRovingTabIndexContainer-bbdf3acd.js} +2 -2
- package/cjs/{useRovingTabIndexContainer-dc12b802.js.map → useRovingTabIndexContainer-bbdf3acd.js.map} +1 -1
- package/cjs/{useScale-a681a5cb.js → useScale-a47864b4.js} +2 -2
- package/cjs/{useScale-a681a5cb.js.map → useScale-a47864b4.js.map} +1 -1
- package/cjs/useSelectCommon-5b46ac60.js +11 -11
- package/cjs/{useSelectDrill-c95b1a51.js → useSelectDrill-51fdccac.js} +3 -3
- package/cjs/{useSelectDrill-c95b1a51.js.map → useSelectDrill-51fdccac.js.map} +1 -1
- package/cjs/{useSelection-228ef3ce.js → useSelection-0dbc2f40.js} +2 -2
- package/cjs/{useSelection-228ef3ce.js.map → useSelection-0dbc2f40.js.map} +1 -1
- package/cjs/{useSelection-efdf0e84.js → useSelection-8362b6c6.js} +5 -5
- package/cjs/{useSelection-efdf0e84.js.map → useSelection-8362b6c6.js.map} +1 -1
- package/cjs/useTabBar-048ffd9f.js +1 -1
- package/cjs/{useTestId-5e6af45d.js → useTestId-e267a39d.js} +2 -2
- package/cjs/{useTestId-5e6af45d.js.map → useTestId-e267a39d.js.map} +1 -1
- package/cjs/{useTheme-8fb5546b.js → useTheme-6cedf9c8.js} +2 -2
- package/cjs/{useTheme-8fb5546b.js.map → useTheme-6cedf9c8.js.map} +1 -1
- package/cjs/{useThemeInterpolations-28ca9a13.js → useThemeInterpolations-316c1636.js} +5 -5
- package/cjs/{useThemeInterpolations-28ca9a13.js.map → useThemeInterpolations-316c1636.js.map} +1 -1
- package/cjs/{useTooltip-81b7b753.js → useTooltip-ea036f82.js} +2 -2
- package/cjs/{useTooltip-81b7b753.js.map → useTooltip-ea036f82.js.map} +1 -1
- package/cjs/{useTooltipControlled-33832163.js → useTooltipControlled-61581889.js} +5 -5
- package/cjs/{useTooltipControlled-33832163.js.map → useTooltipControlled-61581889.js.map} +1 -1
- package/cjs/{useTranslationBundle-51f4c22c.js → useTranslationBundle-6b0281a9.js} +2 -2
- package/cjs/{useTranslationBundle-51f4c22c.js.map → useTranslationBundle-6b0281a9.js.map} +1 -1
- package/cjs/{useUser-a4bfc560.js → useUser-8aaad5a7.js} +2 -2
- package/cjs/{useUser-a4bfc560.js.map → useUser-8aaad5a7.js.map} +1 -1
- package/cjs/useVisDragModeControls-95caebc9.js +1 -1
- package/cjs/{useVisEvents-e48065f4.js → useVisEvents-99f1bf51.js} +2 -2
- package/cjs/{useVisEvents-e48065f4.js.map → useVisEvents-99f1bf51.js.map} +1 -1
- package/cjs/utils/PRIVATE_tooltipUtils.js +14 -14
- package/cjs/utils/PRIVATE_visTestUtils.js +5 -5
- package/cjs/{withDirectionIcon-1affce30.js → withDirectionIcon-7f758093.js} +2 -2
- package/cjs/{withDirectionIcon-1affce30.js.map → withDirectionIcon-7f758093.js.map} +1 -1
- package/cjs/withThemeProps-6e15f1c3.js +2 -2
- package/es/{InputDatePicker-dd3b6c89.js → InputDatePicker-59bbd31d.js} +2 -2
- package/es/{InputDatePicker-dd3b6c89.js.map → InputDatePicker-59bbd31d.js.map} +1 -1
- package/es/MaxLengthCounter-181b4fc9.js +25 -0
- package/{cjs/MaxLengthCounter-9ab3f74b.js.map → es/MaxLengthCounter-181b4fc9.js.map} +1 -1
- package/es/MeterBarVariants.styles.css +4 -4
- package/es/MeterBarVariants.styles2.css +4 -4
- package/es/SplitMenuButtonTheme.styles.css +4 -4
- package/es/SplitMenuButtonTheme.styles2.css +4 -4
- package/es/{TextArea-64b4e972.js → TextArea-7230675f.js} +8 -25
- package/{cjs/TextArea-e7f98e9f.js.map → es/TextArea-7230675f.js.map} +1 -1
- package/es/{TextAreaAutosize-4e0f60ef.js → TextAreaAutosize-0d293016.js} +2 -2
- package/es/{TextAreaAutosize-4e0f60ef.js.map → TextAreaAutosize-0d293016.js.map} +1 -1
- package/es/Theme-redwood/theme.css +378 -378
- package/es/Theme-stable/theme.css +498 -498
- package/es/UNSAFE_ButtonLayout/tests/ButtonLayout.spec.js +1 -1
- package/es/UNSAFE_InputDatePicker.js +91 -91
- package/es/UNSAFE_MeterBar/themes/redwood/MeterBarTheme.js +1 -1
- package/es/UNSAFE_MeterBar/themes/redwood/MeterBarVariants.css.js +1 -1
- package/es/UNSAFE_MeterBar/themes/stable/MeterBarTheme.js +1 -1
- package/es/UNSAFE_MeterBar/themes/stable/MeterBarVariants.css.js +1 -1
- package/es/UNSAFE_MeterBar.js +1 -1
- package/es/UNSAFE_SplitMenuButton/themes/redwood/SplitMenuButtonTheme.css.js +1 -1
- package/es/UNSAFE_SplitMenuButton/themes/stable/SplitMenuButtonTheme.css.js +1 -1
- package/es/UNSAFE_SplitMenuButton.js +1 -1
- package/es/UNSAFE_TextArea.js +3 -2
- package/es/UNSAFE_TextArea.js.map +1 -1
- package/es/UNSAFE_TextAreaAutosize.js +3 -3
- package/es/UNSAFE_Toolbar/tests/Toolbar.spec.js +1 -1
- package/package.json +2 -2
- package/amd/InputDatePicker-fc39f0a6.js +0 -2
- package/cjs/BaseNavigationListItem-ac85812c.js +0 -49
- package/cjs/BaseNavigationListItem-ac85812c.js.map +0 -1
- package/cjs/MaxLengthCounter-9ab3f74b.js +0 -27
- package/cjs/NavigationList-7495908b.js.map +0 -1
- package/cjs/NavigationListItem-d927906d.js +0 -12
- package/cjs/NavigationListItem-d927906d.js.map +0 -1
- package/cjs/index-ce6f9627.js.map +0 -1
- package/cjs/useNavigationListItem-ae481fdc.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UNSAFE_InputTimeMask.js","sources":["../../src/UNSAFE_InputTimeMask/TimeSegment.tsx","../../src/UNSAFE_InputTimeMask/timeReducer.ts","../../src/UNSAFE_InputTimeMask/useTimeField.ts","../../src/UNSAFE_InputTimeMask/LiteralSegment.tsx","../../src/UNSAFE_InputTimeMask/useTimeFieldHandlers.ts","../../src/UNSAFE_InputTimeMask/TimeField.tsx","../../src/UNSAFE_InputTimeMask/InputTimeMask.tsx"],"sourcesContent":["/**\n * @license\n * Copyright (c) %FIRST_YEAR% %CURRENT_YEAR%, Oracle and/or its affiliates.\n * The Universal Permissive License (UPL), Version 1.0\n * as shown at https://oss.oracle.com/licenses/upl/\n * @ignore\n */\n\nimport type { RefObject } from 'preact';\nimport { useCallback, useEffect, useRef } from 'preact/hooks';\nimport { AriaAttributesSignalExcluded } from '#utils/UNSAFE_attributeUtils';\nimport { TimeFieldAction } from './timeReducer';\nimport { EditableTimeSegmentType } from './types';\nimport {\n isBackspaceOrDelete,\n isControlOrFunctionKey,\n isSelectAll\n} from '#utils/PRIVATE_keyboardUtils';\nimport { isNumberOnlyString } from '#utils/PRIVATE_dayUtils';\nimport { classNames } from '#utils/UNSAFE_classNames';\nimport { segmentStyles } from './themes/SegmentStyles.css';\nimport { getClientHints } from '#utils/PRIVATE_clientHints';\nimport { useTranslationBundle } from '#hooks/UNSAFE_useTranslationBundle';\nimport { BundleType } from '#resources/nls/bundle';\nimport { AM_VALUE, AmPmLocalizedValues, getAmPmMatchType, PM_VALUE } from '#utils/UNSAFE_timeUtils';\n\ntype AriaProps = Pick<\n AriaAttributesSignalExcluded,\n 'aria-label' | 'aria-valuemax' | 'aria-valuemin' | 'aria-valuenow' | 'aria-valuetext'\n>;\n\ntype Props = AriaProps & {\n /**\n * The am/pm localized values. This is used when the segment type is 'dayPeriod'.\n */\n amPm?: AmPmLocalizedValues;\n\n /** A ref that is provided for the first segment in a time field. */\n inputRef?: RefObject<HTMLDivElement>;\n\n /**\n * True if the segment is complete in the sense that it contains a complete valid value.\n * For instance, entering '0' and then '1-9' is considered a complete value for a minute since minute has 2-digits.\n * Also true if typing any additional digit would cause the segment value to exceed the max.\n */\n isComplete?: boolean;\n\n /**\n * True if the segment is disabled.\n */\n isDisabled?: boolean;\n\n /**\n * True if the segment should be hidden.\n */\n isHidden?: boolean;\n\n /**\n * True if the entire time field is highlighted.\n */\n isHighlighted?: boolean;\n\n /**\n * True if the segment is invalid.\n */\n isInvalid?: boolean;\n\n /**\n * Specifies for accessibility purposes whether a value is required.\n */\n isRequired?: boolean;\n\n /**\n * True if the segment is selected.\n */\n isSelected?: boolean;\n\n /**\n * Placeholder displayed when the segment has no display value.\n */\n placeholder?: string;\n\n /**\n * The text to display for this segment.\n */\n text?: string;\n\n /**\n * The segment of a time which is being represented, i.e. the hour, minute, second, millisecond, dayPeriod.\n */\n type: EditableTimeSegmentType;\n\n /**\n * Callback invoked when a change to the segment is requested via user action, such as typing\n * a new value or pressing the Backspace or Delete keys.\n */\n onChange?: (action: TimeFieldAction) => void;\n};\n\n// Used to disable browser cut and paste, which don't really work with segments (copy is fine).\nconst preventDefaultHandler = (e: Event) => {\n e.preventDefault();\n};\n\nconst isIos = () => getClientHints().platform === 'ios';\n\n/**\n * A TimeSegment renders a part of a time, e.g. the hour, minute, second, millisecond, dayPeriod.\n * It can be used as a spinbutton to step or spin its value.\n */\nexport const TimeSegment = ({\n amPm,\n 'aria-label': ariaLabel,\n 'aria-valuemax': ariaValueMax,\n 'aria-valuemin': ariaValueMin,\n 'aria-valuenow': ariaValueNow,\n 'aria-valuetext': ariaValueText,\n inputRef,\n isDisabled,\n isHidden,\n isHighlighted,\n isInvalid,\n isRequired,\n isSelected,\n onChange,\n placeholder,\n text,\n type\n}: Props) => {\n const hasDisplayValue = text && text.length > 0;\n const rootClasses = classNames([\n segmentStyles.base,\n isSelected && segmentStyles.selected,\n isHighlighted && segmentStyles.highlighted\n ]);\n const placeholderClasses = classNames([\n segmentStyles.placeholder,\n isHidden || hasDisplayValue ? segmentStyles.hidden : segmentStyles.notHidden\n ]);\n const translations = useTranslationBundle<BundleType>('@oracle/oraclejet-preact');\n const emptySegmentValueText = translations.formControl_empty_segment();\n\n // If a ref was passed in, use it, otherwise get a ref.\n const sRef = useRef<HTMLDivElement>(null);\n const segmentRef = inputRef ?? sRef;\n\n const dayPeriodTextRef = useRef<string | null>(null);\n const onKeyDown = useCallback(\n (event: KeyboardEvent) => {\n if (\n isDisabled === true ||\n event.key === 'Tab' ||\n event.key === 'ArrowLeft' ||\n event.key === 'ArrowRight' ||\n event.key === 'Enter' ||\n isSelectAll(event)\n ) {\n // Let the event pass through.\n return;\n }\n if (isHighlighted) {\n // If time is selected, ignore edits and let backspace/delete pass through to clear.\n if (isBackspaceOrDelete(event) || event.key === 'Backspace') {\n return;\n }\n } else if (isNumberOnlyString(event.key)) {\n // do not send this for a dayPeriod segment since a dayPeriod segment does not have numbers.\n if (type !== 'dayPeriod') {\n onChange?.({\n actionType: 'updateSegment',\n data: { type, text: event.key }\n });\n }\n } else if (isBackspaceOrDelete(event) || event.key === 'Backspace') {\n // Android sends Backspace as event.key, not event.code, so check for it.\n onChange?.({ actionType: 'clearSegment', data: { type } });\n } else if (event.key === 'ArrowUp') {\n onChange?.({ actionType: 'step', data: { direction: 'increase', type } });\n } else if (event.key === 'ArrowDown') {\n onChange?.({ actionType: 'step', data: { direction: 'decrease', type } });\n } else if (event.key === 'PageUp') {\n onChange?.({ actionType: 'page', data: { direction: 'increase', type } });\n } else if (event.key === 'PageDown') {\n onChange?.({ actionType: 'page', data: { direction: 'decrease', type } });\n } else if (event.key === 'Home') {\n onChange?.({ actionType: 'goToHome', data: { type } });\n } else if (event.key === 'End') {\n onChange?.({ actionType: 'goToEnd', data: { type } });\n } else if (\n type === 'dayPeriod' &&\n amPm !== undefined &&\n isLetterOnlyString(event.key, event)\n ) {\n // A user can change the am/pm strings using the up and down arrow keys or by typing in letters.\n // In most locales the first letter of the am/pm strings uniquely identifies am or pm.\n // However, in a couple locales, such as 'ms' (where am is represented 'PG' and pm as 'PTG'), the first letter may not be unique.\n // This scenario requires special handling to account for the ambiguity; we use the\n // dayPeriodTextRef.current to buffer up the text the user types until we figure out if it is the am or pm string they are typing or neither.\n // Once we can recognize that it is the 'am' or 'pm' that they want, we call 'updateDayPeriodSegment' to change it.\n dayPeriodTextRef.current =\n dayPeriodTextRef.current !== null ? dayPeriodTextRef.current + event.key : event.key;\n const matchType = getAmPmMatchType(amPm, dayPeriodTextRef.current);\n if (matchType === 'am' || matchType === 'pm') {\n const value = matchType === 'am' ? AM_VALUE : PM_VALUE;\n onChange?.({\n actionType: 'updateDayPeriodSegment',\n data: { type, 'aria-valuenow': value }\n });\n }\n if (matchType !== 'both') {\n // We clear out the ref here, and also if the segment's isSelected state is false which indicates the dayPeriod segment lost focus.\n dayPeriodTextRef.current = null;\n }\n }\n event.preventDefault();\n event.stopPropagation();\n },\n [amPm, isDisabled, isHighlighted, onChange, type]\n );\n\n // Used to focus the segment when isSelected is true.\n useEffect(() => {\n if (isSelected) {\n segmentRef.current?.focus();\n } else if (type === 'dayPeriod') {\n // This is the ref that in onKeyDown handler is used to buffer up the letters typed into the dayPeriod until a match or no match is found,\n // in which case we clear the buffer.\n // We also clear the ref when the dayPeriod segment loses focus.\n dayPeriodTextRef.current = null;\n }\n }, [isSelected, segmentRef, type]);\n\n // If ariaValueText is undefined, substitute a string that indicates the segment is empty.\n // If ariaValueNow and ariaValueText represent the same value, omit the value text; this\n // is the same as what we do in NumberInputText.\n const valueText =\n ariaValueText === undefined\n ? emptySegmentValueText\n : ariaValueNow?.toString() === ariaValueText\n ? undefined\n : ariaValueText;\n // This attribute is used to distinguish between segments when clicked (see TimeField.tsx).\n const customDataAttribute = { 'data-segment': [type] };\n return (\n <div>\n <div\n ref={segmentRef}\n role={isIos() ? 'textbox' : 'spinbutton'}\n aria-disabled={isDisabled}\n aria-invalid={isInvalid || undefined}\n aria-label={ariaLabel}\n aria-required={isRequired}\n aria-valuemin={isIos() ? undefined : ariaValueMin}\n aria-valuemax={isIos() ? undefined : ariaValueMax}\n aria-valuenow={isIos() ? undefined : ariaValueNow}\n aria-valuetext={isIos() ? undefined : valueText}\n autocapitalize=\"off\"\n autocorrect=\"off\"\n class={rootClasses}\n contentEditable={!isDisabled}\n {...customDataAttribute}\n enterkeyhint={isDisabled ? undefined : 'done'}\n inputMode={isDisabled ? 'none' : type !== 'dayPeriod' ? 'numeric' : 'text'}\n onCut={preventDefaultHandler}\n onKeyDown={onKeyDown}\n onPaste={preventDefaultHandler}\n spellcheck={false}\n tabIndex={isSelected ? 0 : -1}>\n <span aria-hidden=\"true\" class={placeholderClasses} {...customDataAttribute}>\n {placeholder}\n </span>\n {text}\n </div>\n </div>\n );\n};\n\nconst isLetterOnlyString = (input: string, event: KeyboardEvent) => {\n const isLetter = /^\\p{L}$/u.test(input);\n\n // Ensure no modifier keys (Command, Ctrl, Alt) are active\n const modifiers = isControlOrFunctionKey(event);\n\n return isLetter && !modifiers;\n};\n","/**\n * @license\n * Copyright (c) %FIRST_YEAR% %CURRENT_YEAR%, Oracle and/or its affiliates.\n * The Universal Permissive License (UPL), Version 1.0\n * as shown at https://oss.oracle.com/licenses/upl/\n * @ignore\n */\n\nimport type { TimeFieldState, TimeSegmentState } from './useTimeField';\nimport { OrderedTimeSegmentsArray, EditableTimeSegmentType } from './types';\n\n// Carries additional data information for an action.\ntype TimeFieldActionData = Partial<TimeSegmentState> & {\n direction?: 'increase' | 'decrease';\n};\n\n// Describes all possible actions for interacting with the time segments.\n// For example,\n// selectSegment: focuses on one segment (like hour or minute).\n// updateSegment: called when the user types in a number. Figures out if the segment is complete.\n// step: Increments or decrements the value in the segment.\n// commit: Finalizes changes made to the segments.\ntype TimeFieldAction = {\n actionType:\n | 'clearTime'\n | 'clearSegment'\n | 'committed'\n | 'commitOnBlur'\n | 'commitOnEnter'\n | 'deselectAndComplete'\n | 'goToEnd'\n | 'goToHome'\n | 'page'\n | 'selectTime'\n | 'selectFirst'\n | 'selectNext'\n | 'selectPrevious'\n | 'selectSegment'\n | 'step'\n | 'updateDayPeriodSegment'\n | 'updateSegment';\n data?: TimeFieldActionData;\n};\n\n// Used to replace the state with a new one, like when the time value is updated programmatically.\ntype ResetAction = {\n actionType: 'reset';\n data: TimeFieldState;\n};\n\ntype TimeReducerAction = TimeFieldAction | ResetAction;\n\nconst AM_VALUE = 0;\nconst PM_VALUE = 12;\n\n/**\n * Reducer function for updating TimeFieldState per the specified TimeFieldAction.\n * @param state\n * @param action\n */\nconst timeReducer = (state: TimeFieldState, action: TimeReducerAction) => {\n // On mount, the reducer is initialized with initial state derived from the TimeField's value.\n // If that value is changed programmatically afterwards, the only way to push that update\n // into the reducer is to define a \"reset\" action.\n if (action.actionType === 'reset') {\n return action.data;\n }\n\n // Most of the dispatches include type, but not all (like 'commitOnBlur' doesn't include type).\n // Instead of setting these for every actionType that needs it, we do it once here.\n const segmentType = action.data?.type!;\n const segmentState = findSegment(state.segments, segmentType);\n\n // Each action updates the state using helper functions to modify a specific segment or\n // change focus between segments.\n switch (action.actionType) {\n case 'clearTime': {\n // Resets all segments to the default (useful when clearing the entire time)\n const updatedSegments = selectFirst(clearTime(state.segments), state.orderedSegments);\n return createTimeFieldStateWithSelectedTime(state, updatedSegments, false);\n }\n case 'clearSegment': {\n const updatedSegment = clearSegment(segmentState);\n return createTimeFieldState(state, segmentType, updatedSegment);\n }\n case 'deselectAndComplete': {\n let updatedSegments = completeAllSegmentsBasedOnHour(state.segments);\n updatedSegments = deselectAndComplete(updatedSegments);\n return createTimeFieldStateWithSelectedTime(state, updatedSegments, false);\n }\n case 'commitOnEnter': {\n const updatedSegments = completeAllSegmentsBasedOnHour(state.segments);\n const newState = createTimeFieldStateWithSelectedTime(state, updatedSegments, false);\n return { ...newState, committing: true };\n }\n case 'commitOnBlur': {\n let updatedSegments = completeAllSegmentsBasedOnHour(state.segments);\n updatedSegments = deselectAndComplete(updatedSegments);\n const newState = createTimeFieldStateWithSelectedTime(state, updatedSegments, false);\n return { ...newState, committing: true };\n }\n case 'committed': {\n return { ...state, committing: false };\n }\n case 'goToEnd': {\n const updatedSegment = goToEnd(segmentType, segmentState);\n return createTimeFieldState(state, segmentType, updatedSegment, false);\n }\n case 'goToHome': {\n const updatedSegment = goToHome(segmentType, segmentState);\n return createTimeFieldState(state, segmentType, updatedSegment, false);\n }\n case 'page': {\n const direction = action.data?.direction;\n if (direction === undefined) return state;\n const updatedSegment = doStepOrPage(segmentType, segmentState, 'page', direction);\n return createTimeFieldState(state, segmentType, updatedSegment, false);\n }\n case 'selectTime': {\n return selectTime(state);\n }\n case 'selectFirst': {\n const updatedSegments = selectFirst(state.segments, state.orderedSegments);\n return createTimeFieldStateWithSelectedTime(state, updatedSegments, false);\n }\n // Select the segment following the current one.\n case 'selectNext': {\n // If hour has a value and is currently selected when we get the selectNext action, then auto-fill\n // the empty segments.\n const updatedSegments = completeAllEmptySegmentsWhenHourHasValue(state.segments, true);\n const updatedSelectedNextSegments = selectNext(updatedSegments, state.orderedSegments);\n return createTimeFieldStateWithSelectedTime(state, updatedSelectedNextSegments, false);\n }\n case 'selectPrevious': {\n const updatedSegments = selectPrevious(state.segments, state.orderedSegments);\n return createTimeFieldStateWithSelectedTime(state, updatedSegments, false);\n }\n case 'selectSegment': {\n const updatedSegments = selectSegment(state.segments, segmentType);\n return createTimeFieldStateWithSelectedTime(state, updatedSegments, false);\n }\n // Increments or decrements the current segment value.\n case 'step': {\n const direction = action.data?.direction;\n\n if (direction === undefined) return state;\n const updatedSegment = doStepOrPage(segmentType, segmentState, 'step', direction);\n return createTimeFieldState(state, segmentType, updatedSegment, false);\n }\n case 'updateDayPeriodSegment': {\n if (segmentType === 'dayPeriod') {\n const newValue = action.data?.['aria-valuenow'];\n if (newValue === PM_VALUE || newValue === AM_VALUE) {\n // we have a new value for the dayPeriod. Create a new state.\n const updatedSegment = createSegmentFromKeyboardAction(\n segmentType,\n newValue,\n segmentState\n );\n return createTimeFieldState(state, segmentType, updatedSegment, false);\n }\n }\n return state;\n }\n case 'updateSegment': {\n // Modifies the value of a specific time segment while keeping the rest of the time state intact.\n // This gets called from TimeSegment onKeyDown which is called one key at a time.\n const updatedSegment = updateSegment(segmentType, segmentState, action);\n return createTimeFieldState(state, segmentType, updatedSegment);\n }\n default: {\n throw new Error('Unknown action type');\n }\n }\n};\n\nconst stringToNumber = (s: string) => +s;\nconst numberToString = (n: number) => n.toString();\nconst withinRange = (n: number, min: number, max: number) => n >= min && n <= max;\n\n/**\n * Given the array of TimeSegmentStates and the type, returns the segment with that type.\n * @param segments\n * @param type\n * @returns the segment with that type.\n */\nconst findSegment = (\n segments: TimeSegmentState[],\n type: EditableTimeSegmentType\n): TimeSegmentState => {\n return segments.find((segment) => segment.type === type)!;\n};\n\n/**\n * A time segment is considered complete if one of these is true:\n * - digitCount >= targetDigitCount\n * - appending a zero to the current value causes it\n * to exceed the max. For instance, if aria-valuemax which is 12 (for 12-hour times), and\n * 2 is in hour already, if someone typed in 0, it would be 20, and\n * that is greater than the max.\n * \n * digitCount is used to figure out if the segment is complete. \n * It is used to distinguish between\n * the user typing in all 0s or the auto-filling of 0s that happens when the user types in one 0 into an empty or complete field.\n * It is also used to figure out if the user typed in the number of digits to fill the space.\n * Like if the user typed in 0, 0, 5 in millisecond. The segment is complete because the digitCount >= targetDigitCount.\n\n * @param val - the value of the segment for which to check completeness.\n * @param maxVal - the maximum value for the segment. E.g., for seconds it is 59.\n * @param digitCount - the number of digits a user typed.\n * @param targetDigitCount - the number of digits in a segment.\n * @returns true if the segment is considered complete, false otherwise.\n */\nconst isSegmentComplete = (\n val: number,\n maxVal: number,\n digitCount: number,\n targetDigitCount: number\n) => {\n if (digitCount >= targetDigitCount) {\n return true;\n }\n const num = stringToNumber(numberToString(val) + '0');\n return num > maxVal;\n};\n\n/**\n * A time is considered complete if all of its segments have values.\n * We use each segment's 'text' property to determine that.\n * @param allSegments\n * @returns {boolean} every segment has a value.\n */\nconst isTimeComplete = (allSegments: TimeSegmentState[]) => {\n return allSegments.every((seg) => seg.text && seg.text.length > 0);\n};\n\n/**\n * A time is considered a partial time if at least one segment has a value.\n * We use each segment's 'aria-valuenow' property to determine that.\n * @param allSegments\n * @returns {boolean} at least one segment has a value.\n */\nconst isPartialTime = (allSegments: TimeSegmentState[]) => {\n // Even though the dayPeriod field does not read-out the valuenow, we use it\n // to indicate if it is filled in or not.\n return allSegments.some((seg) => seg['aria-valuenow'] !== undefined);\n};\n\n/**\n * Construct a time that reflects the values of each segment.\n * If none of the segments have a value, return undefined.\n * If only the dayPeriod has a value, return undefined, since we filter out dayPeriod; Time has 0-23 hour.\n *\n * @param segments\n * @returns The Time that reflects the values of each segment.\n */\nconst createTimeFromSegments = (segments: TimeSegmentState[]) => {\n const hasAnySegmentWithAValue = isPartialTime(segments);\n if (!hasAnySegmentWithAValue) {\n return undefined;\n }\n\n // get the dayPeriod's value, if it exists\n const dayPeriodValue = segments.find((seg) => seg.type === 'dayPeriod')?.['aria-valuenow'];\n\n // get the hour segment's value if it exists.\n const hourSegmentValue = segments.find((seg) => seg.type === 'hour')?.['aria-valuenow'];\n let adjustedHour = hourSegmentValue;\n\n // if the hour segment has a value and the dayPeriod segment has a value, then\n // we will adjust the hour so that it is a h23 hour.\n if (dayPeriodValue !== undefined && hourSegmentValue !== undefined) {\n adjustedHour = getAdjustedH12ToH23(dayPeriodValue, hourSegmentValue);\n }\n\n // Filter out dayPeriod segment and map the remaining segments to values\n const segmentValues = segments\n .filter((seg) => seg.type !== 'dayPeriod') // Filter out dayPeriod\n .reduce<Record<string, number | undefined>>((acc, seg) => {\n const value = seg.type === 'hour' ? adjustedHour : seg['aria-valuenow'];\n if (value !== undefined) {\n acc[seg.type] = value;\n }\n return acc;\n }, {});\n // If all that was left in the time segments at this point was the dayPeriod, we would get an empty object\n // since the value does not contain dayPeriod. If this is the case return undefined.\n return Object.entries(segmentValues).length === 0 ? undefined : segmentValues;\n};\n\n/**\n * Returns a copy of the ordered segments array from the current state.\n *\n * @param {TimeFieldState} currentState - the current state of the time field.\n * @returns {OrderedTimeSegmentsArray} the orderedSegments in the current state.\n */\nconst getOrderedSegmentsFromState = (currentState: TimeFieldState) => {\n // Typescript loses its typing when we spread, so add it back.\n return [...currentState.orderedSegments] as OrderedTimeSegmentsArray;\n};\n\n/**\n * Replace the updated segment and return a new TimeSegmentState[].\n * @param existingSegments\n * @param updatedSegmentType\n * @param updatedSegment\n * @returns\n */\nconst replaceTimeSegment = (\n existingSegments: TimeSegmentState[],\n updatedSegmentType: EditableTimeSegmentType,\n updatedSegment: TimeSegmentState\n) => {\n return existingSegments.map((seg) => (seg.type === updatedSegmentType ? updatedSegment : seg));\n};\n\n/**\n * Creates a new array of TimeSegmentState objects by updating the specified segment which might\n * affect other segments.\n *\n * If the modified segment type is 'hour', and the 'minute',\n * 'second', 'millisecond', 'dayPeriod' segments, if defined, are not set (i.e., their aria-valuenow is undefined),\n * their values are auto-filled, that is, initialized to 0 or localized version of 'AM' for dayPeriod.\n * @param {TimeSegmentState[]} existingSegments - The current array of time segments.\n * @param {OrderedTimeSegmentsArray} orderedSegments - The ordered list of segments used to determine\n * the segment sequence for selection and auto-advancing.\n * @param {EditableTimeSegmentType} updatedSegmentType - The type of the segment that is being updated.\n * @param {TimeSegmentState} updatedSegment - The updated segment state to replace the current one.\n * @param {boolean} autoAdvance - whether to automatically select the next segment upon completion of the current segment.\n * @returns The new array of TimeSegmentState objects, with the segment updated and other segments\n * modified as needed.\n * If autoAdvance is true, the next segment will be automatically set to isSelected upon segment isCompleted.\n */\nconst createTimeSegmentStates = (\n existingSegments: TimeSegmentState[],\n orderedSegments: OrderedTimeSegmentsArray,\n updatedSegmentType: EditableTimeSegmentType,\n updatedSegment: TimeSegmentState,\n autoAdvance: boolean\n) => {\n // Replace the segment with the updated version.\n const modifiedSegments = replaceTimeSegment(existingSegments, updatedSegmentType, updatedSegment);\n let updatedSegments = modifiedSegments;\n\n const isHourSegmentAndComplete = updatedSegmentType === 'hour' && updatedSegment.isComplete;\n if (isHourSegmentAndComplete) {\n updatedSegments = autoFillEmptyNonHourSegments(updatedSegments);\n }\n // If the updatedSegment is complete, automatically select the next segment.\n updatedSegments =\n updatedSegment.isComplete && autoAdvance\n ? selectNext(updatedSegments, orderedSegments)\n : updatedSegments;\n\n return updatedSegments;\n};\n\n/**\n * This function auto-fills all empty, non-hour segments ('minute', 'second', 'millisecond' and 'dayPeriod').\n * It only auto-fills the empty fields and leaves the other fields alone.\n * For example, if milliseconds is not empty, we leave the milliseconds as is and update all the empty fields;\n * 23:--:--:400 becomes 23:00:00:400. And if there is a dayPeriod segment, 5:--:--:400 -- becomes 5:00:00:400 AM.\n *\n * @param existingSegments\n * @param hourSegmentState\n * @returns\n */\nconst autoFillEmptyNonHourSegments = (existingSegments: TimeSegmentState[]) => {\n // if a segment already has a value, then do nothing.\n const initializedSegments = existingSegments.map((seg) => {\n if (seg['aria-valuenow'] !== undefined) {\n return seg;\n }\n\n let text, ariaValue;\n\n if (seg.type === 'millisecond') {\n text = '000';\n ariaValue = 0;\n } else if (['minute', 'second'].includes(seg.type)) {\n text = '00';\n ariaValue = 0;\n } else if (seg.type === 'dayPeriod') {\n // seg.amPM.am always has a value for the dayPeriod segment, so there is no need to default it.\n text = seg.amPm?.am;\n ariaValue = AM_VALUE;\n }\n\n return text !== undefined\n ? { ...seg, 'aria-valuenow': ariaValue, text, isComplete: true, 'aria-valuetext': text }\n : seg;\n });\n return initializedSegments;\n};\n\n/**\n * Construct a new TimeFieldState from a set of updated segments.\n * @param {TimeFieldState} currentState - The current state of the time field.\n * @param {TimeSegmentState[]} updatedSegments - the updated segments\n * @returns A new TimeFieldState from the set of updated segments.\n */\nconst createTimeFieldStateFromSegments = (\n currentState: TimeFieldState,\n updatedSegments: TimeSegmentState[]\n) => {\n return {\n committing: currentState.committing,\n currentTime: createTimeFromSegments(updatedSegments),\n isCompleteTime: isTimeComplete(updatedSegments),\n isTimeSelected: currentState.isTimeSelected,\n isPartialTime: isPartialTime(updatedSegments),\n orderedSegments: getOrderedSegmentsFromState(currentState),\n segments: updatedSegments\n };\n};\n\n//\n/**\n * Constructs a new TimeFieldState given an updated segment, which may affect other segments.\n * @param {TimeFieldState} currentState - The current state of the time field.\n * @param {EditableTimeSegmentType} updatedSegmentType - The type of the segment that was updated.\n * @param {TimeSegmentState} updatedSegment - The updated state of the specified segment.\n * @param {boolean} autoAdvance - Whether to auto-advance to the next segment if the current segment is complete. Defaults to true.\n * @returns {TimeFieldAction} - A new TimeFieldState based on the updated segment and the current state.\n */\nconst createTimeFieldState = (\n currentState: TimeFieldState,\n updatedSegmentType: EditableTimeSegmentType,\n updatedSegment: TimeSegmentState,\n autoAdvance = true\n): TimeFieldState => {\n const updatedSegments = createTimeSegmentStates(\n currentState.segments,\n currentState.orderedSegments,\n updatedSegmentType,\n updatedSegment,\n autoAdvance\n );\n\n return createTimeFieldStateFromSegments(currentState, updatedSegments);\n};\n\n/**\n * The clearSegment function clears the current state of the time segment by resetting\n * specific properties to indicate that the segment no longer holds a value.\n * Specifically, it sets:\n * 'aria-valuetext': undefined,\n * 'aria-valuenow': undefined,\n * digitCount: 0,\n * text: undefined,\n * isComplete: false\n *\n * This function returns a new segment state reflecting these cleared properties.\n *\n * @param {TimeSegmentState} segmentState - The current state of the time segment to clear.\n * @returns {TimeSegmentState} A new segment state with cleared properties.\n */\nconst clearSegment = (segmentState: TimeSegmentState) => {\n return {\n ...segmentState,\n 'aria-valuetext': undefined,\n 'aria-valuenow': undefined,\n digitCount: 0,\n text: undefined,\n isComplete: false\n };\n};\n\n/**\n * Clears the current state of each segment.\n *\n * @param {TimeSegmentState[]} segments\n * @returns The updated state with all segments cleared.\n */\nconst clearTime = (segments: TimeSegmentState[]) => {\n return segments.map((segmentState) => {\n const cleared = clearSegment(segmentState);\n return { ...cleared };\n });\n};\n\n/**\n * Updates the state of a time segment based on user input, one character at a time,\n * enforcing range constraints, completeness rules,\n * and zero-padding requirements for the segment types.\n * @param segmentType\n * @param segmentState\n * @param action\n * @returns A new copy of the segment state with updated values.\n */\nconst updateSegment = (\n segmentType: EditableTimeSegmentType,\n segmentState: TimeSegmentState,\n action: TimeFieldAction\n) => {\n // Process the input action text\n // actionText - This is one character, the one the user typed.\n const actionText = action.data?.text!;\n // Get the current segment state.\n const maxValue = segmentState['aria-valuemax']!;\n const minValue = segmentState['aria-valuemin']!;\n const minValueZero = minValue === 0;\n // TODO: minute, second, millisecond always have leading zeros, but hour might not; it is based on the locale,\n // and can be overridden with the shouldForceLeadingZeros api. This will need to be implemented later.\n // For all the locales I tested, most h23 clocks use a leading zero, and most h12 clocks do not,\n // so this is what this code figures.\n const hasLeadingZeros = minValueZero;\n const wasComplete = segmentState.isComplete;\n // digitCount is used to figure out if the segment is complete.\n // It is used to distinguish between\n // the user typing in all 0s or the auto-filling of 0s that happens when the user types in one 0 into an empty or complete field.\n // It is also used to figure out if the user typed in the number of digits to fill the space.\n // Like if the user typed in 0, 0, 5 in millisecond. The segment is complete because the digitCount >= targetDigitCount.\n let digitCount = segmentState.digitCount || 0;\n const targetDigitCount = segmentType === 'millisecond' ? 3 : 2;\n\n // Handle special case for segments that do not start with 0: ignore multiple leading 0s.\n // TODO: When I implement the leading zero for the uncommon case - leading zero for h12 or no leading zero for h23, this will\n // likely change.\n if (\n !minValueZero &&\n actionText === '0' &&\n (wasComplete || segmentState.text === undefined || segmentState.text === '')\n ) {\n // keep ignoring 0s, but keep digitCount = 1;\n return {\n ...segmentState,\n digitCount: 1\n };\n }\n\n // Set requestedValStr based on leading zero rules\n let requestedValStr = segmentState.text || '';\n if (wasComplete) {\n // If the value is complete and you type another number, it replaces what is already there.\n requestedValStr = actionText;\n } else {\n requestedValStr = (segmentState.text ?? '') + actionText;\n }\n\n if (hasLeadingZeros && requestedValStr.length > targetDigitCount) {\n requestedValStr = requestedValStr.slice(requestedValStr.length - targetDigitCount);\n } else if (hasLeadingZeros) {\n requestedValStr = requestedValStr.padStart(targetDigitCount, '0');\n }\n\n digitCount += 1;\n\n // Check if the value is in range and apply final adjustments\n // if not in range, then actionText overwrites requestedValStr.\n // E.g., first we type '2', then we type '5'. '25' is out of range for hour24, so we use '5'.\n const inRange = withinRange(stringToNumber(requestedValStr), minValue, maxValue);\n const finalValStr = inRange\n ? requestedValStr\n : hasLeadingZeros\n ? actionText.padStart(targetDigitCount, '0')\n : actionText;\n const finalVal = stringToNumber(finalValStr);\n\n // Determine if the segment is complete.\n const isComplete = isSegmentComplete(finalVal, maxValue, digitCount, targetDigitCount);\n // reset digitCount if the segment is complete.\n // When digitCount is 0, whatever is in the field will be overwritten if the user types into it again,\n // which is the desired behavior.\n digitCount = isComplete ? 0 : digitCount;\n\n return {\n ...segmentState,\n 'aria-valuetext': finalValStr,\n 'aria-valuenow': finalVal,\n digitCount,\n text: finalValStr,\n isComplete\n };\n};\n\n/**\n * Updates the selection state of the segments, setting the isSelected property to true for the\n * segment that has the segmentType and false for all others.\n * @param {TimeSegmentState[]} segments\n * @param {EditableTimeSegmentType} segmentType - The type of the segment that is being updated.\n * @returns {TimeSegmentState[]} A new array of time segments with updated isSelected state.\n */\nconst selectSegment = (segments: TimeSegmentState[], segmentType: EditableTimeSegmentType) => {\n return segments.map((seg) => {\n return { ...seg, isSelected: seg.type === segmentType ? true : false };\n });\n};\n\n/**\n * Updates the isSelected state of the first segment from the ordered segments to true,\n * while setting isSelected to false for all other segments.\n *\n * This function can be used to set the initial focus on the first time segment.\n *\n * @param {TimeSegmentState[]} segments - An array of current time segment states, each\n * representing different parts of the time (e.g., hour, minute, second, dayPeriod).\n * @param {OrderedTimeSegmentsArray} orderedSegments - An array of segment types in the\n * represented order (e.g., ['hour','minute', 'dayPeriod']). This is used to get the type\n * of the first segment.\n * @returns {TimeSegmentState[]} A new array of time segment states with the first segment's isSelected\n * property set to true and all other segment's isSelected properties set to false.\n */\nconst selectFirst = (segments: TimeSegmentState[], orderedSegments: OrderedTimeSegmentsArray) => {\n return selectSegment(segments, orderedSegments[0]);\n};\n\n// Find the index of the selected segment in the ordered list; return -1 if there is no selection.\nconst getSelectedSegmentIndex = (\n segments: TimeSegmentState[],\n orderedSegments: OrderedTimeSegmentsArray\n) => {\n const sel = segments.find((seg) => seg.isSelected === true);\n return sel === undefined ? -1 : orderedSegments.findIndex((type) => type === sel.type);\n};\n\n/**\n * Convenience function to mark the selected segment complete.\n * @param segments\n * @returns The updated segments where if isSelected was true, isComplete is now also true.\n */\nconst markSelectedSegmentComplete = (segments: TimeSegmentState[]) => {\n return segments.map((seg) =>\n seg.isSelected ? { ...seg, isComplete: true, digitCount: 0 } : seg\n );\n};\n\n/**\n * Selects the segment following the one that is currently selected.\n * @param segments\n * @param orderedSegments\n * @returns\n */\nconst selectNext = (segments: TimeSegmentState[], orderedSegments: OrderedTimeSegmentsArray) => {\n const selectedIndex = getSelectedSegmentIndex(segments, orderedSegments);\n const max = orderedSegments.length - 1;\n\n // If we're already at the last position, do nothing. Note if nothing was currently selected\n // then selectedIndex is -1. The first segment will be selected.\n return selectedIndex === max\n ? segments\n : selectSegment(markSelectedSegmentComplete(segments), orderedSegments[selectedIndex + 1]);\n};\n\n/**\n * Selects the segment prior to the one that is currently selected.\n * @param segments\n * @param orderedSegments\n * @returns\n */\nconst selectPrevious = (\n segments: TimeSegmentState[],\n orderedSegments: OrderedTimeSegmentsArray\n) => {\n const selectedIndex = getSelectedSegmentIndex(segments, orderedSegments);\n return selectedIndex === 0\n ? segments\n : selectedIndex === -1\n ? selectFirst(segments, orderedSegments)\n : selectSegment(markSelectedSegmentComplete(segments), orderedSegments[selectedIndex - 1]);\n};\n\n/**\n * Returns a new TimeSegmentState[] where all segments are unselected and any values are\n * marked complete. We want to do this when the user commits the TimeField value (on blur).\n * We do not do this when the user commits the TimeField value on Enter\n * because in that case the component still has focus on Enter, and they could continue typing in the segment.\n * @param segments\n * @returns a new TimeSegmentState[] where all segments have isSelected: false and any\n * with text has isComplete: true.\n */\nconst deselectAndComplete = (segments: TimeSegmentState[]) => {\n return segments.map((seg) => {\n return { ...seg, isSelected: false, isComplete: !!seg.text };\n });\n};\n\n/**\n * Returns a new TimeSegmentState[] where all segments are unselected by setting isSelected: false.\n * @param segments\n * @returns\n */\nconst clearSelection = (segments: TimeSegmentState[]) => {\n return segments.map((seg) => {\n return { ...seg, isSelected: false };\n });\n};\n\n/**\n * Checks if hour is clear and dayPeriod is not clear, and if so, clear the dayPeriod segment.\n * @param segments\n * @returns segments, with the 'dayPeriod' segment updated, if needed.\n */\nconst clearDayPeriodSegmentWhenHourIsEmpty = (segments: TimeSegmentState[]) => {\n // find the dayPeriod segment if it exists.\n const dayPeriodSegment = segments.find((seg) => seg.type === 'dayPeriod');\n // find the hour segment.\n const hourSegmentState = segments.find((seg) => seg.type === 'hour');\n const hourSegmentHasText = hourSegmentState?.text !== undefined;\n const dayPeriodSegmentHasText = dayPeriodSegment?.text !== undefined;\n\n // If hour is clear and dayPeriod is not clear, clear dayPeriod.\n // E.g., --:00 PM becomes --:00 --.\n if (!hourSegmentHasText && dayPeriodSegmentHasText) {\n return segments.map((seg) => {\n if (seg.type === 'dayPeriod') {\n return clearSegment(seg);\n }\n return { ...seg };\n });\n }\n return segments;\n};\n\n/**\n * If the hour segment is filled in, auto-fill empty minute, second, and millisecond segments and dayPeriod segment.\n * The additional parameter checkHourSelected, if true, will make sure that the hour isSelected state is true before auto-filling.\n * This is used for the 'selectNext' action.\n * @param segments\n * @param checkHourSelected {boolean} true, if the hour segment must be selected in order to auto-fill.\n * @returns segments, with the minute, second, millisecond, and dayPeriod segments updated, if needed.\n */\nconst completeAllEmptySegmentsWhenHourHasValue = (\n segments: TimeSegmentState[],\n checkHourSelected?: boolean\n) => {\n const hourSegment = segments.find((seg) => seg.type === 'hour');\n const autoFillRequirementMet = checkHourSelected ? hourSegment?.isSelected : true;\n\n if (autoFillRequirementMet && hourSegment?.text !== undefined) {\n return autoFillEmptyNonHourSegments(segments);\n }\n return segments;\n};\n\n/**\n * If the hour segment is filled in, auto-fill empty minute, second, and millisecond segments and dayPeriod segment.\n * If the hour segment is empty and the dayPeriod segment is filled in, clear out the dayPeriod segment.\n * This is what we do when we leave the component.\n * @param segments\n * @returns segments, with the minute, second, millisecond, and dayPeriod segments updated, if needed.\n */\nconst completeAllSegmentsBasedOnHour = (segments: TimeSegmentState[]) => {\n const updatedSegments = completeAllEmptySegmentsWhenHourHasValue(segments);\n return clearDayPeriodSegmentWhenHourIsEmpty(updatedSegments);\n};\n\n/**\n * This function is called when the user wants to select the entire date.\n * If currentState.isCompleteTime is true,\n * - returns a new TimeFieldState from the currentState where the entire time is marked as selected,\n * and the 'isSelected' property of all the individual segments is set to false.\n *\n * If the time is not complete,\n * - returns the currentState unchanged.\n\n * @param {TimeFieldState} currentState\n * @returns\n */\nconst selectTime = (currentState: TimeFieldState) => {\n if (currentState.isCompleteTime) {\n return createTimeFieldStateWithSelectedTime(\n currentState,\n clearSelection(currentState.segments),\n true\n );\n }\n return currentState;\n};\n\n/**\n * Creates a new TimeFieldState from the updatedSegments and the isTimeSelected param.\n * NOTE: This updates currentTime based on the segments.\n *\n * @param {TimeFieldState} currentState\n * @param {TimeFieldState[]} updatedSegments\n * @param {boolean} isTimeSelected - Indicates whether the entire time field is selected.\n * @returns {TimeFieldState} The updated state of the time field.\n */\nconst createTimeFieldStateWithSelectedTime = (\n currentState: TimeFieldState,\n updatedSegments: TimeSegmentState[],\n isTimeSelected: boolean\n) => {\n return {\n committing: currentState.committing,\n currentTime: createTimeFromSegments(updatedSegments),\n isCompleteTime: isTimeComplete(updatedSegments),\n isTimeSelected,\n isPartialTime: isPartialTime(updatedSegments),\n orderedSegments: getOrderedSegmentsFromState(currentState),\n segments: updatedSegments\n };\n};\n\n/**\n * Gets the minimum value for the segment.\n * @param segmentState\n * @returns the minimum value for the segment.\n */\nconst getHomeSegmentValue = (segmentState: TimeSegmentState) => {\n return segmentState['aria-valuemin']!;\n};\n\n/**\n * Gets the maximum value for the segment.\n * @param segmentState\n * @returns the maximum value for the segment\n */\nconst getEndSegmentValue = (segmentState: TimeSegmentState) => {\n return segmentState['aria-valuemax']!;\n};\n\n/**\n * Adjusts the value of a time segment (e.g., hour, minute, second, millisecond) by a given step.\n * It handles both increasing and decreasing the value with wrapping logic\n * when the value exceeds the max or falls below the min.\n *\n * Uses separate paths for cases when min is 0 and when min is non-zero for clarity.\n *\n * @param {number} value - The current value of the segment.\n * @param {number} step - The amount to increment or decrement the value.\n * @param {number} min - The minimum allowed value for the segment.\n * @param {number} max - The maximum allowed value for the segment.\n * @param {TimeFieldActionData['direction']} direction - Whether to increase or decrease the value.\n * @returns {number} - The new adjusted value after wrapping.\n */\nconst adjustTimeSegment = (\n value: number,\n step: number,\n min: number,\n max: number,\n direction: Exclude<TimeFieldActionData['direction'], undefined>\n) => {\n const range = max - min + 1; // Total values in the range.\n\n if (min === 0) {\n // Path for min === 0 (e.g., minutes, seconds, 0-23 hour time).\n if (direction === 'increase') {\n const steppedValue = value + step;\n return steppedValue % range; // Wrap within range 0 to max.\n } else {\n // direction === 'decrease'\n const steppedValue = value - step;\n return (steppedValue + range) % range; // Wrap below min to max.\n }\n } else {\n // Path for any min !== 0 (e.g., 12-hour clock has min 1 and max 12, or other ranges).\n if (direction === 'increase') {\n const steppedValue = value + step;\n return ((steppedValue - min) % range) + min; // Wrap within min-based range.\n } else {\n // direction === 'decrease'\n const steppedValue = value - step;\n return ((steppedValue - min + range) % range) + min; // Wrap below min to max.\n }\n }\n};\n\n/**\n * Returns the result of stepping currentValue in the requested direction, taking into account min and max.\n * @param {number} currentValue\n * @param direction\n * @param {number} min\n * @param {number} max\n * @returns {number} the result of stepping currentValue in the requested direction, taking into account min and max.\n */\nconst getSteppedSegmentValue = (\n currentValue: number,\n direction: Exclude<TimeFieldActionData['direction'], undefined>,\n min: number,\n max: number\n) => {\n const newValue = adjustTimeSegment(currentValue, 1, min, max, direction);\n return newValue;\n};\n\n/**\n * Returns the result of paging the value up or down, taking into account min and max.\n * @param currentValue\n * @param direction\n * @param min\n * @param max\n * @param segmentType\n * @returns\n */\nconst getPagedSegmentValue = (\n currentValue: number,\n direction: Exclude<TimeFieldActionData['direction'], undefined>,\n min: number,\n max: number,\n segmentType: Exclude<EditableTimeSegmentType, 'dayPeriod'>\n) => {\n let step;\n if (segmentType === 'minute' || segmentType == 'second') {\n step = 10;\n } else if (segmentType === 'millisecond') {\n step = 100;\n } else {\n step = 2;\n }\n\n const newValue = adjustTimeSegment(currentValue, step, min, max, direction);\n return newValue;\n};\n\n/**\n * Creates a new segment state with an updated value from a keyboard action such as step, page, Home, or End.\n * After any keyboard action, the value is complete so that if the user types anything,\n * it will replace the stepped value.\n * @param {EditableTimeSegmentType} segmentType - The type of the segment that is being updated.\n * @param {number} newVal - new value which is used to update the aria-valuenow and aria-valuetext and text properties.\n * @param segmentState\n * @returns A new segment state with an updated value from a keyboard action such as step, page, Homt, or End.\n */\nconst createSegmentFromKeyboardAction = (\n segmentType: EditableTimeSegmentType,\n newVal: number,\n segmentState: TimeSegmentState\n) => {\n // TODO: For now do not zero pad 1-digit 12-hour hours, but pad everything else.\n // We need to be able to override this with an api.\n // Only the hour12 segment has aria-valuemin to be 1. All the other segments' aria-valuemin is 0.\n const hour12 = segmentState['aria-valuemin'] === 1;\n const ariaValueText = getAriaValueText(newVal, segmentState, segmentType, !hour12);\n\n // Create a new segment state that reflects the updated value.\n // After any keyboard action, the value is complete so that if the user types anything,\n // it will replace the stepped value.\n return {\n ...segmentState,\n 'aria-valuetext': ariaValueText,\n 'aria-valuenow': newVal,\n text: ariaValueText,\n isComplete: true\n };\n};\n\n// Set the segment to its minimum value.\nconst goToHome = (segmentType: EditableTimeSegmentType, segmentState: TimeSegmentState) => {\n const newValue = getHomeSegmentValue(segmentState); // gets aria-valuemin\n return createSegmentFromKeyboardAction(segmentType, newValue, segmentState);\n};\n\n// Set the segment to its maximum value.\nconst goToEnd = (segmentType: EditableTimeSegmentType, segmentState: TimeSegmentState) => {\n const newValue = getEndSegmentValue(segmentState); // gets aria-valuemax\n return createSegmentFromKeyboardAction(segmentType, newValue, segmentState);\n};\n\n/**\n * Steps or pages a segment's value. Pass in initialStarting of 12 for hour12, otherwise we want to use the min.\n * Creates a new segment state with an updated value.\n *\n * After any keyboard action, the value is complete so that if the user types anything, it will replace the stepped value.\n * @param segmentType\n * @param segmentState\n * @param type\n * @param direction\n * @returns A new segment state with an updated value from the keyboard action.\n */\nconst doStepOrPage = (\n segmentType: EditableTimeSegmentType,\n segmentState: TimeSegmentState,\n type: 'step' | 'page',\n direction: Exclude<TimeFieldActionData['direction'], undefined>\n) => {\n // aria-valuemin is 0 for all segments except the 12-hour hour segment, where it is 1.\n // When you step or page up when there is no initial value in the segment, we figure it\n // out by using aria-valuemin for all segments (which is 0) except for the 12-hour hour segment.\n // For the 12-hour segment stepping starts at 12.\n const initialStarting =\n segmentType === 'hour' && segmentState['aria-valuemin'] === 1\n ? 12\n : segmentState['aria-valuemin'];\n const valueNow = segmentState['aria-valuenow'];\n const min = segmentState['aria-valuemin']!;\n const max = segmentState['aria-valuemax']!;\n\n let newValue;\n if (segmentType === 'dayPeriod') {\n // toggle aria-valuenow\n newValue = valueNow === AM_VALUE ? PM_VALUE : AM_VALUE;\n } else if (valueNow === undefined) {\n // start at the minimum if there is no value.\n newValue = initialStarting ?? min;\n } else if (type === 'page') {\n newValue = getPagedSegmentValue(valueNow, direction, min, max, segmentType);\n } else {\n newValue = getSteppedSegmentValue(valueNow, direction, min, max);\n }\n return createSegmentFromKeyboardAction(segmentType, newValue, segmentState);\n};\n\n/**\n * Get the text for the segment's aria-valuetext property. For dayPeriod segment, we use the segmentState.amPm?.am and\n * segmentState.amPm?.pm to get the localized value.\n * @param {number} newVal - the segments value.\n * @param {TimeSegmentState} segmentState - the segment's current state.\n * @param {EditableTimeSegmentType} segmentType - the segment's type.\n * @param {boolean} padZero - whether to pad the text with 0, e.g., minute segments pad 0, so 1 minute would be '01'.\n * @returns the text for the segment's aria-valuetext property.\n */\nconst getAriaValueText = (\n newVal: number,\n segmentState: TimeSegmentState,\n segmentType: EditableTimeSegmentType,\n padZero: boolean\n) => {\n if (segmentType === 'dayPeriod') {\n // This is the segmentState for dayPeriod:\n //\n // aria-valuenow=\"0” // 0 if AM, 12 if PM\n // aria-valuetext=\"AM”\n // aria-valuemin=\"0”\n // aria-valuemax=“12\"\n // text=“AM\"\n // aria-label=\"AM/PM\"\n // seg.amPM.am and pm always have a value for the dayPeriod segment, so there is no need to default them.\n const amValue = segmentState.amPm?.am;\n const pmValue = segmentState.amPm?.pm;\n return newVal < PM_VALUE ? amValue : pmValue;\n }\n // TODO: Deal with leading zero. In h23 clocks mostly we use leading zeros, and in h12 clocks mostly we do not.\n // but this can be overridden as well with an api.\n const valStr = numberToString(newVal);\n if (!padZero) {\n return numberToString(newVal);\n }\n const targetDigitCount = segmentType === 'millisecond' ? 3 : 2;\n return valStr.padStart(targetDigitCount, '0');\n};\n\n/**\n * Returns an hour 0-23 given the hour 1-12 and the dayPeriod 0 for AM and 12 for PM.\n * @param dayPeriodValue\n * @param timeHour12\n * @returns The hour 0-23.\n */\nconst getAdjustedH12ToH23 = (dayPeriodValue: number, timeHour12: number) => {\n // If both dayPeriod and hour are available, adjust the hour to h23 format\n if (dayPeriodValue === AM_VALUE && timeHour12 === 12) {\n return 0; // 12 AM (midnight) adjustment.\n }\n if (dayPeriodValue === PM_VALUE && timeHour12 === 12) {\n return 12; // 12 PM, no adjustment needed\n }\n if (dayPeriodValue === PM_VALUE) {\n return timeHour12 + 12; // Convert PM hour to h23 format\n }\n return timeHour12; // AM hours, no adjustment needed.\n};\n\nexport { timeReducer, numberToString, stringToNumber };\nexport type { TimeFieldAction, TimeFieldActionData };\n","/**\n * @license\n * Copyright (c) %FIRST_YEAR% %CURRENT_YEAR%, Oracle and/or its affiliates.\n * The Universal Permissive License (UPL), Version 1.0\n * as shown at https://oss.oracle.com/licenses/upl/\n * @ignore\n */\n\nimport { ComponentProps } from 'preact';\nimport { useReducer, useRef } from 'preact/hooks';\nimport { BCP47Locale } from '#UNSAFE_IntlDateTime';\nimport { TimeSegment } from './TimeSegment';\nimport { stringToNumber, timeReducer } from './timeReducer';\nimport {\n AM_VALUE,\n getDayPeriodValueFromHour,\n getDayPeriodValueStr,\n getHourValueStr,\n padWithZero,\n PM_VALUE,\n timesAreDifferent,\n getAmPmStringsForLocale\n} from '#utils/UNSAFE_timeUtils';\n\nimport type {\n EditableTimeSegmentType,\n OrderedTimeSegmentsArray,\n Time,\n TimeGranularity,\n TimePlaceholders\n} from './types';\nimport { TimeField } from './TimeField';\n\ntype TimeFieldType = ComponentProps<typeof TimeField>;\n\ntype UseTimeFieldProps = {\n ariaLabels: Record<EditableTimeSegmentType, string>;\n granularity: TimeGranularity;\n hasLeadingZeroForHour: boolean;\n locale: BCP47Locale;\n timeMasks: TimePlaceholders;\n value?: TimeFieldType['value'];\n};\n\ntype InitializerProps = {\n ariaLabels: Record<EditableTimeSegmentType, string>;\n currentValue?: Time;\n granularity: TimeGranularity;\n hasLeadingZeroForHour: boolean;\n locale: BCP47Locale;\n timeMasks: TimePlaceholders;\n};\n\n// Make the state properties readonly because in reducers, the state is replaced, not mutated directly.\ntype TimeSegmentState = Readonly<\n ComponentProps<typeof TimeSegment> & {\n /** The current digit count for the segment. When the segment is complete or cleared, this will be set to 0.\n * This is useful for figuring out if the segment is complete.\n */\n digitCount?: number;\n }\n>;\n\ntype TimeFieldState = {\n readonly committing: boolean;\n readonly currentTime: Time | undefined;\n readonly isCompleteTime: boolean;\n readonly isTimeSelected: boolean;\n readonly isPartialTime: boolean;\n readonly orderedSegments: OrderedTimeSegmentsArray;\n readonly segments: TimeSegmentState[];\n};\n\nconst MINUTE_SECOND_MAX = 59;\nconst MILLISECOND_MAX = 999;\n\n/**\n * Hook that returns a TimeFieldState and a dispatch method to request changes to that state.\n *\n * This hook determines the initial state based on the provided input properties\n * and utilizes a reducer (`timeReducer`) to initialize the state.\n *\n * **Important**: Ensure that the `timeMasks` include all placeholders required by the specified `granularity`.\n * For example, if `granularity` is \"second\",\n * the `timeMasks` must include the second placeholder. Since 'InputTimeMask' does this validation,\n * it is not done here in the hook for efficiency sake.\n * @param {Object} props - Configuration properties for the hook.\n * @param {AmPmLocalizedValues} props.amPm - An Object containing a localized string for 'am' and one for 'pm'.\n * @param {Record<EditableTimeSegmentType, string>} props.ariaLabels - ARIA labels for each editable time segment type.\n * @param {TimePlaceholders} props.timeMasks - The time placeholders representing the structure of the time format.\n * e.g.,\n * [ { type: 'hour', value: 'hh' }, { type: 'literal', value: ':' }, { type: 'minute', value: 'mm' }, { type: 'literal', value: ' ' }, { type: 'dayPeriod', value: 'am/pm' } ]\n * @param {TimeGranularity} props.granularity - Specifies the smallest time unit that is displayed by the component.\n * @param {BCP47Locale} props.locale - The locale used for formatting the time.\n * @param {boolean} [props.hasLeadingZeroForHour] - Whether to show a leading zero in the hour field when there is only one digit or not. E.g., 01:00 AM vs 1:00 AM.\n * @param {Time | undefined} [props.value] - The current time value.\n * @returns An object containing the current 'state', a 'dispatch' function, and timeResetRef.\n */\nconst useTimeField = ({\n ariaLabels,\n granularity,\n hasLeadingZeroForHour,\n locale,\n timeMasks,\n value: currentValue\n}: UseTimeFieldProps) => {\n const [state, dispatch] = useReducer(\n timeReducer,\n {\n ariaLabels,\n currentValue,\n hasLeadingZeroForHour,\n granularity,\n locale,\n timeMasks\n },\n reducerInitializer\n );\n\n // currentValue is the controlled value passed from the parent.\n const lastValueFromParentRef = useRef<Time | undefined>(currentValue);\n const timeResetRef = useRef<boolean>(false);\n\n // If a new value is being pushed from the parent, and that value differs from\n // the current value of the reducer, then this is a programmatic update\n // and we need to call 'reset' to update the reducer state. Otherwise, the only\n // time the reducer state is updated from the value is on mount.\n if (timesAreDifferent(lastValueFromParentRef.current, currentValue)) {\n lastValueFromParentRef.current = currentValue;\n if (timesAreDifferent(currentValue, state.currentTime)) {\n const initialState = reducerInitializer({\n ariaLabels,\n currentValue,\n hasLeadingZeroForHour,\n granularity,\n locale,\n timeMasks\n });\n dispatch({ actionType: 'reset', data: initialState });\n timeResetRef.current = true;\n }\n }\n\n return { timeResetRef, dispatch, state };\n};\n\n// The bulk of the work in this hook is to derive data from currentValue\n// that will become part of our initial state.\nconst reducerInitializer = (params: InitializerProps) => {\n const { ariaLabels, currentValue, granularity, hasLeadingZeroForHour, locale, timeMasks } =\n params;\n // Construct an ordered list of the editable segments.\n const ftm = timeMasks.filter(({ type }) => type !== 'literal');\n const orderedSegments = ftm.map(({ type }) => type) as OrderedTimeSegmentsArray;\n\n const minuteValue = currentValue?.minute;\n const secondValue = currentValue?.second;\n const millisecondValue = currentValue?.millisecond;\n\n // The timeMasks has a dayPeriod part when the hour is 1-12. You never see a dayPeriod part\n // when the hour is 0-23.\n const hasDayPeriod = timeMasks.some((part) => part.type === 'dayPeriod');\n const hasHour = currentValue?.hour !== undefined;\n const hourValueStr = hasHour\n ? getHourValueStr(currentValue.hour!, hasDayPeriod, hasLeadingZeroForHour)\n : undefined;\n const hourValue = hourValueStr !== undefined ? stringToNumber(hourValueStr) : undefined;\n const dayPeriodValueStr =\n hasDayPeriod && hasHour ? getDayPeriodValueStr(locale, currentValue.hour!) : undefined;\n const dayPeriodValue =\n dayPeriodValueStr !== undefined ? getDayPeriodValueFromHour(currentValue!.hour!) : undefined;\n\n const minuteValueStr =\n currentValue?.minute === undefined ? undefined : padWithZero(currentValue.minute, 2);\n const secondValueStr =\n currentValue?.second === undefined ? undefined : padWithZero(currentValue.second, 2);\n const millisecondValueStr =\n currentValue?.millisecond === undefined ? undefined : padWithZero(currentValue.millisecond, 3);\n\n const isBaseTimeComplete =\n hourValue !== undefined &&\n minuteValue !== undefined &&\n (granularity !== 'second' || secondValue !== undefined) &&\n (granularity !== 'millisecond' ||\n (secondValue !== undefined && millisecondValue !== undefined));\n\n const isCompleteTime = isBaseTimeComplete && (!hasDayPeriod || dayPeriodValue !== undefined);\n\n // A time is considered a partial time if at least one segment has a value.\n // We need to make sure we look at the granularity, though. The time might have milliseconds only set,\n // but if milliseconds isn't in the orderedSegments, it is not a partial time.\n const isPartialTime =\n hourValue !== undefined ||\n minuteValue !== undefined ||\n ((granularity === 'second' || granularity === 'millisecond') && secondValue !== undefined) ||\n (granularity === 'millisecond' && millisecondValue !== undefined);\n\n const secondSeg = [\n {\n type: 'second' as EditableTimeSegmentType,\n 'aria-label': ariaLabels.second,\n 'aria-valuemin': 0,\n 'aria-valuemax': MINUTE_SECOND_MAX,\n 'aria-valuenow': secondValue,\n 'aria-valuetext': secondValueStr,\n isComplete: secondValue !== undefined,\n isSelected: false,\n text: secondValueStr\n }\n ];\n\n const millisecondSeg = [\n {\n type: 'millisecond' as EditableTimeSegmentType,\n 'aria-label': ariaLabels.millisecond,\n 'aria-valuemin': 0,\n 'aria-valuemax': MILLISECOND_MAX,\n 'aria-valuenow': millisecondValue,\n 'aria-valuetext': millisecondValueStr,\n isComplete: millisecondValueStr !== undefined,\n isSelected: false,\n text: millisecondValueStr\n }\n ];\n\n const dayPeriodSeg = [\n {\n type: 'dayPeriod' as EditableTimeSegmentType,\n amPm: getAmPmStringsForLocale(locale),\n 'aria-label': ariaLabels.dayPeriod,\n 'aria-valuemin': AM_VALUE,\n 'aria-valuemax': PM_VALUE,\n 'aria-valuenow': dayPeriodValue,\n 'aria-valuetext': dayPeriodValueStr,\n isComplete: dayPeriodValueStr !== undefined,\n isSelected: false,\n text: dayPeriodValueStr\n }\n ];\n\n // Create state for each editable segment of a time.\n // This does not have to be in order that you see it rendered.\n // The orderedSegments show the order.\n // The timeMasks show the order as well.\n // hour and minute are required segments.\n\n // hour will be 1-12 if the masks have a 'dayPeriod' part (e.g., 1:00 PM), otherwise the hour is 0-23 (e.g., 13:00).\n const editableSegments = [\n {\n type: 'hour' as EditableTimeSegmentType,\n 'aria-label': ariaLabels.hour,\n 'aria-valuemin': hasDayPeriod ? 1 : 0,\n 'aria-valuemax': hasDayPeriod ? 12 : 23,\n 'aria-valuenow': hourValue,\n 'aria-valuetext': hourValueStr,\n isComplete: hourValue !== undefined,\n isSelected: false,\n text: hourValueStr\n },\n {\n type: 'minute' as EditableTimeSegmentType,\n 'aria-label': ariaLabels.minute,\n 'aria-valuemin': 0,\n 'aria-valuemax': MINUTE_SECOND_MAX,\n 'aria-valuenow': minuteValue,\n 'aria-valuetext': minuteValueStr,\n isComplete: minuteValue !== undefined,\n isSelected: false,\n text: minuteValueStr\n },\n ...(granularity === 'second' || granularity === 'millisecond' ? secondSeg : []),\n ...(granularity === 'millisecond' ? millisecondSeg : []),\n ...(hasDayPeriod ? dayPeriodSeg : [])\n ];\n\n // Done deriving the data for our initial state,\n // now create the initial state object to pass to our reducer.\n const initialState: TimeFieldState = {\n committing: false,\n currentTime: currentValue,\n isCompleteTime,\n isTimeSelected: false,\n isPartialTime,\n orderedSegments,\n segments: editableSegments\n };\n return initialState;\n};\n\nexport { useTimeField };\nexport type { TimeFieldState, TimeSegmentState };\n","/**\n * @license\n * Copyright (c) %FIRST_YEAR% %CURRENT_YEAR%, Oracle and/or its affiliates.\n * The Universal Permissive License (UPL), Version 1.0\n * as shown at https://oss.oracle.com/licenses/upl/\n * @ignore\n */\n\nimport { classNames } from '#utils/UNSAFE_classNames';\nimport { segmentStyles } from './themes/SegmentStyles.css';\n\ntype Props = {\n /**\n * True if the segment should be hidden.\n */\n isHidden?: boolean;\n\n /**\n * True if the segment should be highlighted.\n */\n isHighlighted?: boolean;\n\n /**\n * True if the literal is part of a time placeholder, such as hh:mm:ss:sss.\n * If the time is partially specified or complete, this is false.\n */\n isPlaceholder?: boolean;\n\n /**\n * The text to display for this segment.\n */\n text: string;\n};\n\n/**\n * LiteralSegment is used to represent a literal separator in a time,\n * such as the ':' in 10:00:00:000.\n */\nexport const LiteralSegment = ({ isHidden, isHighlighted, isPlaceholder, text }: Props) => {\n const spanClasses = classNames([\n segmentStyles.literalBase,\n isPlaceholder && segmentStyles.placeholder,\n isHighlighted && segmentStyles.highlighted,\n isHidden ? segmentStyles.hidden : segmentStyles.notHidden\n ]);\n\n return (\n <span aria-hidden=\"true\" class={spanClasses}>\n {text}\n </span>\n );\n};\n","/**\n * @license\n * Copyright (c) %FIRST_YEAR% %CURRENT_YEAR%, Oracle and/or its affiliates.\n * The Universal Permissive License (UPL), Version 1.0\n * as shown at https://oss.oracle.com/licenses/upl/\n * @ignore\n */\n\nimport type { RefObject, ComponentProps } from 'preact';\nimport { Dispatch, MutableRef, useCallback, useRef } from 'preact/hooks';\nimport { timesAreDifferent } from '#utils/UNSAFE_timeUtils';\nimport { TimeFieldAction } from './timeReducer';\nimport { TimeFieldState } from './useTimeField';\nimport { Time, EditableTimeSegmentType } from './types';\nimport { getClientHints } from '#utils/PRIVATE_clientHints';\nimport { isBackspaceOrDelete, isSelectAll } from '#utils/PRIVATE_keyboardUtils';\nimport { InputTimeMask } from './InputTimeMask';\nimport { useDoubleTap } from '#hooks/UNSAFE_useDoubleTap';\nimport { useTabbableMode } from '#hooks/UNSAFE_useTabbableMode';\n\ntype InputTimeMaskProps = ComponentProps<typeof InputTimeMask>;\n\ntype Props = {\n timeResetRef: MutableRef<boolean>;\n direction: 'ltr' | 'rtl';\n dispatch: Dispatch<TimeFieldAction>;\n groupRef?: RefObject<HTMLDivElement>;\n isDisabled?: boolean;\n isFocused?: boolean;\n isInputFocused?: boolean;\n onCommit: InputTimeMaskProps['onCommit'];\n onInput: InputTimeMaskProps['onInput'];\n state: TimeFieldState;\n value?: Time;\n};\n\nfunction isMobile() {\n const deviceType = getClientHints().deviceType;\n return deviceType === 'phone' || deviceType === 'tablet';\n}\n\n/**\n * A hook that creates various handlers and manages effects for a TimeField.\n * This is extremely similar to useDateFieldHandler, and it shouldn't be too hard to share code.\n */\nconst useTimeFieldHandlers = ({\n timeResetRef,\n direction,\n dispatch,\n groupRef,\n isDisabled,\n isFocused,\n isInputFocused,\n onCommit,\n onInput,\n state,\n value: currentValue\n}: Props) => {\n const {\n tabbableModeProps: { tabIndex: tabbableModeIndex }\n } = useTabbableMode();\n const anySegmentSelected = state.segments.some((segment) => !!segment.isSelected);\n\n // If any segment is selected, it is contenteditable=true and it has the focus. If you shift-Tab, you will\n // land on the outer div (TimeField) first meaning it takes 2 shift-tab keys to get the previous element.\n // To prevent this, if any segment is selected the tabindex on the div is set to -1.\n // We also need to set tabindex to -1 for the disabled case, since we are dealing with a div instead\n // of an intrinsic input and have to handle it directly.\n const updatedTabIndex = tabbableModeIndex === -1 || anySegmentSelected || isDisabled ? -1 : 0;\n\n // Keep track of the last changed and last committed time values.\n const lastTimeRef = useRef<Time | undefined>(state.currentTime);\n const lastCommittedTimeRef = useRef<Time | undefined>(state.currentTime);\n\n // Keep track whether the time was cleared.\n const timeClearedRef = useRef<boolean>(false);\n const lastFocusedRef = useRef<boolean>(!!isFocused);\n\n // If the value was programmatically changed (see useTimeField.ts), then update the\n // last changed and last committed date refs to stay in sync.\n // currentValue is the controlled value passed from the parent.\n if (timeResetRef.current) {\n lastTimeRef.current = currentValue;\n lastCommittedTimeRef.current = currentValue;\n }\n\n // Handle requested segment changes by calling the reducer dispatch function.\n const onChange = useCallback(\n (action: TimeFieldAction) => {\n dispatch(action);\n },\n [dispatch]\n );\n\n // If the user clicked on a segment, dispatch a request to select it.\n // If they clicked on the time field itself, select the first segment.\n const onClick = useCallback(\n (e: Event) => {\n const segmentType = (e.target as HTMLElement).getAttribute(\n 'data-segment'\n ) as EditableTimeSegmentType;\n !!segmentType\n ? dispatch({ actionType: 'selectSegment', data: { type: segmentType } })\n : dispatch({ actionType: 'selectFirst' });\n },\n [dispatch]\n );\n\n // If complete, select the time.\n const selectAll = useCallback(\n (isGroupFocus = true) => {\n if (state.isCompleteTime) {\n dispatch({ actionType: 'selectTime' });\n // Focus can end up in different places depending on if the user selected a segment\n // first (via click or arrow key), and then did select all. To make shift-tabbing\n // consistent in all cases, set focus to the group when selecting the time.\n isGroupFocus && groupRef?.current?.focus();\n }\n },\n [dispatch, groupRef, state.isCompleteTime]\n );\n\n const onDoubleClick = useCallback(() => {\n selectAll();\n }, [selectAll]);\n\n const onDoubleTap = useCallback(\n (e: Event) => {\n const segmentType = (e.target as HTMLElement).getAttribute(\n 'data-segment'\n ) as EditableTimeSegmentType;\n\n // Only do select all if a segment was double tapped, which means the\n // mobile keyboard will stay up.\n !!segmentType && selectAll(false);\n },\n [selectAll]\n );\n\n const doubleTapHandlers = useDoubleTap({ onDoubleTap: onDoubleTap, onSingleTap: onClick });\n\n // Handle arrow key navigation between segments. If no segment is currently selected, then select the first one.\n const onKeyDown = useCallback(\n (event: KeyboardEvent) => {\n if (\n (direction === 'ltr' && event.key === 'ArrowLeft') ||\n (direction === 'rtl' && event.key === 'ArrowRight')\n ) {\n // Select the previous segment when pressing Left arrow (or Right arrow in rtl).\n dispatch({ actionType: 'selectPrevious' });\n event.stopPropagation();\n } else if (\n (direction === 'ltr' && event.key === 'ArrowRight') ||\n (direction === 'rtl' && event.key === 'ArrowLeft')\n ) {\n // Select the next segment when pressing Right arrow (or Left arrow in rtl).\n dispatch({ actionType: 'selectNext' });\n event.stopPropagation();\n } else if (\n (isBackspaceOrDelete(event) || event.key === 'Backspace') &&\n state.isTimeSelected\n ) {\n // Clear the entire date.\n dispatch({ actionType: 'clearTime' });\n timeClearedRef.current = true;\n // Kill the event to prevent weird issue with placeholders getting deleted on iOS only.\n event.preventDefault();\n event.stopPropagation();\n event.stopImmediatePropagation();\n } else if (isSelectAll(event)) {\n selectAll();\n event.preventDefault();\n event.stopPropagation();\n } else if (event.key === 'Enter') {\n // Hitting Enter commits any changes.\n // This is also where we set 'AM' if hour is set, and AM isn't set.\n // This is where we set state.committing = true.\n dispatch({ actionType: 'commitOnEnter' });\n event.preventDefault();\n event.stopPropagation();\n }\n },\n [direction, dispatch, selectAll, state.isTimeSelected]\n );\n\n // Blurring commits the time value; clear any selected segments and mark non-empty segments as complete.\n // Sets state.committing = true.\n if (lastFocusedRef.current && !isFocused) {\n dispatch({ actionType: 'commitOnBlur' });\n }\n lastFocusedRef.current = !!isFocused;\n\n if (state.committing) {\n // Call onCommit only if the value is different.\n if (timesAreDifferent(lastCommittedTimeRef.current, state.currentTime)) {\n // freeze the object so that the app developer can't change it.\n const frozeTime =\n state.currentTime !== undefined\n ? Object.freeze({ ...state.currentTime })\n : state.currentTime;\n onCommit?.({ value: frozeTime });\n }\n // This will update the state.committing to false.\n dispatch({ actionType: 'committed' });\n lastCommittedTimeRef.current = state.currentTime;\n }\n\n if (timesAreDifferent(lastTimeRef.current, state.currentTime) && !timeResetRef.current) {\n // freeze the object so that the app developer can't change it.\n const frozeTime =\n state.currentTime !== undefined ? Object.freeze({ ...state.currentTime }) : state.currentTime;\n onInput({ value: frozeTime });\n lastTimeRef.current = frozeTime;\n }\n timeResetRef.current = false;\n\n // The following is a simplified version of how we detect keyboard vs. mouse focus\n // in the useCollectionFocusRing hook. If the user tabs onto the field, we want to\n // automatically select the first segment.\n const recentPointerRef = useRef<boolean>(false);\n const pointerDownTimerRef = useRef<ReturnType<typeof setTimeout> | undefined>();\n const onPointerDown = useCallback(() => {\n recentPointerRef.current = true;\n clearTimeout(pointerDownTimerRef.current);\n\n pointerDownTimerRef.current = setTimeout(() => {\n recentPointerRef.current = false;\n }, 200);\n }, []);\n\n // use ref to keep track of isInputFocused changed.\n const lastInputFocusedRef = useRef<boolean>(false);\n // If we receive focus that is *not* due to the user clicking in the field, i.e. the user\n // tabbed onto the field, then select the first segment. (!recentPointerRef.current means the mouse wasn't used in the component).\n // Note: we cannot check isFocused because it includes the ? icon in compact UAD, and we don't\n // want the time selected when the help icon is focused.\n // Every call to the reducer is always producing a new object and then when we create a new object, this hook gets called again. There are libraries that would fix this.\n if (isInputFocused && !lastInputFocusedRef.current && !recentPointerRef.current) {\n dispatch({ actionType: 'selectFirst' });\n }\n\n // If the keyboard was used and we have changed from focused on the input to not focused on the input, i.e. shift-tabbing onto the compact UAD help icon,\n // then 'deselectAndComplete' which will unselect any selected segments and mark them complete. It also auto-fills at this point if necessary.\n // The spec says, \"If the user tabs out of the field after entering a valid value in the hours segment, the rest of the segments will autofill with 00 and AM/PM\n // so that the value is complete.\"\n // TODO: !recentPointerRef.current is true even if I use the mouse to blur,\n // so this dispatch gets called as well as the regular blur. I can maybe protect against this by checking isFocused, no that didn't work for some reason isFocused is still true at this point.\n // JET-71717 blurring from component triggers two actions\n if (!isInputFocused && lastInputFocusedRef.current && !recentPointerRef.current) {\n dispatch({ actionType: 'deselectAndComplete' });\n }\n // If the inputFocus has changed, then set recentPointerRef.current to false to not wait until the timeout, and update the lastInputFocusedRef.\n // Setting refs does not cause a re-render.\n // TODO: Denise, why do we reset the recentPointerRef to false? We do this in useDateFieldHandler. All my tests pass without this, and demos works fine, but maybe you had a problem that this fixed in useDateFieldHandler.\n if (isInputFocused !== lastInputFocusedRef.current) {\n recentPointerRef.current = false;\n lastInputFocusedRef.current = !!isInputFocused;\n }\n\n const handlers = isMobile()\n ? { ...doubleTapHandlers, onKeyDown }\n : { onClick, onDoubleClick, onKeyDown, onPointerDown };\n\n return {\n timeClearedRef,\n timeFieldHandlers: isDisabled ? {} : handlers,\n segmentHandlers: isDisabled ? {} : { onChange },\n tabIndex: updatedTabIndex\n };\n};\n\nexport { useTimeFieldHandlers };\n","/**\n * @license\n * Copyright (c) %FIRST_YEAR% %CURRENT_YEAR%, Oracle and/or its affiliates.\n * The Universal Permissive License (UPL), Version 1.0\n * as shown at https://oss.oracle.com/licenses/upl/\n * @ignore\n */\n\nimport type { RefObject, ComponentProps } from 'preact';\nimport { useMemo, useRef } from 'preact/hooks';\nimport {\n AriaAttributesSignalExcluded,\n HTMLAttributesSignalExcluded\n} from '#utils/UNSAFE_attributeUtils';\nimport { BundleType } from '#resources/nls/bundle';\nimport { classNames } from '#utils/UNSAFE_classNames';\nimport { TimeSegment } from './TimeSegment';\nimport { TimeSegmentState, useTimeField } from './useTimeField';\nimport { Flex } from '#UNSAFE_Flex';\nimport { HiddenAccessible } from '#UNSAFE_HiddenAccessible';\nimport { InputTimeMask } from './InputTimeMask';\nimport { LiteralSegment } from './LiteralSegment';\nimport { LiveRegion } from '#UNSAFE_LiveRegion';\nimport { merge } from '#utils/UNSAFE_stringUtils';\nimport { useComponentTheme } from '#hooks/UNSAFE_useComponentTheme';\nimport { useFormFieldContext } from '#hooks/UNSAFE_useFormFieldContext';\nimport { useTranslationBundle } from '#hooks/UNSAFE_useTranslationBundle';\nimport { useUser } from '#hooks/UNSAFE_useUser';\nimport { TextFieldInputVariantOptions } from '#UNSAFE_TextField/themes/TextFieldInputStyles.css';\nimport { TextFieldInputRedwoodTheme } from '#UNSAFE_TextField/themes/redwood/TextFieldInputTheme';\nimport type { TimePlaceholders, EditableTimeSegmentType } from './types';\nimport { useTimeFieldHandlers } from './useTimeFieldHandlers';\nimport { formatTimeFromMasks, getAmPmStringsForLocale } from '#utils/UNSAFE_timeUtils';\n\ntype InputTimeMaskProps = ComponentProps<typeof InputTimeMask>;\n\ntype AriaProps = Pick<\n AriaAttributesSignalExcluded,\n 'aria-describedby' | 'aria-invalid' | 'aria-label' | 'aria-labelledby'\n>;\n\ntype HTMLElementProps = Pick<HTMLAttributesSignalExcluded<HTMLElement>, 'onBlur' | 'onFocus'>;\n\nexport type Props = AriaProps &\n HTMLElementProps & {\n /**\n * A base id prefix.\n */\n baseId: string;\n\n /**\n * A ref to the element that receives focus when the field's label is clicked,\n * or when the component is toggled between readonly and enabled. This is the\n * first segment in the field.\n */\n fieldRef?: RefObject<HTMLDivElement>;\n\n /**\n * Specifies the smallest time unit that is displayed by the component.\n * If set to minute, only hour and minute are shown.\n * If set to second then hour, minute, and second are shown.\n * If set to millisecond then hour, minute, second and millisecond are shown.\n */\n granularity?: InputTimeMaskProps['granularity'];\n\n /**\n * Whether to show a leading zero in the hour field when there is only one digit or not.\n */\n hasLeadingZeroForHour: boolean;\n\n /**\n * True if the component has an inside label.\n */\n hasInsideLabel?: boolean;\n\n /**\n * Specifies for accessibility purposes whether a value is required.\n */\n isRequired?: InputTimeMaskProps['isRequired'];\n\n /**\n * The placeholder masks used by the time field.\n */\n masks: TimePlaceholders;\n\n /**\n * Specifies how to align text within the field.\n */\n textAlign?: InputTimeMaskProps['textAlign'];\n\n /**\n * The current value of the component. The value's hour is a 0-23 hour.\n */\n value?: InputTimeMaskProps['value'];\n\n /**\n * The style variant of the component.\n */\n variant?: InputTimeMaskProps['variant'];\n\n /**\n * Callback invoked each time the user changes the value of a segment.\n *\n * For example, if the user\n * types '12' into the minute segment of an empty time field,\n * this callback will be called twice to change the minute\n * first to 1 and then 12.\n *\n * If the user types '1' into the hour segment of an empty time field,\n * this callback will be called once with the hour set to 1.\n * If the user then types '2', the callback will be called again. What it gets called with\n * depends on if the InputTimeMask is displaying a 1-12 hour time with a day period or a 0-23 hour time.\n * This is because the InputTimeMask's value's hour is stored as a 0-23 hour.\n *\n * If the user types in '12', and the time has a day period, the value's hour is 0, since 12 AM is converted to hour 0.\n * If the user types in '12', and the time does not have a day period, the value's hour is 12.\n *\n * If the user types in an hour that completes the segment, the other segments that are empty\n * are automatically filled with 0s, and the callback's value will reflect that, e.g.,\n * {hour: 0, minute: 0}.\n */\n onInput: InputTimeMaskProps['onInput'];\n\n /**\n * Callback invoked when the user commits the entered value by blurring or hitting the enter key.\n * The value's hour is a 0-23 hour.\n *\n * If the InputTimeMask's hour field is showing a 1-12 hour time, the\n * field's display value will be converted to a 0-23 hour, using the dayPeriod segment's value, which defaults to 'AM'.\n */\n onCommit: InputTimeMaskProps['onCommit'];\n };\n\nconst findSegment = (\n segments: TimeSegmentState[],\n type: EditableTimeSegmentType\n): TimeSegmentState => {\n return segments.find((segment) => segment.type === type)!;\n};\n\n/**\n * Container for Segment children that represent different parts of a time with no date.\n */\nconst TimeField = ({\n 'aria-describedby': describedBy,\n 'aria-invalid': ariaInvalid,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n baseId,\n fieldRef,\n granularity = 'minute',\n hasLeadingZeroForHour,\n hasInsideLabel,\n isRequired,\n masks: timeMasks,\n onBlur,\n onCommit,\n onFocus,\n onInput,\n textAlign,\n value,\n variant = 'default'\n}: Props) => {\n const { direction, locale } = useUser();\n\n const { am, pm } = useMemo(() => {\n return getAmPmStringsForLocale(locale);\n }, [locale]);\n\n const translations = useTranslationBundle<BundleType>('@oracle/oraclejet-preact');\n const announceTimeCleared = translations.inputTimeMask_time_cleared();\n const labels = {\n hour: translations.formControl_hour(),\n minute: translations.formControl_minute(),\n second: translations.formControl_second(),\n millisecond: translations.formControl_millisecond(),\n dayPeriod: `${am}/${pm}`\n };\n\n const { isDisabled, isFocused, isInputFocused } = useFormFieldContext();\n\n const hasValue = value !== undefined;\n\n // TimeField is similar to TextFieldInput for styling. The main difference\n // is TextFieldInput renders a textarea or input and TimeField renders a div, so the positioning with\n // padding is different. TimeField and TextFieldInput are both the mainContent\n // of a TextField component.\n const { classes } = useComponentTheme<TextFieldInputVariantOptions>(TextFieldInputRedwoodTheme, {\n type: 'notPassword',\n styleVariant: variant,\n textarea: 'notTextArea',\n input: 'notInput',\n div: 'isDiv',\n prefix: 'noPrefix',\n suffix: 'noSuffix',\n startContent: 'noStartContent',\n endContent: 'noEndContent',\n insideLabel: hasInsideLabel ? 'hasInsideLabel' : 'noInsideLabel',\n value: hasValue ? 'hasValue' : 'noValue',\n focused: isFocused ? 'isFocused' : 'notFocused',\n disabled: isDisabled ? 'isDisabled' : 'notDisabled'\n });\n\n const compClasses = classNames([classes]);\n\n const { state, dispatch, timeResetRef } = useTimeField({\n ariaLabels: labels,\n timeMasks,\n granularity,\n hasLeadingZeroForHour,\n locale,\n value\n });\n\n const { isTimeSelected, isPartialTime, segments: editableSegments } = state;\n const hourSegment = findSegment(editableSegments, 'hour');\n const minuteSegment = findSegment(editableSegments, 'minute');\n const secondSegment =\n granularity === 'second' || granularity === 'millisecond'\n ? findSegment(editableSegments, 'second')\n : undefined;\n const millisecondSegment =\n granularity === 'millisecond' ? findSegment(editableSegments, 'millisecond') : undefined;\n const dayPeriodSegment = findSegment(editableSegments, 'dayPeriod');\n\n const segmentsMap = {\n hour: hourSegment,\n minute: minuteSegment,\n second: secondSegment,\n millisecond: millisecondSegment,\n dayPeriod: dayPeriodSegment\n };\n\n const groupRef = useRef<HTMLDivElement>(null);\n const { timeFieldHandlers, timeClearedRef, segmentHandlers, tabIndex } = useTimeFieldHandlers({\n timeResetRef,\n direction,\n dispatch,\n groupRef,\n isDisabled,\n isFocused,\n isInputFocused,\n onCommit,\n onInput,\n state,\n value\n });\n\n // Like other form components, don't show placeholders for inside labels unless focused.\n // This flag causes the segment placeholders to be hidden.\n const isHidden = value === undefined && hasInsideLabel && !isFocused;\n\n // If the time is complete, create a hidden accessible region with the full formatted time.\n const formattedTimeStr = !state.isCompleteTime\n ? ''\n : formatTimeFromMasks(\n locale,\n state.currentTime!,\n granularity,\n timeMasks,\n hasLeadingZeroForHour\n );\n\n const formattedTimeAriaId = `${baseId}-time`;\n const formattedTimeAria = state.isCompleteTime ? (\n <HiddenAccessible id={formattedTimeAriaId}>{formattedTimeStr}</HiddenAccessible>\n ) : undefined;\n const ariaDescribedBy = state.isCompleteTime\n ? merge([describedBy, formattedTimeAriaId])\n : describedBy;\n\n // Add an announcement to the live region if the time was cleared.\n // Note: we deliberately do not reset timeClearedRef because there are multiple\n // rerenders after clearing the time and we want to make sure the announcement\n // has time to be heard.\n const announceText = timeClearedRef.current ? announceTimeCleared : '';\n\n // firstSegmentType is used to determine on what TimeSegment to put the fieldRef,\n // and fieldRef is a ref to the element that receives focus when the field's label is clicked.\n const firstSegmentType = state.orderedSegments[0];\n\n return (\n <div\n aria-describedby={ariaDescribedBy}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n class={compClasses}\n onFocusIn={onFocus}\n onFocusOut={onBlur}\n ref={groupRef}\n role=\"group\"\n tabIndex={tabIndex}\n {...timeFieldHandlers}>\n <Flex direction=\"row\" wrap=\"nowrap\" justify={textAlign}>\n {timeMasks.map(({ type, value: placeholder }) => {\n const segmentProps = type !== 'literal' ? segmentsMap[type] : {};\n if (type === 'literal') {\n return (\n <LiteralSegment\n isHidden={isHidden}\n isHighlighted={isTimeSelected}\n isPlaceholder={!isPartialTime}\n text={placeholder}></LiteralSegment>\n );\n } else {\n return (\n <TimeSegment\n inputRef={type === firstSegmentType ? fieldRef : undefined}\n isDisabled={isDisabled}\n isInvalid={!!ariaInvalid}\n isHidden={isHidden}\n isHighlighted={isTimeSelected}\n isRequired={isRequired}\n placeholder={placeholder}\n type={type}\n {...segmentHandlers}\n {...segmentProps}></TimeSegment>\n );\n }\n })}\n </Flex>\n {formattedTimeAria}\n <LiveRegion>{announceText}</LiveRegion>\n </div>\n );\n};\n\nexport { TimeField, findSegment };\n","/**\n * @license\n * Copyright (c) %FIRST_YEAR% %CURRENT_YEAR%, Oracle and/or its affiliates.\n * The Universal Permissive License (UPL), Version 1.0\n * as shown at https://oss.oracle.com/licenses/upl/\n * @ignore\n */\n\nimport { ComponentProps, Ref, RefObject } from 'preact';\nimport { forwardRef } from 'preact/compat';\nimport { useCallback, useImperativeHandle, useMemo, useRef } from 'preact/hooks';\n\nimport { AriaAttributesSignalExcluded } from '#utils/UNSAFE_attributeUtils';\nimport type { Time, TimePlaceholders } from './types';\nimport {\n CompactUserAssistance,\n InlineUserAssistance,\n UserAssistanceDensityType\n} from '#UNSAFE_UserAssistance';\nimport { TimeField } from './TimeField';\nimport { FormFieldContext } from '#hooks/UNSAFE_useFormFieldContext';\nimport {\n formatTimeFromMasks,\n getTimeMasksFromLocaleAndOptions,\n getLeadingZeroForHour,\n replaceCustomMasksValuesWithPlaceholders\n} from '#utils/UNSAFE_timeUtils';\nimport { Label } from '#UNSAFE_Label';\nimport { ReadonlyTextField, ReadonlyTextFieldInput, TextField } from '#UNSAFE_TextField';\nimport { Size } from '#utils/UNSAFE_size';\nimport { TextFieldContent } from '#UNSAFE_TextField/TextFieldContent';\nimport type { TestIdProps } from '#hooks/UNSAFE_useTestId';\nimport type { TextProps } from '#utils/UNSAFE_interpolations/text';\nimport { useFocusableTextField, FocusableHandle } from '#hooks/UNSAFE_useFocusableTextField';\nimport { useFormContext } from '#hooks/UNSAFE_useFormContext';\nimport { useTextField } from '#hooks/UNSAFE_useTextField';\nimport { useUser } from '#hooks/UNSAFE_useUser';\nimport { ValueUpdateDetail } from '#utils/UNSAFE_valueUpdateDetail';\nimport { LayoutColumnSpan } from '../utils/UNSAFE_styles/Layout';\n\ntype InlineUserAssistanceProps = ComponentProps<typeof InlineUserAssistance>;\n\ntype TextFieldContentProps = ComponentProps<typeof TextFieldContent>;\n\ntype Props = TestIdProps & {\n /**\n * The ID of an element (or space separated IDs of multiple elements) that\n * describes the input.\n */\n 'aria-describedby'?: AriaAttributesSignalExcluded['aria-describedby'];\n\n /**\n * Text to provide guidance to help the user understand what data to enter.\n */\n assistiveText?: InlineUserAssistanceProps['assistiveText'];\n\n /**\n * Specifies how many columns to span in a FormLayout with direction === 'row'\n */\n columnSpan?: LayoutColumnSpan;\n\n /**\n * Use this property to provide content for the end slot, such as a time icon.\n */\n endContent?: TextFieldContentProps['endContent'];\n\n /**\n * Specifies the smallest time unit that is displayed by the component.\n * If set to minute, only hour and minute are shown.\n * If set to second then hour, minute, and second are shown.\n * If set to millisecond then hour, minute, second and millisecond are shown.\n */\n granularity?: 'minute' | 'second' | 'millisecond';\n\n /**\n * Specifies whether to always show a leading zero in the hour field when the hour is 1-digit,\n * or to never show a leading zero in the hour field when the hour is 1-digit.\n * By default, when this is undefined, this is determined by the user's locale.\n */\n hasLeadingZeroForHour?: boolean;\n\n /**\n * Help source URL associated with the component.\n */\n helpSourceLink?: InlineUserAssistanceProps['helpSourceLink'];\n\n /**\n * Custom text to be rendered for the <code>helpSourceLink</code>.\n */\n helpSourceText?: InlineUserAssistanceProps['helpSourceText'];\n\n /**\n * Specifies whether the time displayed is a 1-12 hour time with a day period or a 0-23 hour time.\n * By default, this is determined by the user's locale.\n */\n isHour12?: boolean;\n\n /**\n * Specifies whether the component is disabled.\n */\n isDisabled?: boolean;\n\n /**\n * Specifies whether the component is readonly.\n */\n isReadonly?: boolean;\n\n /**\n * Specifies for accessibility purposes whether a value is required.\n *\n * Setting this property to <code>false</code> means that a value is not required to be\n * committed by the user. Setting this property to <code>true</code> means that a value\n * is required to be committed by the user.\n */\n isRequired?: boolean;\n\n /**\n * Specifies whether to show an indicator on screen that a value is required, for example\n * before the user has committed a value.\n */\n isRequiredShown?: InlineUserAssistanceProps['isRequiredShown'];\n\n /**\n * Specifies the label associated with the field.\n */\n label: string;\n\n /**\n * Specifies where the label is positioned relative to the field.\n */\n labelEdge?: 'inside' | 'start' | 'top' | 'none';\n\n /**\n * Specifies the width of the label when <code>labelEdge</code> is <code>\"start\"</code>.\n */\n labelStartWidth?: Size;\n\n /**\n * A ref to the component field. This can be used when you are composing with InputTimeMask\n * and need to provide an anchor ref to a floating component.\n */\n mainFieldRef?: RefObject<HTMLDivElement>;\n\n /**\n * Array-based representation of the segments used for time.\n * When specified, this option overrides the locale-specific formatting of the time: the separators, and the placement of the dayPeriod (AM/PM).\n *\n * For the SeparatorPlaceholder, the value is used as the separator between time segments. This is usually a ':' or a '.'.\n * For the DayPeriodPlaceholder the placement can be before the time or after the time.\n * The order of Hour/Minute/Seconds/Milliseconds cannot be changed and this will be enforced by the type.\n *\n * If the DayPeriodPlaceholder is in the masks, and the isHour12 property is set to false, an error is thrown\n * because these property values conflict.\n * If the DayPeriodPlaceholder is not in the masks, and the isHour12 property is set to true, an error is thrown\n * because these property values conflict.\n * If the masks property is specified and the granularity property does not match what is in the masks property, an error is thrown.\n */\n masks?: TimePlaceholders;\n\n /**\n * Messages to show on screen that are associated with the component.\n */\n messages?: InlineUserAssistanceProps['messages'];\n\n /**\n * Specifies how to align text within the field.\n */\n textAlign?: TextProps['textAlign'];\n\n /**\n * Specifies the density of the user assistance presentation. It can be set to:\n * <ul>\n * <li><code>'efficient'</code>: Show inline and reserve space to prevent layout reflow when user\n * assistance text is displayed.</li>\n * <li><code>'reflow'</code>: Show inline. Layout will reflow when text is displayed.</li>\n * <li><code>'compact'</code>: Messages, help, hints, and required will not be shown inline; they will show in a mode that keeps the screen more compact, like a popup for the messages, and a required icon to indicate Required. </li>\n * </ul>\n */\n userAssistanceDensity?: UserAssistanceDensityType;\n\n /**\n * The current value of the component. The value's hour is a 0-23 hour.\n * If the InputTimeMask's hour field is showing a 1-12 hour time, the\n * field's display value will be converted to a 0-23 hour, using the dayPeriod segment's value, which defaults to 'AM'.\n */\n value?: Time;\n\n /**\n * The style variant of the component.\n */\n variant?: 'default' | 'embedded';\n\n /**\n * Callback invoked when the user commits the entered value by blurring or hitting the enter key.\n * The value's hour is a 0-23 hour.\n *\n * If the InputTimeMask's hour field is showing a 1-12 hour time, the\n * field's display value will be converted to a 0-23 hour, using the dayPeriod segment's value, which defaults to 'AM'.\n *\n * Granularity will determine what fields in the value will be sent back in onInput and onCommit\n * as the user interacts with the component. For example, if granularity is 'minute' (the default),\n * then only the hour and minute fields will be shown to the user,\n * and the value sent back via onInput and onCommit will only include the fields the user has set.\n */\n onCommit?: (detail: ValueUpdateDetail<Time>) => void;\n\n /**\n * Callback invoked each time the user changes the value of a segment.\n *\n * For example, if the user\n * types '12' into the minute segment of an empty time field,\n * this callback will be called twice to change the minute\n * first to 1 and then 12.\n *\n * If the user types '1' into the hour segment of an empty time field,\n * this callback will be called once with the hour set to 1.\n * If the user then types '2', the callback will be called again. What it gets called with\n * depends on if the InputTimeMask is displaying a 1-12 hour time with a day period or a 0-23 hour time.\n * This is because the InputTimeMask's value's hour is stored as a 0-23 hour.\n *\n * If the user types in '12', and the time has an empty day period, the value's hour is 0, since the\n * dayPeriod defaults to 'AM' and 12 AM is converted to hour 0.\n * If the user types in '12', and the time does not have a day period, the value's hour is 12.\n *\n * If the user types in an hour that completes the segment, the other segments that are empty\n * are automatically filled with 0s, and the callback's value will reflect that, e.g.,\n * {hour: 0, minute: 0}.\n *\n * Granularity will determine what fields in the value will be sent back in onInput and onCommit\n * as the user interacts with the component. For example, if granularity is 'minute' (the default),\n * then only the hour and minute fields will be shown to the user,\n * and the value sent back via onInput and onCommit will only include the fields the user has set.\n */\n onInput: (detail: ValueUpdateDetail<Time>) => void;\n};\n\n/**\n * An InputTimeMask allows the user to enter, edit, or display a time value.\n */\nexport const InputTimeMask = forwardRef(\n (\n {\n 'aria-describedby': ariaDescribedBy,\n assistiveText,\n columnSpan,\n endContent,\n granularity = 'minute',\n helpSourceLink,\n helpSourceText,\n isHour12,\n isDisabled: propIsDisabled,\n isReadonly: propIsReadonly,\n isRequired,\n isRequiredShown,\n label,\n labelEdge: propLabelEdge,\n labelStartWidth: propLabelStartWidth,\n hasLeadingZeroForHour,\n mainFieldRef,\n messages,\n masks,\n testId,\n textAlign: propTextAlign,\n userAssistanceDensity: propUserAssistanceDensity,\n value,\n variant,\n onCommit,\n onInput\n }: Props,\n ref?: Ref<FocusableHandle>\n ) => {\n const {\n isDisabled: isFormDisabled,\n isReadonly: isFormReadonly,\n labelEdge: formLabelEdge,\n labelStartWidth: formLabelStartWidth,\n textAlign: formTextAlign,\n userAssistanceDensity: formUserAssistanceDensity\n } = useFormContext();\n // default to FormContext values if component properties are not specified\n const isDisabled = propIsDisabled ?? isFormDisabled;\n const isReadonly = propIsReadonly ?? isFormReadonly;\n const labelEdge = propLabelEdge ?? formLabelEdge;\n const labelStartWidth = propLabelStartWidth ?? formLabelStartWidth;\n const textAlign = propTextAlign ?? formTextAlign;\n const userAssistanceDensity = propUserAssistanceDensity ?? formUserAssistanceDensity;\n const enabledElementRef = useRef<HTMLDivElement>(null);\n const readonlyElementRef = useRef<HTMLDivElement>(null);\n\n const {\n focusProps,\n isFocused,\n methods: focusMethods\n } = useFocusableTextField<HTMLDivElement, HTMLDivElement>({\n isDisabled,\n isReadonly,\n enabledElementRef,\n readonlyElementRef\n });\n\n useImperativeHandle(ref!, () => focusMethods, [focusMethods]);\n\n const isComponentFocused = isFocused;\n\n const {\n baseId,\n formFieldContext,\n inputProps,\n labelProps: origLabelProps,\n textFieldProps,\n userAssistanceProps\n } = useTextField({\n ariaDescribedBy,\n helpSourceLink,\n helpSourceText,\n isDisabled,\n isFocused: isComponentFocused,\n isReadonly,\n isRequiredShown,\n labelEdge,\n messages,\n styleVariant: variant,\n userAssistanceDensity,\n value\n });\n\n // When using a div with role=group (i.e. TimeField), you need aria-labelledby instead of a\n // for-id association with a label. Remove forId and id and use aria-labelledby instead.\n const { forId, ...labelProps } = origLabelProps;\n const { id, ...timeFieldProps } = inputProps;\n const ariaLabelledBy = labelProps.id;\n // Because we don't use for-id, clicking the label does not automatically focus the field.\n // We have to do it manually.\n const onClick = useCallback(() => {\n enabledElementRef.current?.focus();\n }, [enabledElementRef]);\n\n const labelComp =\n labelEdge !== 'none' ? (\n <Label {...(!isDisabled && !isReadonly ? { onClick } : {})} {...labelProps}>\n {label}\n </Label>\n ) : undefined;\n\n const fieldLabelProps = {\n label: labelEdge !== 'none' ? labelComp : undefined,\n labelEdge: labelEdge !== 'none' ? labelEdge : undefined,\n labelStartWidth: labelEdge !== 'none' ? labelStartWidth : undefined\n };\n\n const ariaLabel = labelEdge === 'none' ? label : undefined;\n const hasInsideLabel = label !== undefined && labelEdge === 'inside';\n const isInlineDensity =\n userAssistanceDensity === 'efficient' || userAssistanceDensity === 'reflow';\n\n const inlineUserAssistance = isInlineDensity ? (\n isDisabled || isReadonly ? (\n // save space for user assistance if density is 'efficient', even though we don't\n // render user assistance for disabled or readonly fields\n userAssistanceDensity !== 'efficient' ? undefined : (\n <InlineUserAssistance\n userAssistanceDensity={userAssistanceDensity}\n {...userAssistanceProps}\n />\n )\n ) : (\n <InlineUserAssistance\n assistiveText={assistiveText}\n fieldLabel={label}\n helpSourceLink={helpSourceLink}\n helpSourceText={helpSourceText}\n messages={messages}\n isRequiredShown={isRequiredShown}\n userAssistanceDensity={userAssistanceDensity}\n {...userAssistanceProps}\n />\n )\n ) : undefined;\n\n const aRef = useRef<HTMLDivElement>(null);\n const anchorRef = mainFieldRef ?? aRef;\n\n const compactUserAssistance =\n userAssistanceDensity === 'compact' ? (\n <CompactUserAssistance\n anchorRef={anchorRef}\n messages={messages}\n assistiveText={assistiveText}\n {...userAssistanceProps}\n />\n ) : undefined;\n\n const { locale } = useUser();\n\n // Make sure the masks and properties do not conflict. This throws an error if they do conflict.\n validateTimeMasksAgainstProperties(masks, granularity, isHour12);\n\n if (masks !== undefined && isHour12 === undefined) {\n // The isHour12 value defaults to true if the masks include a dayPeriod; otherwise, it defaults to false.\n const hasDayPeriod = masks.find((part) => part.type === 'dayPeriod') !== undefined;\n isHour12 = hasDayPeriod;\n }\n\n // masks look like this:\n // const masks: TimePlaceholder = [\n // {type: 'dayPeriod', value: 'am/pm'},\n // {type: 'hour', value: 'hh'},\n // {type: 'literal', value: ':'},\n // {type: 'minute', value: 'mm'}\n // ]\n const timeMasks = useMemo(() => {\n // Determine the locale specific placeholder masks and separators in the correct order\n // for the locale, unless a custom set of masks was passed in. Each mask represents a\n // placeholder for a segment of a time. The hour/minute/second/millisecond's order never changes.\n // The dayPeriod segment can change: it can be at the start or at the end.\n // Memoize because we shouldn't need to recreate this data often.\n const placeholderMasks = masks\n ? replaceCustomMasksValuesWithPlaceholders(locale, masks) // no need to pass in isHour12. if masks has dayPeriod, then we use it since we checked before this if mask has dayPeriod and hour 12 is explicitly set to false, we throw an error.\n : // we get masks from locale.\n // hour12, if explicitly set, will take precedence.\n // This works: new Intl.DateTimeFormat('en-GB', {timeStyle: 'short', hour12: true}).format(datetime),\n getTimeMasksFromLocaleAndOptions(locale, granularity, isHour12);\n\n return placeholderMasks;\n }, [granularity, isHour12, locale, masks]);\n\n // We want the app dev to be able to force the hour to have a leading zero or force the hour to not have a leading zero.\n // This is useful for user preferences where the user wants the time to be in a particular format that is different than their locale.\n // Most commonly apps want to determine the leading zero from the locale, and therefore that is the default.\n const resolvedLeadingZeroForHour = hasLeadingZeroForHour ?? getLeadingZeroForHour(locale);\n if (isReadonly) {\n return (\n <FormFieldContext.Provider value={formFieldContext}>\n <ReadonlyTextField\n role=\"presentation\"\n columnSpan={columnSpan}\n compactUserAssistance={compactUserAssistance}\n inlineUserAssistance={inlineUserAssistance}\n onBlur={focusProps.onFocusOut}\n onFocus={focusProps.onFocusIn}\n ref={anchorRef}\n testId={testId}\n mainContent={\n <ReadonlyTextFieldInput\n aria-describedby={timeFieldProps['aria-describedby']}\n aria-label={ariaLabel}\n aria-labelledby={labelProps.id}\n as=\"div\"\n elementRef={readonlyElementRef}\n textAlign={textAlign}\n value={\n value === undefined\n ? ''\n : formatTimeFromMasks(\n locale,\n value,\n granularity,\n timeMasks,\n resolvedLeadingZeroForHour\n )\n }\n hasEmptyLabel={label === '' && labelEdge === 'none'}\n hasInsideLabel={hasInsideLabel}\n />\n }\n {...fieldLabelProps}></ReadonlyTextField>\n </FormFieldContext.Provider>\n );\n }\n\n // The main content inside TextField is a TimeField (not TextFieldInput) in this case.\n // We reuse the TextField building blocks and hooks, but recompose them.\n const mainContent = (\n <TimeField\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n baseId={baseId}\n fieldRef={enabledElementRef}\n granularity={granularity}\n hasInsideLabel={labelComp !== undefined && labelEdge === 'inside'}\n hasLeadingZeroForHour={resolvedLeadingZeroForHour}\n isRequired={isRequired}\n masks={timeMasks}\n onCommit={onCommit}\n onInput={onInput}\n textAlign={textAlign}\n value={value}\n {...timeFieldProps}\n />\n );\n\n return (\n <FormFieldContext.Provider value={formFieldContext}>\n <TextField\n columnSpan={columnSpan}\n compactUserAssistance={compactUserAssistance}\n endContent={endContent}\n inlineUserAssistance={inlineUserAssistance}\n mainContent={mainContent}\n onBlur={focusProps.onFocusOut}\n onFocus={focusProps.onFocusIn}\n mainFieldRef={anchorRef}\n testId={testId}\n {...textFieldProps}\n {...fieldLabelProps}\n />\n </FormFieldContext.Provider>\n );\n }\n);\n\n/**\n * This function checks the following:\n * - If both 'masks' and 'isHour12' are provided, it ensures that the 'isHour12' flag matches the presence of a 'dayPeriod' in the 'masks'.\n * - It verifies that the 'masks' contain the correct time placeholders based on the granularity.\n *\n * It throws an error if anything is not set correctly.\n * It never throws an error if masks is undefined; it just returns.\n * @param masks\n * @param granularity\n * @param isHour12\n * @throws if there is a conflict between masks and the granularity and isHour12 properties.\n */\nconst validateTimeMasksAgainstProperties = (\n masks: TimePlaceholders | undefined,\n granularity: 'minute' | 'second' | 'millisecond',\n isHour12?: boolean\n) => {\n if (masks === undefined) {\n return;\n }\n // If the user passes in masks and isHour12, we look at masks to see what the isHour12 should be.\n // If isHour12 is passed in and it is different than what we expect, we throw an error.\n if (isHour12 !== undefined) {\n const hasDayPeriod = masks.find((part) => part.type === 'dayPeriod') !== undefined;\n if (!hasDayPeriod && isHour12) {\n throw new Error(\n `The masks object does not have a dayPeriod property. isHour12 should be set to false to match masks.`\n );\n }\n if (hasDayPeriod && !isHour12) {\n throw new Error(\n `The masks object does not have a dayPeriod property. isHour12 should be set to true to match masks.`\n );\n }\n }\n // Type checking will make sure hour and minute are there since they are required.\n // Throw errors if masks does not contain the properties it should based on granularity.\n const hasSecond = masks.find((part) => part.type === 'second') !== undefined;\n const hasMillisecond = masks.find((part) => part.type === 'millisecond') !== undefined;\n const commonErrorMsg = `Change granularity to match the properties you have in the masks object.`;\n\n if (granularity === 'second' && !hasSecond) {\n const errorMsg = `granularity is second, but the masks does not contain the second property. \n ${commonErrorMsg}`;\n throw new Error(errorMsg);\n }\n if (granularity === 'second' && hasMillisecond) {\n const errorMsg = `granularity is second, but the masks object contains the millisecond property. \n ${commonErrorMsg}`;\n throw new Error(errorMsg);\n }\n if (granularity === 'millisecond' && (!hasSecond || !hasMillisecond)) {\n const errorMsg = `\"Granularity is set to millisecond. The masks object should contain both the second and millisecond properties, but one or both are missing.\" \n ${commonErrorMsg}`;\n throw new Error(errorMsg);\n }\n if (granularity === 'minute') {\n if (hasSecond || hasMillisecond) {\n throw new Error(`granularity is minute, but the masks object contains the second and/or millisecond property.\n ${commonErrorMsg}`);\n }\n }\n};\n"],"names":["preventDefaultHandler","e","preventDefault","isIos","getClientHints","platform","TimeSegment","amPm","ariaLabel","ariaValueMax","ariaValueMin","ariaValueNow","ariaValueText","inputRef","isDisabled","isHidden","isHighlighted","isInvalid","isRequired","isSelected","onChange","placeholder","text","type","hasDisplayValue","length","rootClasses","classNames","segmentStyles","base","selected","highlighted","placeholderClasses","hidden","notHidden","emptySegmentValueText","useTranslationBundle","formControl_empty_segment","sRef","useRef","segmentRef","dayPeriodTextRef","onKeyDown","useCallback","event","key","isSelectAll","isBackspaceOrDelete","isNumberOnlyString","actionType","data","direction","undefined","isLetterOnlyString","current","matchType","getAmPmMatchType","value","AM_VALUE","PM_VALUE","stopPropagation","useEffect","focus","valueText","toString","customDataAttribute","_jsx","jsx","children","_jsxs","ref","role","autocapitalize","autocorrect","class","contentEditable","enterkeyhint","inputMode","onCut","onPaste","spellcheck","tabIndex","input","isLetter","test","modifiers","isControlOrFunctionKey","timeReducer","state","action","segmentType","segmentState","findSegment","segments","updatedSegments","selectFirst","clearTime","orderedSegments","createTimeFieldStateWithSelectedTime","updatedSegment","clearSegment","createTimeFieldState","completeAllSegmentsBasedOnHour","deselectAndComplete","committing","goToEnd","goToHome","doStepOrPage","selectTime","completeAllEmptySegmentsWhenHourHasValue","updatedSelectedNextSegments","selectNext","selectPrevious","selectSegment","newValue","createSegmentFromKeyboardAction","updateSegment","Error","stringToNumber","s","numberToString","n","find","segment","isTimeComplete","allSegments","every","seg","isPartialTime","some","createTimeFromSegments","dayPeriodValue","hourSegmentValue","adjustedHour","getAdjustedH12ToH23","segmentValues","filter","reduce","acc","Object","entries","getOrderedSegmentsFromState","currentState","autoFillEmptyNonHourSegments","existingSegments","map","ariaValue","includes","am","isComplete","updatedSegmentType","autoAdvance","modifiedSegments","replaceTimeSegment","createTimeSegmentStates","currentTime","isCompleteTime","isTimeSelected","createTimeFieldStateFromSegments","digitCount","actionText","maxValue","minValue","minValueZero","hasLeadingZeros","wasComplete","targetDigitCount","requestedValStr","slice","padStart","max","finalValStr","finalVal","val","maxVal","isSegmentComplete","getSelectedSegmentIndex","sel","findIndex","markSelectedSegmentComplete","selectedIndex","checkHourSelected","hourSegment","dayPeriodSegment","hourSegmentState","clearDayPeriodSegmentWhenHourIsEmpty","adjustTimeSegment","step","min","range","newVal","hour12","getAriaValueText","getHomeSegmentValue","getEndSegmentValue","initialStarting","valueNow","currentValue","getPagedSegmentValue","getSteppedSegmentValue","padZero","amValue","pmValue","pm","valStr","timeHour12","reducerInitializer","params","ariaLabels","granularity","hasLeadingZeroForHour","locale","timeMasks","minuteValue","minute","secondValue","second","millisecondValue","millisecond","hasDayPeriod","part","hasHour","hour","hourValueStr","getHourValueStr","hourValue","dayPeriodValueStr","getDayPeriodValueStr","getDayPeriodValueFromHour","minuteValueStr","padWithZero","secondValueStr","millisecondValueStr","secondSeg","millisecondSeg","dayPeriodSeg","getAmPmStringsForLocale","dayPeriod","LiteralSegment","isPlaceholder","spanClasses","literalBase","useTimeFieldHandlers","timeResetRef","dispatch","groupRef","isFocused","isInputFocused","onCommit","onInput","tabbableModeProps","tabbableModeIndex","useTabbableMode","anySegmentSelected","updatedTabIndex","lastTimeRef","lastCommittedTimeRef","timeClearedRef","lastFocusedRef","onClick","target","getAttribute","selectAll","isGroupFocus","onDoubleClick","onDoubleTap","doubleTapHandlers","useDoubleTap","onSingleTap","stopImmediatePropagation","timesAreDifferent","frozeTime","freeze","recentPointerRef","pointerDownTimerRef","onPointerDown","clearTimeout","setTimeout","lastInputFocusedRef","handlers","deviceType","isMobile","timeFieldHandlers","segmentHandlers","TimeField","describedBy","ariaInvalid","ariaLabelledBy","baseId","fieldRef","hasInsideLabel","masks","onBlur","onFocus","textAlign","variant","useUser","useMemo","translations","announceTimeCleared","inputTimeMask_time_cleared","labels","formControl_hour","formControl_minute","formControl_second","formControl_millisecond","useFormFieldContext","hasValue","classes","useComponentTheme","TextFieldInputRedwoodTheme","styleVariant","textarea","div","prefix","suffix","startContent","endContent","insideLabel","focused","disabled","compClasses","useReducer","lastValueFromParentRef","useTimeField","editableSegments","segmentsMap","formattedTimeStr","formatTimeFromMasks","formattedTimeAriaId","formattedTimeAria","HiddenAccessible","id","ariaDescribedBy","merge","announceText","firstSegmentType","jsxs","onFocusIn","onFocusOut","Flex","wrap","justify","segmentProps","LiveRegion","InputTimeMask","forwardRef","assistiveText","columnSpan","helpSourceLink","helpSourceText","isHour12","propIsDisabled","isReadonly","propIsReadonly","isRequiredShown","label","labelEdge","propLabelEdge","labelStartWidth","propLabelStartWidth","mainFieldRef","messages","testId","propTextAlign","userAssistanceDensity","propUserAssistanceDensity","isFormDisabled","isFormReadonly","formLabelEdge","formLabelStartWidth","formTextAlign","formUserAssistanceDensity","useFormContext","enabledElementRef","readonlyElementRef","focusProps","methods","focusMethods","useFocusableTextField","useImperativeHandle","isComponentFocused","formFieldContext","inputProps","labelProps","origLabelProps","textFieldProps","userAssistanceProps","useTextField","forId","timeFieldProps","labelComp","Label","fieldLabelProps","inlineUserAssistance","InlineUserAssistance","fieldLabel","aRef","anchorRef","compactUserAssistance","CompactUserAssistance","validateTimeMasksAgainstProperties","replaceCustomMasksValuesWithPlaceholders","getTimeMasksFromLocaleAndOptions","resolvedLeadingZeroForHour","getLeadingZeroForHour","FormFieldContext","Provider","ReadonlyTextField","mainContent","ReadonlyTextFieldInput","as","elementRef","hasEmptyLabel","TextField","hasSecond","hasMillisecond","commonErrorMsg"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"UNSAFE_InputTimeMask.js","sources":["../../src/UNSAFE_InputTimeMask/TimeSegment.tsx","../../src/UNSAFE_InputTimeMask/timeReducer.ts","../../src/UNSAFE_InputTimeMask/useTimeField.ts","../../src/UNSAFE_InputTimeMask/LiteralSegment.tsx","../../src/UNSAFE_InputTimeMask/useTimeFieldHandlers.ts","../../src/UNSAFE_InputTimeMask/TimeField.tsx","../../src/UNSAFE_InputTimeMask/InputTimeMask.tsx"],"sourcesContent":["/**\n * @license\n * Copyright (c) %FIRST_YEAR% %CURRENT_YEAR%, Oracle and/or its affiliates.\n * The Universal Permissive License (UPL), Version 1.0\n * as shown at https://oss.oracle.com/licenses/upl/\n * @ignore\n */\n\nimport type { RefObject } from 'preact';\nimport { useCallback, useEffect, useRef } from 'preact/hooks';\nimport { AriaAttributesSignalExcluded } from '#utils/UNSAFE_attributeUtils';\nimport { TimeFieldAction } from './timeReducer';\nimport { EditableTimeSegmentType } from './types';\nimport {\n isBackspaceOrDelete,\n isControlOrFunctionKey,\n isSelectAll\n} from '#utils/PRIVATE_keyboardUtils';\nimport { isNumberOnlyString } from '#utils/PRIVATE_dayUtils';\nimport { classNames } from '#utils/UNSAFE_classNames';\nimport { segmentStyles } from './themes/SegmentStyles.css';\nimport { getClientHints } from '#utils/PRIVATE_clientHints';\nimport { useTranslationBundle } from '#hooks/UNSAFE_useTranslationBundle';\nimport { BundleType } from '#resources/nls/bundle';\nimport { AM_VALUE, AmPmLocalizedValues, getAmPmMatchType, PM_VALUE } from '#utils/UNSAFE_timeUtils';\n\ntype AriaProps = Pick<\n AriaAttributesSignalExcluded,\n 'aria-label' | 'aria-valuemax' | 'aria-valuemin' | 'aria-valuenow' | 'aria-valuetext'\n>;\n\ntype Props = AriaProps & {\n /**\n * The am/pm localized values. This is used when the segment type is 'dayPeriod'.\n */\n amPm?: AmPmLocalizedValues;\n\n /** A ref that is provided for the first segment in a time field. */\n inputRef?: RefObject<HTMLDivElement>;\n\n /**\n * True if the segment is complete in the sense that it contains a complete valid value.\n * For instance, entering '0' and then '1-9' is considered a complete value for a minute since minute has 2-digits.\n * Also true if typing any additional digit would cause the segment value to exceed the max.\n */\n isComplete?: boolean;\n\n /**\n * True if the segment is disabled.\n */\n isDisabled?: boolean;\n\n /**\n * True if the segment should be hidden.\n */\n isHidden?: boolean;\n\n /**\n * True if the entire time field is highlighted.\n */\n isHighlighted?: boolean;\n\n /**\n * True if the segment is invalid.\n */\n isInvalid?: boolean;\n\n /**\n * Specifies for accessibility purposes whether a value is required.\n */\n isRequired?: boolean;\n\n /**\n * True if the segment is selected.\n */\n isSelected?: boolean;\n\n /**\n * Placeholder displayed when the segment has no display value.\n */\n placeholder?: string;\n\n /**\n * The text to display for this segment.\n */\n text?: string;\n\n /**\n * The segment of a time which is being represented, i.e. the hour, minute, second, millisecond, dayPeriod.\n */\n type: EditableTimeSegmentType;\n\n /**\n * Callback invoked when a change to the segment is requested via user action, such as typing\n * a new value or pressing the Backspace or Delete keys.\n */\n onChange?: (action: TimeFieldAction) => void;\n};\n\n// Used to disable browser cut and paste, which don't really work with segments (copy is fine).\nconst preventDefaultHandler = (e: Event) => {\n e.preventDefault();\n};\n\nconst isIos = () => getClientHints().platform === 'ios';\n\n/**\n * A TimeSegment renders a part of a time, e.g. the hour, minute, second, millisecond, dayPeriod.\n * It can be used as a spinbutton to step or spin its value.\n */\nexport const TimeSegment = ({\n amPm,\n 'aria-label': ariaLabel,\n 'aria-valuemax': ariaValueMax,\n 'aria-valuemin': ariaValueMin,\n 'aria-valuenow': ariaValueNow,\n 'aria-valuetext': ariaValueText,\n inputRef,\n isDisabled,\n isHidden,\n isHighlighted,\n isInvalid,\n isRequired,\n isSelected,\n onChange,\n placeholder,\n text,\n type\n}: Props) => {\n const hasDisplayValue = text && text.length > 0;\n const rootClasses = classNames([\n segmentStyles.base,\n isSelected && segmentStyles.selected,\n isHighlighted && segmentStyles.highlighted\n ]);\n const placeholderClasses = classNames([\n segmentStyles.placeholder,\n isHidden || hasDisplayValue ? segmentStyles.hidden : segmentStyles.notHidden\n ]);\n const translations = useTranslationBundle<BundleType>('@oracle/oraclejet-preact');\n const emptySegmentValueText = translations.formControl_empty_segment();\n\n // If a ref was passed in, use it, otherwise get a ref.\n const sRef = useRef<HTMLDivElement>(null);\n const segmentRef = inputRef ?? sRef;\n\n const dayPeriodTextRef = useRef<string | null>(null);\n const onKeyDown = useCallback(\n (event: KeyboardEvent) => {\n if (\n isDisabled === true ||\n event.key === 'Tab' ||\n event.key === 'ArrowLeft' ||\n event.key === 'ArrowRight' ||\n event.key === 'Enter' ||\n isSelectAll(event)\n ) {\n // Let the event pass through.\n return;\n }\n if (isHighlighted) {\n // If time is selected, ignore edits and let backspace/delete pass through to clear.\n if (isBackspaceOrDelete(event) || event.key === 'Backspace') {\n return;\n }\n } else if (isNumberOnlyString(event.key)) {\n // do not send this for a dayPeriod segment since a dayPeriod segment does not have numbers.\n if (type !== 'dayPeriod') {\n onChange?.({\n actionType: 'updateSegment',\n data: { type, text: event.key }\n });\n }\n } else if (isBackspaceOrDelete(event) || event.key === 'Backspace') {\n // Android sends Backspace as event.key, not event.code, so check for it.\n onChange?.({ actionType: 'clearSegment', data: { type } });\n } else if (event.key === 'ArrowUp') {\n onChange?.({ actionType: 'step', data: { direction: 'increase', type } });\n } else if (event.key === 'ArrowDown') {\n onChange?.({ actionType: 'step', data: { direction: 'decrease', type } });\n } else if (event.key === 'PageUp') {\n onChange?.({ actionType: 'page', data: { direction: 'increase', type } });\n } else if (event.key === 'PageDown') {\n onChange?.({ actionType: 'page', data: { direction: 'decrease', type } });\n } else if (event.key === 'Home') {\n onChange?.({ actionType: 'goToHome', data: { type } });\n } else if (event.key === 'End') {\n onChange?.({ actionType: 'goToEnd', data: { type } });\n } else if (\n type === 'dayPeriod' &&\n amPm !== undefined &&\n isLetterOnlyString(event.key, event)\n ) {\n // A user can change the am/pm strings using the up and down arrow keys or by typing in letters.\n // In most locales the first letter of the am/pm strings uniquely identifies am or pm.\n // However, in a couple locales, such as 'ms' (where am is represented 'PG' and pm as 'PTG'), the first letter may not be unique.\n // This scenario requires special handling to account for the ambiguity; we use the\n // dayPeriodTextRef.current to buffer up the text the user types until we figure out if it is the am or pm string they are typing or neither.\n // Once we can recognize that it is the 'am' or 'pm' that they want, we call 'updateDayPeriodSegment' to change it.\n dayPeriodTextRef.current =\n dayPeriodTextRef.current !== null ? dayPeriodTextRef.current + event.key : event.key;\n const matchType = getAmPmMatchType(amPm, dayPeriodTextRef.current);\n if (matchType === 'am' || matchType === 'pm') {\n const value = matchType === 'am' ? AM_VALUE : PM_VALUE;\n onChange?.({\n actionType: 'updateDayPeriodSegment',\n data: { type, 'aria-valuenow': value }\n });\n }\n if (matchType !== 'both') {\n // We clear out the ref here, and also if the segment's isSelected state is false which indicates the dayPeriod segment lost focus.\n dayPeriodTextRef.current = null;\n }\n }\n event.preventDefault();\n event.stopPropagation();\n },\n [amPm, isDisabled, isHighlighted, onChange, type]\n );\n\n // Used to focus the segment when isSelected is true.\n useEffect(() => {\n if (isSelected) {\n segmentRef.current?.focus();\n } else if (type === 'dayPeriod') {\n // This is the ref that in onKeyDown handler is used to buffer up the letters typed into the dayPeriod until a match or no match is found,\n // in which case we clear the buffer.\n // We also clear the ref when the dayPeriod segment loses focus.\n dayPeriodTextRef.current = null;\n }\n }, [isSelected, segmentRef, type]);\n\n // If ariaValueText is undefined, substitute a string that indicates the segment is empty.\n // If ariaValueNow and ariaValueText represent the same value, omit the value text; this\n // is the same as what we do in NumberInputText.\n const valueText =\n ariaValueText === undefined\n ? emptySegmentValueText\n : ariaValueNow?.toString() === ariaValueText\n ? undefined\n : ariaValueText;\n // This attribute is used to distinguish between segments when clicked (see TimeField.tsx).\n const customDataAttribute = { 'data-segment': [type] };\n return (\n <div>\n <div\n ref={segmentRef}\n role={isIos() ? 'textbox' : 'spinbutton'}\n aria-disabled={isDisabled}\n aria-invalid={isInvalid || undefined}\n aria-label={ariaLabel}\n aria-required={isRequired}\n aria-valuemin={isIos() ? undefined : ariaValueMin}\n aria-valuemax={isIos() ? undefined : ariaValueMax}\n aria-valuenow={isIos() ? undefined : ariaValueNow}\n aria-valuetext={isIos() ? undefined : valueText}\n autocapitalize=\"off\"\n autocorrect=\"off\"\n class={rootClasses}\n contentEditable={!isDisabled}\n {...customDataAttribute}\n enterkeyhint={isDisabled ? undefined : 'done'}\n inputMode={isDisabled ? 'none' : type !== 'dayPeriod' ? 'numeric' : 'text'}\n onCut={preventDefaultHandler}\n onKeyDown={onKeyDown}\n onPaste={preventDefaultHandler}\n spellcheck={false}\n tabIndex={isSelected ? 0 : -1}>\n <span aria-hidden=\"true\" class={placeholderClasses} {...customDataAttribute}>\n {placeholder}\n </span>\n {text}\n </div>\n </div>\n );\n};\n\nconst isLetterOnlyString = (input: string, event: KeyboardEvent) => {\n const isLetter = /^\\p{L}$/u.test(input);\n\n // Ensure no modifier keys (Command, Ctrl, Alt) are active\n const modifiers = isControlOrFunctionKey(event);\n\n return isLetter && !modifiers;\n};\n","/**\n * @license\n * Copyright (c) %FIRST_YEAR% %CURRENT_YEAR%, Oracle and/or its affiliates.\n * The Universal Permissive License (UPL), Version 1.0\n * as shown at https://oss.oracle.com/licenses/upl/\n * @ignore\n */\n\nimport type { TimeFieldState, TimeSegmentState } from './useTimeField';\nimport { OrderedTimeSegmentsArray, EditableTimeSegmentType } from './types';\n\n// Carries additional data information for an action.\ntype TimeFieldActionData = Partial<TimeSegmentState> & {\n direction?: 'increase' | 'decrease';\n};\n\n// Describes all possible actions for interacting with the time segments.\n// For example,\n// selectSegment: focuses on one segment (like hour or minute).\n// updateSegment: called when the user types in a number. Figures out if the segment is complete.\n// step: Increments or decrements the value in the segment.\n// commit: Finalizes changes made to the segments.\ntype TimeFieldAction = {\n actionType:\n | 'clearTime'\n | 'clearSegment'\n | 'committed'\n | 'commitOnBlur'\n | 'commitOnEnter'\n | 'deselectAndComplete'\n | 'goToEnd'\n | 'goToHome'\n | 'page'\n | 'selectTime'\n | 'selectFirst'\n | 'selectNext'\n | 'selectPrevious'\n | 'selectSegment'\n | 'step'\n | 'updateDayPeriodSegment'\n | 'updateSegment';\n data?: TimeFieldActionData;\n};\n\n// Used to replace the state with a new one, like when the time value is updated programmatically.\ntype ResetAction = {\n actionType: 'reset';\n data: TimeFieldState;\n};\n\ntype TimeReducerAction = TimeFieldAction | ResetAction;\n\nconst AM_VALUE = 0;\nconst PM_VALUE = 12;\n\n/**\n * Reducer function for updating TimeFieldState per the specified TimeFieldAction.\n * @param state\n * @param action\n */\nconst timeReducer = (state: TimeFieldState, action: TimeReducerAction) => {\n // On mount, the reducer is initialized with initial state derived from the TimeField's value.\n // If that value is changed programmatically afterwards, the only way to push that update\n // into the reducer is to define a \"reset\" action.\n if (action.actionType === 'reset') {\n return action.data;\n }\n\n // Most of the dispatches include type, but not all (like 'commitOnBlur' doesn't include type).\n // Instead of setting these for every actionType that needs it, we do it once here.\n const segmentType = action.data?.type!;\n const segmentState = findSegment(state.segments, segmentType);\n\n // Each action updates the state using helper functions to modify a specific segment or\n // change focus between segments.\n switch (action.actionType) {\n case 'clearTime': {\n // Resets all segments to the default (useful when clearing the entire time)\n const updatedSegments = selectFirst(clearTime(state.segments), state.orderedSegments);\n return createTimeFieldStateWithSelectedTime(state, updatedSegments, false);\n }\n case 'clearSegment': {\n const updatedSegment = clearSegment(segmentState);\n return createTimeFieldState(state, segmentType, updatedSegment);\n }\n case 'deselectAndComplete': {\n let updatedSegments = completeAllSegmentsBasedOnHour(state.segments);\n updatedSegments = deselectAndComplete(updatedSegments);\n return createTimeFieldStateWithSelectedTime(state, updatedSegments, false);\n }\n case 'commitOnEnter': {\n const updatedSegments = completeAllSegmentsBasedOnHour(state.segments);\n const newState = createTimeFieldStateWithSelectedTime(state, updatedSegments, false);\n return { ...newState, committing: true };\n }\n case 'commitOnBlur': {\n let updatedSegments = completeAllSegmentsBasedOnHour(state.segments);\n updatedSegments = deselectAndComplete(updatedSegments);\n const newState = createTimeFieldStateWithSelectedTime(state, updatedSegments, false);\n return { ...newState, committing: true };\n }\n case 'committed': {\n return { ...state, committing: false };\n }\n case 'goToEnd': {\n const updatedSegment = goToEnd(segmentType, segmentState);\n return createTimeFieldState(state, segmentType, updatedSegment, false);\n }\n case 'goToHome': {\n const updatedSegment = goToHome(segmentType, segmentState);\n return createTimeFieldState(state, segmentType, updatedSegment, false);\n }\n case 'page': {\n const direction = action.data?.direction;\n if (direction === undefined) return state;\n const updatedSegment = doStepOrPage(segmentType, segmentState, 'page', direction);\n return createTimeFieldState(state, segmentType, updatedSegment, false);\n }\n case 'selectTime': {\n return selectTime(state);\n }\n case 'selectFirst': {\n const updatedSegments = selectFirst(state.segments, state.orderedSegments);\n return createTimeFieldStateWithSelectedTime(state, updatedSegments, false);\n }\n // Select the segment following the current one.\n case 'selectNext': {\n // If hour has a value and is currently selected when we get the selectNext action, then auto-fill\n // the empty segments.\n const updatedSegments = completeAllEmptySegmentsWhenHourHasValue(state.segments, true);\n const updatedSelectedNextSegments = selectNext(updatedSegments, state.orderedSegments);\n return createTimeFieldStateWithSelectedTime(state, updatedSelectedNextSegments, false);\n }\n case 'selectPrevious': {\n const updatedSegments = selectPrevious(state.segments, state.orderedSegments);\n return createTimeFieldStateWithSelectedTime(state, updatedSegments, false);\n }\n case 'selectSegment': {\n const updatedSegments = selectSegment(state.segments, segmentType);\n return createTimeFieldStateWithSelectedTime(state, updatedSegments, false);\n }\n // Increments or decrements the current segment value.\n case 'step': {\n const direction = action.data?.direction;\n\n if (direction === undefined) return state;\n const updatedSegment = doStepOrPage(segmentType, segmentState, 'step', direction);\n return createTimeFieldState(state, segmentType, updatedSegment, false);\n }\n case 'updateDayPeriodSegment': {\n if (segmentType === 'dayPeriod') {\n const newValue = action.data?.['aria-valuenow'];\n if (newValue === PM_VALUE || newValue === AM_VALUE) {\n // we have a new value for the dayPeriod. Create a new state.\n const updatedSegment = createSegmentFromKeyboardAction(\n segmentType,\n newValue,\n segmentState\n );\n return createTimeFieldState(state, segmentType, updatedSegment, false);\n }\n }\n return state;\n }\n case 'updateSegment': {\n // Modifies the value of a specific time segment while keeping the rest of the time state intact.\n // This gets called from TimeSegment onKeyDown which is called one key at a time.\n const updatedSegment = updateSegment(segmentType, segmentState, action);\n return createTimeFieldState(state, segmentType, updatedSegment);\n }\n default: {\n throw new Error('Unknown action type');\n }\n }\n};\n\nconst stringToNumber = (s: string) => +s;\nconst numberToString = (n: number) => n.toString();\nconst withinRange = (n: number, min: number, max: number) => n >= min && n <= max;\n\n/**\n * Given the array of TimeSegmentStates and the type, returns the segment with that type.\n * @param segments\n * @param type\n * @returns the segment with that type.\n */\nconst findSegment = (\n segments: TimeSegmentState[],\n type: EditableTimeSegmentType\n): TimeSegmentState => {\n return segments.find((segment) => segment.type === type)!;\n};\n\n/**\n * A time segment is considered complete if one of these is true:\n * - digitCount >= targetDigitCount\n * - appending a zero to the current value causes it\n * to exceed the max. For instance, if aria-valuemax which is 12 (for 12-hour times), and\n * 2 is in hour already, if someone typed in 0, it would be 20, and\n * that is greater than the max.\n * \n * digitCount is used to figure out if the segment is complete. \n * It is used to distinguish between\n * the user typing in all 0s or the auto-filling of 0s that happens when the user types in one 0 into an empty or complete field.\n * It is also used to figure out if the user typed in the number of digits to fill the space.\n * Like if the user typed in 0, 0, 5 in millisecond. The segment is complete because the digitCount >= targetDigitCount.\n\n * @param val - the value of the segment for which to check completeness.\n * @param maxVal - the maximum value for the segment. E.g., for seconds it is 59.\n * @param digitCount - the number of digits a user typed.\n * @param targetDigitCount - the number of digits in a segment.\n * @returns true if the segment is considered complete, false otherwise.\n */\nconst isSegmentComplete = (\n val: number,\n maxVal: number,\n digitCount: number,\n targetDigitCount: number\n) => {\n if (digitCount >= targetDigitCount) {\n return true;\n }\n const num = stringToNumber(numberToString(val) + '0');\n return num > maxVal;\n};\n\n/**\n * A time is considered complete if all of its segments have values.\n * We use each segment's 'text' property to determine that.\n * @param allSegments\n * @returns {boolean} every segment has a value.\n */\nconst isTimeComplete = (allSegments: TimeSegmentState[]) => {\n return allSegments.every((seg) => seg.text && seg.text.length > 0);\n};\n\n/**\n * A time is considered a partial time if at least one segment has a value.\n * We use each segment's 'aria-valuenow' property to determine that.\n * @param allSegments\n * @returns {boolean} at least one segment has a value.\n */\nconst isPartialTime = (allSegments: TimeSegmentState[]) => {\n // Even though the dayPeriod field does not read-out the valuenow, we use it\n // to indicate if it is filled in or not.\n return allSegments.some((seg) => seg['aria-valuenow'] !== undefined);\n};\n\n/**\n * Construct a time that reflects the values of each segment.\n * If none of the segments have a value, return undefined.\n * If only the dayPeriod has a value, return undefined, since we filter out dayPeriod; Time has 0-23 hour.\n *\n * @param segments\n * @returns The Time that reflects the values of each segment.\n */\nconst createTimeFromSegments = (segments: TimeSegmentState[]) => {\n const hasAnySegmentWithAValue = isPartialTime(segments);\n if (!hasAnySegmentWithAValue) {\n return undefined;\n }\n\n // get the dayPeriod's value, if it exists\n const dayPeriodValue = segments.find((seg) => seg.type === 'dayPeriod')?.['aria-valuenow'];\n\n // get the hour segment's value if it exists.\n const hourSegmentValue = segments.find((seg) => seg.type === 'hour')?.['aria-valuenow'];\n let adjustedHour = hourSegmentValue;\n\n // if the hour segment has a value and the dayPeriod segment has a value, then\n // we will adjust the hour so that it is a h23 hour.\n if (dayPeriodValue !== undefined && hourSegmentValue !== undefined) {\n adjustedHour = getAdjustedH12ToH23(dayPeriodValue, hourSegmentValue);\n }\n\n // Filter out dayPeriod segment and map the remaining segments to values\n const segmentValues = segments\n .filter((seg) => seg.type !== 'dayPeriod') // Filter out dayPeriod\n .reduce<Record<string, number | undefined>>((acc, seg) => {\n const value = seg.type === 'hour' ? adjustedHour : seg['aria-valuenow'];\n if (value !== undefined) {\n acc[seg.type] = value;\n }\n return acc;\n }, {});\n // If all that was left in the time segments at this point was the dayPeriod, we would get an empty object\n // since the value does not contain dayPeriod. If this is the case return undefined.\n return Object.entries(segmentValues).length === 0 ? undefined : segmentValues;\n};\n\n/**\n * Returns a copy of the ordered segments array from the current state.\n *\n * @param {TimeFieldState} currentState - the current state of the time field.\n * @returns {OrderedTimeSegmentsArray} the orderedSegments in the current state.\n */\nconst getOrderedSegmentsFromState = (currentState: TimeFieldState) => {\n // Typescript loses its typing when we spread, so add it back.\n return [...currentState.orderedSegments] as OrderedTimeSegmentsArray;\n};\n\n/**\n * Replace the updated segment and return a new TimeSegmentState[].\n * @param existingSegments\n * @param updatedSegmentType\n * @param updatedSegment\n * @returns\n */\nconst replaceTimeSegment = (\n existingSegments: TimeSegmentState[],\n updatedSegmentType: EditableTimeSegmentType,\n updatedSegment: TimeSegmentState\n) => {\n return existingSegments.map((seg) => (seg.type === updatedSegmentType ? updatedSegment : seg));\n};\n\n/**\n * Creates a new array of TimeSegmentState objects by updating the specified segment which might\n * affect other segments.\n *\n * If the modified segment type is 'hour', and the 'minute',\n * 'second', 'millisecond', 'dayPeriod' segments, if defined, are not set (i.e., their aria-valuenow is undefined),\n * their values are auto-filled, that is, initialized to 0 or localized version of 'AM' for dayPeriod.\n * @param {TimeSegmentState[]} existingSegments - The current array of time segments.\n * @param {OrderedTimeSegmentsArray} orderedSegments - The ordered list of segments used to determine\n * the segment sequence for selection and auto-advancing.\n * @param {EditableTimeSegmentType} updatedSegmentType - The type of the segment that is being updated.\n * @param {TimeSegmentState} updatedSegment - The updated segment state to replace the current one.\n * @param {boolean} autoAdvance - whether to automatically select the next segment upon completion of the current segment.\n * @returns The new array of TimeSegmentState objects, with the segment updated and other segments\n * modified as needed.\n * If autoAdvance is true, the next segment will be automatically set to isSelected upon segment isCompleted.\n */\nconst createTimeSegmentStates = (\n existingSegments: TimeSegmentState[],\n orderedSegments: OrderedTimeSegmentsArray,\n updatedSegmentType: EditableTimeSegmentType,\n updatedSegment: TimeSegmentState,\n autoAdvance: boolean\n) => {\n // Replace the segment with the updated version.\n const modifiedSegments = replaceTimeSegment(existingSegments, updatedSegmentType, updatedSegment);\n let updatedSegments = modifiedSegments;\n\n const isHourSegmentAndComplete = updatedSegmentType === 'hour' && updatedSegment.isComplete;\n if (isHourSegmentAndComplete) {\n updatedSegments = autoFillEmptyNonHourSegments(updatedSegments);\n }\n // If the updatedSegment is complete, automatically select the next segment.\n updatedSegments =\n updatedSegment.isComplete && autoAdvance\n ? selectNext(updatedSegments, orderedSegments)\n : updatedSegments;\n\n return updatedSegments;\n};\n\n/**\n * This function auto-fills all empty, non-hour segments ('minute', 'second', 'millisecond' and 'dayPeriod').\n * It only auto-fills the empty fields and leaves the other fields alone.\n * For example, if milliseconds is not empty, we leave the milliseconds as is and update all the empty fields;\n * 23:--:--:400 becomes 23:00:00:400. And if there is a dayPeriod segment, 5:--:--:400 -- becomes 5:00:00:400 AM.\n *\n * @param existingSegments\n * @param hourSegmentState\n * @returns\n */\nconst autoFillEmptyNonHourSegments = (existingSegments: TimeSegmentState[]) => {\n // if a segment already has a value, then do nothing.\n const initializedSegments = existingSegments.map((seg) => {\n if (seg['aria-valuenow'] !== undefined) {\n return seg;\n }\n\n let text, ariaValue;\n\n if (seg.type === 'millisecond') {\n text = '000';\n ariaValue = 0;\n } else if (['minute', 'second'].includes(seg.type)) {\n text = '00';\n ariaValue = 0;\n } else if (seg.type === 'dayPeriod') {\n // seg.amPM.am always has a value for the dayPeriod segment, so there is no need to default it.\n text = seg.amPm?.am;\n ariaValue = AM_VALUE;\n }\n\n return text !== undefined\n ? { ...seg, 'aria-valuenow': ariaValue, text, isComplete: true, 'aria-valuetext': text }\n : seg;\n });\n return initializedSegments;\n};\n\n/**\n * Construct a new TimeFieldState from a set of updated segments.\n * @param {TimeFieldState} currentState - The current state of the time field.\n * @param {TimeSegmentState[]} updatedSegments - the updated segments\n * @returns A new TimeFieldState from the set of updated segments.\n */\nconst createTimeFieldStateFromSegments = (\n currentState: TimeFieldState,\n updatedSegments: TimeSegmentState[]\n) => {\n return {\n committing: currentState.committing,\n currentTime: createTimeFromSegments(updatedSegments),\n isCompleteTime: isTimeComplete(updatedSegments),\n isTimeSelected: currentState.isTimeSelected,\n isPartialTime: isPartialTime(updatedSegments),\n orderedSegments: getOrderedSegmentsFromState(currentState),\n segments: updatedSegments\n };\n};\n\n//\n/**\n * Constructs a new TimeFieldState given an updated segment, which may affect other segments.\n * @param {TimeFieldState} currentState - The current state of the time field.\n * @param {EditableTimeSegmentType} updatedSegmentType - The type of the segment that was updated.\n * @param {TimeSegmentState} updatedSegment - The updated state of the specified segment.\n * @param {boolean} autoAdvance - Whether to auto-advance to the next segment if the current segment is complete. Defaults to true.\n * @returns {TimeFieldAction} - A new TimeFieldState based on the updated segment and the current state.\n */\nconst createTimeFieldState = (\n currentState: TimeFieldState,\n updatedSegmentType: EditableTimeSegmentType,\n updatedSegment: TimeSegmentState,\n autoAdvance = true\n): TimeFieldState => {\n const updatedSegments = createTimeSegmentStates(\n currentState.segments,\n currentState.orderedSegments,\n updatedSegmentType,\n updatedSegment,\n autoAdvance\n );\n\n return createTimeFieldStateFromSegments(currentState, updatedSegments);\n};\n\n/**\n * The clearSegment function clears the current state of the time segment by resetting\n * specific properties to indicate that the segment no longer holds a value.\n * Specifically, it sets:\n * 'aria-valuetext': undefined,\n * 'aria-valuenow': undefined,\n * digitCount: 0,\n * text: undefined,\n * isComplete: false\n *\n * This function returns a new segment state reflecting these cleared properties.\n *\n * @param {TimeSegmentState} segmentState - The current state of the time segment to clear.\n * @returns {TimeSegmentState} A new segment state with cleared properties.\n */\nconst clearSegment = (segmentState: TimeSegmentState) => {\n return {\n ...segmentState,\n 'aria-valuetext': undefined,\n 'aria-valuenow': undefined,\n digitCount: 0,\n text: undefined,\n isComplete: false\n };\n};\n\n/**\n * Clears the current state of each segment.\n *\n * @param {TimeSegmentState[]} segments\n * @returns The updated state with all segments cleared.\n */\nconst clearTime = (segments: TimeSegmentState[]) => {\n return segments.map((segmentState) => {\n const cleared = clearSegment(segmentState);\n return { ...cleared };\n });\n};\n\n/**\n * Updates the state of a time segment based on user input, one character at a time,\n * enforcing range constraints, completeness rules,\n * and zero-padding requirements for the segment types.\n * @param segmentType\n * @param segmentState\n * @param action\n * @returns A new copy of the segment state with updated values.\n */\nconst updateSegment = (\n segmentType: EditableTimeSegmentType,\n segmentState: TimeSegmentState,\n action: TimeFieldAction\n) => {\n // Process the input action text\n // actionText - This is one character, the one the user typed.\n const actionText = action.data?.text!;\n // Get the current segment state.\n const maxValue = segmentState['aria-valuemax']!;\n const minValue = segmentState['aria-valuemin']!;\n const minValueZero = minValue === 0;\n // TODO: minute, second, millisecond always have leading zeros, but hour might not; it is based on the locale,\n // and can be overridden with the shouldForceLeadingZeros api. This will need to be implemented later.\n // For all the locales I tested, most h23 clocks use a leading zero, and most h12 clocks do not,\n // so this is what this code figures.\n const hasLeadingZeros = minValueZero;\n const wasComplete = segmentState.isComplete;\n // digitCount is used to figure out if the segment is complete.\n // It is used to distinguish between\n // the user typing in all 0s or the auto-filling of 0s that happens when the user types in one 0 into an empty or complete field.\n // It is also used to figure out if the user typed in the number of digits to fill the space.\n // Like if the user typed in 0, 0, 5 in millisecond. The segment is complete because the digitCount >= targetDigitCount.\n let digitCount = segmentState.digitCount || 0;\n const targetDigitCount = segmentType === 'millisecond' ? 3 : 2;\n\n // Handle special case for segments that do not start with 0: ignore multiple leading 0s.\n // TODO: When I implement the leading zero for the uncommon case - leading zero for h12 or no leading zero for h23, this will\n // likely change.\n if (\n !minValueZero &&\n actionText === '0' &&\n (wasComplete || segmentState.text === undefined || segmentState.text === '')\n ) {\n // keep ignoring 0s, but keep digitCount = 1;\n return {\n ...segmentState,\n digitCount: 1\n };\n }\n\n // Set requestedValStr based on leading zero rules\n let requestedValStr = segmentState.text || '';\n if (wasComplete) {\n // If the value is complete and you type another number, it replaces what is already there.\n requestedValStr = actionText;\n } else {\n requestedValStr = (segmentState.text ?? '') + actionText;\n }\n\n if (hasLeadingZeros && requestedValStr.length > targetDigitCount) {\n requestedValStr = requestedValStr.slice(requestedValStr.length - targetDigitCount);\n } else if (hasLeadingZeros) {\n requestedValStr = requestedValStr.padStart(targetDigitCount, '0');\n }\n\n digitCount += 1;\n\n // Check if the value is in range and apply final adjustments\n // if not in range, then actionText overwrites requestedValStr.\n // E.g., first we type '2', then we type '5'. '25' is out of range for hour24, so we use '5'.\n const inRange = withinRange(stringToNumber(requestedValStr), minValue, maxValue);\n const finalValStr = inRange\n ? requestedValStr\n : hasLeadingZeros\n ? actionText.padStart(targetDigitCount, '0')\n : actionText;\n const finalVal = stringToNumber(finalValStr);\n\n // Determine if the segment is complete.\n const isComplete = isSegmentComplete(finalVal, maxValue, digitCount, targetDigitCount);\n // reset digitCount if the segment is complete.\n // When digitCount is 0, whatever is in the field will be overwritten if the user types into it again,\n // which is the desired behavior.\n digitCount = isComplete ? 0 : digitCount;\n\n return {\n ...segmentState,\n 'aria-valuetext': finalValStr,\n 'aria-valuenow': finalVal,\n digitCount,\n text: finalValStr,\n isComplete\n };\n};\n\n/**\n * Updates the selection state of the segments, setting the isSelected property to true for the\n * segment that has the segmentType and false for all others.\n * @param {TimeSegmentState[]} segments\n * @param {EditableTimeSegmentType} segmentType - The type of the segment that is being updated.\n * @returns {TimeSegmentState[]} A new array of time segments with updated isSelected state.\n */\nconst selectSegment = (segments: TimeSegmentState[], segmentType: EditableTimeSegmentType) => {\n return segments.map((seg) => {\n return { ...seg, isSelected: seg.type === segmentType ? true : false };\n });\n};\n\n/**\n * Updates the isSelected state of the first segment from the ordered segments to true,\n * while setting isSelected to false for all other segments.\n *\n * This function can be used to set the initial focus on the first time segment.\n *\n * @param {TimeSegmentState[]} segments - An array of current time segment states, each\n * representing different parts of the time (e.g., hour, minute, second, dayPeriod).\n * @param {OrderedTimeSegmentsArray} orderedSegments - An array of segment types in the\n * represented order (e.g., ['hour','minute', 'dayPeriod']). This is used to get the type\n * of the first segment.\n * @returns {TimeSegmentState[]} A new array of time segment states with the first segment's isSelected\n * property set to true and all other segment's isSelected properties set to false.\n */\nconst selectFirst = (segments: TimeSegmentState[], orderedSegments: OrderedTimeSegmentsArray) => {\n return selectSegment(segments, orderedSegments[0]);\n};\n\n// Find the index of the selected segment in the ordered list; return -1 if there is no selection.\nconst getSelectedSegmentIndex = (\n segments: TimeSegmentState[],\n orderedSegments: OrderedTimeSegmentsArray\n) => {\n const sel = segments.find((seg) => seg.isSelected === true);\n return sel === undefined ? -1 : orderedSegments.findIndex((type) => type === sel.type);\n};\n\n/**\n * Convenience function to mark the selected segment complete.\n * @param segments\n * @returns The updated segments where if isSelected was true, isComplete is now also true.\n */\nconst markSelectedSegmentComplete = (segments: TimeSegmentState[]) => {\n return segments.map((seg) =>\n seg.isSelected ? { ...seg, isComplete: true, digitCount: 0 } : seg\n );\n};\n\n/**\n * Selects the segment following the one that is currently selected.\n * @param segments\n * @param orderedSegments\n * @returns\n */\nconst selectNext = (segments: TimeSegmentState[], orderedSegments: OrderedTimeSegmentsArray) => {\n const selectedIndex = getSelectedSegmentIndex(segments, orderedSegments);\n const max = orderedSegments.length - 1;\n\n // If we're already at the last position, do nothing. Note if nothing was currently selected\n // then selectedIndex is -1. The first segment will be selected.\n return selectedIndex === max\n ? segments\n : selectSegment(markSelectedSegmentComplete(segments), orderedSegments[selectedIndex + 1]);\n};\n\n/**\n * Selects the segment prior to the one that is currently selected.\n * @param segments\n * @param orderedSegments\n * @returns\n */\nconst selectPrevious = (\n segments: TimeSegmentState[],\n orderedSegments: OrderedTimeSegmentsArray\n) => {\n const selectedIndex = getSelectedSegmentIndex(segments, orderedSegments);\n return selectedIndex === 0\n ? segments\n : selectedIndex === -1\n ? selectFirst(segments, orderedSegments)\n : selectSegment(markSelectedSegmentComplete(segments), orderedSegments[selectedIndex - 1]);\n};\n\n/**\n * Returns a new TimeSegmentState[] where all segments are unselected and any values are\n * marked complete. We want to do this when the user commits the TimeField value (on blur).\n * We do not do this when the user commits the TimeField value on Enter\n * because in that case the component still has focus on Enter, and they could continue typing in the segment.\n * @param segments\n * @returns a new TimeSegmentState[] where all segments have isSelected: false and any\n * with text has isComplete: true.\n */\nconst deselectAndComplete = (segments: TimeSegmentState[]) => {\n return segments.map((seg) => {\n return { ...seg, isSelected: false, isComplete: !!seg.text };\n });\n};\n\n/**\n * Returns a new TimeSegmentState[] where all segments are unselected by setting isSelected: false.\n * @param segments\n * @returns\n */\nconst clearSelection = (segments: TimeSegmentState[]) => {\n return segments.map((seg) => {\n return { ...seg, isSelected: false };\n });\n};\n\n/**\n * Checks if hour is clear and dayPeriod is not clear, and if so, clear the dayPeriod segment.\n * @param segments\n * @returns segments, with the 'dayPeriod' segment updated, if needed.\n */\nconst clearDayPeriodSegmentWhenHourIsEmpty = (segments: TimeSegmentState[]) => {\n // find the dayPeriod segment if it exists.\n const dayPeriodSegment = segments.find((seg) => seg.type === 'dayPeriod');\n // find the hour segment.\n const hourSegmentState = segments.find((seg) => seg.type === 'hour');\n const hourSegmentHasText = hourSegmentState?.text !== undefined;\n const dayPeriodSegmentHasText = dayPeriodSegment?.text !== undefined;\n\n // If hour is clear and dayPeriod is not clear, clear dayPeriod.\n // E.g., --:00 PM becomes --:00 --.\n if (!hourSegmentHasText && dayPeriodSegmentHasText) {\n return segments.map((seg) => {\n if (seg.type === 'dayPeriod') {\n return clearSegment(seg);\n }\n return { ...seg };\n });\n }\n return segments;\n};\n\n/**\n * If the hour segment is filled in, auto-fill empty minute, second, and millisecond segments and dayPeriod segment.\n * The additional parameter checkHourSelected, if true, will make sure that the hour isSelected state is true before auto-filling.\n * This is used for the 'selectNext' action.\n * @param segments\n * @param checkHourSelected {boolean} true, if the hour segment must be selected in order to auto-fill.\n * @returns segments, with the minute, second, millisecond, and dayPeriod segments updated, if needed.\n */\nconst completeAllEmptySegmentsWhenHourHasValue = (\n segments: TimeSegmentState[],\n checkHourSelected?: boolean\n) => {\n const hourSegment = segments.find((seg) => seg.type === 'hour');\n const autoFillRequirementMet = checkHourSelected ? hourSegment?.isSelected : true;\n\n if (autoFillRequirementMet && hourSegment?.text !== undefined) {\n return autoFillEmptyNonHourSegments(segments);\n }\n return segments;\n};\n\n/**\n * If the hour segment is filled in, auto-fill empty minute, second, and millisecond segments and dayPeriod segment.\n * If the hour segment is empty and the dayPeriod segment is filled in, clear out the dayPeriod segment.\n * This is what we do when we leave the component.\n * @param segments\n * @returns segments, with the minute, second, millisecond, and dayPeriod segments updated, if needed.\n */\nconst completeAllSegmentsBasedOnHour = (segments: TimeSegmentState[]) => {\n const updatedSegments = completeAllEmptySegmentsWhenHourHasValue(segments);\n return clearDayPeriodSegmentWhenHourIsEmpty(updatedSegments);\n};\n\n/**\n * This function is called when the user wants to select the entire date.\n * If currentState.isCompleteTime is true,\n * - returns a new TimeFieldState from the currentState where the entire time is marked as selected,\n * and the 'isSelected' property of all the individual segments is set to false.\n *\n * If the time is not complete,\n * - returns the currentState unchanged.\n\n * @param {TimeFieldState} currentState\n * @returns\n */\nconst selectTime = (currentState: TimeFieldState) => {\n if (currentState.isCompleteTime) {\n return createTimeFieldStateWithSelectedTime(\n currentState,\n clearSelection(currentState.segments),\n true\n );\n }\n return currentState;\n};\n\n/**\n * Creates a new TimeFieldState from the updatedSegments and the isTimeSelected param.\n * NOTE: This updates currentTime based on the segments.\n *\n * @param {TimeFieldState} currentState\n * @param {TimeFieldState[]} updatedSegments\n * @param {boolean} isTimeSelected - Indicates whether the entire time field is selected.\n * @returns {TimeFieldState} The updated state of the time field.\n */\nconst createTimeFieldStateWithSelectedTime = (\n currentState: TimeFieldState,\n updatedSegments: TimeSegmentState[],\n isTimeSelected: boolean\n) => {\n return {\n committing: currentState.committing,\n currentTime: createTimeFromSegments(updatedSegments),\n isCompleteTime: isTimeComplete(updatedSegments),\n isTimeSelected,\n isPartialTime: isPartialTime(updatedSegments),\n orderedSegments: getOrderedSegmentsFromState(currentState),\n segments: updatedSegments\n };\n};\n\n/**\n * Gets the minimum value for the segment.\n * @param segmentState\n * @returns the minimum value for the segment.\n */\nconst getHomeSegmentValue = (segmentState: TimeSegmentState) => {\n return segmentState['aria-valuemin']!;\n};\n\n/**\n * Gets the maximum value for the segment.\n * @param segmentState\n * @returns the maximum value for the segment\n */\nconst getEndSegmentValue = (segmentState: TimeSegmentState) => {\n return segmentState['aria-valuemax']!;\n};\n\n/**\n * Adjusts the value of a time segment (e.g., hour, minute, second, millisecond) by a given step.\n * It handles both increasing and decreasing the value with wrapping logic\n * when the value exceeds the max or falls below the min.\n *\n * Uses separate paths for cases when min is 0 and when min is non-zero for clarity.\n *\n * @param {number} value - The current value of the segment.\n * @param {number} step - The amount to increment or decrement the value.\n * @param {number} min - The minimum allowed value for the segment.\n * @param {number} max - The maximum allowed value for the segment.\n * @param {TimeFieldActionData['direction']} direction - Whether to increase or decrease the value.\n * @returns {number} - The new adjusted value after wrapping.\n */\nconst adjustTimeSegment = (\n value: number,\n step: number,\n min: number,\n max: number,\n direction: Exclude<TimeFieldActionData['direction'], undefined>\n) => {\n const range = max - min + 1; // Total values in the range.\n\n if (min === 0) {\n // Path for min === 0 (e.g., minutes, seconds, 0-23 hour time).\n if (direction === 'increase') {\n const steppedValue = value + step;\n return steppedValue % range; // Wrap within range 0 to max.\n } else {\n // direction === 'decrease'\n const steppedValue = value - step;\n return (steppedValue + range) % range; // Wrap below min to max.\n }\n } else {\n // Path for any min !== 0 (e.g., 12-hour clock has min 1 and max 12, or other ranges).\n if (direction === 'increase') {\n const steppedValue = value + step;\n return ((steppedValue - min) % range) + min; // Wrap within min-based range.\n } else {\n // direction === 'decrease'\n const steppedValue = value - step;\n return ((steppedValue - min + range) % range) + min; // Wrap below min to max.\n }\n }\n};\n\n/**\n * Returns the result of stepping currentValue in the requested direction, taking into account min and max.\n * @param {number} currentValue\n * @param direction\n * @param {number} min\n * @param {number} max\n * @returns {number} the result of stepping currentValue in the requested direction, taking into account min and max.\n */\nconst getSteppedSegmentValue = (\n currentValue: number,\n direction: Exclude<TimeFieldActionData['direction'], undefined>,\n min: number,\n max: number\n) => {\n const newValue = adjustTimeSegment(currentValue, 1, min, max, direction);\n return newValue;\n};\n\n/**\n * Returns the result of paging the value up or down, taking into account min and max.\n * @param currentValue\n * @param direction\n * @param min\n * @param max\n * @param segmentType\n * @returns\n */\nconst getPagedSegmentValue = (\n currentValue: number,\n direction: Exclude<TimeFieldActionData['direction'], undefined>,\n min: number,\n max: number,\n segmentType: Exclude<EditableTimeSegmentType, 'dayPeriod'>\n) => {\n let step;\n if (segmentType === 'minute' || segmentType == 'second') {\n step = 10;\n } else if (segmentType === 'millisecond') {\n step = 100;\n } else {\n step = 2;\n }\n\n const newValue = adjustTimeSegment(currentValue, step, min, max, direction);\n return newValue;\n};\n\n/**\n * Creates a new segment state with an updated value from a keyboard action such as step, page, Home, or End.\n * After any keyboard action, the value is complete so that if the user types anything,\n * it will replace the stepped value.\n * @param {EditableTimeSegmentType} segmentType - The type of the segment that is being updated.\n * @param {number} newVal - new value which is used to update the aria-valuenow and aria-valuetext and text properties.\n * @param segmentState\n * @returns A new segment state with an updated value from a keyboard action such as step, page, Homt, or End.\n */\nconst createSegmentFromKeyboardAction = (\n segmentType: EditableTimeSegmentType,\n newVal: number,\n segmentState: TimeSegmentState\n) => {\n // TODO: For now do not zero pad 1-digit 12-hour hours, but pad everything else.\n // We need to be able to override this with an api.\n // Only the hour12 segment has aria-valuemin to be 1. All the other segments' aria-valuemin is 0.\n const hour12 = segmentState['aria-valuemin'] === 1;\n const ariaValueText = getAriaValueText(newVal, segmentState, segmentType, !hour12);\n\n // Create a new segment state that reflects the updated value.\n // After any keyboard action, the value is complete so that if the user types anything,\n // it will replace the stepped value.\n return {\n ...segmentState,\n 'aria-valuetext': ariaValueText,\n 'aria-valuenow': newVal,\n text: ariaValueText,\n isComplete: true\n };\n};\n\n// Set the segment to its minimum value.\nconst goToHome = (segmentType: EditableTimeSegmentType, segmentState: TimeSegmentState) => {\n const newValue = getHomeSegmentValue(segmentState); // gets aria-valuemin\n return createSegmentFromKeyboardAction(segmentType, newValue, segmentState);\n};\n\n// Set the segment to its maximum value.\nconst goToEnd = (segmentType: EditableTimeSegmentType, segmentState: TimeSegmentState) => {\n const newValue = getEndSegmentValue(segmentState); // gets aria-valuemax\n return createSegmentFromKeyboardAction(segmentType, newValue, segmentState);\n};\n\n/**\n * Steps or pages a segment's value. Pass in initialStarting of 12 for hour12, otherwise we want to use the min.\n * Creates a new segment state with an updated value.\n *\n * After any keyboard action, the value is complete so that if the user types anything, it will replace the stepped value.\n * @param segmentType\n * @param segmentState\n * @param type\n * @param direction\n * @returns A new segment state with an updated value from the keyboard action.\n */\nconst doStepOrPage = (\n segmentType: EditableTimeSegmentType,\n segmentState: TimeSegmentState,\n type: 'step' | 'page',\n direction: Exclude<TimeFieldActionData['direction'], undefined>\n) => {\n // aria-valuemin is 0 for all segments except the 12-hour hour segment, where it is 1.\n // When you step or page up when there is no initial value in the segment, we figure it\n // out by using aria-valuemin for all segments (which is 0) except for the 12-hour hour segment.\n // For the 12-hour segment stepping starts at 12.\n const initialStarting =\n segmentType === 'hour' && segmentState['aria-valuemin'] === 1\n ? 12\n : segmentState['aria-valuemin'];\n const valueNow = segmentState['aria-valuenow'];\n const min = segmentState['aria-valuemin']!;\n const max = segmentState['aria-valuemax']!;\n\n let newValue;\n if (segmentType === 'dayPeriod') {\n // toggle aria-valuenow\n newValue = valueNow === AM_VALUE ? PM_VALUE : AM_VALUE;\n } else if (valueNow === undefined) {\n // start at the minimum if there is no value.\n newValue = initialStarting ?? min;\n } else if (type === 'page') {\n newValue = getPagedSegmentValue(valueNow, direction, min, max, segmentType);\n } else {\n newValue = getSteppedSegmentValue(valueNow, direction, min, max);\n }\n return createSegmentFromKeyboardAction(segmentType, newValue, segmentState);\n};\n\n/**\n * Get the text for the segment's aria-valuetext property. For dayPeriod segment, we use the segmentState.amPm?.am and\n * segmentState.amPm?.pm to get the localized value.\n * @param {number} newVal - the segments value.\n * @param {TimeSegmentState} segmentState - the segment's current state.\n * @param {EditableTimeSegmentType} segmentType - the segment's type.\n * @param {boolean} padZero - whether to pad the text with 0, e.g., minute segments pad 0, so 1 minute would be '01'.\n * @returns the text for the segment's aria-valuetext property.\n */\nconst getAriaValueText = (\n newVal: number,\n segmentState: TimeSegmentState,\n segmentType: EditableTimeSegmentType,\n padZero: boolean\n) => {\n if (segmentType === 'dayPeriod') {\n // This is the segmentState for dayPeriod:\n //\n // aria-valuenow=\"0” // 0 if AM, 12 if PM\n // aria-valuetext=\"AM”\n // aria-valuemin=\"0”\n // aria-valuemax=“12\"\n // text=“AM\"\n // aria-label=\"AM/PM\"\n // seg.amPM.am and pm always have a value for the dayPeriod segment, so there is no need to default them.\n const amValue = segmentState.amPm?.am;\n const pmValue = segmentState.amPm?.pm;\n return newVal < PM_VALUE ? amValue : pmValue;\n }\n // TODO: Deal with leading zero. In h23 clocks mostly we use leading zeros, and in h12 clocks mostly we do not.\n // but this can be overridden as well with an api.\n const valStr = numberToString(newVal);\n if (!padZero) {\n return numberToString(newVal);\n }\n const targetDigitCount = segmentType === 'millisecond' ? 3 : 2;\n return valStr.padStart(targetDigitCount, '0');\n};\n\n/**\n * Returns an hour 0-23 given the hour 1-12 and the dayPeriod 0 for AM and 12 for PM.\n * @param dayPeriodValue\n * @param timeHour12\n * @returns The hour 0-23.\n */\nconst getAdjustedH12ToH23 = (dayPeriodValue: number, timeHour12: number) => {\n // If both dayPeriod and hour are available, adjust the hour to h23 format\n if (dayPeriodValue === AM_VALUE && timeHour12 === 12) {\n return 0; // 12 AM (midnight) adjustment.\n }\n if (dayPeriodValue === PM_VALUE && timeHour12 === 12) {\n return 12; // 12 PM, no adjustment needed\n }\n if (dayPeriodValue === PM_VALUE) {\n return timeHour12 + 12; // Convert PM hour to h23 format\n }\n return timeHour12; // AM hours, no adjustment needed.\n};\n\nexport { timeReducer, numberToString, stringToNumber };\nexport type { TimeFieldAction, TimeFieldActionData };\n","/**\n * @license\n * Copyright (c) %FIRST_YEAR% %CURRENT_YEAR%, Oracle and/or its affiliates.\n * The Universal Permissive License (UPL), Version 1.0\n * as shown at https://oss.oracle.com/licenses/upl/\n * @ignore\n */\n\nimport { ComponentProps } from 'preact';\nimport { useReducer, useRef } from 'preact/hooks';\nimport { BCP47Locale } from '#UNSAFE_IntlDateTime';\nimport { TimeSegment } from './TimeSegment';\nimport { stringToNumber, timeReducer } from './timeReducer';\nimport {\n AM_VALUE,\n getDayPeriodValueFromHour,\n getDayPeriodValueStr,\n getHourValueStr,\n padWithZero,\n PM_VALUE,\n timesAreDifferent,\n getAmPmStringsForLocale\n} from '#utils/UNSAFE_timeUtils';\n\nimport type {\n EditableTimeSegmentType,\n OrderedTimeSegmentsArray,\n Time,\n TimeGranularity,\n TimePlaceholders\n} from './types';\nimport { TimeField } from './TimeField';\n\ntype TimeFieldType = ComponentProps<typeof TimeField>;\n\ntype UseTimeFieldProps = {\n ariaLabels: Record<EditableTimeSegmentType, string>;\n granularity: TimeGranularity;\n hasLeadingZeroForHour: boolean;\n locale: BCP47Locale;\n timeMasks: TimePlaceholders;\n value?: TimeFieldType['value'];\n};\n\ntype InitializerProps = {\n ariaLabels: Record<EditableTimeSegmentType, string>;\n currentValue?: Time;\n granularity: TimeGranularity;\n hasLeadingZeroForHour: boolean;\n locale: BCP47Locale;\n timeMasks: TimePlaceholders;\n};\n\n// Make the state properties readonly because in reducers, the state is replaced, not mutated directly.\ntype TimeSegmentState = Readonly<\n ComponentProps<typeof TimeSegment> & {\n /** The current digit count for the segment. When the segment is complete or cleared, this will be set to 0.\n * This is useful for figuring out if the segment is complete.\n */\n digitCount?: number;\n }\n>;\n\ntype TimeFieldState = {\n readonly committing: boolean;\n readonly currentTime: Time | undefined;\n readonly isCompleteTime: boolean;\n readonly isTimeSelected: boolean;\n readonly isPartialTime: boolean;\n readonly orderedSegments: OrderedTimeSegmentsArray;\n readonly segments: TimeSegmentState[];\n};\n\nconst MINUTE_SECOND_MAX = 59;\nconst MILLISECOND_MAX = 999;\n\n/**\n * Hook that returns a TimeFieldState and a dispatch method to request changes to that state.\n *\n * This hook determines the initial state based on the provided input properties\n * and utilizes a reducer (`timeReducer`) to initialize the state.\n *\n * **Important**: Ensure that the `timeMasks` include all placeholders required by the specified `granularity`.\n * For example, if `granularity` is \"second\",\n * the `timeMasks` must include the second placeholder. Since 'InputTimeMask' does this validation,\n * it is not done here in the hook for efficiency sake.\n * @param {Object} props - Configuration properties for the hook.\n * @param {AmPmLocalizedValues} props.amPm - An Object containing a localized string for 'am' and one for 'pm'.\n * @param {Record<EditableTimeSegmentType, string>} props.ariaLabels - ARIA labels for each editable time segment type.\n * @param {TimePlaceholders} props.timeMasks - The time placeholders representing the structure of the time format.\n * e.g.,\n * [ { type: 'hour', value: 'hh' }, { type: 'literal', value: ':' }, { type: 'minute', value: 'mm' }, { type: 'literal', value: ' ' }, { type: 'dayPeriod', value: 'am/pm' } ]\n * @param {TimeGranularity} props.granularity - Specifies the smallest time unit that is displayed by the component.\n * @param {BCP47Locale} props.locale - The locale used for formatting the time.\n * @param {boolean} [props.hasLeadingZeroForHour] - Whether to show a leading zero in the hour field when there is only one digit or not. E.g., 01:00 AM vs 1:00 AM.\n * @param {Time | undefined} [props.value] - The current time value.\n * @returns An object containing the current 'state', a 'dispatch' function, and timeResetRef.\n */\nconst useTimeField = ({\n ariaLabels,\n granularity,\n hasLeadingZeroForHour,\n locale,\n timeMasks,\n value: currentValue\n}: UseTimeFieldProps) => {\n const [state, dispatch] = useReducer(\n timeReducer,\n {\n ariaLabels,\n currentValue,\n hasLeadingZeroForHour,\n granularity,\n locale,\n timeMasks\n },\n reducerInitializer\n );\n\n // currentValue is the controlled value passed from the parent.\n const lastValueFromParentRef = useRef<Time | undefined>(currentValue);\n const timeResetRef = useRef<boolean>(false);\n\n // If a new value is being pushed from the parent, and that value differs from\n // the current value of the reducer, then this is a programmatic update\n // and we need to call 'reset' to update the reducer state. Otherwise, the only\n // time the reducer state is updated from the value is on mount.\n if (timesAreDifferent(lastValueFromParentRef.current, currentValue)) {\n lastValueFromParentRef.current = currentValue;\n if (timesAreDifferent(currentValue, state.currentTime)) {\n const initialState = reducerInitializer({\n ariaLabels,\n currentValue,\n hasLeadingZeroForHour,\n granularity,\n locale,\n timeMasks\n });\n dispatch({ actionType: 'reset', data: initialState });\n timeResetRef.current = true;\n }\n }\n\n return { timeResetRef, dispatch, state };\n};\n\n// The bulk of the work in this hook is to derive data from currentValue\n// that will become part of our initial state.\nconst reducerInitializer = (params: InitializerProps) => {\n const { ariaLabels, currentValue, granularity, hasLeadingZeroForHour, locale, timeMasks } =\n params;\n // Construct an ordered list of the editable segments.\n const ftm = timeMasks.filter(({ type }) => type !== 'literal');\n const orderedSegments = ftm.map(({ type }) => type) as OrderedTimeSegmentsArray;\n\n const minuteValue = currentValue?.minute;\n const secondValue = currentValue?.second;\n const millisecondValue = currentValue?.millisecond;\n\n // The timeMasks has a dayPeriod part when the hour is 1-12. You never see a dayPeriod part\n // when the hour is 0-23.\n const hasDayPeriod = timeMasks.some((part) => part.type === 'dayPeriod');\n const hasHour = currentValue?.hour !== undefined;\n const hourValueStr = hasHour\n ? getHourValueStr(currentValue.hour!, hasDayPeriod, hasLeadingZeroForHour)\n : undefined;\n const hourValue = hourValueStr !== undefined ? stringToNumber(hourValueStr) : undefined;\n const dayPeriodValueStr =\n hasDayPeriod && hasHour ? getDayPeriodValueStr(locale, currentValue.hour!) : undefined;\n const dayPeriodValue =\n dayPeriodValueStr !== undefined ? getDayPeriodValueFromHour(currentValue!.hour!) : undefined;\n\n const minuteValueStr =\n currentValue?.minute === undefined ? undefined : padWithZero(currentValue.minute, 2);\n const secondValueStr =\n currentValue?.second === undefined ? undefined : padWithZero(currentValue.second, 2);\n const millisecondValueStr =\n currentValue?.millisecond === undefined ? undefined : padWithZero(currentValue.millisecond, 3);\n\n const isBaseTimeComplete =\n hourValue !== undefined &&\n minuteValue !== undefined &&\n (granularity !== 'second' || secondValue !== undefined) &&\n (granularity !== 'millisecond' ||\n (secondValue !== undefined && millisecondValue !== undefined));\n\n const isCompleteTime = isBaseTimeComplete && (!hasDayPeriod || dayPeriodValue !== undefined);\n\n // A time is considered a partial time if at least one segment has a value.\n // We need to make sure we look at the granularity, though. The time might have milliseconds only set,\n // but if milliseconds isn't in the orderedSegments, it is not a partial time.\n const isPartialTime =\n hourValue !== undefined ||\n minuteValue !== undefined ||\n ((granularity === 'second' || granularity === 'millisecond') && secondValue !== undefined) ||\n (granularity === 'millisecond' && millisecondValue !== undefined);\n\n const secondSeg = [\n {\n type: 'second' as EditableTimeSegmentType,\n 'aria-label': ariaLabels.second,\n 'aria-valuemin': 0,\n 'aria-valuemax': MINUTE_SECOND_MAX,\n 'aria-valuenow': secondValue,\n 'aria-valuetext': secondValueStr,\n isComplete: secondValue !== undefined,\n isSelected: false,\n text: secondValueStr\n }\n ];\n\n const millisecondSeg = [\n {\n type: 'millisecond' as EditableTimeSegmentType,\n 'aria-label': ariaLabels.millisecond,\n 'aria-valuemin': 0,\n 'aria-valuemax': MILLISECOND_MAX,\n 'aria-valuenow': millisecondValue,\n 'aria-valuetext': millisecondValueStr,\n isComplete: millisecondValueStr !== undefined,\n isSelected: false,\n text: millisecondValueStr\n }\n ];\n\n const dayPeriodSeg = [\n {\n type: 'dayPeriod' as EditableTimeSegmentType,\n amPm: getAmPmStringsForLocale(locale),\n 'aria-label': ariaLabels.dayPeriod,\n 'aria-valuemin': AM_VALUE,\n 'aria-valuemax': PM_VALUE,\n 'aria-valuenow': dayPeriodValue,\n 'aria-valuetext': dayPeriodValueStr,\n isComplete: dayPeriodValueStr !== undefined,\n isSelected: false,\n text: dayPeriodValueStr\n }\n ];\n\n // Create state for each editable segment of a time.\n // This does not have to be in order that you see it rendered.\n // The orderedSegments show the order.\n // The timeMasks show the order as well.\n // hour and minute are required segments.\n\n // hour will be 1-12 if the masks have a 'dayPeriod' part (e.g., 1:00 PM), otherwise the hour is 0-23 (e.g., 13:00).\n const editableSegments = [\n {\n type: 'hour' as EditableTimeSegmentType,\n 'aria-label': ariaLabels.hour,\n 'aria-valuemin': hasDayPeriod ? 1 : 0,\n 'aria-valuemax': hasDayPeriod ? 12 : 23,\n 'aria-valuenow': hourValue,\n 'aria-valuetext': hourValueStr,\n isComplete: hourValue !== undefined,\n isSelected: false,\n text: hourValueStr\n },\n {\n type: 'minute' as EditableTimeSegmentType,\n 'aria-label': ariaLabels.minute,\n 'aria-valuemin': 0,\n 'aria-valuemax': MINUTE_SECOND_MAX,\n 'aria-valuenow': minuteValue,\n 'aria-valuetext': minuteValueStr,\n isComplete: minuteValue !== undefined,\n isSelected: false,\n text: minuteValueStr\n },\n ...(granularity === 'second' || granularity === 'millisecond' ? secondSeg : []),\n ...(granularity === 'millisecond' ? millisecondSeg : []),\n ...(hasDayPeriod ? dayPeriodSeg : [])\n ];\n\n // Done deriving the data for our initial state,\n // now create the initial state object to pass to our reducer.\n const initialState: TimeFieldState = {\n committing: false,\n currentTime: currentValue,\n isCompleteTime,\n isTimeSelected: false,\n isPartialTime,\n orderedSegments,\n segments: editableSegments\n };\n return initialState;\n};\n\nexport { useTimeField };\nexport type { TimeFieldState, TimeSegmentState };\n","/**\n * @license\n * Copyright (c) %FIRST_YEAR% %CURRENT_YEAR%, Oracle and/or its affiliates.\n * The Universal Permissive License (UPL), Version 1.0\n * as shown at https://oss.oracle.com/licenses/upl/\n * @ignore\n */\n\nimport { classNames } from '#utils/UNSAFE_classNames';\nimport { segmentStyles } from './themes/SegmentStyles.css';\n\ntype Props = {\n /**\n * True if the segment should be hidden.\n */\n isHidden?: boolean;\n\n /**\n * True if the segment should be highlighted.\n */\n isHighlighted?: boolean;\n\n /**\n * True if the literal is part of a time placeholder, such as hh:mm:ss:sss.\n * If the time is partially specified or complete, this is false.\n */\n isPlaceholder?: boolean;\n\n /**\n * The text to display for this segment.\n */\n text: string;\n};\n\n/**\n * LiteralSegment is used to represent a literal separator in a time,\n * such as the ':' in 10:00:00:000.\n */\nexport const LiteralSegment = ({ isHidden, isHighlighted, isPlaceholder, text }: Props) => {\n const spanClasses = classNames([\n segmentStyles.literalBase,\n isPlaceholder && segmentStyles.placeholder,\n isHighlighted && segmentStyles.highlighted,\n isHidden ? segmentStyles.hidden : segmentStyles.notHidden\n ]);\n\n return (\n <span aria-hidden=\"true\" class={spanClasses}>\n {text}\n </span>\n );\n};\n","/**\n * @license\n * Copyright (c) %FIRST_YEAR% %CURRENT_YEAR%, Oracle and/or its affiliates.\n * The Universal Permissive License (UPL), Version 1.0\n * as shown at https://oss.oracle.com/licenses/upl/\n * @ignore\n */\n\nimport type { RefObject, ComponentProps } from 'preact';\nimport { Dispatch, MutableRef, useCallback, useRef } from 'preact/hooks';\nimport { timesAreDifferent } from '#utils/UNSAFE_timeUtils';\nimport { TimeFieldAction } from './timeReducer';\nimport { TimeFieldState } from './useTimeField';\nimport { Time, EditableTimeSegmentType } from './types';\nimport { getClientHints } from '#utils/PRIVATE_clientHints';\nimport { isBackspaceOrDelete, isSelectAll } from '#utils/PRIVATE_keyboardUtils';\nimport { InputTimeMask } from './InputTimeMask';\nimport { useDoubleTap } from '#hooks/UNSAFE_useDoubleTap';\nimport { useTabbableMode } from '#hooks/UNSAFE_useTabbableMode';\n\ntype InputTimeMaskProps = ComponentProps<typeof InputTimeMask>;\n\ntype Props = {\n timeResetRef: MutableRef<boolean>;\n direction: 'ltr' | 'rtl';\n dispatch: Dispatch<TimeFieldAction>;\n groupRef?: RefObject<HTMLDivElement>;\n isDisabled?: boolean;\n isFocused?: boolean;\n isInputFocused?: boolean;\n onCommit: InputTimeMaskProps['onCommit'];\n onInput: InputTimeMaskProps['onInput'];\n state: TimeFieldState;\n value?: Time;\n};\n\nfunction isMobile() {\n const deviceType = getClientHints().deviceType;\n return deviceType === 'phone' || deviceType === 'tablet';\n}\n\n/**\n * A hook that creates various handlers and manages effects for a TimeField.\n * This is extremely similar to useDateFieldHandler, and it shouldn't be too hard to share code.\n */\nconst useTimeFieldHandlers = ({\n timeResetRef,\n direction,\n dispatch,\n groupRef,\n isDisabled,\n isFocused,\n isInputFocused,\n onCommit,\n onInput,\n state,\n value: currentValue\n}: Props) => {\n const {\n tabbableModeProps: { tabIndex: tabbableModeIndex }\n } = useTabbableMode();\n const anySegmentSelected = state.segments.some((segment) => !!segment.isSelected);\n\n // If any segment is selected, it is contenteditable=true and it has the focus. If you shift-Tab, you will\n // land on the outer div (TimeField) first meaning it takes 2 shift-tab keys to get the previous element.\n // To prevent this, if any segment is selected the tabindex on the div is set to -1.\n // We also need to set tabindex to -1 for the disabled case, since we are dealing with a div instead\n // of an intrinsic input and have to handle it directly.\n const updatedTabIndex = tabbableModeIndex === -1 || anySegmentSelected || isDisabled ? -1 : 0;\n\n // Keep track of the last changed and last committed time values.\n const lastTimeRef = useRef<Time | undefined>(state.currentTime);\n const lastCommittedTimeRef = useRef<Time | undefined>(state.currentTime);\n\n // Keep track whether the time was cleared.\n const timeClearedRef = useRef<boolean>(false);\n const lastFocusedRef = useRef<boolean>(!!isFocused);\n\n // If the value was programmatically changed (see useTimeField.ts), then update the\n // last changed and last committed date refs to stay in sync.\n // currentValue is the controlled value passed from the parent.\n if (timeResetRef.current) {\n lastTimeRef.current = currentValue;\n lastCommittedTimeRef.current = currentValue;\n }\n\n // Handle requested segment changes by calling the reducer dispatch function.\n const onChange = useCallback(\n (action: TimeFieldAction) => {\n dispatch(action);\n },\n [dispatch]\n );\n\n // If the user clicked on a segment, dispatch a request to select it.\n // If they clicked on the time field itself, select the first segment.\n const onClick = useCallback(\n (e: Event) => {\n const segmentType = (e.target as HTMLElement).getAttribute(\n 'data-segment'\n ) as EditableTimeSegmentType;\n !!segmentType\n ? dispatch({ actionType: 'selectSegment', data: { type: segmentType } })\n : dispatch({ actionType: 'selectFirst' });\n },\n [dispatch]\n );\n\n // If complete, select the time.\n const selectAll = useCallback(\n (isGroupFocus = true) => {\n if (state.isCompleteTime) {\n dispatch({ actionType: 'selectTime' });\n // Focus can end up in different places depending on if the user selected a segment\n // first (via click or arrow key), and then did select all. To make shift-tabbing\n // consistent in all cases, set focus to the group when selecting the time.\n isGroupFocus && groupRef?.current?.focus();\n }\n },\n [dispatch, groupRef, state.isCompleteTime]\n );\n\n const onDoubleClick = useCallback(() => {\n selectAll();\n }, [selectAll]);\n\n const onDoubleTap = useCallback(\n (e: Event) => {\n const segmentType = (e.target as HTMLElement).getAttribute(\n 'data-segment'\n ) as EditableTimeSegmentType;\n\n // Only do select all if a segment was double tapped, which means the\n // mobile keyboard will stay up.\n !!segmentType && selectAll(false);\n },\n [selectAll]\n );\n\n const doubleTapHandlers = useDoubleTap({ onDoubleTap: onDoubleTap, onSingleTap: onClick });\n\n // Handle arrow key navigation between segments. If no segment is currently selected, then select the first one.\n const onKeyDown = useCallback(\n (event: KeyboardEvent) => {\n if (\n (direction === 'ltr' && event.key === 'ArrowLeft') ||\n (direction === 'rtl' && event.key === 'ArrowRight')\n ) {\n // Select the previous segment when pressing Left arrow (or Right arrow in rtl).\n dispatch({ actionType: 'selectPrevious' });\n event.stopPropagation();\n } else if (\n (direction === 'ltr' && event.key === 'ArrowRight') ||\n (direction === 'rtl' && event.key === 'ArrowLeft')\n ) {\n // Select the next segment when pressing Right arrow (or Left arrow in rtl).\n dispatch({ actionType: 'selectNext' });\n event.stopPropagation();\n } else if (\n (isBackspaceOrDelete(event) || event.key === 'Backspace') &&\n state.isTimeSelected\n ) {\n // Clear the entire date.\n dispatch({ actionType: 'clearTime' });\n timeClearedRef.current = true;\n // Kill the event to prevent weird issue with placeholders getting deleted on iOS only.\n event.preventDefault();\n event.stopPropagation();\n event.stopImmediatePropagation();\n } else if (isSelectAll(event)) {\n selectAll();\n event.preventDefault();\n event.stopPropagation();\n } else if (event.key === 'Enter') {\n // Hitting Enter commits any changes.\n // This is also where we set 'AM' if hour is set, and AM isn't set.\n // This is where we set state.committing = true.\n dispatch({ actionType: 'commitOnEnter' });\n event.preventDefault();\n event.stopPropagation();\n }\n },\n [direction, dispatch, selectAll, state.isTimeSelected]\n );\n\n // Blurring commits the time value; clear any selected segments and mark non-empty segments as complete.\n // Sets state.committing = true.\n if (lastFocusedRef.current && !isFocused) {\n dispatch({ actionType: 'commitOnBlur' });\n }\n lastFocusedRef.current = !!isFocused;\n\n if (state.committing) {\n // Call onCommit only if the value is different.\n if (timesAreDifferent(lastCommittedTimeRef.current, state.currentTime)) {\n // freeze the object so that the app developer can't change it.\n const frozeTime =\n state.currentTime !== undefined\n ? Object.freeze({ ...state.currentTime })\n : state.currentTime;\n onCommit?.({ value: frozeTime });\n }\n // This will update the state.committing to false.\n dispatch({ actionType: 'committed' });\n lastCommittedTimeRef.current = state.currentTime;\n }\n\n if (timesAreDifferent(lastTimeRef.current, state.currentTime) && !timeResetRef.current) {\n // freeze the object so that the app developer can't change it.\n const frozeTime =\n state.currentTime !== undefined ? Object.freeze({ ...state.currentTime }) : state.currentTime;\n onInput({ value: frozeTime });\n lastTimeRef.current = frozeTime;\n }\n timeResetRef.current = false;\n\n // The following is a simplified version of how we detect keyboard vs. mouse focus\n // in the useCollectionFocusRing hook. If the user tabs onto the field, we want to\n // automatically select the first segment.\n const recentPointerRef = useRef<boolean>(false);\n const pointerDownTimerRef = useRef<ReturnType<typeof setTimeout> | undefined>();\n const onPointerDown = useCallback(() => {\n recentPointerRef.current = true;\n clearTimeout(pointerDownTimerRef.current);\n\n pointerDownTimerRef.current = setTimeout(() => {\n recentPointerRef.current = false;\n }, 200);\n }, []);\n\n // use ref to keep track of isInputFocused changed.\n const lastInputFocusedRef = useRef<boolean>(false);\n // If we receive focus that is *not* due to the user clicking in the field, i.e. the user\n // tabbed onto the field, then select the first segment. (!recentPointerRef.current means the mouse wasn't used in the component).\n // Note: we cannot check isFocused because it includes the ? icon in compact UAD, and we don't\n // want the time selected when the help icon is focused.\n // Every call to the reducer is always producing a new object and then when we create a new object, this hook gets called again. There are libraries that would fix this.\n if (isInputFocused && !lastInputFocusedRef.current && !recentPointerRef.current) {\n dispatch({ actionType: 'selectFirst' });\n }\n\n // If the keyboard was used and we have changed from focused on the input to not focused on the input, i.e. shift-tabbing onto the compact UAD help icon,\n // then 'deselectAndComplete' which will unselect any selected segments and mark them complete. It also auto-fills at this point if necessary.\n // The spec says, \"If the user tabs out of the field after entering a valid value in the hours segment, the rest of the segments will autofill with 00 and AM/PM\n // so that the value is complete.\"\n // TODO: !recentPointerRef.current is true even if I use the mouse to blur,\n // so this dispatch gets called as well as the regular blur. I can maybe protect against this by checking isFocused, no that didn't work for some reason isFocused is still true at this point.\n // JET-71717 blurring from component triggers two actions\n if (!isInputFocused && lastInputFocusedRef.current && !recentPointerRef.current) {\n dispatch({ actionType: 'deselectAndComplete' });\n }\n // If the inputFocus has changed, then set recentPointerRef.current to false to not wait until the timeout, and update the lastInputFocusedRef.\n // Setting refs does not cause a re-render.\n // TODO: Denise, why do we reset the recentPointerRef to false? We do this in useDateFieldHandler. All my tests pass without this, and demos works fine, but maybe you had a problem that this fixed in useDateFieldHandler.\n if (isInputFocused !== lastInputFocusedRef.current) {\n recentPointerRef.current = false;\n lastInputFocusedRef.current = !!isInputFocused;\n }\n\n const handlers = isMobile()\n ? { ...doubleTapHandlers, onKeyDown }\n : { onClick, onDoubleClick, onKeyDown, onPointerDown };\n\n return {\n timeClearedRef,\n timeFieldHandlers: isDisabled ? {} : handlers,\n segmentHandlers: isDisabled ? {} : { onChange },\n tabIndex: updatedTabIndex\n };\n};\n\nexport { useTimeFieldHandlers };\n","/**\n * @license\n * Copyright (c) %FIRST_YEAR% %CURRENT_YEAR%, Oracle and/or its affiliates.\n * The Universal Permissive License (UPL), Version 1.0\n * as shown at https://oss.oracle.com/licenses/upl/\n * @ignore\n */\n\nimport type { RefObject, ComponentProps } from 'preact';\nimport { useMemo, useRef } from 'preact/hooks';\nimport {\n AriaAttributesSignalExcluded,\n HTMLAttributesSignalExcluded\n} from '#utils/UNSAFE_attributeUtils';\nimport { BundleType } from '#resources/nls/bundle';\nimport { classNames } from '#utils/UNSAFE_classNames';\nimport { TimeSegment } from './TimeSegment';\nimport { TimeSegmentState, useTimeField } from './useTimeField';\nimport { Flex } from '#UNSAFE_Flex';\nimport { HiddenAccessible } from '#UNSAFE_HiddenAccessible';\nimport { InputTimeMask } from './InputTimeMask';\nimport { LiteralSegment } from './LiteralSegment';\nimport { LiveRegion } from '#UNSAFE_LiveRegion';\nimport { merge } from '#utils/UNSAFE_stringUtils';\nimport { useComponentTheme } from '#hooks/UNSAFE_useComponentTheme';\nimport { useFormFieldContext } from '#hooks/UNSAFE_useFormFieldContext';\nimport { useTranslationBundle } from '#hooks/UNSAFE_useTranslationBundle';\nimport { useUser } from '#hooks/UNSAFE_useUser';\nimport { TextFieldInputVariantOptions } from '#UNSAFE_TextField/themes/TextFieldInputStyles.css';\nimport { TextFieldInputRedwoodTheme } from '#UNSAFE_TextField/themes/redwood/TextFieldInputTheme';\nimport type { TimePlaceholders, EditableTimeSegmentType } from './types';\nimport { useTimeFieldHandlers } from './useTimeFieldHandlers';\nimport { formatTimeFromMasks, getAmPmStringsForLocale } from '#utils/UNSAFE_timeUtils';\n\ntype InputTimeMaskProps = ComponentProps<typeof InputTimeMask>;\n\ntype AriaProps = Pick<\n AriaAttributesSignalExcluded,\n 'aria-describedby' | 'aria-invalid' | 'aria-label' | 'aria-labelledby'\n>;\n\ntype HTMLElementProps = Pick<HTMLAttributesSignalExcluded<HTMLElement>, 'onBlur' | 'onFocus'>;\n\nexport type Props = AriaProps &\n HTMLElementProps & {\n /**\n * A base id prefix.\n */\n baseId: string;\n\n /**\n * A ref to the element that receives focus when the field's label is clicked,\n * or when the component is toggled between readonly and enabled. This is the\n * first segment in the field.\n */\n fieldRef?: RefObject<HTMLDivElement>;\n\n /**\n * Specifies the smallest time unit that is displayed by the component.\n * If set to minute, only hour and minute are shown.\n * If set to second then hour, minute, and second are shown.\n * If set to millisecond then hour, minute, second and millisecond are shown.\n */\n granularity?: InputTimeMaskProps['granularity'];\n\n /**\n * Whether to show a leading zero in the hour field when there is only one digit or not.\n */\n hasLeadingZeroForHour: boolean;\n\n /**\n * True if the component has an inside label.\n */\n hasInsideLabel?: boolean;\n\n /**\n * Specifies for accessibility purposes whether a value is required.\n */\n isRequired?: InputTimeMaskProps['isRequired'];\n\n /**\n * The placeholder masks used by the time field.\n */\n masks: TimePlaceholders;\n\n /**\n * Specifies how to align text within the field.\n */\n textAlign?: InputTimeMaskProps['textAlign'];\n\n /**\n * The current value of the component. The value's hour is a 0-23 hour.\n */\n value?: InputTimeMaskProps['value'];\n\n /**\n * The style variant of the component.\n */\n variant?: InputTimeMaskProps['variant'];\n\n /**\n * Callback invoked each time the user changes the value of a segment.\n *\n * For example, if the user\n * types '12' into the minute segment of an empty time field,\n * this callback will be called twice to change the minute\n * first to 1 and then 12.\n *\n * If the user types '1' into the hour segment of an empty time field,\n * this callback will be called once with the hour set to 1.\n * If the user then types '2', the callback will be called again. What it gets called with\n * depends on if the InputTimeMask is displaying a 1-12 hour time with a day period or a 0-23 hour time.\n * This is because the InputTimeMask's value's hour is stored as a 0-23 hour.\n *\n * If the user types in '12', and the time has a day period, the value's hour is 0, since 12 AM is converted to hour 0.\n * If the user types in '12', and the time does not have a day period, the value's hour is 12.\n *\n * If the user types in an hour that completes the segment, the other segments that are empty\n * are automatically filled with 0s, and the callback's value will reflect that, e.g.,\n * {hour: 0, minute: 0}.\n */\n onInput: InputTimeMaskProps['onInput'];\n\n /**\n * Callback invoked when the user commits the entered value by blurring or hitting the enter key.\n * The value's hour is a 0-23 hour.\n *\n * If the InputTimeMask's hour field is showing a 1-12 hour time, the\n * field's display value will be converted to a 0-23 hour, using the dayPeriod segment's value, which defaults to 'AM'.\n */\n onCommit: InputTimeMaskProps['onCommit'];\n };\n\nconst findSegment = (\n segments: TimeSegmentState[],\n type: EditableTimeSegmentType\n): TimeSegmentState => {\n return segments.find((segment) => segment.type === type)!;\n};\n\n/**\n * Container for Segment children that represent different parts of a time with no date.\n */\nconst TimeField = ({\n 'aria-describedby': describedBy,\n 'aria-invalid': ariaInvalid,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n baseId,\n fieldRef,\n granularity = 'minute',\n hasLeadingZeroForHour,\n hasInsideLabel,\n isRequired,\n masks: timeMasks,\n onBlur,\n onCommit,\n onFocus,\n onInput,\n textAlign,\n value,\n variant = 'default'\n}: Props) => {\n const { direction, locale } = useUser();\n\n const { am, pm } = useMemo(() => {\n return getAmPmStringsForLocale(locale);\n }, [locale]);\n\n const translations = useTranslationBundle<BundleType>('@oracle/oraclejet-preact');\n const announceTimeCleared = translations.inputTimeMask_time_cleared();\n const labels = {\n hour: translations.formControl_hour(),\n minute: translations.formControl_minute(),\n second: translations.formControl_second(),\n millisecond: translations.formControl_millisecond(),\n dayPeriod: `${am}/${pm}`\n };\n\n const { isDisabled, isFocused, isInputFocused } = useFormFieldContext();\n\n const hasValue = value !== undefined;\n\n // TimeField is similar to TextFieldInput for styling. The main difference\n // is TextFieldInput renders a textarea or input and TimeField renders a div, so the positioning with\n // padding is different. TimeField and TextFieldInput are both the mainContent\n // of a TextField component.\n const { classes } = useComponentTheme<TextFieldInputVariantOptions>(TextFieldInputRedwoodTheme, {\n type: 'notPassword',\n styleVariant: variant,\n textarea: 'notTextArea',\n input: 'notInput',\n div: 'isDiv',\n prefix: 'noPrefix',\n suffix: 'noSuffix',\n startContent: 'noStartContent',\n endContent: 'noEndContent',\n insideLabel: hasInsideLabel ? 'hasInsideLabel' : 'noInsideLabel',\n value: hasValue ? 'hasValue' : 'noValue',\n focused: isFocused ? 'isFocused' : 'notFocused',\n disabled: isDisabled ? 'isDisabled' : 'notDisabled'\n });\n\n const compClasses = classNames([classes]);\n\n const { state, dispatch, timeResetRef } = useTimeField({\n ariaLabels: labels,\n timeMasks,\n granularity,\n hasLeadingZeroForHour,\n locale,\n value\n });\n\n const { isTimeSelected, isPartialTime, segments: editableSegments } = state;\n const hourSegment = findSegment(editableSegments, 'hour');\n const minuteSegment = findSegment(editableSegments, 'minute');\n const secondSegment =\n granularity === 'second' || granularity === 'millisecond'\n ? findSegment(editableSegments, 'second')\n : undefined;\n const millisecondSegment =\n granularity === 'millisecond' ? findSegment(editableSegments, 'millisecond') : undefined;\n const dayPeriodSegment = findSegment(editableSegments, 'dayPeriod');\n\n const segmentsMap = {\n hour: hourSegment,\n minute: minuteSegment,\n second: secondSegment,\n millisecond: millisecondSegment,\n dayPeriod: dayPeriodSegment\n };\n\n const groupRef = useRef<HTMLDivElement>(null);\n const { timeFieldHandlers, timeClearedRef, segmentHandlers, tabIndex } = useTimeFieldHandlers({\n timeResetRef,\n direction,\n dispatch,\n groupRef,\n isDisabled,\n isFocused,\n isInputFocused,\n onCommit,\n onInput,\n state,\n value\n });\n\n // Like other form components, don't show placeholders for inside labels unless focused.\n // This flag causes the segment placeholders to be hidden.\n const isHidden = value === undefined && hasInsideLabel && !isFocused;\n\n // If the time is complete, create a hidden accessible region with the full formatted time.\n const formattedTimeStr = !state.isCompleteTime\n ? ''\n : formatTimeFromMasks(\n locale,\n state.currentTime!,\n granularity,\n timeMasks,\n hasLeadingZeroForHour\n );\n\n const formattedTimeAriaId = `${baseId}-time`;\n const formattedTimeAria = state.isCompleteTime ? (\n <HiddenAccessible id={formattedTimeAriaId}>{formattedTimeStr}</HiddenAccessible>\n ) : undefined;\n const ariaDescribedBy = state.isCompleteTime\n ? merge([describedBy, formattedTimeAriaId])\n : describedBy;\n\n // Add an announcement to the live region if the time was cleared.\n // Note: we deliberately do not reset timeClearedRef because there are multiple\n // rerenders after clearing the time and we want to make sure the announcement\n // has time to be heard.\n const announceText = timeClearedRef.current ? announceTimeCleared : '';\n\n // firstSegmentType is used to determine on what TimeSegment to put the fieldRef,\n // and fieldRef is a ref to the element that receives focus when the field's label is clicked.\n const firstSegmentType = state.orderedSegments[0];\n\n return (\n <div\n aria-describedby={ariaDescribedBy}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n class={compClasses}\n onFocusIn={onFocus}\n onFocusOut={onBlur}\n ref={groupRef}\n role=\"group\"\n tabIndex={tabIndex}\n {...timeFieldHandlers}>\n <Flex direction=\"row\" wrap=\"nowrap\" justify={textAlign}>\n {timeMasks.map(({ type, value: placeholder }) => {\n const segmentProps = type !== 'literal' ? segmentsMap[type] : {};\n if (type === 'literal') {\n return (\n <LiteralSegment\n isHidden={isHidden}\n isHighlighted={isTimeSelected}\n isPlaceholder={!isPartialTime}\n text={placeholder}></LiteralSegment>\n );\n } else {\n return (\n <TimeSegment\n inputRef={type === firstSegmentType ? fieldRef : undefined}\n isDisabled={isDisabled}\n isInvalid={!!ariaInvalid}\n isHidden={isHidden}\n isHighlighted={isTimeSelected}\n isRequired={isRequired}\n placeholder={placeholder}\n type={type}\n {...segmentHandlers}\n {...segmentProps}></TimeSegment>\n );\n }\n })}\n </Flex>\n {formattedTimeAria}\n <LiveRegion>{announceText}</LiveRegion>\n </div>\n );\n};\n\nexport { TimeField, findSegment };\n","/**\n * @license\n * Copyright (c) %FIRST_YEAR% %CURRENT_YEAR%, Oracle and/or its affiliates.\n * The Universal Permissive License (UPL), Version 1.0\n * as shown at https://oss.oracle.com/licenses/upl/\n * @ignore\n */\n\nimport { ComponentProps, Ref, RefObject } from 'preact';\nimport { forwardRef } from 'preact/compat';\nimport { useCallback, useImperativeHandle, useMemo, useRef } from 'preact/hooks';\n\nimport { AriaAttributesSignalExcluded } from '#utils/UNSAFE_attributeUtils';\nimport type { Time, TimePlaceholders } from './types';\nimport {\n CompactUserAssistance,\n InlineUserAssistance,\n UserAssistanceDensityType\n} from '#UNSAFE_UserAssistance';\nimport { TimeField } from './TimeField';\nimport { FormFieldContext } from '#hooks/UNSAFE_useFormFieldContext';\nimport {\n formatTimeFromMasks,\n getTimeMasksFromLocaleAndOptions,\n getLeadingZeroForHour,\n replaceCustomMasksValuesWithPlaceholders\n} from '#utils/UNSAFE_timeUtils';\nimport { Label } from '#UNSAFE_Label';\nimport { ReadonlyTextField, ReadonlyTextFieldInput, TextField } from '#UNSAFE_TextField';\nimport { Size } from '#utils/UNSAFE_size';\nimport { TextFieldContent } from '#UNSAFE_TextField/TextFieldContent';\nimport type { TestIdProps } from '#hooks/UNSAFE_useTestId';\nimport type { TextProps } from '#utils/UNSAFE_interpolations/text';\nimport { useFocusableTextField, FocusableHandle } from '#hooks/UNSAFE_useFocusableTextField';\nimport { useFormContext } from '#hooks/UNSAFE_useFormContext';\nimport { useTextField } from '#hooks/UNSAFE_useTextField';\nimport { useUser } from '#hooks/UNSAFE_useUser';\nimport { ValueUpdateDetail } from '#utils/UNSAFE_valueUpdateDetail';\nimport { LayoutColumnSpan } from '../utils/UNSAFE_styles/Layout';\n\ntype InlineUserAssistanceProps = ComponentProps<typeof InlineUserAssistance>;\n\ntype TextFieldContentProps = ComponentProps<typeof TextFieldContent>;\n\ntype Props = TestIdProps & {\n /**\n * The ID of an element (or space separated IDs of multiple elements) that\n * describes the input.\n */\n 'aria-describedby'?: AriaAttributesSignalExcluded['aria-describedby'];\n\n /**\n * Text to provide guidance to help the user understand what data to enter.\n */\n assistiveText?: InlineUserAssistanceProps['assistiveText'];\n\n /**\n * Specifies how many columns to span in a FormLayout with direction === 'row'\n */\n columnSpan?: LayoutColumnSpan;\n\n /**\n * Use this property to provide content for the end slot, such as a time icon.\n */\n endContent?: TextFieldContentProps['endContent'];\n\n /**\n * Specifies the smallest time unit that is displayed by the component.\n * If set to minute, only hour and minute are shown.\n * If set to second then hour, minute, and second are shown.\n * If set to millisecond then hour, minute, second and millisecond are shown.\n */\n granularity?: 'minute' | 'second' | 'millisecond';\n\n /**\n * Specifies whether to always show a leading zero in the hour field when the hour is 1-digit,\n * or to never show a leading zero in the hour field when the hour is 1-digit.\n * By default, when this is undefined, this is determined by the user's locale.\n */\n hasLeadingZeroForHour?: boolean;\n\n /**\n * Help source URL associated with the component.\n */\n helpSourceLink?: InlineUserAssistanceProps['helpSourceLink'];\n\n /**\n * Custom text to be rendered for the <code>helpSourceLink</code>.\n */\n helpSourceText?: InlineUserAssistanceProps['helpSourceText'];\n\n /**\n * Specifies whether the time displayed is a 1-12 hour time with a day period or a 0-23 hour time.\n * By default, this is determined by the user's locale.\n */\n isHour12?: boolean;\n\n /**\n * Specifies whether the component is disabled.\n */\n isDisabled?: boolean;\n\n /**\n * Specifies whether the component is readonly.\n */\n isReadonly?: boolean;\n\n /**\n * Specifies for accessibility purposes whether a value is required.\n *\n * Setting this property to <code>false</code> means that a value is not required to be\n * committed by the user. Setting this property to <code>true</code> means that a value\n * is required to be committed by the user.\n */\n isRequired?: boolean;\n\n /**\n * Specifies whether to show an indicator on screen that a value is required, for example\n * before the user has committed a value.\n */\n isRequiredShown?: InlineUserAssistanceProps['isRequiredShown'];\n\n /**\n * Specifies the label associated with the field.\n */\n label: string;\n\n /**\n * Specifies where the label is positioned relative to the field.\n */\n labelEdge?: 'inside' | 'start' | 'top' | 'none';\n\n /**\n * Specifies the width of the label when <code>labelEdge</code> is <code>\"start\"</code>.\n */\n labelStartWidth?: Size;\n\n /**\n * A ref to the component field. This can be used when you are composing with InputTimeMask\n * and need to provide an anchor ref to a floating component.\n */\n mainFieldRef?: RefObject<HTMLDivElement>;\n\n /**\n * Array-based representation of the segments used for time.\n * When specified, this option overrides the locale-specific formatting of the time: the separators, and the placement of the dayPeriod (AM/PM).\n *\n * For the SeparatorPlaceholder, the value is used as the separator between time segments. This is usually a ':' or a '.'.\n * For the DayPeriodPlaceholder the placement can be before the time or after the time.\n * The order of Hour/Minute/Seconds/Milliseconds cannot be changed and this will be enforced by the type.\n *\n * If the DayPeriodPlaceholder is in the masks, and the isHour12 property is set to false, an error is thrown\n * because these property values conflict.\n * If the DayPeriodPlaceholder is not in the masks, and the isHour12 property is set to true, an error is thrown\n * because these property values conflict.\n * If the masks property is specified and the granularity property does not match what is in the masks property, an error is thrown.\n */\n masks?: TimePlaceholders;\n\n /**\n * Messages to show on screen that are associated with the component.\n */\n messages?: InlineUserAssistanceProps['messages'];\n\n /**\n * Specifies how to align text within the field.\n */\n textAlign?: TextProps['textAlign'];\n\n /**\n * Specifies the density of the user assistance presentation. It can be set to:\n * <ul>\n * <li><code>'efficient'</code>: Show inline and reserve space to prevent layout reflow when user\n * assistance text is displayed.</li>\n * <li><code>'reflow'</code>: Show inline. Layout will reflow when text is displayed.</li>\n * <li><code>'compact'</code>: Messages, help, hints, and required will not be shown inline; they will show in a mode that keeps the screen more compact, like a popup for the messages, and a required icon to indicate Required. </li>\n * </ul>\n */\n userAssistanceDensity?: UserAssistanceDensityType;\n\n /**\n * The current value of the component. The value's hour is a 0-23 hour.\n * If the InputTimeMask's hour field is showing a 1-12 hour time, the\n * field's display value will be converted to a 0-23 hour, using the dayPeriod segment's value, which defaults to 'AM'.\n */\n value?: Time;\n\n /**\n * The style variant of the component.\n */\n variant?: 'default' | 'embedded';\n\n /**\n * Callback invoked when the user commits the entered value by blurring or hitting the enter key.\n * The value's hour is a 0-23 hour.\n *\n * If the InputTimeMask's hour field is showing a 1-12 hour time, the\n * field's display value will be converted to a 0-23 hour, using the dayPeriod segment's value, which defaults to 'AM'.\n *\n * Granularity will determine what fields in the value will be sent back in onInput and onCommit\n * as the user interacts with the component. For example, if granularity is 'minute' (the default),\n * then only the hour and minute fields will be shown to the user,\n * and the value sent back via onInput and onCommit will only include the fields the user has set.\n */\n onCommit?: (detail: ValueUpdateDetail<Time>) => void;\n\n /**\n * Callback invoked each time the user changes the value of a segment.\n *\n * For example, if the user\n * types '12' into the minute segment of an empty time field,\n * this callback will be called twice to change the minute\n * first to 1 and then 12.\n *\n * If the user types '1' into the hour segment of an empty time field,\n * this callback will be called once with the hour set to 1.\n * If the user then types '2', the callback will be called again. What it gets called with\n * depends on if the InputTimeMask is displaying a 1-12 hour time with a day period or a 0-23 hour time.\n * This is because the InputTimeMask's value's hour is stored as a 0-23 hour.\n *\n * If the user types in '12', and the time has an empty day period, the value's hour is 0, since the\n * dayPeriod defaults to 'AM' and 12 AM is converted to hour 0.\n * If the user types in '12', and the time does not have a day period, the value's hour is 12.\n *\n * If the user types in an hour that completes the segment, the other segments that are empty\n * are automatically filled with 0s, and the callback's value will reflect that, e.g.,\n * {hour: 0, minute: 0}.\n *\n * Granularity will determine what fields in the value will be sent back in onInput and onCommit\n * as the user interacts with the component. For example, if granularity is 'minute' (the default),\n * then only the hour and minute fields will be shown to the user,\n * and the value sent back via onInput and onCommit will only include the fields the user has set.\n */\n onInput: (detail: ValueUpdateDetail<Time>) => void;\n};\n\n/**\n * An InputTimeMask allows the user to enter, edit, or display a time value.\n */\nexport const InputTimeMask = forwardRef(\n (\n {\n 'aria-describedby': ariaDescribedBy,\n assistiveText,\n columnSpan,\n endContent,\n granularity = 'minute',\n helpSourceLink,\n helpSourceText,\n isHour12,\n isDisabled: propIsDisabled,\n isReadonly: propIsReadonly,\n isRequired,\n isRequiredShown,\n label,\n labelEdge: propLabelEdge,\n labelStartWidth: propLabelStartWidth,\n hasLeadingZeroForHour,\n mainFieldRef,\n messages,\n masks,\n testId,\n textAlign: propTextAlign,\n userAssistanceDensity: propUserAssistanceDensity,\n value,\n variant,\n onCommit,\n onInput\n }: Props,\n ref?: Ref<FocusableHandle>\n ) => {\n const {\n isDisabled: isFormDisabled,\n isReadonly: isFormReadonly,\n labelEdge: formLabelEdge,\n labelStartWidth: formLabelStartWidth,\n textAlign: formTextAlign,\n userAssistanceDensity: formUserAssistanceDensity\n } = useFormContext();\n // default to FormContext values if component properties are not specified\n const isDisabled = propIsDisabled ?? isFormDisabled;\n const isReadonly = propIsReadonly ?? isFormReadonly;\n const labelEdge = propLabelEdge ?? formLabelEdge;\n const labelStartWidth = propLabelStartWidth ?? formLabelStartWidth;\n const textAlign = propTextAlign ?? formTextAlign;\n const userAssistanceDensity = propUserAssistanceDensity ?? formUserAssistanceDensity;\n const enabledElementRef = useRef<HTMLDivElement>(null);\n const readonlyElementRef = useRef<HTMLDivElement>(null);\n\n const {\n focusProps,\n isFocused,\n methods: focusMethods\n } = useFocusableTextField<HTMLDivElement, HTMLDivElement>({\n isDisabled,\n isReadonly,\n enabledElementRef,\n readonlyElementRef\n });\n\n useImperativeHandle(ref!, () => focusMethods, [focusMethods]);\n\n const isComponentFocused = isFocused;\n\n const {\n baseId,\n formFieldContext,\n inputProps,\n labelProps: origLabelProps,\n textFieldProps,\n userAssistanceProps\n } = useTextField({\n ariaDescribedBy,\n helpSourceLink,\n helpSourceText,\n isDisabled,\n isFocused: isComponentFocused,\n isReadonly,\n isRequiredShown,\n labelEdge,\n messages,\n styleVariant: variant,\n userAssistanceDensity,\n value\n });\n\n // When using a div with role=group (i.e. TimeField), you need aria-labelledby instead of a\n // for-id association with a label. Remove forId and id and use aria-labelledby instead.\n const { forId, ...labelProps } = origLabelProps;\n const { id, ...timeFieldProps } = inputProps;\n const ariaLabelledBy = labelProps.id;\n // Because we don't use for-id, clicking the label does not automatically focus the field.\n // We have to do it manually.\n const onClick = useCallback(() => {\n enabledElementRef.current?.focus();\n }, [enabledElementRef]);\n\n const labelComp =\n labelEdge !== 'none' ? (\n <Label {...(!isDisabled && !isReadonly ? { onClick } : {})} {...labelProps}>\n {label}\n </Label>\n ) : undefined;\n\n const fieldLabelProps = {\n label: labelEdge !== 'none' ? labelComp : undefined,\n labelEdge: labelEdge !== 'none' ? labelEdge : undefined,\n labelStartWidth: labelEdge !== 'none' ? labelStartWidth : undefined\n };\n\n const ariaLabel = labelEdge === 'none' ? label : undefined;\n const hasInsideLabel = label !== undefined && labelEdge === 'inside';\n const isInlineDensity =\n userAssistanceDensity === 'efficient' || userAssistanceDensity === 'reflow';\n\n const inlineUserAssistance = isInlineDensity ? (\n isDisabled || isReadonly ? (\n // save space for user assistance if density is 'efficient', even though we don't\n // render user assistance for disabled or readonly fields\n userAssistanceDensity !== 'efficient' ? undefined : (\n <InlineUserAssistance\n userAssistanceDensity={userAssistanceDensity}\n {...userAssistanceProps}\n />\n )\n ) : (\n <InlineUserAssistance\n assistiveText={assistiveText}\n fieldLabel={label}\n helpSourceLink={helpSourceLink}\n helpSourceText={helpSourceText}\n messages={messages}\n isRequiredShown={isRequiredShown}\n userAssistanceDensity={userAssistanceDensity}\n {...userAssistanceProps}\n />\n )\n ) : undefined;\n\n const aRef = useRef<HTMLDivElement>(null);\n const anchorRef = mainFieldRef ?? aRef;\n\n const compactUserAssistance =\n userAssistanceDensity === 'compact' ? (\n <CompactUserAssistance\n anchorRef={anchorRef}\n messages={messages}\n assistiveText={assistiveText}\n {...userAssistanceProps}\n />\n ) : undefined;\n\n const { locale } = useUser();\n\n // Make sure the masks and properties do not conflict. This throws an error if they do conflict.\n validateTimeMasksAgainstProperties(masks, granularity, isHour12);\n\n if (masks !== undefined && isHour12 === undefined) {\n // The isHour12 value defaults to true if the masks include a dayPeriod; otherwise, it defaults to false.\n const hasDayPeriod = masks.find((part) => part.type === 'dayPeriod') !== undefined;\n isHour12 = hasDayPeriod;\n }\n\n // masks look like this:\n // const masks: TimePlaceholder = [\n // {type: 'dayPeriod', value: 'am/pm'},\n // {type: 'hour', value: 'hh'},\n // {type: 'literal', value: ':'},\n // {type: 'minute', value: 'mm'}\n // ]\n const timeMasks = useMemo(() => {\n // Determine the locale specific placeholder masks and separators in the correct order\n // for the locale, unless a custom set of masks was passed in. Each mask represents a\n // placeholder for a segment of a time. The hour/minute/second/millisecond's order never changes.\n // The dayPeriod segment can change: it can be at the start or at the end.\n // Memoize because we shouldn't need to recreate this data often.\n const placeholderMasks = masks\n ? replaceCustomMasksValuesWithPlaceholders(locale, masks) // no need to pass in isHour12. if masks has dayPeriod, then we use it since we checked before this if mask has dayPeriod and hour 12 is explicitly set to false, we throw an error.\n : // we get masks from locale.\n // hour12, if explicitly set, will take precedence.\n // This works: new Intl.DateTimeFormat('en-GB', {timeStyle: 'short', hour12: true}).format(datetime),\n getTimeMasksFromLocaleAndOptions(locale, granularity, isHour12);\n\n return placeholderMasks;\n }, [granularity, isHour12, locale, masks]);\n\n // We want the app dev to be able to force the hour to have a leading zero or force the hour to not have a leading zero.\n // This is useful for user preferences where the user wants the time to be in a particular format that is different than their locale.\n // Most commonly apps want to determine the leading zero from the locale, and therefore that is the default.\n const resolvedLeadingZeroForHour = hasLeadingZeroForHour ?? getLeadingZeroForHour(locale);\n if (isReadonly) {\n return (\n <FormFieldContext.Provider value={formFieldContext}>\n <ReadonlyTextField\n role=\"presentation\"\n columnSpan={columnSpan}\n compactUserAssistance={compactUserAssistance}\n inlineUserAssistance={inlineUserAssistance}\n onBlur={focusProps.onFocusOut}\n onFocus={focusProps.onFocusIn}\n ref={anchorRef}\n testId={testId}\n mainContent={\n <ReadonlyTextFieldInput\n aria-describedby={timeFieldProps['aria-describedby']}\n aria-label={ariaLabel}\n aria-labelledby={labelProps.id}\n as=\"div\"\n elementRef={readonlyElementRef}\n textAlign={textAlign}\n value={\n value === undefined\n ? ''\n : formatTimeFromMasks(\n locale,\n value,\n granularity,\n timeMasks,\n resolvedLeadingZeroForHour\n )\n }\n hasEmptyLabel={label === '' && labelEdge === 'none'}\n hasInsideLabel={hasInsideLabel}\n />\n }\n {...fieldLabelProps}></ReadonlyTextField>\n </FormFieldContext.Provider>\n );\n }\n\n // The main content inside TextField is a TimeField (not TextFieldInput) in this case.\n // We reuse the TextField building blocks and hooks, but recompose them.\n const mainContent = (\n <TimeField\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n baseId={baseId}\n fieldRef={enabledElementRef}\n granularity={granularity}\n hasInsideLabel={labelComp !== undefined && labelEdge === 'inside'}\n hasLeadingZeroForHour={resolvedLeadingZeroForHour}\n isRequired={isRequired}\n masks={timeMasks}\n onCommit={onCommit}\n onInput={onInput}\n textAlign={textAlign}\n value={value}\n {...timeFieldProps}\n />\n );\n\n return (\n <FormFieldContext.Provider value={formFieldContext}>\n <TextField\n columnSpan={columnSpan}\n compactUserAssistance={compactUserAssistance}\n endContent={endContent}\n inlineUserAssistance={inlineUserAssistance}\n mainContent={mainContent}\n onBlur={focusProps.onFocusOut}\n onFocus={focusProps.onFocusIn}\n mainFieldRef={anchorRef}\n testId={testId}\n {...textFieldProps}\n {...fieldLabelProps}\n />\n </FormFieldContext.Provider>\n );\n }\n);\n\n/**\n * This function checks the following:\n * - If both 'masks' and 'isHour12' are provided, it ensures that the 'isHour12' flag matches the presence of a 'dayPeriod' in the 'masks'.\n * - It verifies that the 'masks' contain the correct time placeholders based on the granularity.\n *\n * It throws an error if anything is not set correctly.\n * It never throws an error if masks is undefined; it just returns.\n * @param masks\n * @param granularity\n * @param isHour12\n * @throws if there is a conflict between masks and the granularity and isHour12 properties.\n */\nconst validateTimeMasksAgainstProperties = (\n masks: TimePlaceholders | undefined,\n granularity: 'minute' | 'second' | 'millisecond',\n isHour12?: boolean\n) => {\n if (masks === undefined) {\n return;\n }\n // If the user passes in masks and isHour12, we look at masks to see what the isHour12 should be.\n // If isHour12 is passed in and it is different than what we expect, we throw an error.\n if (isHour12 !== undefined) {\n const hasDayPeriod = masks.find((part) => part.type === 'dayPeriod') !== undefined;\n if (!hasDayPeriod && isHour12) {\n throw new Error(\n `The masks object does not have a dayPeriod property. isHour12 should be set to false to match masks.`\n );\n }\n if (hasDayPeriod && !isHour12) {\n throw new Error(\n `The masks object does not have a dayPeriod property. isHour12 should be set to true to match masks.`\n );\n }\n }\n // Type checking will make sure hour and minute are there since they are required.\n // Throw errors if masks does not contain the properties it should based on granularity.\n const hasSecond = masks.find((part) => part.type === 'second') !== undefined;\n const hasMillisecond = masks.find((part) => part.type === 'millisecond') !== undefined;\n const commonErrorMsg = `Change granularity to match the properties you have in the masks object.`;\n\n if (granularity === 'second' && !hasSecond) {\n const errorMsg = `granularity is second, but the masks does not contain the second property. \n ${commonErrorMsg}`;\n throw new Error(errorMsg);\n }\n if (granularity === 'second' && hasMillisecond) {\n const errorMsg = `granularity is second, but the masks object contains the millisecond property. \n ${commonErrorMsg}`;\n throw new Error(errorMsg);\n }\n if (granularity === 'millisecond' && (!hasSecond || !hasMillisecond)) {\n const errorMsg = `\"Granularity is set to millisecond. The masks object should contain both the second and millisecond properties, but one or both are missing.\" \n ${commonErrorMsg}`;\n throw new Error(errorMsg);\n }\n if (granularity === 'minute') {\n if (hasSecond || hasMillisecond) {\n throw new Error(`granularity is minute, but the masks object contains the second and/or millisecond property.\n ${commonErrorMsg}`);\n }\n }\n};\n"],"names":["preventDefaultHandler","e","preventDefault","isIos","getClientHints","platform","TimeSegment","amPm","ariaLabel","ariaValueMax","ariaValueMin","ariaValueNow","ariaValueText","inputRef","isDisabled","isHidden","isHighlighted","isInvalid","isRequired","isSelected","onChange","placeholder","text","type","hasDisplayValue","length","rootClasses","classNames","segmentStyles","base","selected","highlighted","placeholderClasses","hidden","notHidden","emptySegmentValueText","useTranslationBundle","formControl_empty_segment","sRef","useRef","segmentRef","dayPeriodTextRef","onKeyDown","useCallback","event","key","isSelectAll","isBackspaceOrDelete","isNumberOnlyString","actionType","data","direction","undefined","isLetterOnlyString","current","matchType","getAmPmMatchType","value","AM_VALUE","PM_VALUE","stopPropagation","useEffect","focus","valueText","toString","customDataAttribute","_jsx","jsx","children","_jsxs","ref","role","autocapitalize","autocorrect","class","contentEditable","enterkeyhint","inputMode","onCut","onPaste","spellcheck","tabIndex","input","isLetter","test","modifiers","isControlOrFunctionKey","timeReducer","state","action","segmentType","segmentState","findSegment","segments","updatedSegments","selectFirst","clearTime","orderedSegments","createTimeFieldStateWithSelectedTime","updatedSegment","clearSegment","createTimeFieldState","completeAllSegmentsBasedOnHour","deselectAndComplete","committing","goToEnd","goToHome","doStepOrPage","selectTime","completeAllEmptySegmentsWhenHourHasValue","updatedSelectedNextSegments","selectNext","selectPrevious","selectSegment","newValue","createSegmentFromKeyboardAction","updateSegment","Error","stringToNumber","s","numberToString","n","find","segment","isTimeComplete","allSegments","every","seg","isPartialTime","some","createTimeFromSegments","dayPeriodValue","hourSegmentValue","adjustedHour","getAdjustedH12ToH23","segmentValues","filter","reduce","acc","Object","entries","getOrderedSegmentsFromState","currentState","autoFillEmptyNonHourSegments","existingSegments","map","ariaValue","includes","am","isComplete","updatedSegmentType","autoAdvance","modifiedSegments","replaceTimeSegment","createTimeSegmentStates","currentTime","isCompleteTime","isTimeSelected","createTimeFieldStateFromSegments","digitCount","actionText","maxValue","minValue","minValueZero","hasLeadingZeros","wasComplete","targetDigitCount","requestedValStr","slice","padStart","max","finalValStr","finalVal","val","maxVal","isSegmentComplete","getSelectedSegmentIndex","sel","findIndex","markSelectedSegmentComplete","selectedIndex","checkHourSelected","hourSegment","dayPeriodSegment","hourSegmentState","clearDayPeriodSegmentWhenHourIsEmpty","adjustTimeSegment","step","min","range","newVal","hour12","getAriaValueText","getHomeSegmentValue","getEndSegmentValue","initialStarting","valueNow","currentValue","getPagedSegmentValue","getSteppedSegmentValue","padZero","amValue","pmValue","pm","valStr","timeHour12","reducerInitializer","params","ariaLabels","granularity","hasLeadingZeroForHour","locale","timeMasks","minuteValue","minute","secondValue","second","millisecondValue","millisecond","hasDayPeriod","part","hasHour","hour","hourValueStr","getHourValueStr","hourValue","dayPeriodValueStr","getDayPeriodValueStr","getDayPeriodValueFromHour","minuteValueStr","padWithZero","secondValueStr","millisecondValueStr","secondSeg","millisecondSeg","dayPeriodSeg","getAmPmStringsForLocale","dayPeriod","LiteralSegment","isPlaceholder","spanClasses","literalBase","useTimeFieldHandlers","timeResetRef","dispatch","groupRef","isFocused","isInputFocused","onCommit","onInput","tabbableModeProps","tabbableModeIndex","useTabbableMode","anySegmentSelected","updatedTabIndex","lastTimeRef","lastCommittedTimeRef","timeClearedRef","lastFocusedRef","onClick","target","getAttribute","selectAll","isGroupFocus","onDoubleClick","onDoubleTap","doubleTapHandlers","useDoubleTap","onSingleTap","stopImmediatePropagation","timesAreDifferent","frozeTime","freeze","recentPointerRef","pointerDownTimerRef","onPointerDown","clearTimeout","setTimeout","lastInputFocusedRef","handlers","deviceType","isMobile","timeFieldHandlers","segmentHandlers","TimeField","describedBy","ariaInvalid","ariaLabelledBy","baseId","fieldRef","hasInsideLabel","masks","onBlur","onFocus","textAlign","variant","useUser","useMemo","translations","announceTimeCleared","inputTimeMask_time_cleared","labels","formControl_hour","formControl_minute","formControl_second","formControl_millisecond","useFormFieldContext","hasValue","classes","useComponentTheme","TextFieldInputRedwoodTheme","styleVariant","textarea","div","prefix","suffix","startContent","endContent","insideLabel","focused","disabled","compClasses","useReducer","lastValueFromParentRef","useTimeField","editableSegments","segmentsMap","formattedTimeStr","formatTimeFromMasks","formattedTimeAriaId","formattedTimeAria","HiddenAccessible","id","ariaDescribedBy","merge","announceText","firstSegmentType","jsxs","onFocusIn","onFocusOut","Flex","wrap","justify","segmentProps","LiveRegion","InputTimeMask","forwardRef","assistiveText","columnSpan","helpSourceLink","helpSourceText","isHour12","propIsDisabled","isReadonly","propIsReadonly","isRequiredShown","label","labelEdge","propLabelEdge","labelStartWidth","propLabelStartWidth","mainFieldRef","messages","testId","propTextAlign","userAssistanceDensity","propUserAssistanceDensity","isFormDisabled","isFormReadonly","formLabelEdge","formLabelStartWidth","formTextAlign","formUserAssistanceDensity","useFormContext","enabledElementRef","readonlyElementRef","focusProps","methods","focusMethods","useFocusableTextField","useImperativeHandle","isComponentFocused","formFieldContext","inputProps","labelProps","origLabelProps","textFieldProps","userAssistanceProps","useTextField","forId","timeFieldProps","labelComp","Label","fieldLabelProps","inlineUserAssistance","InlineUserAssistance","fieldLabel","aRef","anchorRef","compactUserAssistance","CompactUserAssistance","validateTimeMasksAgainstProperties","replaceCustomMasksValuesWithPlaceholders","getTimeMasksFromLocaleAndOptions","resolvedLeadingZeroForHour","getLeadingZeroForHour","FormFieldContext","Provider","ReadonlyTextField","mainContent","ReadonlyTextFieldInput","as","elementRef","hasEmptyLabel","TextField","hasSecond","hasMillisecond","commonErrorMsg"],"mappings":"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"}
|