@oracle/oraclejet-preact 20.1.1 → 20.1.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/AccordionItemMultiple-7cfecf03.js +1 -1
- package/amd/AccordionItemSingle-6c70951e.js +1 -1
- package/amd/BarChart-379e0e10.js +1 -1
- package/amd/{BaseButton-9bf908ec.js → BaseButton-5a0ad529.js} +2 -2
- package/amd/{BaseButton-9bf908ec.js.map → BaseButton-5a0ad529.js.map} +1 -1
- package/amd/BaseCardView-825b1327.js +1 -1
- package/amd/{BaseCardViewSelectionTest-ac780d4f.js → BaseCardViewSelectionTest-66f166ce.js} +2 -2
- package/amd/{BaseCardViewSelectionTest-ac780d4f.js.map → BaseCardViewSelectionTest-66f166ce.js.map} +1 -1
- package/amd/BaseDiagram-7757c344.js +1 -1
- package/amd/BaseRichSelection-57e02c2d.js +1 -1
- package/amd/BaseSelector-3c7b8b87.js +1 -1
- package/amd/BaseSwatchView-2c401b4d.js +1 -1
- package/amd/BaseTabBarItem-6e22fcbc.js +1 -1
- package/amd/Button-e5d7c0e3.js +2 -0
- package/amd/{Button-d541cd67.js.map → Button-e5d7c0e3.js.map} +1 -1
- package/amd/ButtonSet-9f26cc51.js +1 -1
- package/amd/ButtonSetButton-ded680bb.js +1 -1
- package/amd/ButtonSetIconButton-b64b0830.js +1 -1
- package/amd/{Center-27a71002.js → Center-17925696.js} +2 -2
- package/amd/{Center-27a71002.js.map → Center-17925696.js.map} +1 -1
- package/amd/Chart-57d1c518.js +1 -1
- package/amd/Checkbox-3e80f017.js +1 -1
- package/amd/CheckboxControl-0746682f.js +1 -1
- package/amd/CheckboxRadioField-03179844.js +1 -1
- package/amd/CheckboxRadioLabelValueLayout-b728e6ec.js +1 -1
- package/amd/CheckboxSetContext-2e486ea8.js +2 -0
- package/{es/CheckboxSetContext-1be56556.js.map → amd/CheckboxSetContext-2e486ea8.js.map} +1 -1
- package/amd/Chip-8280de2e.js +1 -1
- package/amd/ClearIcon-a066df59.js +1 -1
- package/amd/CollapseIcon-a62fd41c.js +1 -1
- package/amd/Collapsible-0bf0c371.js +1 -1
- package/amd/CollapsibleNavigationList-91858994.js +1 -1
- package/amd/ColorPalette-43ffde6d.js +2 -0
- package/amd/{ColorPalette-f05a9dad.js.map → ColorPalette-43ffde6d.js.map} +1 -1
- package/amd/ColorPicker-3b4180e9.js +2 -0
- package/amd/{ColorPicker-236d84f0.js.map → ColorPicker-3b4180e9.js.map} +1 -1
- package/amd/ColorSwatch-52a06d25.js +1 -1
- package/amd/ComboChart-9cc157af.js +1 -1
- package/amd/CompactHelpSource-09ac9fe1.js +1 -1
- package/amd/CompactLabelAssistance-65c63769.js +2 -0
- package/amd/{CompactLabelAssistance-7bb76228.js.map → CompactLabelAssistance-65c63769.js.map} +1 -1
- package/amd/CompactUserAssistance-2fc90192.js +1 -1
- package/amd/ComponentMessageContainer-d5d70f71.js +1 -1
- package/amd/ConveyorBelt-e54ce1f7.js +1 -1
- package/amd/{DatePicker-89255880.js → DatePicker-ed971798.js} +2 -2
- package/amd/{DatePicker-89255880.js.map → DatePicker-ed971798.js.map} +1 -1
- package/amd/DatePickerHeader-b75e4c72.js +1 -1
- package/amd/{Dialog-ed9c4105.js → Dialog-9a4dbe57.js} +2 -2
- package/amd/{Dialog-ed9c4105.js.map → Dialog-9a4dbe57.js.map} +1 -1
- package/amd/DirectionalCollapseArrowIcon-ddc18f4b.js +1 -1
- package/amd/DirectionalExpandArrowIcon-9c710193.js +1 -1
- package/amd/DragHandle-29eba15d.js +2 -0
- package/amd/{DragHandle-652ffa0f.js.map → DragHandle-29eba15d.js.map} +1 -1
- package/amd/{DrawerPopup-ff31d785.js → DrawerPopup-c9e6374e.js} +2 -2
- package/amd/{DrawerPopup-ff31d785.js.map → DrawerPopup-c9e6374e.js.map} +1 -1
- package/amd/{Dropdown-d1438b58.js → Dropdown-9eed614a.js} +2 -2
- package/amd/{Dropdown-d1438b58.js.map → Dropdown-9eed614a.js.map} +1 -1
- package/amd/EmbeddedIconButton-d1472ac1.js +2 -0
- package/amd/{EmbeddedIconButton-c3cb14c0.js.map → EmbeddedIconButton-d1472ac1.js.map} +1 -1
- package/amd/{EnvironmentProvider-75ba928e.js → EnvironmentProvider-403bf554.js} +2 -2
- package/amd/{EnvironmentProvider-75ba928e.js.map → EnvironmentProvider-403bf554.js.map} +1 -1
- package/amd/ExpandableList-d7b3d65c.js +1 -1
- package/amd/Expander-683df228.js +1 -1
- package/amd/FilePicker-9e24c421.js +1 -1
- package/amd/FlatTreeView-5de96ffd.js +1 -1
- package/amd/Flex-4b81b412.js +2 -0
- package/amd/{Flex-71f83c12.js.map → Flex-4b81b412.js.map} +1 -1
- package/amd/{Floating-08c98ebd.js → Floating-9d6ab071.js} +2 -2
- package/amd/{Floating-08c98ebd.js.map → Floating-9d6ab071.js.map} +1 -1
- package/amd/FormLayout-023ab8de.js +1 -1
- package/amd/Gantt-cdd9d3cb.js +1 -1
- package/amd/{Grid-5324e17b.js → Grid-caac1c86.js} +2 -2
- package/amd/{Grid-5324e17b.js.map → Grid-caac1c86.js.map} +1 -1
- package/amd/GroupLoadingIndicator-4daed099.js +1 -1
- package/amd/HighlightText-ee76c447.js +2 -0
- package/amd/{HighlightText-365ba020.js.map → HighlightText-ee76c447.js.map} +1 -1
- package/amd/Icon-b9a01da9.js +1 -1
- package/amd/IconButton-d78fe636.js +1 -1
- package/amd/IconMenuButton-74b41e62.js +1 -1
- package/amd/IconProgressButton-28f72faa.js +1 -1
- package/amd/IconSwitchButton-22893e1f.js +1 -1
- package/amd/IconToggleButton-9f1c8265.js +1 -1
- package/amd/{IconUserAssistance-e80bf779.js → IconUserAssistance-682b85a2.js} +2 -2
- package/amd/{IconUserAssistance-e80bf779.js.map → IconUserAssistance-682b85a2.js.map} +1 -1
- package/amd/Indexer-27340b0e.js +1 -1
- package/amd/InlineHelpSource-8d8b6a8b.js +1 -1
- package/amd/InlineSelectSingle-4e6a631c.js +1 -1
- package/amd/InlineUserAssistance-91f9ace1.js +1 -1
- package/amd/InputColor-3eca248b.js +2 -0
- package/amd/{InputColor-a1fcd3b3.js.map → InputColor-3eca248b.js.map} +1 -1
- package/amd/InputDateMask-acdfc589.js +1 -1
- package/amd/InputDatePicker-22518a24.js +2 -0
- package/amd/{InputDatePicker-b16a1592.js.map → InputDatePicker-22518a24.js.map} +1 -1
- package/amd/InputPassword-9a1d268d.js +1 -1
- package/amd/InputSensitiveText-e6519508.js +1 -1
- package/amd/InputText-8712623e.js +1 -1
- package/amd/Label-286bacb8.js +1 -1
- package/amd/LabelValueLayout-36bc12e2.js +1 -1
- package/amd/{Layer-64bf71ad.js → Layer-1971eddb.js} +2 -2
- package/amd/{Layer-64bf71ad.js.map → Layer-1971eddb.js.map} +1 -1
- package/amd/{LayerHost-1a734852.js → LayerHost-0b288129.js} +2 -2
- package/amd/{LayerHost-1a734852.js.map → LayerHost-0b288129.js.map} +1 -1
- package/amd/LayerManager-426c669d.js +2 -0
- package/amd/{LayerManager-5ba8e6ed.js.map → LayerManager-426c669d.js.map} +1 -1
- package/amd/Legend-e09a1733.js +1 -1
- package/amd/LineAreaChart-08247f99.js +1 -1
- package/amd/Link-20f7e72d.js +1 -1
- package/amd/List-8d95a024.js +1 -1
- package/amd/{ListItemLayout-23390b90.js → ListItemLayout-2dbba38a.js} +2 -2
- package/amd/{ListItemLayout-23390b90.js.map → ListItemLayout-2dbba38a.js.map} +1 -1
- package/amd/ListView-fe5d340a.js +1 -1
- package/amd/LiveRegion-dbefb95b.js +2 -0
- package/amd/{LiveRegion-1553833d.js.map → LiveRegion-dbefb95b.js.map} +1 -1
- package/amd/{MaxLengthLiveRegion-5172c87a.js → MaxLengthLiveRegion-8f9f7247.js} +2 -2
- package/amd/{MaxLengthLiveRegion-5172c87a.js.map → MaxLengthLiveRegion-8f9f7247.js.map} +1 -1
- package/amd/Menu-4b445ba5.js +1 -1
- package/amd/MenuButton-8428a792.js +1 -1
- package/amd/MenuItem-f3de5e35.js +1 -1
- package/amd/Message-bbea21c4.js +1 -1
- package/amd/MessageBanner-5c18f23c.js +1 -1
- package/amd/MessageLayer-cb7cbb34.js +2 -0
- package/amd/{MessageLayer-24870def.js.map → MessageLayer-cb7cbb34.js.map} +1 -1
- package/amd/MessageToast-9e27adaa.js +1 -1
- package/amd/MessagesManager-4d5f6217.js +1 -1
- package/amd/MeterBar-e8e95881.js +1 -1
- package/amd/MeterCircle-46d479de.js +1 -1
- package/amd/Modal-95bf034f.js +1 -1
- package/amd/{MonthView-15e7e2cc.js → MonthView-93a866a6.js} +2 -2
- package/amd/{MonthView-15e7e2cc.js.map → MonthView-93a866a6.js.map} +1 -1
- package/amd/NavigationListItem-dea4c9e9.js +1 -1
- package/amd/NavigationListLinkItem-e376a039.js +1 -1
- package/amd/NumberInputText-4a58ed41.js +1 -1
- package/amd/OverflowTabBarItem-f23d35fd.js +1 -1
- package/amd/PRIVATE_BaseCardView.js +1 -1
- package/amd/PRIVATE_BaseDiagram.js +1 -1
- package/amd/PRIVATE_BaseSelector.js +1 -1
- package/amd/PRIVATE_BaseSwatchView.js +1 -1
- package/amd/PRIVATE_Chart.js +1 -1
- package/amd/PRIVATE_CheckboxControl.js +1 -1
- package/amd/PRIVATE_CheckboxRadioField.js +1 -1
- package/amd/PRIVATE_ClearIcon.js +1 -1
- package/amd/PRIVATE_CollapsibleNavigationList.js +1 -1
- package/amd/PRIVATE_DatePickerHeader.js +1 -1
- package/amd/PRIVATE_DatePickerLayout.js +1 -1
- package/amd/PRIVATE_EmbeddedIconButton.js +1 -1
- package/amd/PRIVATE_Expander.js +1 -1
- package/amd/PRIVATE_FormControls.js +1 -1
- package/amd/PRIVATE_IconSwitchButton.js +1 -1
- package/amd/PRIVATE_Icons/CheckboxCrossed.js +1 -1
- package/amd/PRIVATE_Icons/CheckboxMixed.js +1 -1
- package/amd/PRIVATE_Icons/CheckboxOff.js +1 -1
- package/amd/PRIVATE_Icons/CheckboxOn.js +1 -1
- package/amd/PRIVATE_Icons/DragV.js +1 -1
- package/amd/PRIVATE_Icons/None.js +1 -1
- package/amd/PRIVATE_List.js +1 -1
- package/amd/PRIVATE_Message.js +1 -1
- package/amd/PRIVATE_MessageLayer.js +1 -1
- package/amd/PRIVATE_MonthView.js +1 -1
- package/amd/PRIVATE_MonthYearGridView.js +1 -1
- package/amd/PRIVATE_PlotArea.js +1 -1
- package/amd/PRIVATE_RevealToggleIcon.js +1 -1
- package/amd/PRIVATE_RichSelectionCommon.js +1 -1
- package/amd/PRIVATE_SelectCommon.js +1 -1
- package/amd/PRIVATE_StyledCard.js +1 -1
- package/amd/PRIVATE_StyledCheckbox.js +1 -1
- package/amd/PRIVATE_StyledSwitch.js +1 -1
- package/amd/PRIVATE_SwatchFlexView.js +1 -1
- package/amd/PRIVATE_Table.js +1 -1
- package/amd/PRIVATE_TableDisplay.js +1 -1
- package/amd/PRIVATE_TableList.js +1 -1
- package/amd/PRIVATE_ThemedIcons/CalendarIcon.js +1 -1
- package/amd/PRIVATE_ThemedIcons/ChartMarqueeSelectIcon.js +1 -1
- package/amd/PRIVATE_ThemedIcons/ChartPanIcon.js +1 -1
- package/amd/PRIVATE_ThemedIcons/ChartZoomIcon.js +1 -1
- package/amd/PRIVATE_ThemedIcons/CheckIcon.js +1 -1
- package/amd/PRIVATE_ThemedIcons/CheckboxCrossedIcon.js +1 -1
- package/amd/PRIVATE_ThemedIcons/CheckboxMixedIcon.js +1 -1
- package/amd/PRIVATE_ThemedIcons/CheckboxOffIcon.js +1 -1
- package/amd/PRIVATE_ThemedIcons/CheckboxOnIcon.js +1 -1
- package/amd/PRIVATE_ThemedIcons/CloseIcon.js +1 -1
- package/amd/PRIVATE_ThemedIcons/CollapseIcon.js +1 -1
- package/amd/PRIVATE_ThemedIcons/CollapseUpIcon.js +1 -1
- package/amd/PRIVATE_ThemedIcons/DecrementIcon.js +1 -1
- package/amd/PRIVATE_ThemedIcons/DeleteIcon.js +1 -1
- package/amd/PRIVATE_ThemedIcons/DirectionalCollapseArrowIcon.js +1 -1
- package/amd/PRIVATE_ThemedIcons/DirectionalExpandArrowIcon.js +1 -1
- package/amd/PRIVATE_ThemedIcons/DragHandleIcon.js +1 -1
- package/amd/PRIVATE_ThemedIcons/DropdownArrowIcon.js +1 -1
- package/amd/PRIVATE_ThemedIcons/ExpandIcon.js +1 -1
- package/amd/PRIVATE_ThemedIcons/HelpIcon.js +1 -1
- package/amd/PRIVATE_ThemedIcons/IncrementIcon.js +1 -1
- package/amd/PRIVATE_ThemedIcons/MenuButtonDropdownIcon.js +1 -1
- package/amd/PRIVATE_ThemedIcons/MessageConfirmationIcon.js +1 -1
- package/amd/PRIVATE_ThemedIcons/MessageErrorIcon.js +1 -1
- package/amd/PRIVATE_ThemedIcons/MessageInfoIcon.js +1 -1
- package/amd/PRIVATE_ThemedIcons/MessageWarningIcon.js +1 -1
- package/amd/PRIVATE_ThemedIcons/MinusIcon.js +1 -1
- package/amd/PRIVATE_ThemedIcons/NavDownIcon.js +1 -1
- package/amd/PRIVATE_ThemedIcons/None.js +1 -1
- package/amd/PRIVATE_ThemedIcons/OverviewHorizontalDragHandleIcon.js +1 -1
- package/amd/PRIVATE_ThemedIcons/PlusIcon.js +1 -1
- package/amd/PRIVATE_ThemedIcons/RadioOffIcon.js +1 -1
- package/amd/PRIVATE_ThemedIcons/RadioOnIcon.js +1 -1
- package/amd/PRIVATE_ThemedIcons/SortAscendingIcon.js +1 -1
- package/amd/PRIVATE_ThemedIcons/SortDescendingIcon.js +1 -1
- package/amd/PRIVATE_ThemedIcons/ViewHideIcon.js +1 -1
- package/amd/PRIVATE_ThemedIcons/ViewIcon.js +1 -1
- package/amd/PRIVATE_TimeComponent.js +1 -1
- package/amd/PRIVATE_TruncatingLink.js +1 -1
- package/amd/PRIVATE_VisOverview.js +1 -1
- package/amd/PRIVATE_VisStatusMessage.js +1 -1
- package/amd/PRIVATE_VisTabularDatatip.js +1 -1
- package/amd/PictoChart-1262b65e.js +1 -1
- package/amd/PieChart-0e4eacd7.js +1 -1
- package/amd/{Popup-575d49f7.js → Popup-feb5bf60.js} +2 -2
- package/amd/{Popup-575d49f7.js.map → Popup-feb5bf60.js.map} +1 -1
- package/amd/{ProgressBar-4074bb67.js → ProgressBar-d7aa356a.js} +2 -2
- package/amd/{ProgressBar-4074bb67.js.map → ProgressBar-d7aa356a.js.map} +1 -1
- package/amd/ProgressButton-71c1dda9.js +1 -1
- package/amd/ProgressButtonLabelLayout-4f7aa87d.js +1 -1
- package/amd/{ProgressCircle-df7641ef.js → ProgressCircle-8a94e670.js} +2 -2
- package/amd/{ProgressCircle-df7641ef.js.map → ProgressCircle-8a94e670.js.map} +1 -1
- package/amd/RadioItem-c5f0676c.js +1 -1
- package/amd/RadioSet-c3ad77d7.js +1 -1
- package/amd/RatingGauge-d0e95f46.js +1 -1
- package/amd/ReadonlyTextFieldInput-41384d7e.js +1 -1
- package/amd/{ReferenceLineArea-27698a8f.js → ReferenceLineArea-450530dd.js} +2 -2
- package/amd/{ReferenceLineArea-27698a8f.js.map → ReferenceLineArea-450530dd.js.map} +1 -1
- package/amd/RemovableNavigationListItem-5e5a9068.js +1 -1
- package/amd/RemovableTabBarItem-ce314e8b.js +1 -1
- package/amd/ReorderableTabBar-3ff37ba7.js +1 -1
- package/amd/RevealToggleIcon-bd35b257.js +1 -1
- package/amd/ScatterChart-af0d8118.js +1 -1
- package/amd/SectionalLegend-aa7254ff.js +1 -1
- package/amd/{SectionedContent-32ec078e.js → SectionedContent-a89bafc6.js} +2 -2
- package/amd/{SectionedContent-32ec078e.js.map → SectionedContent-a89bafc6.js.map} +1 -1
- package/amd/SegmentStyles.styles.css +12 -9
- package/amd/SegmentStyles.styles2.css +9 -12
- package/amd/SelectMobileFieldInput-b1524b1e.js +1 -1
- package/amd/SelectMultiple-f70618cf.js +1 -1
- package/amd/SelectSingle-971886ab.js +1 -1
- package/amd/{SelectorAll-e9acae58.js → SelectorAll-6652fd3f.js} +2 -2
- package/amd/{SelectorAll-e9acae58.js.map → SelectorAll-6652fd3f.js.map} +1 -1
- package/amd/Sheet-1d02491d.js +1 -1
- package/amd/SortControl-ec2db600.js +1 -1
- package/amd/SplitMenuButton-bf59897c.js +1 -1
- package/amd/StyledCard-4baafee3.js +1 -1
- package/amd/{StyledLabelValueLayout-16ac9a5e.js → StyledLabelValueLayout-907bc2d3.js} +2 -2
- package/amd/{StyledLabelValueLayout-16ac9a5e.js.map → StyledLabelValueLayout-907bc2d3.js.map} +1 -1
- package/amd/StyledSwitch-0881e505.js +1 -1
- package/amd/StyledTextField-f533c9e9.js +1 -1
- package/amd/Submenu-99c05da1.js +1 -1
- package/amd/TabBar-8ab0fd0d.js +1 -1
- package/amd/TabBarContextMenu-06f7beb2.js +1 -1
- package/amd/TabBarLayout-4eb6c732.js +1 -1
- package/amd/TabBarMixed-41258b80.js +1 -1
- package/amd/{TabBarMixedSeparator-c77d8e96.js → TabBarMixedSeparator-019d266b.js} +2 -2
- package/amd/{TabBarMixedSeparator-c77d8e96.js.map → TabBarMixedSeparator-019d266b.js.map} +1 -1
- package/amd/Table-2d35f829.js +1 -1
- package/amd/TableColGroup-30abc1ce.js +1 -1
- package/amd/TableDisplay-e3a86f26.js +1 -1
- package/amd/TagCloud-4970d243.js +1 -1
- package/amd/TextArea-6b324b42.js +1 -1
- package/amd/TextAreaAutosize-5d9bf2b2.js +1 -1
- package/amd/TextField-1da09ebc.js +1 -1
- package/amd/TextFieldInput-f8635c62.js +1 -1
- package/amd/Theme-redwood/theme.css +147 -147
- package/amd/Theme-stable/theme.css +255 -255
- package/amd/TimeComponentCanvas2D-a17f51f1.js +1 -1
- package/amd/ToggleButton-c9e433d4.js +1 -1
- package/amd/Toolbar-663b9254.js +1 -1
- package/amd/TruncatingBadge-80a8c903.js +1 -1
- package/amd/TruncatingLink-aa577ffc.js +1 -1
- package/amd/TruncatingText-bdbdd4d4.js +1 -1
- package/amd/UNSAFE_AccordionItemMultiple.js +1 -1
- package/amd/UNSAFE_AccordionItemSingle.js +1 -1
- package/amd/UNSAFE_ActionCard.js +1 -1
- package/amd/UNSAFE_BarChart/__test__/BarChart.spec.js +1 -1
- package/amd/UNSAFE_BarChart.js +1 -1
- package/amd/UNSAFE_BareButton.js +1 -1
- package/amd/UNSAFE_BaseButton.js +1 -1
- package/amd/UNSAFE_Button.js +1 -1
- package/amd/UNSAFE_ButtonLayout/tests/ButtonLayout.spec.js +1 -1
- package/amd/UNSAFE_ButtonSet.js +1 -1
- package/amd/UNSAFE_ButtonSetButton.js +1 -1
- package/amd/UNSAFE_ButtonSetIconButton.js +1 -1
- package/amd/UNSAFE_ButtonSetItem.js +1 -1
- package/amd/UNSAFE_ButtonSetMultiple.js +1 -1
- package/amd/UNSAFE_ButtonSetSingle.js +1 -1
- package/amd/UNSAFE_Card.js +1 -1
- package/amd/UNSAFE_CardFlexView.js +1 -1
- package/amd/UNSAFE_CardGridView.js +1 -1
- package/amd/UNSAFE_Center.js +1 -1
- package/amd/UNSAFE_Checkbox.js +1 -1
- package/amd/UNSAFE_CheckboxItem.js +1 -1
- package/amd/UNSAFE_CheckboxItem.js.map +1 -1
- package/amd/UNSAFE_CheckboxRadioField.js +1 -1
- package/amd/UNSAFE_CheckboxSet.js +1 -1
- package/amd/UNSAFE_CheckboxSet.js.map +1 -1
- package/amd/UNSAFE_Chip.js +1 -1
- package/amd/UNSAFE_Collapsible.js +1 -1
- package/amd/UNSAFE_ColorPalette.js +1 -1
- package/amd/UNSAFE_ColorPicker.js +1 -1
- package/amd/UNSAFE_ColorSwatch.js +1 -1
- package/amd/UNSAFE_ComboChart.js +1 -1
- package/amd/UNSAFE_ComponentMessage.js +1 -1
- package/amd/UNSAFE_ContainerDiagram.js +1 -1
- package/amd/UNSAFE_ConveyorBelt.js +1 -1
- package/amd/UNSAFE_DatePicker.js +1 -1
- package/amd/UNSAFE_Diagram.js +1 -1
- package/amd/UNSAFE_Dialog.js +1 -1
- package/amd/UNSAFE_DragHandle.js +1 -1
- package/amd/UNSAFE_DrawerLayout.js +1 -1
- package/amd/UNSAFE_DrawerPopup.js +1 -1
- package/amd/UNSAFE_Dropdown.js +1 -1
- package/amd/UNSAFE_Environment.js +1 -1
- package/amd/UNSAFE_ExpandableList.js +1 -1
- package/amd/UNSAFE_FilePicker.js +1 -1
- package/amd/UNSAFE_FlatTreeView.js +1 -1
- package/amd/UNSAFE_Flex.js +1 -1
- package/amd/UNSAFE_Floating.js +1 -1
- package/amd/UNSAFE_FormLayout.js +1 -1
- package/amd/UNSAFE_Gantt.js +1 -1
- package/amd/UNSAFE_Grid.js +1 -1
- package/amd/UNSAFE_HighlightText.js +1 -1
- package/amd/UNSAFE_Icon.js +1 -1
- package/amd/UNSAFE_IconButton.js +1 -1
- package/amd/UNSAFE_IconMenuButton.js +1 -1
- package/amd/UNSAFE_IconProgressButton.js +1 -1
- package/amd/UNSAFE_IconToggleButton.js +1 -1
- package/amd/UNSAFE_Indexer.js +1 -1
- package/amd/UNSAFE_InlineSelectSingle.js +1 -1
- package/amd/UNSAFE_InputColor.js +1 -1
- package/amd/UNSAFE_InputDateMask/themes/SegmentStyles.css.js +1 -1
- 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_InputText.js +1 -1
- package/amd/UNSAFE_InputTimeMask/themes/SegmentStyles.css.js +1 -1
- package/amd/UNSAFE_InputTimeMask.js +1 -1
- package/amd/UNSAFE_InputTimeMask.js.map +1 -1
- package/amd/UNSAFE_Label.js +1 -1
- package/amd/UNSAFE_LabelValueLayout.js +1 -1
- package/amd/UNSAFE_LabelledLink.js +1 -1
- package/amd/UNSAFE_Layer.js +1 -1
- package/amd/UNSAFE_Legend.js +1 -1
- package/amd/UNSAFE_LineAreaChart.js +1 -1
- package/amd/UNSAFE_Link.js +1 -1
- package/amd/UNSAFE_ListItemLayout.js +1 -1
- package/amd/UNSAFE_ListView.js +1 -1
- package/amd/UNSAFE_LiveRegion.js +1 -1
- package/amd/UNSAFE_Menu.js +1 -1
- package/amd/UNSAFE_MenuButton.js +1 -1
- package/amd/UNSAFE_MessageBanner.js +1 -1
- package/amd/UNSAFE_MessageToast.js +1 -1
- package/amd/UNSAFE_MeterBar.js +1 -1
- package/amd/UNSAFE_MeterCircle.js +1 -1
- package/amd/UNSAFE_Modal.js +1 -1
- package/amd/UNSAFE_NavigationList.js +1 -1
- package/amd/UNSAFE_NavigationListCommon.js +1 -1
- package/amd/UNSAFE_NumberInputText.js +1 -1
- package/amd/UNSAFE_OverflowTabBar.js +1 -1
- package/amd/UNSAFE_PictoChart.js +1 -1
- package/amd/UNSAFE_PieChart/__test__/PieChart.spec.js +1 -1
- package/amd/UNSAFE_PieChart.js +1 -1
- package/amd/UNSAFE_Popup.js +1 -1
- package/amd/UNSAFE_ProgressBar.js +1 -1
- package/amd/UNSAFE_ProgressButton.js +1 -1
- package/amd/UNSAFE_ProgressButtonLabelLayout.js +1 -1
- package/amd/UNSAFE_ProgressCircle.js +1 -1
- package/amd/UNSAFE_RadioItem.js +1 -1
- package/amd/UNSAFE_RadioSet.js +1 -1
- package/amd/UNSAFE_RatingGauge.js +1 -1
- package/amd/UNSAFE_ReorderableTabBar.js +1 -1
- package/amd/UNSAFE_RichCheckboxSet.js +1 -1
- package/amd/UNSAFE_RichCheckboxSet.js.map +1 -1
- package/amd/UNSAFE_RichRadioSet.js +1 -1
- package/amd/UNSAFE_RichSelectionItem.js +1 -1
- package/amd/UNSAFE_RichSelectionItem.js.map +1 -1
- package/amd/UNSAFE_ScatterChart.js +1 -1
- package/amd/UNSAFE_SectionalLegend.js +1 -1
- package/amd/UNSAFE_SelectMultiple.js +1 -1
- package/amd/UNSAFE_SelectSingle.js +1 -1
- package/amd/UNSAFE_SelectionCard.js +1 -1
- package/amd/UNSAFE_Selector.js +1 -1
- package/amd/UNSAFE_SelectorAll.js +1 -1
- package/amd/UNSAFE_Sheet/__test__/Sheet.spec.js +1 -1
- package/amd/UNSAFE_Sheet.js +1 -1
- package/amd/UNSAFE_SortControl.js +1 -1
- package/amd/UNSAFE_SplitMenuButton.js +1 -1
- package/amd/UNSAFE_Switch.js +1 -1
- package/amd/UNSAFE_TabBar.js +1 -1
- package/amd/UNSAFE_TabBarCommon.js +1 -1
- package/amd/UNSAFE_TabBarMixed.js +1 -1
- package/amd/UNSAFE_TableView.js +1 -1
- package/amd/UNSAFE_TagCloud.js +1 -1
- package/amd/UNSAFE_TextArea.js +1 -1
- package/amd/UNSAFE_TextAreaAutosize.js +1 -1
- package/amd/UNSAFE_TextField.js +1 -1
- package/amd/UNSAFE_ToggleButton.js +1 -1
- package/amd/UNSAFE_Toolbar/tests/Toolbar.spec.js +1 -1
- package/amd/UNSAFE_Toolbar.js +1 -1
- package/amd/UNSAFE_Train.js +1 -1
- package/amd/UNSAFE_TruncatingBadge.js +1 -1
- package/amd/UNSAFE_TruncatingText.js +1 -1
- package/amd/UNSAFE_UserAssistance.js +1 -1
- package/amd/UNSAFE_View.js +1 -1
- package/amd/UNSAFE_VirtualizedListView.js +1 -1
- package/amd/UNSAFE_VisInvalidDataMessage.js +1 -1
- package/amd/UNSAFE_VisNoDataMessage.js +1 -1
- package/amd/UNSAFE_VisProgressiveLoader/__test__/VisProgressiveLoader.spec.js +1 -1
- package/amd/UNSAFE_VisProgressiveLoader.js +1 -1
- package/amd/UNSAFE_WindowOverlay.js +1 -1
- package/amd/{View-215ec211.js → View-35699bb2.js} +2 -2
- package/amd/{View-215ec211.js.map → View-35699bb2.js.map} +1 -1
- package/amd/{VisInvalidDataMessage-139a0bf8.js → VisInvalidDataMessage-8e7534a7.js} +2 -2
- package/amd/{VisInvalidDataMessage-139a0bf8.js.map → VisInvalidDataMessage-8e7534a7.js.map} +1 -1
- package/amd/VisNoDataMessage-fc41dae3.js +2 -0
- package/amd/{VisNoDataMessage-e4eb08f6.js.map → VisNoDataMessage-fc41dae3.js.map} +1 -1
- package/amd/{VisPlaceholder-a7cac338.js → VisPlaceholder-1bbfb2f0.js} +2 -2
- package/amd/{VisPlaceholder-a7cac338.js.map → VisPlaceholder-1bbfb2f0.js.map} +1 -1
- package/amd/{VisProgressiveLoader-10192b41.js → VisProgressiveLoader-eeac2e00.js} +2 -2
- package/amd/{VisProgressiveLoader-10192b41.js.map → VisProgressiveLoader-eeac2e00.js.map} +1 -1
- package/amd/{VisStatusMessage-307f20e9.js → VisStatusMessage-ac3a90aa.js} +2 -2
- package/amd/{VisStatusMessage-307f20e9.js.map → VisStatusMessage-ac3a90aa.js.map} +1 -1
- package/amd/{VisTabularDatatip-d6b9f28f.js → VisTabularDatatip-93d56ae8.js} +2 -2
- package/amd/{VisTabularDatatip-d6b9f28f.js.map → VisTabularDatatip-93d56ae8.js.map} +1 -1
- package/amd/{WindowOverlay-55232139.js → WindowOverlay-11d88211.js} +2 -2
- package/amd/{WindowOverlay-55232139.js.map → WindowOverlay-11d88211.js.map} +1 -1
- package/amd/{YearsGridView-ef191926.js → YearsGridView-09b45b4e.js} +2 -2
- package/amd/{YearsGridView-ef191926.js.map → YearsGridView-09b45b4e.js.map} +1 -1
- package/amd/hoc/PRIVATE_withDirectionIcon.js +1 -1
- package/amd/hoc/PRIVATE_withThemeIcon.js +1 -1
- package/amd/hoc/UNSAFE_withThemeProps.js +1 -1
- package/amd/hooks/PRIVATE_useChartContextMenu.js +1 -1
- package/amd/hooks/PRIVATE_useChartDatatip.js +1 -1
- package/amd/hooks/PRIVATE_useChartEvents.js +1 -1
- package/amd/hooks/PRIVATE_useChartMarquee.js +1 -1
- package/amd/hooks/PRIVATE_useCollectionFocusRing.js +1 -1
- package/amd/hooks/PRIVATE_useCssVars.js +1 -1
- package/amd/hooks/PRIVATE_useCurrentKey.js +1 -1
- package/amd/hooks/PRIVATE_useDatatip.js +1 -1
- package/amd/hooks/PRIVATE_useDetectHorizontalOverflow.js +1 -1
- package/amd/hooks/PRIVATE_useFloating.js +1 -1
- package/amd/hooks/PRIVATE_useItemAction.js +1 -1
- package/amd/hooks/PRIVATE_useListCommon.js +1 -1
- package/amd/hooks/PRIVATE_useOutsideMousedown.js +1 -1
- package/amd/hooks/PRIVATE_useRadioFocusManager.js +1 -1
- package/amd/hooks/PRIVATE_useReorderable.js +1 -1
- package/amd/hooks/PRIVATE_useRovingTabIndexContainer.js +1 -1
- package/amd/hooks/PRIVATE_useSelection.js +1 -1
- package/amd/hooks/PRIVATE_useTabBar.js +1 -1
- package/amd/hooks/PRIVATE_useTabbableModeSet.js +1 -1
- package/amd/hooks/PRIVATE_useTooltipOnTruncation.js +1 -1
- package/amd/hooks/PRIVATE_useVisContextMenu.js +1 -1
- package/amd/hooks/PRIVATE_useVisDragModeControls.js +1 -1
- package/amd/hooks/PRIVATE_useVisEvents.js +1 -1
- package/amd/hooks/PRIVATE_useVisMeterEvents.js +1 -1
- package/amd/hooks/PRIVATE_useVisSelection.js +1 -1
- package/amd/hooks/UNSAFE_useBareButton.js +1 -1
- package/amd/hooks/UNSAFE_useColorScheme.js +1 -1
- package/amd/hooks/UNSAFE_useCurrentBgColor.js +1 -1
- package/amd/hooks/UNSAFE_useDensity.js +1 -1
- package/amd/hooks/UNSAFE_useHiddenTestMethod.js +1 -1
- package/amd/hooks/UNSAFE_useOutsideClick.js +1 -1
- package/amd/hooks/UNSAFE_usePrefixSuffix.js +1 -1
- package/amd/hooks/UNSAFE_useScale.js +1 -1
- package/amd/hooks/UNSAFE_useTestId.js +1 -1
- package/amd/hooks/UNSAFE_useTheme.js +1 -1
- package/amd/hooks/UNSAFE_useThemeInterpolations.js +1 -1
- package/amd/hooks/UNSAFE_useTooltip.js +1 -1
- package/amd/hooks/UNSAFE_useTranslationBundle.js +1 -1
- package/amd/hooks/UNSAFE_useUser.js +1 -1
- package/amd/{index-4f562976.js → index-5899fd61.js} +2 -2
- package/amd/index-5899fd61.js.map +1 -0
- package/amd/listViewSelectionTests-c5492828.js +1 -1
- package/amd/popupUtils-d42db8bf.js +2 -0
- package/amd/{popupUtils-71ea5dd1.js.map → popupUtils-d42db8bf.js.map} +1 -1
- package/amd/render-0e124b25.js +2 -0
- package/amd/{render-40923005.js.map → render-0e124b25.js.map} +1 -1
- package/amd/{tabbableUtils-7fa099af.js → tabbableUtils-0f5a148a.js} +2 -2
- package/amd/{tabbableUtils-7fa099af.js.map → tabbableUtils-0f5a148a.js.map} +1 -1
- package/amd/{testData-db08ddc1.js → testData-0ee09770.js} +2 -2
- package/amd/{testData-db08ddc1.js.map → testData-0ee09770.js.map} +1 -1
- package/amd/{testData-d92d6bdb.js → testData-c84b4335.js} +2 -2
- package/amd/{testData-d92d6bdb.js.map → testData-c84b4335.js.map} +1 -1
- package/amd/{tooltipUtils-0761844d.js → tooltipUtils-66f3844a.js} +2 -2
- package/amd/{tooltipUtils-0761844d.js.map → tooltipUtils-66f3844a.js.map} +1 -1
- package/amd/useBareButton-0afa84c2.js +1 -1
- package/amd/useCellNavigation-fe5a7be7.js +1 -1
- package/amd/useChartContextMenu-1490ade6.js +1 -1
- package/amd/{useChartDatatip-1255260f.js → useChartDatatip-1dc977ae.js} +2 -2
- package/amd/{useChartDatatip-1255260f.js.map → useChartDatatip-1dc977ae.js.map} +1 -1
- package/amd/{useColorScheme-6cb3a3b7.js → useColorScheme-097c31ff.js} +2 -2
- package/amd/{useColorScheme-6cb3a3b7.js.map → useColorScheme-097c31ff.js.map} +1 -1
- package/amd/useContextMenu-c4fc924d.js +1 -1
- package/amd/{useCssVars-d0c0bfa2.js → useCssVars-3194b2f6.js} +2 -2
- package/amd/{useCssVars-d0c0bfa2.js.map → useCssVars-3194b2f6.js.map} +1 -1
- package/amd/{useCurrentBgColor-3044b50a.js → useCurrentBgColor-6f440613.js} +2 -2
- package/amd/{useCurrentBgColor-3044b50a.js.map → useCurrentBgColor-6f440613.js.map} +1 -1
- package/amd/useCurrentKey-5749e7fb.js +2 -0
- package/amd/{useCurrentKey-05038cac.js.map → useCurrentKey-5749e7fb.js.map} +1 -1
- package/amd/{useDatatip-656c8df6.js → useDatatip-df022581.js} +2 -2
- package/amd/{useDatatip-656c8df6.js.map → useDatatip-df022581.js.map} +1 -1
- package/amd/{useDensity-622a2d34.js → useDensity-8a10fc70.js} +2 -2
- package/amd/{useDensity-622a2d34.js.map → useDensity-8a10fc70.js.map} +1 -1
- package/amd/useDisplayValue-a15b1a34.js +1 -1
- package/amd/{useExpandCollapse-d8799966.js → useExpandCollapse-41860b2a.js} +2 -2
- package/amd/{useExpandCollapse-d8799966.js.map → useExpandCollapse-41860b2a.js.map} +1 -1
- package/amd/{useFloating-0bdf9133.js → useFloating-5cb85d2b.js} +2 -2
- package/amd/{useFloating-0bdf9133.js.map → useFloating-5cb85d2b.js.map} +1 -1
- package/amd/{useHiddenTestMethod-6bbe8a43.js → useHiddenTestMethod-8321d341.js} +2 -2
- package/amd/{useHiddenTestMethod-6bbe8a43.js.map → useHiddenTestMethod-8321d341.js.map} +1 -1
- package/amd/useKeyboardEvents-f0419128.js +2 -0
- package/amd/{useKeyboardEvents-191a444a.js.map → useKeyboardEvents-f0419128.js.map} +1 -1
- package/amd/useLegendContextMenu-9b6f6083.js +1 -1
- package/amd/useMeterDatatip-5598534c.js +2 -0
- package/amd/{useMeterDatatip-d6977d41.js.map → useMeterDatatip-5598534c.js.map} +1 -1
- package/amd/useNavigation-8d7dae30.js +1 -1
- package/amd/{useOutsideClick-ace4f686.js → useOutsideClick-b9b661a4.js} +2 -2
- package/amd/{useOutsideClick-ace4f686.js.map → useOutsideClick-b9b661a4.js.map} +1 -1
- package/amd/{useOutsideMousedown-62fa309c.js → useOutsideMousedown-cb88da60.js} +2 -2
- package/amd/{useOutsideMousedown-62fa309c.js.map → useOutsideMousedown-cb88da60.js.map} +1 -1
- package/amd/usePopupAnimation-dc282b02.js +2 -0
- package/amd/{usePopupAnimation-389749fc.js.map → usePopupAnimation-dc282b02.js.map} +1 -1
- package/amd/usePrefixSuffix-dd2cae55.js +2 -0
- package/amd/{usePrefixSuffix-7371ec52.js.map → usePrefixSuffix-dd2cae55.js.map} +1 -1
- package/amd/useRadioFocusManager-462e28eb.js +2 -0
- package/amd/{useRadioFocusManager-c613d2fc.js.map → useRadioFocusManager-462e28eb.js.map} +1 -1
- package/amd/{useReorderableItem-6ab59e42.js → useReorderableItem-0f9d7742.js} +2 -2
- package/amd/{useReorderableItem-6ab59e42.js.map → useReorderableItem-0f9d7742.js.map} +1 -1
- package/amd/{useRovingTabIndexContainer-a8b8ab8f.js → useRovingTabIndexContainer-9aa2fbcf.js} +2 -2
- package/amd/{useRovingTabIndexContainer-a8b8ab8f.js.map → useRovingTabIndexContainer-9aa2fbcf.js.map} +1 -1
- package/amd/{useScale-404175fb.js → useScale-04a448c3.js} +2 -2
- package/amd/{useScale-404175fb.js.map → useScale-04a448c3.js.map} +1 -1
- package/amd/useSelectCommon-be138f8d.js +1 -1
- package/amd/{useSelectDrill-a749b7f8.js → useSelectDrill-2a3c2b81.js} +2 -2
- package/amd/{useSelectDrill-a749b7f8.js.map → useSelectDrill-2a3c2b81.js.map} +1 -1
- package/amd/{useSelection-8f66e2ab.js → useSelection-00add7e4.js} +2 -2
- package/amd/{useSelection-8f66e2ab.js.map → useSelection-00add7e4.js.map} +1 -1
- package/amd/{useSelection-48cb7bdf.js → useSelection-aecb6b23.js} +2 -2
- package/amd/{useSelection-48cb7bdf.js.map → useSelection-aecb6b23.js.map} +1 -1
- package/amd/useTabBar-50c4da2d.js +1 -1
- package/amd/{useTabBarItemTooltip-0c13e9b4.js → useTabBarItemTooltip-fac844e2.js} +2 -2
- package/amd/{useTabBarItemTooltip-0c13e9b4.js.map → useTabBarItemTooltip-fac844e2.js.map} +1 -1
- package/amd/{useTestId-6160e7a2.js → useTestId-f4240cbd.js} +2 -2
- package/amd/{useTestId-6160e7a2.js.map → useTestId-f4240cbd.js.map} +1 -1
- package/amd/{useTheme-59bafcbb.js → useTheme-da27e1d1.js} +2 -2
- package/amd/{useTheme-59bafcbb.js.map → useTheme-da27e1d1.js.map} +1 -1
- package/amd/useThemeInterpolations-cc05b0f0.js +2 -0
- package/amd/{useThemeInterpolations-53e9343f.js.map → useThemeInterpolations-cc05b0f0.js.map} +1 -1
- package/amd/useTooltip-c8aaf38a.js +2 -0
- package/amd/{useTooltip-5615359f.js.map → useTooltip-c8aaf38a.js.map} +1 -1
- package/amd/{useTooltipControlled-0e181f1a.js → useTooltipControlled-af5409d4.js} +2 -2
- package/amd/{useTooltipControlled-0e181f1a.js.map → useTooltipControlled-af5409d4.js.map} +1 -1
- package/amd/useTooltipOnTruncation-129d7663.js +2 -0
- package/amd/{useTooltipOnTruncation-5c26fe42.js.map → useTooltipOnTruncation-129d7663.js.map} +1 -1
- package/amd/{useTranslationBundle-db326955.js → useTranslationBundle-e4dd341e.js} +2 -2
- package/amd/{useTranslationBundle-db326955.js.map → useTranslationBundle-e4dd341e.js.map} +1 -1
- package/amd/{useUser-e0677e8d.js → useUser-08901aba.js} +2 -2
- package/amd/{useUser-e0677e8d.js.map → useUser-08901aba.js.map} +1 -1
- package/amd/useVisDragModeControls-47a4f754.js +1 -1
- package/amd/{useVisEvents-4860cd24.js → useVisEvents-5f18ab46.js} +2 -2
- package/amd/{useVisEvents-4860cd24.js.map → useVisEvents-5f18ab46.js.map} +1 -1
- package/amd/utils/PRIVATE_collectionUtils.js +1 -1
- package/amd/utils/PRIVATE_tabBarUtils.js +1 -1
- package/amd/utils/PRIVATE_tooltipUtils.js +1 -1
- package/amd/utils/PRIVATE_visTestUtils.js +1 -1
- package/amd/utils/UNSAFE_popupUtils.js +1 -1
- package/amd/{withDirectionIcon-07d1a4ee.js → withDirectionIcon-cea07c6e.js} +2 -2
- package/amd/{withDirectionIcon-07d1a4ee.js.map → withDirectionIcon-cea07c6e.js.map} +1 -1
- package/amd/withThemeProps-88ad9dea.js +1 -1
- package/cjs/{BaseCardView-b34fe51b.js → BaseCardView-5690e60a.js} +1 -4
- package/cjs/{BaseCardView-b34fe51b.js.map → BaseCardView-5690e60a.js.map} +1 -1
- package/cjs/{ColorPicker-24ef1a81.js → ColorPicker-3e500453.js} +2 -2
- package/cjs/{ColorPicker-24ef1a81.js.map → ColorPicker-3e500453.js.map} +1 -1
- package/cjs/PRIVATE_BaseCardView.js +1 -1
- package/cjs/PRIVATE_TableList.js +4 -4
- package/cjs/{TabBar-ab270d09.js → TabBar-a6629ef8.js} +1 -3
- package/cjs/{TabBar-ab270d09.js.map → TabBar-a6629ef8.js.map} +1 -1
- package/cjs/Theme-redwood/theme.css +152 -152
- package/cjs/Theme-stable/theme.css +164 -164
- package/cjs/UNSAFE_CardFlexView.js +1 -1
- package/cjs/UNSAFE_CardGridView.js +1 -1
- package/cjs/UNSAFE_ColorPicker.js +25 -25
- package/cjs/UNSAFE_InputColor.js +2 -2
- package/cjs/UNSAFE_ListView.js +53 -53
- package/cjs/UNSAFE_OverflowTabBar.js +10 -10
- package/cjs/UNSAFE_ReorderableTabBar.js +12 -12
- package/cjs/UNSAFE_TabBar.js +10 -10
- package/cjs/UNSAFE_TabBarMixed.js +8 -8
- package/es/{Chart-c9ad6478.js → Chart-ec6a48d2.js} +2 -2
- package/es/{Chart-c9ad6478.js.map → Chart-ec6a48d2.js.map} +1 -1
- package/es/CheckboxSet-ac2fc1ca.js +51 -0
- package/{amd/CheckboxSet-2242fd14.js.map → es/CheckboxSet-ac2fc1ca.js.map} +1 -1
- package/es/FormLayoutVariants.styles.css +14 -14
- package/es/FormLayoutVariants.styles2.css +14 -14
- package/es/PRIVATE_Chart.js +4 -4
- package/es/Theme-redwood/theme.css +435 -435
- package/es/Theme-stable/theme.css +552 -552
- package/es/UNSAFE_BarChart.js +4 -4
- package/es/UNSAFE_CheckboxItem.js +122 -61
- package/es/UNSAFE_CheckboxItem.js.map +1 -1
- package/es/UNSAFE_CheckboxSet.js +15 -49
- package/es/UNSAFE_CheckboxSet.js.map +1 -1
- package/es/UNSAFE_ComboChart.js +4 -4
- package/es/UNSAFE_FormLayout/themes/redwood/FormLayoutTheme.js +1 -1
- package/es/UNSAFE_FormLayout/themes/redwood/FormLayoutVariants.css.js +1 -1
- package/es/UNSAFE_FormLayout/themes/stable/FormLayoutTheme.js +1 -1
- package/es/UNSAFE_FormLayout/themes/stable/FormLayoutVariants.css.js +1 -1
- package/es/UNSAFE_FormLayout.js +1 -1
- package/es/UNSAFE_InputDatePicker.js +92 -92
- package/es/UNSAFE_LineAreaChart.js +4 -4
- package/es/UNSAFE_RichCheckboxSet.js +46 -42
- package/es/UNSAFE_RichCheckboxSet.js.map +1 -1
- package/es/UNSAFE_RichSelectionItem.js +152 -89
- package/es/UNSAFE_RichSelectionItem.js.map +1 -1
- package/es/UNSAFE_ScatterChart.js +4 -4
- package/es/UNSAFE_TextArea.js +226 -106
- package/es/UNSAFE_TextArea.js.map +1 -1
- package/es/UNSAFE_TextAreaAutosize.js +1 -1
- package/es/useTextAreaAltEnter-ac460f4c.js +61 -0
- package/es/useTextAreaAltEnter-ac460f4c.js.map +1 -0
- package/package.json +2 -2
- package/amd/Button-d541cd67.js +0 -2
- package/amd/CheckboxSet-2242fd14.js +0 -2
- package/amd/ColorPalette-f05a9dad.js +0 -2
- package/amd/ColorPicker-236d84f0.js +0 -2
- package/amd/CompactLabelAssistance-7bb76228.js +0 -2
- package/amd/DragHandle-652ffa0f.js +0 -2
- package/amd/EmbeddedIconButton-c3cb14c0.js +0 -2
- package/amd/Flex-71f83c12.js +0 -2
- package/amd/HighlightText-365ba020.js +0 -2
- package/amd/InputColor-a1fcd3b3.js +0 -2
- package/amd/InputDatePicker-b16a1592.js +0 -2
- package/amd/LayerManager-5ba8e6ed.js +0 -2
- package/amd/LiveRegion-1553833d.js +0 -2
- package/amd/MessageLayer-24870def.js +0 -2
- package/amd/VisNoDataMessage-e4eb08f6.js +0 -2
- package/amd/index-4f562976.js.map +0 -1
- package/amd/popupUtils-71ea5dd1.js +0 -2
- package/amd/render-40923005.js +0 -2
- package/amd/useCurrentKey-05038cac.js +0 -2
- package/amd/useKeyboardEvents-191a444a.js +0 -2
- package/amd/useMeterDatatip-d6977d41.js +0 -2
- package/amd/usePopupAnimation-389749fc.js +0 -2
- package/amd/usePrefixSuffix-7371ec52.js +0 -2
- package/amd/useRadioFocusManager-c613d2fc.js +0 -2
- package/amd/useThemeInterpolations-53e9343f.js +0 -2
- package/amd/useTooltip-5615359f.js +0 -2
- package/amd/useTooltipOnTruncation-5c26fe42.js +0 -2
- package/es/CheckboxSetContext-1be56556.js +0 -9
- package/es/TextArea-72682112.js +0 -225
- package/es/TextArea-72682112.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UNSAFE_InputTimeMask.js","sources":["../../src/UNSAFE_InputTimeMask/LiteralSegment.tsx","../../src/UNSAFE_InputTimeMask/useDayPeriodInputHandlers.ts","../../src/UNSAFE_InputTimeMask/TimeSegment.tsx","../../src/UNSAFE_InputTimeMask/useTimeFieldHandlers.ts","../../src/PRIVATE_InputMaskCommon/useInputMaskSelectFirstHandler.ts","../../src/UNSAFE_InputTimeMask/timeReducer.ts","../../src/UNSAFE_InputTimeMask/getTimeFieldInitialState.ts","../../src/UNSAFE_InputTimeMask/useTimeAriaLabels.ts","../../src/UNSAFE_InputTimeMask/TimeField.tsx","../../src/UNSAFE_InputTimeMask/useTimeReset.ts","../../src/UNSAFE_InputTimeMask/useTimeFieldCommitInput.ts","../../src/UNSAFE_InputTimeMask/InputTimeMask.tsx","../../src/UNSAFE_InputTimeMask/useTimeFieldState.ts"],"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 { 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 * If text is only spaces, then the text is not rendered, and instead the space is rendered using css.\n * This is more consistent in all browsers than whitespace is.\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 or the space between the time and the dayPeriod, 8:00 AM.\n */\nexport const LiteralSegment = ({ isHidden, isHighlighted, isPlaceholder, text }: Props) => {\n const isTextOnlyWhitespace = text.trim() === '';\n const spanClasses = classNames([\n segmentStyles.literalBase,\n isPlaceholder && segmentStyles.placeholder,\n isTextOnlyWhitespace && segmentStyles.space,\n isHighlighted && segmentStyles.highlighted,\n isHidden ? segmentStyles.hidden : segmentStyles.notHidden\n ]);\n\n return (\n <span aria-hidden=\"true\" class={spanClasses}>\n {isTextOnlyWhitespace ? ' ' : text}\n </span>\n );\n};\n","import { useCallback, useRef } from 'preact/hooks';\nimport type { RefObject } from 'preact';\nimport { AM_VALUE, getAmPmMatchType, PM_VALUE } from '#utils/UNSAFE_timeUtils';\nimport type { AmPmLocalizedValues } from '#utils/UNSAFE_timeUtils';\nimport type { TimeReducerAction } from './timeReducer';\n\n// A hook that returns handlers for input events that spread on the day period segment so that the user\n// can type in a letter to toggle the day period (e.g., AM/PM).\nexport function useDayPeriodInputHandlers(\n amPm: AmPmLocalizedValues,\n ref: RefObject<HTMLDivElement>,\n onChange?: (action: TimeReducerAction) => void\n) {\n // Used to record the current state of the element in beforeinput so we can restore it in the `input` event below, for inputType 'insertCompositionText'.\n const compositionRef = useRef<string | null>(null);\n\n const updateDayPeriodSegmentState = useCallback(\n (value: number) => {\n onChange?.({\n actionType: 'updateDayPeriodSegment',\n data: { type: 'dayPeriod', 'aria-valuenow': value }\n });\n },\n [onChange]\n );\n\n // This is useful if the AM/PM strings start with the same\n // letter. In that case when we get a letter that matches\n // the start of both, we simply toggle the dayPeriod.\n const toggleDayPeriodSegmentState = useCallback(() => {\n onChange?.({\n actionType: 'step',\n data: { type: 'dayPeriod', direction: 'increase' }\n });\n }, [onChange]);\n\n const changeDayPeriodIfMatch = useCallback(\n (data: string | null) => {\n if (data !== null && data.trim() !== '' && isLetterOnlyString(data)) {\n // In most locales the first letter of the am/pm strings uniquely identifies am or pm.\n // In a couple locales, such as 'ms' (where am is represented 'PG' and pm as 'PTG'), the first letter may not be unique.\n // In this case we toggle the day period if matchType === 'both'.\n const matchType = getAmPmMatchType(amPm, data);\n if (matchType === 'am' || matchType === 'pm') {\n const value = matchType === 'am' ? AM_VALUE : PM_VALUE;\n\n updateDayPeriodSegmentState(value);\n } else if (matchType === 'both') {\n toggleDayPeriodSegmentState();\n }\n }\n },\n [amPm, toggleDayPeriodSegmentState, updateDayPeriodSegmentState]\n );\n\n // inputType 'insertText': Android Samsung, ios, Mac, Windows.\n // inputType 'insertCompositionText': Input Method Editor (IME), such as Pinyin for Chinese, and Android Google.\n // 'insertCompositionText' represents immediate text that is part of an ongoing composition, meaning the user has not yet finalized their input.\n const handleBeforeInput = useCallback(\n (e: InputEvent) => {\n e.preventDefault();\n switch (e.inputType) {\n case 'insertCompositionText':\n // insertCompositionText cannot be cancelled so preventDefault does not keep the user's input from showing in the field.\n // (https://www.w3.org/TR/input-events-2/).\n // To workaround this, record the current state of the element so we can restore it in the `input` event below.\n if (ref.current) {\n compositionRef.current = getTextContentFilterOutAriaHidden(ref.current);\n }\n break;\n default:\n // Android Google never gets here, so we need to change the dayPeriod in handleInput's insertCompositionText.\n changeDayPeriodIfMatch(e.data);\n break;\n }\n },\n [changeDayPeriodIfMatch, ref]\n );\n\n const handleInput = useCallback(\n (e: InputEvent) => {\n const { inputType, data } = e;\n switch (inputType) {\n // we handle the 'insertText' case entirely in handleBeforeInput, but since you cannot cancel 'insertCompositionText' events,\n // we have to do some work here.\n case 'insertCompositionText':\n // Reset the DOM to how it was in the beforeinput event.\n // If we don't do this the user will see what they typed in multi-byte text like Chinese.\n if (ref.current && compositionRef.current !== null) {\n setVisibleText(ref.current, compositionRef.current);\n }\n // Android Google gets here, so this is where we need to check day period.\n changeDayPeriodIfMatch(data);\n break;\n }\n },\n [changeDayPeriodIfMatch, ref]\n );\n\n // NOTE: I could not get oncompositionend to be called when using Chinese or Korean IME keyboard.\n\n return {\n onBeforeInput: handleBeforeInput,\n onInput: handleInput\n };\n}\n\nconst isLetterOnlyString = (input: string) => {\n // /u flag: This enables Unicode matching in Javascript regular expressions, allowing you to match Unicode characters properly,\n // including those outside of the ASCII range.\n // p{L}: This is a Unicode property escape, which matches any letter in any language, not just ASCII letters.\n // The L property refers to Letter characters, which includes\n // * Upper and lowercase letters in the Latin alphabet.\n // * Letters in non-Latin scripts (e.g., Cyrillic, Greek, Arabic, and also Chinese characters.)\n const isLetter = /^\\p{L}$/u.test(input);\n\n return isLetter;\n};\n\nconst getTextContentFilterOutAriaHidden = (elem: HTMLDivElement) => {\n const textContent = getVisibleTextNodes(elem)\n .map((node) => node.textContent)\n .join('');\n return textContent;\n};\n\nconst setVisibleText = (elem: HTMLDivElement, newText: string) => {\n // there is always only one visible text node for the AM/PM segment.\n getVisibleTextNodes(elem)[0].textContent = newText;\n};\n\nconst getVisibleTextNodes = (elem: HTMLDivElement) => {\n return Array.from(elem.childNodes).filter(\n (node) =>\n !(\n node.nodeType === Node.ELEMENT_NODE &&\n (node as HTMLElement).getAttribute('aria-hidden') === 'true'\n )\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, JSX } from 'preact';\nimport { useCallback, useEffect, useRef } from 'preact/hooks';\nimport type { UnpackSignals } from '@oracle/oraclejet-internal-utilities/attributeUtils';\nimport type { TimeReducerAction } from './timeReducer';\nimport type { EditableTimeSegmentType } from './types';\nimport { isBackspaceOrDelete, isSelectAll } 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 type { BundleType } from '#resources/nls/bundle';\nimport type { AmPmLocalizedValues } from '#utils/UNSAFE_timeUtils';\nimport { useDayPeriodInputHandlers } from './useDayPeriodInputHandlers';\n\ntype AriaProps = Pick<\n UnpackSignals<JSX.AriaAttributes>,\n 'aria-label' | 'aria-valuemax' | 'aria-valuemin' | 'aria-valuenow' | 'aria-valuetext'\n>;\n\ntype DayPeriodProps = {\n type: 'dayPeriod';\n /**\n * The am/pm localized values. This is used when the segment type is 'dayPeriod'\n * and is required.\n */\n amPm: AmPmLocalizedValues;\n};\n\ntype NonDayPeriodProps = {\n type: Exclude<EditableTimeSegmentType, 'dayPeriod'>;\n amPm?: never;\n};\n\ntype Props = AriaProps &\n (DayPeriodProps | NonDayPeriodProps) & {\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 field is in focused state.\n */\n isFieldFocused?: 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: TimeReducerAction) => 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 isFieldFocused,\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 isFieldFocused && segmentStyles.accessibleTouchTarget\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 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 // JET-73547: let Escape pass through in order to close a popup or dialog.\n event.key === 'Escape' ||\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 (type === 'dayPeriod') {\n // return and don't call preventDefault so that we can use input handlers for dayPeriod\n // that we get from useDayPeriodInputHandlers.\n // keydown does not work for Android (event.key is 'Unspecified') or IME (like Chinese), and input handlers work for everything.\n return;\n }\n event.preventDefault();\n event.stopPropagation();\n },\n [isDisabled, isHighlighted, onChange, type]\n );\n\n // Gets the input handlers that we need for the dayPeriod segment to allow typing letters to toggle.\n const dayPeriodHandler = useDayPeriodInputHandlers(\n amPm ?? { am: 'AM', pm: 'PM' },\n segmentRef,\n onChange\n );\n\n // Used to focus the segment when isSelected is true.\n useEffect(() => {\n if (isSelected) {\n segmentRef.current?.focus();\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 // Introduce a div wrapper around the contentEditable element to prevent it from grabbing focus.\n // https://stackoverflow.com/questions/34354085/clicking-outside-a-contenteditable-div-stills-give-focus-to-it\n // JET-64874: We change the segment's role to \"textbox\" on iOS to work around a VoiceOver bug, and when we do that\n // we need to add aria-multiline={false}\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-multiline={isIos() ? false : undefined}\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 {...(type === 'dayPeriod' ? dayPeriodHandler : {})}\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","/**\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, useRef } from 'preact/hooks';\nimport type { Dispatch } from 'preact/hooks';\nimport type { TimeReducerAction } from './timeReducer';\nimport type { TimeFieldState } from './getTimeFieldInitialState';\nimport type { EditableTimeSegmentType } from './types';\nimport { getClientHints } from '#utils/PRIVATE_clientHints';\nimport { isBackspaceOrDelete, isSelectAll } from '#utils/PRIVATE_keyboardUtils';\nimport { useDoubleTap } from '#hooks/UNSAFE_useDoubleTap';\nimport { useTabbableMode } from '#hooks/UNSAFE_useTabbableMode';\nimport { useInputMaskSelectFirstHandler } from '#PRIVATE_InputMaskCommon/useInputMaskSelectFirstHandler';\n\ntype Props = {\n direction: 'ltr' | 'rtl';\n dispatch: Dispatch<TimeReducerAction>;\n groupRef?: RefObject<HTMLDivElement>;\n isDisabled?: boolean;\n isInputFocused?: boolean;\n state: TimeFieldState;\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 for a TimeField.\n * This is extremely similar to useDateFieldHandler, and it shouldn't be too hard to share code.\n *\n * This hook creates a timeClearedRef. It is set to false by default and whenever the\n * currentTime has a value, including a partial value.\n * When the user's action is to clear the field, this hook dispatches the 'clearTime' action,\n * and sets timeClearedRef to true.\n * timeClearedRef is returned from the hook so that the aria-live DOM can be updated to say Time Cleared\n * or to clear this text.\n */\nconst useTimeFieldHandlers = ({\n direction,\n dispatch,\n groupRef,\n isDisabled,\n isInputFocused,\n state\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 whether the time was cleared.\n const timeClearedRef = useRef<boolean>(false);\n\n // The timeClearedRef.current is set to true when the user does a clear all.\n // We set it back to false whenever the currentTime has a value.\n if (state.currentTime != null && Object.keys(state.currentTime).length > 0) {\n timeClearedRef.current = false;\n }\n\n // Handle requested segment changes by calling the reducer dispatch function.\n const onChange = useCallback(\n (action: TimeReducerAction) => {\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 if (segmentType !== null) {\n dispatch({ actionType: 'selectSegment', data: { type: segmentType } });\n } else {\n dispatch({ actionType: 'selectFirst' });\n }\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.isCommitting = true.\n dispatch({ actionType: 'commitOnEnter' });\n event.preventDefault();\n event.stopPropagation();\n }\n },\n [direction, dispatch, selectAll, state.isTimeSelected]\n );\n\n const onPointerDown = useInputMaskSelectFirstHandler({ dispatch, isInputFocused });\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","// useInputFocusHandler.ts\nimport { useRef, useCallback } from 'preact/hooks';\nimport type { Dispatch } from 'preact/hooks';\n\ntype SelectFirstAction = { actionType: 'selectFirst' };\n\n/**\n * Hook that determines whether to dispatch a 'selectFirst' action when an input field receives focus.\n *\n * @param {Object} options\n * @param {Dispatch<A>} options.dispatch - Dispatch function for actions of type A that must contain {actionType: 'selectFirst'}.\n * @param {boolean} [options.isInputFocused] - Whether the input field is currently focused.\n * @returns {function} - An `onPointerDown` handler.\n */\nconst useInputMaskSelectFirstHandler = <A extends SelectFirstAction>({\n dispatch,\n isInputFocused\n}: {\n dispatch: Dispatch<A>;\n isInputFocused?: boolean;\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 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 text 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 const action: SelectFirstAction = { actionType: 'selectFirst' };\n dispatch(action as A); // safe because A must include SelectFirstAction\n }\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 if (isInputFocused !== lastInputFocusedRef.current) {\n recentPointerRef.current = false;\n lastInputFocusedRef.current = !!isInputFocused;\n }\n\n return onPointerDown;\n};\n\nexport { useInputMaskSelectFirstHandler };\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 './getTimeFieldInitialState';\nimport { OrderedTimeSegmentsArray, EditableTimeSegmentType } from './types';\nimport {\n displayedTimeSegmentsAreDifferent,\n hasSegmentsNotDisplayed\n} from '#utils/UNSAFE_timeUtils';\nimport { numberToString, stringToNumber, withinRange } from '#utils/PRIVATE_dayUtils/maskUtils';\n\ntype DirectionType = 'increase' | 'decrease';\n\ntype SegmentActionData = Pick<TimeSegmentState, 'type'>;\n\ntype DayPeriodSegmentActionData = SegmentActionData & {\n 'aria-valuenow'?: number;\n};\n\ntype PageStepActionData = SegmentActionData & {\n direction: DirectionType;\n};\n\ntype UpdateActionData = SegmentActionData & {\n text: string;\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 TimeReducerAction =\n | { actionType: 'clearTime'; data?: never }\n | { actionType: 'clearSegment'; data: SegmentActionData }\n | { actionType: 'commitOnBlur'; data?: never }\n | { actionType: 'commitOnEnter'; data?: never }\n | { actionType: 'committed'; data?: never }\n | { actionType: 'goToEnd'; data: SegmentActionData }\n | { actionType: 'goToHome'; data: SegmentActionData }\n | { actionType: 'page'; data: PageStepActionData }\n | { actionType: 'selectFirst'; data?: never }\n | { actionType: 'selectNext'; data?: never }\n | { actionType: 'selectPrevious'; data?: never }\n | { actionType: 'selectSegment'; data: SegmentActionData }\n | { actionType: 'selectTime'; data?: never }\n | { actionType: 'step'; data: PageStepActionData }\n | { actionType: 'updateDayPeriodSegment'; data: DayPeriodSegmentActionData }\n | { actionType: 'updateSegment'; data: UpdateActionData }\n | { actionType: 'reset'; data: TimeFieldState };\n\nconst AM_VALUE = 0;\nconst PM_VALUE = 12;\n\n/**\n * Reducer function for updating TimeFieldState per the specified TimeReducerAction.\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 // 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 createTimeFieldStateFromUpdatedSegments(state, updatedSegments, false);\n }\n case 'clearSegment': {\n const updatedSegment = clearSegment(findSegment(state.segments, action.data.type));\n return createTimeFieldStateFromUpdatedSegment(state, action.data.type, updatedSegment);\n }\n case 'commitOnEnter': {\n const updatedSegments = completeAllSegmentsBasedOnHour(state.segments);\n const newState = createTimeFieldStateFromUpdatedSegments(state, updatedSegments, false);\n return { ...newState, isCommitting: true };\n }\n case 'commitOnBlur': {\n let updatedSegments = completeAllSegmentsBasedOnHour(state.segments);\n updatedSegments = deselectAndComplete(updatedSegments);\n const newState = createTimeFieldStateFromUpdatedSegments(state, updatedSegments, false);\n return { ...newState, isCommitting: true };\n }\n case 'committed': {\n return { ...state, isCommitting: false };\n }\n case 'goToEnd': {\n const updatedSegment = goToEnd(\n action.data.type,\n findSegment(state.segments, action.data.type)\n );\n return createTimeFieldStateFromUpdatedSegment(state, action.data.type, updatedSegment, false);\n }\n case 'goToHome': {\n const updatedSegment = goToHome(\n action.data.type,\n findSegment(state.segments, action.data.type)\n );\n return createTimeFieldStateFromUpdatedSegment(state, action.data.type, updatedSegment, false);\n }\n case 'page': {\n const direction = action.data.direction;\n if (direction === undefined) return state;\n const updatedSegment = doStepOrPage(\n action.data.type,\n findSegment(state.segments, action.data.type),\n 'page',\n direction\n );\n return createTimeFieldStateFromUpdatedSegment(state, action.data.type, updatedSegment, false);\n }\n case 'selectTime': {\n return selectTime(state);\n }\n case 'selectFirst': {\n const updatedSegments = selectFirst(state.segments, state.orderedSegments);\n return createTimeFieldStateFromUpdatedSegments(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 createTimeFieldStateFromUpdatedSegments(state, updatedSelectedNextSegments, false);\n }\n case 'selectPrevious': {\n const updatedSegments = selectPrevious(state.segments, state.orderedSegments);\n return createTimeFieldStateFromUpdatedSegments(state, updatedSegments, false);\n }\n case 'selectSegment': {\n const updatedSegments = selectSegment(state.segments, action.data.type);\n return createTimeFieldStateFromUpdatedSegments(state, updatedSegments, false);\n }\n // Increments or decrements the current segment value.\n case 'step': {\n const direction = action.data.direction;\n if (direction === undefined) return state;\n const updatedSegment = doStepOrPage(\n action.data.type,\n findSegment(state.segments, action.data.type),\n 'step',\n direction\n );\n return createTimeFieldStateFromUpdatedSegment(state, action.data.type, updatedSegment, false);\n }\n case 'updateDayPeriodSegment': {\n if (action.data.type === '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 action.data.type,\n newValue,\n findSegment(state.segments, action.data.type)\n );\n return createTimeFieldStateFromUpdatedSegment(\n state,\n action.data.type,\n updatedSegment,\n false\n );\n }\n }\n return state;\n }\n case 'updateSegment': {\n const segmentState = findSegment(state.segments, action.data.type);\n // If hour is 1-12, ignore typing '0' under certain circumstances\n if (\n action.data?.text === '0' &&\n action.data.type === 'hour' &&\n segmentState['aria-valuemin'] === 1 &&\n (segmentState.isComplete || segmentState['aria-valuenow'] === undefined)\n ) {\n const updatedSegment = { ...segmentState, digitCount: 1 };\n return createTimeFieldStateFromUpdatedSegment(\n state,\n action.data.type,\n updatedSegment,\n false,\n false\n );\n }\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(action.data.type, segmentState, action);\n return createTimeFieldStateFromUpdatedSegment(state, action.data.type, updatedSegment);\n }\n default: {\n throw new Error('Unknown action type');\n }\n }\n};\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 currentState.orderedSegments. The orderedSegments is an array of the name of each segment type\n * in the order they appear to the user.\n * E.g., ['hour', 'minute, 'dayPeriod'], when the InputTimeMask component shows the hour, minute, and dayPeriod segments in that order.\n * E.g., ['hour', 'minute', 'second'] when the InputTimeMask component shows the hour, minute, and second segments in that order.\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 *\n * If the segment is complete, and autoAdvance is true, then the next segment will be selected.\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 * @param {boolean} autoFill - whether to automatically fill the next segments 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 autoFill: 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 && autoFill) {\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;\n let 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 ? {\n ...seg,\n 'aria-valuenow': ariaValue,\n text,\n isComplete: true,\n 'aria-valuetext': text,\n isAutoFilled: true\n }\n : seg;\n });\n return initializedSegments;\n};\n\n/**\n * Constructs a new TimeFieldState given an updated segment, which may affect other segments.\n * Called from actions like updateSegment, stepping/paging/home/end, clearing a segment.\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 * @param {boolean} autoFill - Whether to auto-fill to the next segments if the current hour segment is complete. Defaults to true\n * since we almost always want to autoFill. The one instance where we do not auto-fill is when we ignore 0s in the hour field.\n * @returns {TimeFieldState} - A new TimeFieldState based on the updated segment and the current state.\n */\nconst createTimeFieldStateFromUpdatedSegment = (\n currentState: TimeFieldState,\n updatedSegmentType: EditableTimeSegmentType,\n updatedSegment: TimeSegmentState,\n autoAdvance = true,\n autoFill = true\n): TimeFieldState => {\n let updatedSegments = createTimeSegmentStates(\n currentState.segments,\n currentState.orderedSegments,\n updatedSegmentType,\n updatedSegment,\n autoAdvance,\n autoFill\n );\n // If updatedSegmentType is not hour, then set isAutoFilled to false for all segments.\n // The use case that this covers is this:\n // Type in hour, this auto-fills which sets all the segments to isAutoFilled: true, then we render the aria-live.\n // Now go to change the AM field. This sets isAutoFilled: false for that segment, but we do not want to update\n // aria-live to a new time, so at this point we set isAutoFilled to false for all the other segments\n // which will cause aria-live to be cleared. This is why we have this here.\n if (!(updatedSegmentType === 'hour')) {\n updatedSegments = updatedSegments.map((seg) => {\n return { ...seg, isAutoFilled: false };\n });\n }\n return createTimeFieldStateFromUpdatedSegments(\n currentState,\n updatedSegments,\n currentState.isTimeSelected\n );\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, isAutoFilled: false };\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: Extract<TimeReducerAction, { actionType: 'updateSegment' }>\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 // minute, second, millisecond always have leading zeros, but hour might not.\n const hasLeadingZeros = segmentState.hasLeadingZeros ?? minValue === 0;\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 // 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 let 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 // do the opposite of padStart by removing the leading zero if it is complete.\n if (\n hasLeadingZeros === false &&\n segmentType === 'hour' &&\n isComplete &&\n finalValStr.startsWith('0')\n ) {\n finalValStr = finalValStr.substring(1);\n }\n return {\n ...segmentState,\n 'aria-valuetext': finalValStr,\n 'aria-valuenow': finalVal,\n digitCount,\n text: finalValStr,\n isComplete,\n isAutoFilled: false\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 if it has a value.\n * @param segments\n * @returns The updated segments where if isSelected was true and it has a value, isComplete is now also true.\n */\nconst markSelectedSegmentComplete = (segments: TimeSegmentState[]) => {\n return segments.map((seg) =>\n seg.isSelected && seg['aria-valuenow'] !== undefined\n ? { ...seg, isComplete: true, digitCount: 0 }\n : 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. This is the case for the 'selectNext' action.\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 doAutoFill = checkHourSelected\n ? hourSegment?.isSelected && hourSegment?.text !== undefined\n : hourSegment?.text !== undefined;\n const updatedSegments = doAutoFill ? autoFillEmptyNonHourSegments(segments) : segments;\n return updatedSegments;\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 createTimeFieldStateFromUpdatedSegments(\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 createTimeFieldStateFromUpdatedSegments = (\n currentState: TimeFieldState,\n updatedSegments: TimeSegmentState[],\n isTimeSelected: boolean\n) => {\n const orderedSegmentsFromCurrentState = getOrderedSegmentsFromState(currentState);\n const timeBeforeUpdate = currentState.currentTime;\n const timeAfterUpdate = createTimeFromSegments(updatedSegments);\n let useUpdatedValue = true;\n // if either one of these is undefined, then go ahead and update the value\n if (timeBeforeUpdate !== undefined && timeAfterUpdate !== undefined) {\n // Handle the case where the user has not updated the value, but the value we create from the segments is different only because\n // the new time represents the time with the segments shown. We do not want to update the time in this case.\n // Example, initial time value is {hour: 1, minute: 29, second: 66, millisecond: 888}, and granularity='minute', so orderedSegments is ['hour', 'minute'].\n // The updated time will be {hour:1, minute: 29}. In this case the user hasn't change the time. It's only different because of the segments, so we leave the initial time.\n const hasExtraSegments = hasSegmentsNotDisplayed(\n orderedSegmentsFromCurrentState,\n timeBeforeUpdate\n );\n if (hasExtraSegments) {\n useUpdatedValue = displayedTimeSegmentsAreDifferent(\n orderedSegmentsFromCurrentState,\n timeBeforeUpdate,\n timeAfterUpdate\n );\n }\n }\n\n // If any of the segments have isAutoFilled set to true, then set the state isTimeAutoFilled.\n const isAnySegmentAutoFilled = updatedSegments.some((seg) => seg.isAutoFilled === true);\n\n return {\n isCommitting: currentState.isCommitting,\n currentTime: useUpdatedValue ? timeAfterUpdate : timeBeforeUpdate,\n isTimeAutoFilled: isAnySegmentAutoFilled,\n isCompleteTime: isTimeComplete(updatedSegments),\n isTimeSelected,\n isPartialTime: isPartialTime(updatedSegments),\n orderedSegments: orderedSegmentsFromCurrentState,\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 {DirectionType} 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: DirectionType\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: DirectionType,\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: DirectionType,\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, Home, or End.\n */\nconst createSegmentFromKeyboardAction = (\n segmentType: EditableTimeSegmentType,\n newVal: number,\n segmentState: TimeSegmentState\n) => {\n // Only the hour12 segment has aria-valuemin to be 1. All the other segments' aria-valuemin is 0.\n // Most locales that have hour12 by default also do not pad zero so this is why it is the default.\n const padZero = segmentState.hasLeadingZeros ?? segmentState['aria-valuemin'] === 0;\n const ariaValueText = getAriaValueText(newVal, segmentState, segmentType, padZero);\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 isAutoFilled: false\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: DirectionType\n) => {\n // aria-valuemin is 0 for all segments except the 12-hour hour segment, where it is 1.\n // The Redwood design states that when you step or page up or down when there is no initial value in the segment,\n // it initializes the hour segment to 12, and auto-fills any empty segments for a 12-hour clock,\n // and it initializes the hour segment to 0, and auto-fills any empty segments for a 24-hour clock.\n // To get the initial value, we use the aria-valuemin for all segments (which is 0) except for the 12-hour hour segment.\n // For the 12-hour segment stepping or paging 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 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 { TimeReducerAction, DirectionType };\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 */\nimport { stringToNumber } from './timeReducer';\nimport {\n AM_VALUE,\n getDayPeriodValueFromHour,\n getDayPeriodValueStr,\n getHourValueStr,\n padWithZero,\n PM_VALUE,\n getAmPmStringsForLocale\n} from '#utils/UNSAFE_timeUtils';\nimport type {\n EditableTimeSegmentType,\n OrderedTimeSegmentsArray,\n Time,\n TimeGranularity,\n TimePlaceholders\n} from './types';\nimport type { BCP47Locale } from '#UNSAFE_IntlDateTime';\nimport { TimeSegment } from './TimeSegment';\nimport type { ComponentProps } from 'preact';\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\ntype TimeFieldState = {\n readonly isCommitting: boolean;\n readonly currentTime: Time | undefined;\n readonly isCompleteTime: boolean;\n /**\n * This will be true if any segment has isAutoFilled set to true.\n * This is used to figure out when to render an aria-live region with the full time so\n * a screen reader user will know the time has been auto-filled.\n */\n readonly isTimeAutoFilled: boolean;\n readonly isTimeSelected: boolean;\n readonly isPartialTime: boolean;\n /**\n * An array of the name of each segment type in the order they appear to the user.\n * E.g., ['hour', 'minute, 'dayPeriod'], when the InputTimeMask component shows the hour, minute, and dayPeriod segments in that order.\n * E.g., ['hour', 'minute', 'second'] when the InputTimeMask component shows the hour, minute, and second segments in that order.\n */\n readonly orderedSegments: OrderedTimeSegmentsArray;\n readonly segments: TimeSegmentState[];\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 * True if the segment has leading zeros. minute, second, millisecond always have leading zeros, but hour might not;\n * it is based on the locale, and can be overridden with the InputTimeMask's leadingZeroForHour api.\n * Most h23 clocks use a leading zero, and most h12 clocks do not.\n */\n hasLeadingZeros?: boolean;\n\n /**\n * True if the segment is auto-filled. If any segment has isAutoFilled set to true,\n * then the TimeFieldState's isTimeAutoFilled is set to true, and isTimeAutoFilled is\n * used to figure out when to render an aria-live region with the full time so\n * a screen reader user will know the time has been auto-filled.\n */\n isAutoFilled?: boolean;\n }\n>;\n\nconst MINUTE_SECOND_MAX = 59;\nconst MILLISECOND_MAX = 999;\n\n/**\n * Derives the initial state of a time field based on the provided properties.\n *\n * The initial state of the time field can be passed to the timeReducer when the component\n * mounts, and can also be used to reset the state when the value changes programmatically.\n *\n * @param props - An object containing the properties used to derive the initial state.\n * @param props.ariaLabels - An object containing aria labels for the time segments.\n * @param props.timeMasks - An array of time placeholders that define the format of the time.\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 props.currentValue The current value\n * @returns The initial state of the time field that can be passed to the timeReducer.\n **/\nconst getTimeFieldInitialState = (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 const,\n 'aria-label': ariaLabels.second,\n 'aria-valuemin': 0,\n 'aria-valuemax': MINUTE_SECOND_MAX,\n 'aria-valuenow': secondValue,\n 'aria-valuetext': secondValueStr,\n hasLeadingZeros: true,\n isComplete: secondValue !== undefined,\n isSelected: false,\n text: secondValueStr\n }\n ];\n\n const millisecondSeg = [\n {\n type: 'millisecond' as const,\n 'aria-label': ariaLabels.millisecond,\n 'aria-valuemin': 0,\n 'aria-valuemax': MILLISECOND_MAX,\n 'aria-valuenow': millisecondValue,\n 'aria-valuetext': millisecondValueStr,\n hasLeadingZeros: true,\n isComplete: millisecondValueStr !== undefined,\n isSelected: false,\n text: millisecondValueStr\n }\n ];\n\n const dayPeriodSeg = [\n {\n type: 'dayPeriod' as const,\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 const,\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 hasLeadingZeros: hasLeadingZeroForHour,\n isComplete: hourValue !== undefined,\n isSelected: false,\n text: hourValueStr\n },\n {\n type: 'minute' as const,\n 'aria-label': ariaLabels.minute,\n 'aria-valuemin': 0,\n 'aria-valuemax': MINUTE_SECOND_MAX,\n 'aria-valuenow': minuteValue,\n 'aria-valuetext': minuteValueStr,\n hasLeadingZeros: true,\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 isCommitting: false,\n currentTime: currentValue,\n isCompleteTime,\n isTimeAutoFilled: false,\n isTimeSelected: false,\n isPartialTime,\n orderedSegments,\n segments: editableSegments\n };\n return initialState;\n};\n\nexport { getTimeFieldInitialState };\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 { useMemo } from 'preact/hooks';\nimport type { BCP47Locale } from '#UNSAFE_IntlDateTime';\nimport { getAmPmStringsForLocale } from '#utils/UNSAFE_timeUtils';\n\nimport { useTranslationBundle } from '#hooks/UNSAFE_useTranslationBundle';\nimport type { BundleType } from '#resources/nls/bundle';\n\ntype Props = {\n locale: BCP47Locale;\n};\n\n/**\n * Hook to generate ARIA labels for time input fields based on the provided locale.\n *\n * @param {Props} props - Hook properties.\n * @param {BCP47Locale} props.locale - The locale to use for generating ARIA labels.\n *\n * @returns {Object} An object containing ARIA labels for hour, minute, second, millisecond, and day period.\n */\nconst useTimeAriaLabels = ({ locale }: Props) => {\n const { am, pm } = useMemo(() => {\n return getAmPmStringsForLocale(locale);\n }, [locale]);\n\n const translations = useTranslationBundle<BundleType>('@oracle/oraclejet-preact');\n const ariaLabels = {\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 return ariaLabels;\n};\n\nexport { useTimeAriaLabels };\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 { ComponentProps, RefObject, JSX } from 'preact';\nimport { useRef } from 'preact/hooks';\n\nimport type { UnpackSignals } from '@oracle/oraclejet-internal-utilities/attributeUtils';\nimport { merge } from '@oracle/oraclejet-internal-utilities/stringUtils';\n\nimport { Flex } from '#UNSAFE_Flex';\nimport { HiddenAccessible } from '#UNSAFE_HiddenAccessible';\nimport { LiveRegion } from '#UNSAFE_LiveRegion';\nimport type { TextFieldInputVariantOptions } from '#UNSAFE_TextField/themes/TextFieldInputStyles.css';\nimport { TextFieldInputRedwoodTheme } from '#UNSAFE_TextField/themes/redwood/TextFieldInputTheme';\nimport { useComponentTheme } from '#hooks/UNSAFE_useComponentTheme';\nimport { useFormFieldContext } from '#hooks/UNSAFE_useFormFieldContext';\nimport { TestIdProps } from '#hooks/UNSAFE_useTestId';\nimport { useTranslationBundle } from '#hooks/UNSAFE_useTranslationBundle';\nimport { useUser } from '#hooks/UNSAFE_useUser';\nimport type { BundleType } from '#resources/nls/bundle';\nimport { isEmbeddedVariant } from '#utils/PRIVATE_formControlUtils';\nimport { classNames } from '#utils/UNSAFE_classNames';\nimport { formatTimeFromMasks } from '#utils/UNSAFE_timeUtils';\nimport { InputTimeMask } from './InputTimeMask';\nimport { LiteralSegment } from './LiteralSegment';\nimport { TimeSegment } from './TimeSegment';\nimport type { EditableTimeSegmentType, TimePlaceholders } from './types';\nimport { useTimeFieldHandlers } from './useTimeFieldHandlers';\nimport { TimeFieldState, TimeSegmentState } from './getTimeFieldInitialState';\nimport { useTimeReset } from './useTimeReset';\nimport type { TimeReducerAction } from './timeReducer';\nimport type { Dispatch } from 'preact/hooks';\nimport { useTimeFieldCommitInput } from './useTimeFieldCommitInput';\n\ntype InputTimeMaskProps = ComponentProps<typeof InputTimeMask>;\n\ntype AriaProps = Pick<\n UnpackSignals<JSX.AriaAttributes>,\n 'aria-describedby' | 'aria-invalid' | 'aria-label' | 'aria-labelledby'\n>;\n\ntype HTMLElementProps = Pick<UnpackSignals<JSX.HTMLAttributes<HTMLElement>>, 'onBlur' | 'onFocus'>;\n\nexport type Props = AriaProps &\n TestIdProps &\n HTMLElementProps & {\n /**\n * A base id prefix.\n */\n baseId: string;\n\n /**\n * The reducer's dispatch function. The dispatch function lets you update the state to a different value and trigger a re-render.\n */\n dispatch: Dispatch<TimeReducerAction>;\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 * The state for the TimeField.\n */\n state: TimeFieldState;\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 dispatch,\n fieldRef,\n granularity = 'minute',\n hasLeadingZeroForHour,\n hasInsideLabel,\n isRequired,\n masks: timeMasks,\n onBlur,\n onCommit,\n onFocus,\n onInput,\n state,\n testId,\n textAlign,\n value,\n variant = 'default'\n}: Props) => {\n const { direction, locale } = useUser();\n\n const translations = useTranslationBundle<BundleType>('@oracle/oraclejet-preact');\n const announceTimeCleared = translations.inputTimeMask_time_cleared();\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: isEmbeddedVariant(variant) ? 'embedded' : 'default',\n textarea: 'notTextArea',\n input: 'notInput',\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 { 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\n const { timeFieldHandlers, timeClearedRef, segmentHandlers, tabIndex } = useTimeFieldHandlers({\n direction,\n dispatch,\n groupRef,\n isDisabled,\n isInputFocused,\n state\n });\n\n const { timeResetRef } = useTimeReset({\n dispatch,\n granularity,\n hasLeadingZeroForHour,\n locale,\n state,\n timeMasks,\n value\n });\n\n useTimeFieldCommitInput({\n timeResetRef,\n dispatch,\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 announceTimeClearedText = timeClearedRef.current ? announceTimeCleared : '';\n const announceAutoFilledTime = state.isTimeAutoFilled ? formattedTimeStr : '';\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} height=\"100%\" align=\"center\">\n {timeMasks.map(({ type, value: placeholder }) => {\n if (type === 'literal') {\n return (\n <LiteralSegment\n isHidden={isHidden}\n isHighlighted={isTimeSelected}\n isPlaceholder={!isPartialTime}\n text={placeholder}></LiteralSegment>\n );\n } else if (segmentsMap[type] !== undefined) {\n const segmentProps = segmentsMap[type];\n\n return (\n <TimeSegment\n inputRef={type === firstSegmentType ? fieldRef : undefined}\n isDisabled={isDisabled}\n isFieldFocused={isFocused}\n isInvalid={!!ariaInvalid}\n isHidden={isHidden}\n isHighlighted={isTimeSelected}\n isRequired={isRequired}\n placeholder={placeholder}\n {...segmentHandlers}\n {...segmentProps}></TimeSegment>\n );\n }\n return null;\n })}\n </Flex>\n {formattedTimeAria}\n {!isDisabled && <LiveRegion>{announceTimeClearedText}</LiveRegion>}\n {!isDisabled && (\n <LiveRegion testId={testId ? testId + '_autoFilledTime' : undefined}>\n {announceAutoFilledTime}\n </LiveRegion>\n )}\n </div>\n );\n};\n\nexport { findSegment, TimeField };\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 { TimeField } from './TimeField';\nimport type { Time, TimeGranularity, TimePlaceholders } from './types';\nimport { useRef } from 'preact/hooks';\nimport type { Dispatch } from 'preact/hooks';\nimport { timesAreDifferent } from '#utils/UNSAFE_timeUtils';\nimport { getTimeFieldInitialState } from './getTimeFieldInitialState';\nimport type { TimeFieldState } from './getTimeFieldInitialState';\nimport type { TimeReducerAction } from './timeReducer';\nimport type { BCP47Locale } from '#UNSAFE_IntlDateTime';\nimport { useTimeAriaLabels } from './useTimeAriaLabels';\n\ntype TimeFieldType = ComponentProps<typeof TimeField>;\n\ntype UseTimeResetProps = {\n dispatch: Dispatch<TimeReducerAction>;\n granularity: TimeGranularity;\n hasLeadingZeroForHour: boolean;\n locale: BCP47Locale;\n state: TimeFieldState;\n timeMasks: TimePlaceholders;\n value: TimeFieldType['value'];\n};\n\n/**\n * Hook that creates and updates a timeResetRef.\n * The timeResetRef is used to track whether the time value has been reset programmatically.\n *\n * When a programmatic update is detected, the hook dispatches a 'reset' action to update\n * the reducer state with a new initial state using the new currentValue.\n * After dispatching the 'reset' action,\n * timeResetRef.current is set to true to indicate that the time value has been reset\n * programmatically.\n *\n */\nconst useTimeReset = ({\n dispatch,\n granularity,\n hasLeadingZeroForHour,\n locale,\n state,\n timeMasks,\n value: currentValue\n}: UseTimeResetProps) => {\n const ariaLabels = useTimeAriaLabels({ locale });\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 = getTimeFieldInitialState({\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 };\n};\n\nexport { useTimeReset };\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 { ComponentProps } from 'preact';\nimport { useCallback, useLayoutEffect, useRef } from 'preact/hooks';\nimport type { Dispatch, MutableRef } from 'preact/hooks';\nimport type { TimeReducerAction } from './timeReducer';\nimport type { TimeFieldState } from './getTimeFieldInitialState';\nimport type { Time } from './types';\nimport type { InputTimeMask } from './InputTimeMask';\nimport { timesAreDifferent } from '#utils/UNSAFE_timeUtils';\n\ntype InputTimeMaskProps = ComponentProps<typeof InputTimeMask>;\n\ntype Props = {\n timeResetRef: MutableRef<boolean>;\n dispatch: Dispatch<TimeReducerAction>;\n onCommit: InputTimeMaskProps['onCommit'];\n onInput: InputTimeMaskProps['onInput'];\n state: TimeFieldState;\n value?: Time;\n};\n\n/**\n * A hook that manages the onInput and onCommit in a useLayoutEffect. The reason for the\n * useLayoutEffect is we do not want to call onInput or onCommit during the render cycle.\n *\n * The timeResetRef is used to track whether the time value has been programmatically changed\n * (i.e., reset) from outside the component.\n *\n * When timeResetRef.current is true, it indicates that the time value has been reset, and the hook\n * uptimes the lastTimeRef an the lastCommittedTimeRef to the new value.\n * The hook checks timeResetRef.current to be false before calling onInput. This prevents onInput\n * from being called when the time value is reset programmatically. Then timeResetRef.current is set to false.\n *\n * timeResetRef.current is set to true in useTimeFieldState.\n */\nconst useTimeFieldCommitInput = ({\n timeResetRef,\n dispatch,\n onCommit,\n onInput,\n state,\n value: currentValue\n}: Props) => {\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 // If the value was programmatically changed, then uptime the\n // last changed and last committed time 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 // Call onCommit, only if the value is different.\n const doCommitIfNeeded = useCallback(() => {\n if (timesAreDifferent(lastCommittedTimeRef.current, state.currentTime)) {\n onCommit?.({ value: state.currentTime });\n lastCommittedTimeRef.current = state.currentTime;\n }\n }, [onCommit, state.currentTime]);\n\n // If you try to call onInput from onChange directly it doesn't work. The value of\n // state.currentTime is from the current render, not the render *after* the dispatch.\n // So wait for the state to finish updating.\n useLayoutEffect(() => {\n // do not call onInput if the time has been reset programmatically\n if (timesAreDifferent(lastTimeRef.current, state.currentTime) && !timeResetRef.current) {\n const frozenTime =\n state.currentTime !== undefined\n ? Object.freeze({ ...state.currentTime })\n : state.currentTime;\n onInput({ value: frozenTime });\n lastTimeRef.current = frozenTime;\n }\n timeResetRef.current = false;\n }, [onInput, state.currentTime, timeResetRef]);\n\n // Check state.isCommitting which is set when we are done updating the state's value\n // on Enter or Blur and ready to call onCommit. We do not want to call onCommit during render,\n // so we use useLayoutEffect. useEffect might trigger this issue - JET-73689 oj-c-input-time-picker onValueChange triggered after button submit function.\n useLayoutEffect(() => {\n if (state.isCommitting) {\n doCommitIfNeeded();\n // This will uptime the state.isCommitting to false.\n dispatch({ actionType: 'committed' });\n }\n }, [dispatch, doCommitIfNeeded, state.isCommitting]);\n\n return;\n};\n\nexport { useTimeFieldCommitInput };\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 { ComponentProps, ContextType, Ref, RefObject, JSX } from 'preact';\nimport { forwardRef } from 'preact/compat';\nimport { useCallback, useImperativeHandle, useMemo, useRef } from 'preact/hooks';\n\nimport type { UnpackSignals } from '@oracle/oraclejet-internal-utilities/attributeUtils';\n\nimport { Label } from '#UNSAFE_Label';\nimport { ReadonlyTextField, ReadonlyTextFieldInput, TextField } from '#UNSAFE_TextField';\nimport { TextFieldContent } from '#UNSAFE_TextField/TextFieldContent';\nimport {\n CompactUserAssistance,\n InlineUserAssistance,\n type UserAssistanceDensityType\n} from '#UNSAFE_UserAssistance';\nimport { useFocusableTextField, type FocusableHandle } from '#hooks/UNSAFE_useFocusableTextField';\nimport { useFormContext } from '#hooks/UNSAFE_useFormContext';\nimport { FormFieldContext } from '#hooks/UNSAFE_useFormFieldContext';\nimport type { FormVariantContext } from '#hooks/UNSAFE_useFormVariantContext';\nimport type { TestIdProps } from '#hooks/UNSAFE_useTestId';\nimport { useTextField } from '#hooks/UNSAFE_useTextField';\nimport { useUser } from '#hooks/UNSAFE_useUser';\nimport type { TextProps } from '#utils/UNSAFE_interpolations/text';\nimport type { Size } from '#utils/UNSAFE_size';\nimport type { LayoutColumnSpan } from '#utils/UNSAFE_styles/Layout';\nimport {\n formatTimeFromMasks,\n getLeadingZeroForHour,\n getTimeMasksFromLocaleAndOptions,\n replaceCustomMasksValuesWithPlaceholders\n} from '#utils/UNSAFE_timeUtils';\nimport type { ValueUpdateDetail } from '#utils/UNSAFE_valueUpdateDetail';\nimport { TimeField } from './TimeField';\nimport type { Time, TimePlaceholders } from './types';\nimport { useTimeFieldState } from './useTimeFieldState';\nimport { mergeProps } from '#utils/UNSAFE_mergeProps';\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'?: UnpackSignals<JSX.AriaAttributes>['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 hide a leading zero in the hour field when the hour is 1-digit, or whether to determine the leading zero by the user's locale.\n * By default, this is determined by the user's locale.\n */\n leadingZeroForHour?: 'show' | 'hide' | 'fromLocale';\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 12-hour clock with a day period or a 24-hour clock.\n * If set to 'fromLocale', the hour clock is determined by the user's locale, unless the masks property is also specified,\n * in which case the hour clock is 12 if the masks property has a dayPeriod (e.g., AM/PM) or 24 if the masks property does not have a dayPeriod.\n */\n hourClock?: '12' | '24' | 'fromLocale';\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 hourClock property is set to '24', an error is thrown\n * because these property values conflict.\n * If the DayPeriodPlaceholder is not in the masks, and the hourClock property is set to '12', 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?: ContextType<typeof FormVariantContext>;\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 hourClock = 'fromLocale',\n isDisabled: propIsDisabled,\n isReadonly: propIsReadonly,\n isRequired,\n isRequiredShown,\n label,\n labelEdge: propLabelEdge,\n labelStartWidth: propLabelStartWidth,\n leadingZeroForHour = 'fromLocale',\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 // JET-72775 - Form control alignment in tables\n // default to 'start' if no text align is set\n const textAlign = propTextAlign ?? formTextAlign ?? 'start';\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, onBlur: inputPropsOnBlur, ...timeFieldProps } = inputProps;\n\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 labelText: labelEdge === 'inside' && !isDisabled ? label : 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 ? (\n // save space for user assistance if density is 'efficient', even though we don't\n // render user assistance for disabled fields\n userAssistanceDensity !== 'efficient' ? undefined : (\n <InlineUserAssistance\n userAssistanceDensity={userAssistanceDensity}\n {...userAssistanceProps}\n />\n )\n ) : isReadonly ? (\n <InlineUserAssistance\n fieldLabel={label}\n messages={messages}\n userAssistanceDensity={userAssistanceDensity}\n {...userAssistanceProps}\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, hourClock);\n\n // hour12 is true or false or undefined in TimeField because it is passed directly to Intl.DateTimeFormat and this is the api for that.\n let hour12: boolean | undefined;\n if (masks !== undefined && hourClock === 'fromLocale') {\n // If we have masks and the hourClock is set to 'fromLocale' which is the default as well, then we look at the masks\n // to set what hour12 we want to pass on to TimeField. If masks include a dayPeriod, then hour12 is true.\n const hasDayPeriod = masks.find((part) => part.type === 'dayPeriod') !== undefined;\n hour12 = hasDayPeriod;\n } else {\n hour12 = hourClock === '12' ? true : hourClock === '24' ? false : undefined;\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 hourClock. 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, hour12);\n\n return placeholderMasks;\n }, [granularity, hour12, 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 resolvedHasLeadingZeroForHour =\n leadingZeroForHour === 'fromLocale'\n ? getLeadingZeroForHour(locale)\n : leadingZeroForHour === 'show';\n\n const { state, dispatch } = useTimeFieldState({\n granularity,\n hasLeadingZeroForHour: resolvedHasLeadingZeroForHour,\n locale,\n timeMasks,\n value\n });\n\n // JET-73689: When we get onFocusOut on the time field, we delegate isCommitting to TimeField.\n // We do not want to commit if we are simply moving between segments.\n const onTimeFieldFocusOut = useCallback(\n (event: FocusEvent) => {\n !(event.currentTarget as HTMLElement).contains(event.relatedTarget as HTMLElement) &&\n dispatch({ actionType: 'commitOnBlur' }); // sets 'isCommitting' state. This might update the state, so we need to wait before calling onCommit.\n },\n [dispatch]\n );\n\n // merge the time field's onblurs.\n const { onBlur: handleTimeFieldBlur } = useMemo(() => {\n return mergeProps({ onBlur: onTimeFieldFocusOut }, { onBlur: inputPropsOnBlur });\n }, [inputPropsOnBlur, onTimeFieldFocusOut]);\n\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 resolvedHasLeadingZeroForHour\n )\n }\n hasEmptyLabel={label === '' && labelEdge === 'none'}\n hasInsideLabel={hasInsideLabel}\n onBlur={inputProps.onBlur}\n onFocus={inputProps.onFocus}\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 dispatch={dispatch}\n fieldRef={enabledElementRef}\n granularity={granularity}\n hasInsideLabel={labelComp !== undefined && labelEdge === 'inside'}\n hasLeadingZeroForHour={resolvedHasLeadingZeroForHour}\n isRequired={isRequired}\n masks={timeMasks}\n onBlur={handleTimeFieldBlur}\n onCommit={onCommit}\n onInput={onInput}\n state={state}\n testId={testId ? testId + '_timeField' : undefined}\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 'hourClock' are provided, it ensures that the 'hourClock' 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 hourClock\n * @throws if there is a conflict between masks and the granularity and hourClock properties.\n */\nconst validateTimeMasksAgainstProperties = (\n masks: TimePlaceholders | undefined,\n granularity: 'minute' | 'second' | 'millisecond',\n hourClock?: '12' | '24' | 'fromLocale'\n) => {\n if (masks === undefined) {\n return;\n }\n // If the user passes in masks and hourClock, we look at masks to see what the hourClock should be.\n // If hourClock is passed in and it is different than what we expect, we throw an error.\n if (hourClock !== undefined && hourClock !== 'fromLocale') {\n const hasDayPeriod = masks.find((part) => part.type === 'dayPeriod') !== undefined;\n if (!hasDayPeriod && hourClock === '12') {\n throw new Error(\n `The masks object does not have a dayPeriod property. hourClock should be set to '24' to match masks.`\n );\n }\n if (hasDayPeriod && hourClock === '24') {\n throw new Error(\n `The masks object does have a dayPeriod property. hourClock should be set to '12' 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","/**\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 } from 'preact/hooks';\nimport type { BCP47Locale } from '#UNSAFE_IntlDateTime';\nimport { timeReducer } from './timeReducer';\n\nimport type { TimeGranularity, TimePlaceholders } from './types';\nimport { TimeField } from './TimeField';\nimport { getTimeFieldInitialState } from './getTimeFieldInitialState';\nimport { useTimeAriaLabels } from './useTimeAriaLabels';\n\ntype TimeFieldType = ComponentProps<typeof TimeField>;\n\ntype UseTimeFieldProps = {\n granularity: TimeGranularity;\n hasLeadingZeroForHour: boolean;\n locale: BCP47Locale;\n timeMasks: TimePlaceholders;\n value?: TimeFieldType['value'];\n};\n\n/**\n * Hook that initializes the time state by calling useReducer.\n * It returns a state and a dispatch method to request changes to that 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 {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' and a 'dispatch' function.\n */\nconst useTimeFieldState = ({\n granularity,\n hasLeadingZeroForHour,\n locale,\n timeMasks,\n value: currentValue\n}: UseTimeFieldProps) => {\n const ariaLabels = useTimeAriaLabels({ locale });\n\n const [state, dispatch] = useReducer(\n timeReducer,\n {\n ariaLabels,\n currentValue,\n hasLeadingZeroForHour,\n granularity,\n locale,\n timeMasks\n },\n getTimeFieldInitialState\n );\n\n return { dispatch, state };\n};\n\nexport { useTimeFieldState };\n"],"names":["LiteralSegment","isHidden","isHighlighted","isPlaceholder","text","isTextOnlyWhitespace","trim","spanClasses","classNames","segmentStyles","literalBase","placeholder","space","highlighted","hidden","notHidden","_jsx","class","children","isLetterOnlyString","input","test","getTextContentFilterOutAriaHidden","elem","getVisibleTextNodes","map","node","textContent","join","setVisibleText","newText","Array","from","childNodes","filter","nodeType","Node","ELEMENT_NODE","getAttribute","preventDefaultHandler","e","preventDefault","isIos","getClientHints","platform","TimeSegment","amPm","ariaLabel","ariaValueMax","ariaValueMin","ariaValueNow","ariaValueText","inputRef","isDisabled","isFieldFocused","isInvalid","isRequired","isSelected","onChange","type","hasDisplayValue","length","rootClasses","base","selected","accessibleTouchTarget","placeholderClasses","emptySegmentValueText","useTranslationBundle","formControl_empty_segment","sRef","useRef","segmentRef","onKeyDown","useCallback","event","key","isSelectAll","isBackspaceOrDelete","isNumberOnlyString","actionType","data","direction","stopPropagation","dayPeriodHandler","ref","compositionRef","updateDayPeriodSegmentState","value","toggleDayPeriodSegmentState","changeDayPeriodIfMatch","matchType","getAmPmMatchType","AM_VALUE","PM_VALUE","onBeforeInput","inputType","current","onInput","useDayPeriodInputHandlers","am","pm","useEffect","focus","valueText","undefined","toString","customDataAttribute","_jsxs","role","autocapitalize","autocorrect","contentEditable","enterkeyhint","inputMode","onCut","onPaste","spellcheck","tabIndex","useTimeFieldHandlers","dispatch","groupRef","isInputFocused","state","tabbableModeProps","tabbableModeIndex","useTabbableMode","anySegmentSelected","segments","some","segment","updatedTabIndex","timeClearedRef","currentTime","Object","keys","action","onClick","segmentType","target","selectAll","isGroupFocus","isCompleteTime","onDoubleClick","onDoubleTap","doubleTapHandlers","useDoubleTap","onSingleTap","isTimeSelected","stopImmediatePropagation","onPointerDown","recentPointerRef","pointerDownTimerRef","clearTimeout","setTimeout","lastInputFocusedRef","useInputMaskSelectFirstHandler","handlers","deviceType","isMobile","timeFieldHandlers","segmentHandlers","timeReducer","updatedSegments","selectFirst","clearTime","orderedSegments","createTimeFieldStateFromUpdatedSegments","updatedSegment","clearSegment","findSegment","createTimeFieldStateFromUpdatedSegment","completeAllSegmentsBasedOnHour","isCommitting","deselectAndComplete","goToEnd","goToHome","doStepOrPage","selectTime","completeAllEmptySegmentsWhenHourHasValue","updatedSelectedNextSegments","selectNext","selectPrevious","selectSegment","newValue","createSegmentFromKeyboardAction","segmentState","isComplete","digitCount","updateSegment","Error","find","isPartialTime","allSegments","seg","autoFillEmptyNonHourSegments","existingSegments","ariaValue","includes","isAutoFilled","currentState","updatedSegmentType","autoAdvance","autoFill","modifiedSegments","replaceTimeSegment","createTimeSegmentStates","actionText","maxValue","minValue","hasLeadingZeros","wasComplete","targetDigitCount","requestedValStr","slice","padStart","finalValStr","withinRange","stringToNumber","finalVal","val","maxVal","numberToString","isSegmentComplete","startsWith","substring","getSelectedSegmentIndex","sel","findIndex","markSelectedSegmentComplete","selectedIndex","checkHourSelected","hourSegment","dayPeriodSegment","hourSegmentState","clearDayPeriodSegmentWhenHourIsEmpty","orderedSegmentsFromCurrentState","getOrderedSegmentsFromState","timeBeforeUpdate","timeAfterUpdate","dayPeriodValue","hourSegmentValue","adjustedHour","getAdjustedH12ToH23","segmentValues","reduce","acc","entries","createTimeFromSegments","useUpdatedValue","hasSegmentsNotDisplayed","displayedTimeSegmentsAreDifferent","isAnySegmentAutoFilled","isTimeAutoFilled","every","adjustTimeSegment","step","min","max","range","newVal","padZero","getAriaValueText","getHomeSegmentValue","getEndSegmentValue","initialStarting","valueNow","currentValue","getPagedSegmentValue","getSteppedSegmentValue","amValue","pmValue","valStr","timeHour12","getTimeFieldInitialState","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","useTimeAriaLabels","useMemo","translations","formControl_hour","formControl_minute","formControl_second","formControl_millisecond","TimeField","describedBy","ariaInvalid","ariaLabelledBy","baseId","fieldRef","hasInsideLabel","masks","onBlur","onCommit","onFocus","testId","textAlign","variant","useUser","announceTimeCleared","inputTimeMask_time_cleared","isFocused","useFormFieldContext","hasValue","classes","useComponentTheme","TextFieldInputRedwoodTheme","styleVariant","isEmbeddedVariant","textarea","prefix","suffix","startContent","endContent","insideLabel","focused","disabled","compClasses","editableSegments","segmentsMap","timeResetRef","lastValueFromParentRef","timesAreDifferent","useTimeReset","lastTimeRef","lastCommittedTimeRef","doCommitIfNeeded","useLayoutEffect","frozenTime","freeze","useTimeFieldCommitInput","formattedTimeStr","formatTimeFromMasks","formattedTimeAriaId","formattedTimeAria","jsx","HiddenAccessible","id","ariaDescribedBy","merge","announceTimeClearedText","announceAutoFilledTime","firstSegmentType","jsxs","onFocusIn","onFocusOut","Flex","wrap","justify","height","align","segmentProps","LiveRegion","InputTimeMask","forwardRef","assistiveText","columnSpan","helpSourceLink","helpSourceText","hourClock","propIsDisabled","isReadonly","propIsReadonly","isRequiredShown","label","labelEdge","propLabelEdge","labelStartWidth","propLabelStartWidth","leadingZeroForHour","mainFieldRef","messages","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","inputPropsOnBlur","timeFieldProps","labelComp","Label","fieldLabelProps","labelText","inlineUserAssistance","InlineUserAssistance","fieldLabel","aRef","anchorRef","compactUserAssistance","CompactUserAssistance","hour12","validateTimeMasksAgainstProperties","replaceCustomMasksValuesWithPlaceholders","getTimeMasksFromLocaleAndOptions","resolvedHasLeadingZeroForHour","getLeadingZeroForHour","useReducer","useTimeFieldState","onTimeFieldFocusOut","currentTarget","contains","relatedTarget","handleTimeFieldBlur","mergeProps","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/LiteralSegment.tsx","../../src/UNSAFE_InputTimeMask/useDayPeriodInputHandlers.ts","../../src/UNSAFE_InputTimeMask/TimeSegment.tsx","../../src/UNSAFE_InputTimeMask/useTimeFieldHandlers.ts","../../src/PRIVATE_InputMaskCommon/useInputMaskSelectFirstHandler.ts","../../src/UNSAFE_InputTimeMask/timeReducer.ts","../../src/UNSAFE_InputTimeMask/getTimeFieldInitialState.ts","../../src/UNSAFE_InputTimeMask/useTimeAriaLabels.ts","../../src/UNSAFE_InputTimeMask/TimeField.tsx","../../src/UNSAFE_InputTimeMask/useTimeReset.ts","../../src/UNSAFE_InputTimeMask/useTimeFieldCommitInput.ts","../../src/UNSAFE_InputTimeMask/InputTimeMask.tsx","../../src/UNSAFE_InputTimeMask/useTimeFieldState.ts"],"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 { 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 * If text is only spaces, then the text is not rendered, and instead the space is rendered using css.\n * This is more consistent in all browsers than whitespace is.\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 or the space between the time and the dayPeriod, 8:00 AM.\n */\nexport const LiteralSegment = ({ isHidden, isHighlighted, isPlaceholder, text }: Props) => {\n const isTextOnlyWhitespace = text.trim() === '';\n const spanClasses = classNames([\n segmentStyles.literalBase,\n isPlaceholder && segmentStyles.placeholder,\n isTextOnlyWhitespace && segmentStyles.space,\n isHighlighted && segmentStyles.highlighted,\n isHidden ? segmentStyles.hidden : segmentStyles.notHidden\n ]);\n\n return (\n <span aria-hidden=\"true\" class={spanClasses}>\n {isTextOnlyWhitespace ? ' ' : text}\n </span>\n );\n};\n","import { useCallback, useRef } from 'preact/hooks';\nimport type { RefObject } from 'preact';\nimport { AM_VALUE, getAmPmMatchType, PM_VALUE } from '#utils/UNSAFE_timeUtils';\nimport type { AmPmLocalizedValues } from '#utils/UNSAFE_timeUtils';\nimport type { TimeReducerAction } from './timeReducer';\n\n// A hook that returns handlers for input events that spread on the day period segment so that the user\n// can type in a letter to toggle the day period (e.g., AM/PM).\nexport function useDayPeriodInputHandlers(\n amPm: AmPmLocalizedValues,\n ref: RefObject<HTMLDivElement>,\n onChange?: (action: TimeReducerAction) => void\n) {\n // Used to record the current state of the element in beforeinput so we can restore it in the `input` event below, for inputType 'insertCompositionText'.\n const compositionRef = useRef<string | null>(null);\n\n const updateDayPeriodSegmentState = useCallback(\n (value: number) => {\n onChange?.({\n actionType: 'updateDayPeriodSegment',\n data: { type: 'dayPeriod', 'aria-valuenow': value }\n });\n },\n [onChange]\n );\n\n // This is useful if the AM/PM strings start with the same\n // letter. In that case when we get a letter that matches\n // the start of both, we simply toggle the dayPeriod.\n const toggleDayPeriodSegmentState = useCallback(() => {\n onChange?.({\n actionType: 'step',\n data: { type: 'dayPeriod', direction: 'increase' }\n });\n }, [onChange]);\n\n const changeDayPeriodIfMatch = useCallback(\n (data: string | null) => {\n if (data !== null && data.trim() !== '' && isLetterOnlyString(data)) {\n // In most locales the first letter of the am/pm strings uniquely identifies am or pm.\n // In a couple locales, such as 'ms' (where am is represented 'PG' and pm as 'PTG'), the first letter may not be unique.\n // In this case we toggle the day period if matchType === 'both'.\n const matchType = getAmPmMatchType(amPm, data);\n if (matchType === 'am' || matchType === 'pm') {\n const value = matchType === 'am' ? AM_VALUE : PM_VALUE;\n\n updateDayPeriodSegmentState(value);\n } else if (matchType === 'both') {\n toggleDayPeriodSegmentState();\n }\n }\n },\n [amPm, toggleDayPeriodSegmentState, updateDayPeriodSegmentState]\n );\n\n // inputType 'insertText': Android Samsung, ios, Mac, Windows.\n // inputType 'insertCompositionText': Input Method Editor (IME), such as Pinyin for Chinese, and Android Google.\n // 'insertCompositionText' represents immediate text that is part of an ongoing composition, meaning the user has not yet finalized their input.\n const handleBeforeInput = useCallback(\n (e: InputEvent) => {\n e.preventDefault();\n switch (e.inputType) {\n case 'insertCompositionText':\n // insertCompositionText cannot be cancelled so preventDefault does not keep the user's input from showing in the field.\n // (https://www.w3.org/TR/input-events-2/).\n // To workaround this, record the current state of the element so we can restore it in the `input` event below.\n if (ref.current) {\n compositionRef.current = getTextContentFilterOutAriaHidden(ref.current);\n }\n break;\n default:\n // Android Google never gets here, so we need to change the dayPeriod in handleInput's insertCompositionText.\n changeDayPeriodIfMatch(e.data);\n break;\n }\n },\n [changeDayPeriodIfMatch, ref]\n );\n\n const handleInput = useCallback(\n (e: InputEvent) => {\n const { inputType, data } = e;\n switch (inputType) {\n // we handle the 'insertText' case entirely in handleBeforeInput, but since you cannot cancel 'insertCompositionText' events,\n // we have to do some work here.\n case 'insertCompositionText':\n // Reset the DOM to how it was in the beforeinput event.\n // If we don't do this the user will see what they typed in multi-byte text like Chinese.\n if (ref.current && compositionRef.current !== null) {\n setVisibleText(ref.current, compositionRef.current);\n }\n // Android Google gets here, so this is where we need to check day period.\n changeDayPeriodIfMatch(data);\n break;\n }\n },\n [changeDayPeriodIfMatch, ref]\n );\n\n // NOTE: I could not get oncompositionend to be called when using Chinese or Korean IME keyboard.\n\n return {\n onBeforeInput: handleBeforeInput,\n onInput: handleInput\n };\n}\n\nconst isLetterOnlyString = (input: string) => {\n // /u flag: This enables Unicode matching in Javascript regular expressions, allowing you to match Unicode characters properly,\n // including those outside of the ASCII range.\n // p{L}: This is a Unicode property escape, which matches any letter in any language, not just ASCII letters.\n // The L property refers to Letter characters, which includes\n // * Upper and lowercase letters in the Latin alphabet.\n // * Letters in non-Latin scripts (e.g., Cyrillic, Greek, Arabic, and also Chinese characters.)\n const isLetter = /^\\p{L}$/u.test(input);\n\n return isLetter;\n};\n\nconst getTextContentFilterOutAriaHidden = (elem: HTMLDivElement) => {\n const textContent = getVisibleTextNodes(elem)\n .map((node) => node.textContent)\n .join('');\n return textContent;\n};\n\nconst setVisibleText = (elem: HTMLDivElement, newText: string) => {\n // there is always only one visible text node for the AM/PM segment.\n getVisibleTextNodes(elem)[0].textContent = newText;\n};\n\nconst getVisibleTextNodes = (elem: HTMLDivElement) => {\n return Array.from(elem.childNodes).filter(\n (node) =>\n !(\n node.nodeType === Node.ELEMENT_NODE &&\n (node as HTMLElement).getAttribute('aria-hidden') === 'true'\n )\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, JSX } from 'preact';\nimport { useCallback, useEffect, useRef } from 'preact/hooks';\nimport type { UnpackSignals } from '@oracle/oraclejet-internal-utilities/attributeUtils';\nimport type { TimeReducerAction } from './timeReducer';\nimport type { EditableTimeSegmentType } from './types';\nimport { isBackspaceOrDelete, isSelectAll } 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 type { BundleType } from '#resources/nls/bundle';\nimport type { AmPmLocalizedValues } from '#utils/UNSAFE_timeUtils';\nimport { useDayPeriodInputHandlers } from './useDayPeriodInputHandlers';\n\ntype AriaProps = Pick<\n UnpackSignals<JSX.AriaAttributes>,\n 'aria-label' | 'aria-valuemax' | 'aria-valuemin' | 'aria-valuenow' | 'aria-valuetext'\n>;\n\ntype DayPeriodProps = {\n type: 'dayPeriod';\n /**\n * The am/pm localized values. This is used when the segment type is 'dayPeriod'\n * and is required.\n */\n amPm: AmPmLocalizedValues;\n};\n\ntype NonDayPeriodProps = {\n type: Exclude<EditableTimeSegmentType, 'dayPeriod'>;\n amPm?: never;\n};\n\ntype Props = AriaProps &\n (DayPeriodProps | NonDayPeriodProps) & {\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 field is in focused state.\n */\n isFieldFocused?: 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: TimeReducerAction) => 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 isFieldFocused,\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 isFieldFocused && segmentStyles.accessibleTouchTarget\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 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 // JET-73547: let Escape pass through in order to close a popup or dialog.\n event.key === 'Escape' ||\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 (type === 'dayPeriod') {\n // return and don't call preventDefault so that we can use input handlers for dayPeriod\n // that we get from useDayPeriodInputHandlers.\n // keydown does not work for Android (event.key is 'Unspecified') or IME (like Chinese), and input handlers work for everything.\n return;\n }\n event.preventDefault();\n event.stopPropagation();\n },\n [isDisabled, isHighlighted, onChange, type]\n );\n\n // Gets the input handlers that we need for the dayPeriod segment to allow typing letters to toggle.\n const dayPeriodHandler = useDayPeriodInputHandlers(\n amPm ?? { am: 'AM', pm: 'PM' },\n segmentRef,\n onChange\n );\n\n // Used to focus the segment when isSelected is true.\n useEffect(() => {\n if (isSelected) {\n segmentRef.current?.focus();\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 // Introduce a div wrapper around the contentEditable element to prevent it from grabbing focus.\n // https://stackoverflow.com/questions/34354085/clicking-outside-a-contenteditable-div-stills-give-focus-to-it\n // JET-64874: We change the segment's role to \"textbox\" on iOS to work around a VoiceOver bug, and when we do that\n // we need to add aria-multiline={false}\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-multiline={isIos() ? false : undefined}\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 {...(type === 'dayPeriod' ? dayPeriodHandler : {})}\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","/**\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, useRef } from 'preact/hooks';\nimport type { Dispatch } from 'preact/hooks';\nimport type { TimeReducerAction } from './timeReducer';\nimport type { TimeFieldState } from './getTimeFieldInitialState';\nimport type { EditableTimeSegmentType } from './types';\nimport { getClientHints } from '#utils/PRIVATE_clientHints';\nimport { isBackspaceOrDelete, isSelectAll } from '#utils/PRIVATE_keyboardUtils';\nimport { useDoubleTap } from '#hooks/UNSAFE_useDoubleTap';\nimport { useTabbableMode } from '#hooks/UNSAFE_useTabbableMode';\nimport { useInputMaskSelectFirstHandler } from '#PRIVATE_InputMaskCommon/useInputMaskSelectFirstHandler';\n\ntype Props = {\n direction: 'ltr' | 'rtl';\n dispatch: Dispatch<TimeReducerAction>;\n groupRef?: RefObject<HTMLDivElement>;\n isDisabled?: boolean;\n isInputFocused?: boolean;\n state: TimeFieldState;\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 for a TimeField.\n * This is extremely similar to useDateFieldHandler, and it shouldn't be too hard to share code.\n *\n * This hook creates a timeClearedRef. It is set to false by default and whenever the\n * currentTime has a value, including a partial value.\n * When the user's action is to clear the field, this hook dispatches the 'clearTime' action,\n * and sets timeClearedRef to true.\n * timeClearedRef is returned from the hook so that the aria-live DOM can be updated to say Time Cleared\n * or to clear this text.\n */\nconst useTimeFieldHandlers = ({\n direction,\n dispatch,\n groupRef,\n isDisabled,\n isInputFocused,\n state\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 whether the time was cleared.\n const timeClearedRef = useRef<boolean>(false);\n\n // The timeClearedRef.current is set to true when the user does a clear all.\n // We set it back to false whenever the currentTime has a value.\n if (state.currentTime != null && Object.keys(state.currentTime).length > 0) {\n timeClearedRef.current = false;\n }\n\n // Handle requested segment changes by calling the reducer dispatch function.\n const onChange = useCallback(\n (action: TimeReducerAction) => {\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 if (segmentType !== null) {\n dispatch({ actionType: 'selectSegment', data: { type: segmentType } });\n } else {\n dispatch({ actionType: 'selectFirst' });\n }\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.isCommitting = true.\n dispatch({ actionType: 'commitOnEnter' });\n event.preventDefault();\n event.stopPropagation();\n }\n },\n [direction, dispatch, selectAll, state.isTimeSelected]\n );\n\n const onPointerDown = useInputMaskSelectFirstHandler({ dispatch, isInputFocused });\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","// useInputFocusHandler.ts\nimport { useRef, useCallback } from 'preact/hooks';\nimport type { Dispatch } from 'preact/hooks';\n\ntype SelectFirstAction = { actionType: 'selectFirst' };\n\n/**\n * Hook that determines whether to dispatch a 'selectFirst' action when an input field receives focus.\n *\n * @param {Object} options\n * @param {Dispatch<A>} options.dispatch - Dispatch function for actions of type A that must contain {actionType: 'selectFirst'}.\n * @param {boolean} [options.isInputFocused] - Whether the input field is currently focused.\n * @returns {function} - An `onPointerDown` handler.\n */\nconst useInputMaskSelectFirstHandler = <A extends SelectFirstAction>({\n dispatch,\n isInputFocused\n}: {\n dispatch: Dispatch<A>;\n isInputFocused?: boolean;\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 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 text 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 const action: SelectFirstAction = { actionType: 'selectFirst' };\n dispatch(action as A); // safe because A must include SelectFirstAction\n }\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 if (isInputFocused !== lastInputFocusedRef.current) {\n recentPointerRef.current = false;\n lastInputFocusedRef.current = !!isInputFocused;\n }\n\n return onPointerDown;\n};\n\nexport { useInputMaskSelectFirstHandler };\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 './getTimeFieldInitialState';\nimport { OrderedTimeSegmentsArray, EditableTimeSegmentType } from './types';\nimport {\n displayedTimeSegmentsAreDifferent,\n hasSegmentsNotDisplayed\n} from '#utils/UNSAFE_timeUtils';\nimport { numberToString, stringToNumber, withinRange } from '#utils/PRIVATE_dayUtils/maskUtils';\n\ntype DirectionType = 'increase' | 'decrease';\n\ntype SegmentActionData = Pick<TimeSegmentState, 'type'>;\n\ntype DayPeriodSegmentActionData = SegmentActionData & {\n 'aria-valuenow'?: number;\n};\n\ntype PageStepActionData = SegmentActionData & {\n direction: DirectionType;\n};\n\ntype UpdateActionData = SegmentActionData & {\n text: string;\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 TimeReducerAction =\n | { actionType: 'clearTime'; data?: never }\n | { actionType: 'clearSegment'; data: SegmentActionData }\n | { actionType: 'commitOnBlur'; data?: never }\n | { actionType: 'commitOnEnter'; data?: never }\n | { actionType: 'committed'; data?: never }\n | { actionType: 'goToEnd'; data: SegmentActionData }\n | { actionType: 'goToHome'; data: SegmentActionData }\n | { actionType: 'page'; data: PageStepActionData }\n | { actionType: 'selectFirst'; data?: never }\n | { actionType: 'selectNext'; data?: never }\n | { actionType: 'selectPrevious'; data?: never }\n | { actionType: 'selectSegment'; data: SegmentActionData }\n | { actionType: 'selectTime'; data?: never }\n | { actionType: 'step'; data: PageStepActionData }\n | { actionType: 'updateDayPeriodSegment'; data: DayPeriodSegmentActionData }\n | { actionType: 'updateSegment'; data: UpdateActionData }\n | { actionType: 'reset'; data: TimeFieldState };\n\nconst AM_VALUE = 0;\nconst PM_VALUE = 12;\n\n/**\n * Reducer function for updating TimeFieldState per the specified TimeReducerAction.\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 // 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 createTimeFieldStateFromUpdatedSegments(state, updatedSegments, false);\n }\n case 'clearSegment': {\n const updatedSegment = clearSegment(findSegment(state.segments, action.data.type));\n return createTimeFieldStateFromUpdatedSegment(state, action.data.type, updatedSegment);\n }\n case 'commitOnEnter': {\n const updatedSegments = completeAllSegmentsBasedOnHour(state.segments);\n const newState = createTimeFieldStateFromUpdatedSegments(state, updatedSegments, false);\n return { ...newState, isCommitting: true };\n }\n case 'commitOnBlur': {\n let updatedSegments = completeAllSegmentsBasedOnHour(state.segments);\n updatedSegments = deselectAndComplete(updatedSegments);\n const newState = createTimeFieldStateFromUpdatedSegments(state, updatedSegments, false);\n return { ...newState, isCommitting: true };\n }\n case 'committed': {\n return { ...state, isCommitting: false };\n }\n case 'goToEnd': {\n const updatedSegment = goToEnd(\n action.data.type,\n findSegment(state.segments, action.data.type)\n );\n return createTimeFieldStateFromUpdatedSegment(state, action.data.type, updatedSegment, false);\n }\n case 'goToHome': {\n const updatedSegment = goToHome(\n action.data.type,\n findSegment(state.segments, action.data.type)\n );\n return createTimeFieldStateFromUpdatedSegment(state, action.data.type, updatedSegment, false);\n }\n case 'page': {\n const direction = action.data.direction;\n if (direction === undefined) return state;\n const updatedSegment = doStepOrPage(\n action.data.type,\n findSegment(state.segments, action.data.type),\n 'page',\n direction\n );\n return createTimeFieldStateFromUpdatedSegment(state, action.data.type, updatedSegment, false);\n }\n case 'selectTime': {\n return selectTime(state);\n }\n case 'selectFirst': {\n const updatedSegments = selectFirst(state.segments, state.orderedSegments);\n return createTimeFieldStateFromUpdatedSegments(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 createTimeFieldStateFromUpdatedSegments(state, updatedSelectedNextSegments, false);\n }\n case 'selectPrevious': {\n const updatedSegments = selectPrevious(state.segments, state.orderedSegments);\n return createTimeFieldStateFromUpdatedSegments(state, updatedSegments, false);\n }\n case 'selectSegment': {\n const updatedSegments = selectSegment(state.segments, action.data.type);\n return createTimeFieldStateFromUpdatedSegments(state, updatedSegments, false);\n }\n // Increments or decrements the current segment value.\n case 'step': {\n const direction = action.data.direction;\n if (direction === undefined) return state;\n const updatedSegment = doStepOrPage(\n action.data.type,\n findSegment(state.segments, action.data.type),\n 'step',\n direction\n );\n return createTimeFieldStateFromUpdatedSegment(state, action.data.type, updatedSegment, false);\n }\n case 'updateDayPeriodSegment': {\n if (action.data.type === '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 action.data.type,\n newValue,\n findSegment(state.segments, action.data.type)\n );\n return createTimeFieldStateFromUpdatedSegment(\n state,\n action.data.type,\n updatedSegment,\n false\n );\n }\n }\n return state;\n }\n case 'updateSegment': {\n const segmentState = findSegment(state.segments, action.data.type);\n // If hour is 1-12, ignore typing '0' under certain circumstances\n if (\n action.data?.text === '0' &&\n action.data.type === 'hour' &&\n segmentState['aria-valuemin'] === 1 &&\n (segmentState.isComplete || segmentState['aria-valuenow'] === undefined)\n ) {\n const updatedSegment = { ...segmentState, digitCount: 1 };\n return createTimeFieldStateFromUpdatedSegment(\n state,\n action.data.type,\n updatedSegment,\n false,\n false\n );\n }\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(action.data.type, segmentState, action);\n return createTimeFieldStateFromUpdatedSegment(state, action.data.type, updatedSegment);\n }\n default: {\n throw new Error('Unknown action type');\n }\n }\n};\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 currentState.orderedSegments. The orderedSegments is an array of the name of each segment type\n * in the order they appear to the user.\n * E.g., ['hour', 'minute, 'dayPeriod'], when the InputTimeMask component shows the hour, minute, and dayPeriod segments in that order.\n * E.g., ['hour', 'minute', 'second'] when the InputTimeMask component shows the hour, minute, and second segments in that order.\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 *\n * If the segment is complete, and autoAdvance is true, then the next segment will be selected.\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 * @param {boolean} autoFill - whether to automatically fill the next segments 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 autoFill: 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 && autoFill) {\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;\n let 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 ? {\n ...seg,\n 'aria-valuenow': ariaValue,\n text,\n isComplete: true,\n 'aria-valuetext': text,\n isAutoFilled: true\n }\n : seg;\n });\n return initializedSegments;\n};\n\n/**\n * Constructs a new TimeFieldState given an updated segment, which may affect other segments.\n * Called from actions like updateSegment, stepping/paging/home/end, clearing a segment.\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 * @param {boolean} autoFill - Whether to auto-fill to the next segments if the current hour segment is complete. Defaults to true\n * since we almost always want to autoFill. The one instance where we do not auto-fill is when we ignore 0s in the hour field.\n * @returns {TimeFieldState} - A new TimeFieldState based on the updated segment and the current state.\n */\nconst createTimeFieldStateFromUpdatedSegment = (\n currentState: TimeFieldState,\n updatedSegmentType: EditableTimeSegmentType,\n updatedSegment: TimeSegmentState,\n autoAdvance = true,\n autoFill = true\n): TimeFieldState => {\n let updatedSegments = createTimeSegmentStates(\n currentState.segments,\n currentState.orderedSegments,\n updatedSegmentType,\n updatedSegment,\n autoAdvance,\n autoFill\n );\n // If updatedSegmentType is not hour, then set isAutoFilled to false for all segments.\n // The use case that this covers is this:\n // Type in hour, this auto-fills which sets all the segments to isAutoFilled: true, then we render the aria-live.\n // Now go to change the AM field. This sets isAutoFilled: false for that segment, but we do not want to update\n // aria-live to a new time, so at this point we set isAutoFilled to false for all the other segments\n // which will cause aria-live to be cleared. This is why we have this here.\n if (!(updatedSegmentType === 'hour')) {\n updatedSegments = updatedSegments.map((seg) => {\n return { ...seg, isAutoFilled: false };\n });\n }\n return createTimeFieldStateFromUpdatedSegments(\n currentState,\n updatedSegments,\n currentState.isTimeSelected\n );\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, isAutoFilled: false };\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: Extract<TimeReducerAction, { actionType: 'updateSegment' }>\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 // minute, second, millisecond always have leading zeros, but hour might not.\n const hasLeadingZeros = segmentState.hasLeadingZeros ?? minValue === 0;\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 // 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 let 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 // do the opposite of padStart by removing the leading zero if it is complete.\n if (\n hasLeadingZeros === false &&\n segmentType === 'hour' &&\n isComplete &&\n finalValStr.startsWith('0')\n ) {\n finalValStr = finalValStr.substring(1);\n }\n return {\n ...segmentState,\n 'aria-valuetext': finalValStr,\n 'aria-valuenow': finalVal,\n digitCount,\n text: finalValStr,\n isComplete,\n isAutoFilled: false\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 if it has a value.\n * @param segments\n * @returns The updated segments where if isSelected was true and it has a value, isComplete is now also true.\n */\nconst markSelectedSegmentComplete = (segments: TimeSegmentState[]) => {\n return segments.map((seg) =>\n seg.isSelected && seg['aria-valuenow'] !== undefined\n ? { ...seg, isComplete: true, digitCount: 0 }\n : 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. This is the case for the 'selectNext' action.\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 doAutoFill = checkHourSelected\n ? hourSegment?.isSelected && hourSegment?.text !== undefined\n : hourSegment?.text !== undefined;\n const updatedSegments = doAutoFill ? autoFillEmptyNonHourSegments(segments) : segments;\n return updatedSegments;\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 createTimeFieldStateFromUpdatedSegments(\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 createTimeFieldStateFromUpdatedSegments = (\n currentState: TimeFieldState,\n updatedSegments: TimeSegmentState[],\n isTimeSelected: boolean\n) => {\n const orderedSegmentsFromCurrentState = getOrderedSegmentsFromState(currentState);\n const timeBeforeUpdate = currentState.currentTime;\n const timeAfterUpdate = createTimeFromSegments(updatedSegments);\n let useUpdatedValue = true;\n // if either one of these is undefined, then go ahead and update the value\n if (timeBeforeUpdate !== undefined && timeAfterUpdate !== undefined) {\n // Handle the case where the user has not updated the value, but the value we create from the segments is different only because\n // the new time represents the time with the segments shown. We do not want to update the time in this case.\n // Example, initial time value is {hour: 1, minute: 29, second: 66, millisecond: 888}, and granularity='minute', so orderedSegments is ['hour', 'minute'].\n // The updated time will be {hour:1, minute: 29}. In this case the user hasn't change the time. It's only different because of the segments, so we leave the initial time.\n const hasExtraSegments = hasSegmentsNotDisplayed(\n orderedSegmentsFromCurrentState,\n timeBeforeUpdate\n );\n if (hasExtraSegments) {\n useUpdatedValue = displayedTimeSegmentsAreDifferent(\n orderedSegmentsFromCurrentState,\n timeBeforeUpdate,\n timeAfterUpdate\n );\n }\n }\n\n // If any of the segments have isAutoFilled set to true, then set the state isTimeAutoFilled.\n const isAnySegmentAutoFilled = updatedSegments.some((seg) => seg.isAutoFilled === true);\n\n return {\n isCommitting: currentState.isCommitting,\n currentTime: useUpdatedValue ? timeAfterUpdate : timeBeforeUpdate,\n isTimeAutoFilled: isAnySegmentAutoFilled,\n isCompleteTime: isTimeComplete(updatedSegments),\n isTimeSelected,\n isPartialTime: isPartialTime(updatedSegments),\n orderedSegments: orderedSegmentsFromCurrentState,\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 {DirectionType} 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: DirectionType\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: DirectionType,\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: DirectionType,\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, Home, or End.\n */\nconst createSegmentFromKeyboardAction = (\n segmentType: EditableTimeSegmentType,\n newVal: number,\n segmentState: TimeSegmentState\n) => {\n // Only the hour12 segment has aria-valuemin to be 1. All the other segments' aria-valuemin is 0.\n // Most locales that have hour12 by default also do not pad zero so this is why it is the default.\n const padZero = segmentState.hasLeadingZeros ?? segmentState['aria-valuemin'] === 0;\n const ariaValueText = getAriaValueText(newVal, segmentState, segmentType, padZero);\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 isAutoFilled: false\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: DirectionType\n) => {\n // aria-valuemin is 0 for all segments except the 12-hour hour segment, where it is 1.\n // The Redwood design states that when you step or page up or down when there is no initial value in the segment,\n // it initializes the hour segment to 12, and auto-fills any empty segments for a 12-hour clock,\n // and it initializes the hour segment to 0, and auto-fills any empty segments for a 24-hour clock.\n // To get the initial value, we use the aria-valuemin for all segments (which is 0) except for the 12-hour hour segment.\n // For the 12-hour segment stepping or paging 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 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 { TimeReducerAction, DirectionType };\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 */\nimport { stringToNumber } from './timeReducer';\nimport {\n AM_VALUE,\n getDayPeriodValueFromHour,\n getDayPeriodValueStr,\n getHourValueStr,\n padWithZero,\n PM_VALUE,\n getAmPmStringsForLocale\n} from '#utils/UNSAFE_timeUtils';\nimport type {\n EditableTimeSegmentType,\n OrderedTimeSegmentsArray,\n Time,\n TimeGranularity,\n TimePlaceholders\n} from './types';\nimport type { BCP47Locale } from '#UNSAFE_IntlDateTime';\nimport { TimeSegment } from './TimeSegment';\nimport type { ComponentProps } from 'preact';\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\ntype TimeFieldState = {\n readonly isCommitting: boolean;\n readonly currentTime: Time | undefined;\n readonly isCompleteTime: boolean;\n /**\n * This will be true if any segment has isAutoFilled set to true.\n * This is used to figure out when to render an aria-live region with the full time so\n * a screen reader user will know the time has been auto-filled.\n */\n readonly isTimeAutoFilled: boolean;\n readonly isTimeSelected: boolean;\n readonly isPartialTime: boolean;\n /**\n * An array of the name of each segment type in the order they appear to the user.\n * E.g., ['hour', 'minute, 'dayPeriod'], when the InputTimeMask component shows the hour, minute, and dayPeriod segments in that order.\n * E.g., ['hour', 'minute', 'second'] when the InputTimeMask component shows the hour, minute, and second segments in that order.\n */\n readonly orderedSegments: OrderedTimeSegmentsArray;\n readonly segments: TimeSegmentState[];\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 * True if the segment has leading zeros. minute, second, millisecond always have leading zeros, but hour might not;\n * it is based on the locale, and can be overridden with the InputTimeMask's leadingZeroForHour api.\n * Most h23 clocks use a leading zero, and most h12 clocks do not.\n */\n hasLeadingZeros?: boolean;\n\n /**\n * True if the segment is auto-filled. If any segment has isAutoFilled set to true,\n * then the TimeFieldState's isTimeAutoFilled is set to true, and isTimeAutoFilled is\n * used to figure out when to render an aria-live region with the full time so\n * a screen reader user will know the time has been auto-filled.\n */\n isAutoFilled?: boolean;\n }\n>;\n\nconst MINUTE_SECOND_MAX = 59;\nconst MILLISECOND_MAX = 999;\n\n/**\n * Derives the initial state of a time field based on the provided properties.\n *\n * The initial state of the time field can be passed to the timeReducer when the component\n * mounts, and can also be used to reset the state when the value changes programmatically.\n *\n * @param props - An object containing the properties used to derive the initial state.\n * @param props.ariaLabels - An object containing aria labels for the time segments.\n * @param props.timeMasks - An array of time placeholders that define the format of the time.\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 props.currentValue The current value\n * @returns The initial state of the time field that can be passed to the timeReducer.\n **/\nconst getTimeFieldInitialState = (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 const,\n 'aria-label': ariaLabels.second,\n 'aria-valuemin': 0,\n 'aria-valuemax': MINUTE_SECOND_MAX,\n 'aria-valuenow': secondValue,\n 'aria-valuetext': secondValueStr,\n hasLeadingZeros: true,\n isComplete: secondValue !== undefined,\n isSelected: false,\n text: secondValueStr\n }\n ];\n\n const millisecondSeg = [\n {\n type: 'millisecond' as const,\n 'aria-label': ariaLabels.millisecond,\n 'aria-valuemin': 0,\n 'aria-valuemax': MILLISECOND_MAX,\n 'aria-valuenow': millisecondValue,\n 'aria-valuetext': millisecondValueStr,\n hasLeadingZeros: true,\n isComplete: millisecondValueStr !== undefined,\n isSelected: false,\n text: millisecondValueStr\n }\n ];\n\n const dayPeriodSeg = [\n {\n type: 'dayPeriod' as const,\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 const,\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 hasLeadingZeros: hasLeadingZeroForHour,\n isComplete: hourValue !== undefined,\n isSelected: false,\n text: hourValueStr\n },\n {\n type: 'minute' as const,\n 'aria-label': ariaLabels.minute,\n 'aria-valuemin': 0,\n 'aria-valuemax': MINUTE_SECOND_MAX,\n 'aria-valuenow': minuteValue,\n 'aria-valuetext': minuteValueStr,\n hasLeadingZeros: true,\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 isCommitting: false,\n currentTime: currentValue,\n isCompleteTime,\n isTimeAutoFilled: false,\n isTimeSelected: false,\n isPartialTime,\n orderedSegments,\n segments: editableSegments\n };\n return initialState;\n};\n\nexport { getTimeFieldInitialState };\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 { useMemo } from 'preact/hooks';\nimport type { BCP47Locale } from '#UNSAFE_IntlDateTime';\nimport { getAmPmStringsForLocale } from '#utils/UNSAFE_timeUtils';\n\nimport { useTranslationBundle } from '#hooks/UNSAFE_useTranslationBundle';\nimport type { BundleType } from '#resources/nls/bundle';\n\ntype Props = {\n locale: BCP47Locale;\n};\n\n/**\n * Hook to generate ARIA labels for time input fields based on the provided locale.\n *\n * @param {Props} props - Hook properties.\n * @param {BCP47Locale} props.locale - The locale to use for generating ARIA labels.\n *\n * @returns {Object} An object containing ARIA labels for hour, minute, second, millisecond, and day period.\n */\nconst useTimeAriaLabels = ({ locale }: Props) => {\n const { am, pm } = useMemo(() => {\n return getAmPmStringsForLocale(locale);\n }, [locale]);\n\n const translations = useTranslationBundle<BundleType>('@oracle/oraclejet-preact');\n const ariaLabels = {\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 return ariaLabels;\n};\n\nexport { useTimeAriaLabels };\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 { ComponentProps, RefObject, JSX } from 'preact';\nimport { useRef } from 'preact/hooks';\n\nimport type { UnpackSignals } from '@oracle/oraclejet-internal-utilities/attributeUtils';\nimport { merge } from '@oracle/oraclejet-internal-utilities/stringUtils';\n\nimport { Flex } from '#UNSAFE_Flex';\nimport { HiddenAccessible } from '#UNSAFE_HiddenAccessible';\nimport { LiveRegion } from '#UNSAFE_LiveRegion';\nimport type { TextFieldInputVariantOptions } from '#UNSAFE_TextField/themes/TextFieldInputStyles.css';\nimport { TextFieldInputRedwoodTheme } from '#UNSAFE_TextField/themes/redwood/TextFieldInputTheme';\nimport { useComponentTheme } from '#hooks/UNSAFE_useComponentTheme';\nimport { useFormFieldContext } from '#hooks/UNSAFE_useFormFieldContext';\nimport { TestIdProps } from '#hooks/UNSAFE_useTestId';\nimport { useTranslationBundle } from '#hooks/UNSAFE_useTranslationBundle';\nimport { useUser } from '#hooks/UNSAFE_useUser';\nimport type { BundleType } from '#resources/nls/bundle';\nimport { isEmbeddedVariant } from '#utils/PRIVATE_formControlUtils';\nimport { classNames } from '#utils/UNSAFE_classNames';\nimport { formatTimeFromMasks } from '#utils/UNSAFE_timeUtils';\nimport { InputTimeMask } from './InputTimeMask';\nimport { LiteralSegment } from './LiteralSegment';\nimport { TimeSegment } from './TimeSegment';\nimport type { EditableTimeSegmentType, TimePlaceholders } from './types';\nimport { useTimeFieldHandlers } from './useTimeFieldHandlers';\nimport { TimeFieldState, TimeSegmentState } from './getTimeFieldInitialState';\nimport { useTimeReset } from './useTimeReset';\nimport type { TimeReducerAction } from './timeReducer';\nimport type { Dispatch } from 'preact/hooks';\nimport { useTimeFieldCommitInput } from './useTimeFieldCommitInput';\n\ntype InputTimeMaskProps = ComponentProps<typeof InputTimeMask>;\n\ntype AriaProps = Pick<\n UnpackSignals<JSX.AriaAttributes>,\n 'aria-describedby' | 'aria-invalid' | 'aria-label' | 'aria-labelledby'\n>;\n\ntype HTMLElementProps = Pick<UnpackSignals<JSX.HTMLAttributes<HTMLElement>>, 'onBlur' | 'onFocus'>;\n\nexport type Props = AriaProps &\n TestIdProps &\n HTMLElementProps & {\n /**\n * A base id prefix.\n */\n baseId: string;\n\n /**\n * The reducer's dispatch function. The dispatch function lets you update the state to a different value and trigger a re-render.\n */\n dispatch: Dispatch<TimeReducerAction>;\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 * The state for the TimeField.\n */\n state: TimeFieldState;\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 dispatch,\n fieldRef,\n granularity = 'minute',\n hasLeadingZeroForHour,\n hasInsideLabel,\n isRequired,\n masks: timeMasks,\n onBlur,\n onCommit,\n onFocus,\n onInput,\n state,\n testId,\n textAlign,\n value,\n variant = 'default'\n}: Props) => {\n const { direction, locale } = useUser();\n\n const translations = useTranslationBundle<BundleType>('@oracle/oraclejet-preact');\n const announceTimeCleared = translations.inputTimeMask_time_cleared();\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: isEmbeddedVariant(variant) ? 'embedded' : 'default',\n textarea: 'notTextArea',\n input: 'notInput',\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 { 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\n const { timeFieldHandlers, timeClearedRef, segmentHandlers, tabIndex } = useTimeFieldHandlers({\n direction,\n dispatch,\n groupRef,\n isDisabled,\n isInputFocused,\n state\n });\n\n const { timeResetRef } = useTimeReset({\n dispatch,\n granularity,\n hasLeadingZeroForHour,\n locale,\n state,\n timeMasks,\n value\n });\n\n useTimeFieldCommitInput({\n timeResetRef,\n dispatch,\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 announceTimeClearedText = timeClearedRef.current ? announceTimeCleared : '';\n const announceAutoFilledTime = state.isTimeAutoFilled ? formattedTimeStr : '';\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} height=\"100%\" align=\"center\">\n {timeMasks.map(({ type, value: placeholder }) => {\n if (type === 'literal') {\n return (\n <LiteralSegment\n isHidden={isHidden}\n isHighlighted={isTimeSelected}\n isPlaceholder={!isPartialTime}\n text={placeholder}></LiteralSegment>\n );\n } else if (segmentsMap[type] !== undefined) {\n const segmentProps = segmentsMap[type];\n\n return (\n <TimeSegment\n inputRef={type === firstSegmentType ? fieldRef : undefined}\n isDisabled={isDisabled}\n isFieldFocused={isFocused}\n isInvalid={!!ariaInvalid}\n isHidden={isHidden}\n isHighlighted={isTimeSelected}\n isRequired={isRequired}\n placeholder={placeholder}\n {...segmentHandlers}\n {...segmentProps}></TimeSegment>\n );\n }\n return null;\n })}\n </Flex>\n {formattedTimeAria}\n {!isDisabled && <LiveRegion>{announceTimeClearedText}</LiveRegion>}\n {!isDisabled && (\n <LiveRegion testId={testId ? testId + '_autoFilledTime' : undefined}>\n {announceAutoFilledTime}\n </LiveRegion>\n )}\n </div>\n );\n};\n\nexport { findSegment, TimeField };\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 { TimeField } from './TimeField';\nimport type { Time, TimeGranularity, TimePlaceholders } from './types';\nimport { useRef } from 'preact/hooks';\nimport type { Dispatch } from 'preact/hooks';\nimport { timesAreDifferent } from '#utils/UNSAFE_timeUtils';\nimport { getTimeFieldInitialState } from './getTimeFieldInitialState';\nimport type { TimeFieldState } from './getTimeFieldInitialState';\nimport type { TimeReducerAction } from './timeReducer';\nimport type { BCP47Locale } from '#UNSAFE_IntlDateTime';\nimport { useTimeAriaLabels } from './useTimeAriaLabels';\n\ntype TimeFieldType = ComponentProps<typeof TimeField>;\n\ntype UseTimeResetProps = {\n dispatch: Dispatch<TimeReducerAction>;\n granularity: TimeGranularity;\n hasLeadingZeroForHour: boolean;\n locale: BCP47Locale;\n state: TimeFieldState;\n timeMasks: TimePlaceholders;\n value: TimeFieldType['value'];\n};\n\n/**\n * Hook that creates and updates a timeResetRef.\n * The timeResetRef is used to track whether the time value has been reset programmatically.\n *\n * When a programmatic update is detected, the hook dispatches a 'reset' action to update\n * the reducer state with a new initial state using the new currentValue.\n * After dispatching the 'reset' action,\n * timeResetRef.current is set to true to indicate that the time value has been reset\n * programmatically.\n *\n */\nconst useTimeReset = ({\n dispatch,\n granularity,\n hasLeadingZeroForHour,\n locale,\n state,\n timeMasks,\n value: currentValue\n}: UseTimeResetProps) => {\n const ariaLabels = useTimeAriaLabels({ locale });\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 = getTimeFieldInitialState({\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 };\n};\n\nexport { useTimeReset };\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 { ComponentProps } from 'preact';\nimport { useCallback, useLayoutEffect, useRef } from 'preact/hooks';\nimport type { Dispatch, MutableRef } from 'preact/hooks';\nimport type { TimeReducerAction } from './timeReducer';\nimport type { TimeFieldState } from './getTimeFieldInitialState';\nimport type { Time } from './types';\nimport type { InputTimeMask } from './InputTimeMask';\nimport { timesAreDifferent } from '#utils/UNSAFE_timeUtils';\n\ntype InputTimeMaskProps = ComponentProps<typeof InputTimeMask>;\n\ntype Props = {\n timeResetRef: MutableRef<boolean>;\n dispatch: Dispatch<TimeReducerAction>;\n onCommit: InputTimeMaskProps['onCommit'];\n onInput: InputTimeMaskProps['onInput'];\n state: TimeFieldState;\n value?: Time;\n};\n\n/**\n * A hook that manages the onInput and onCommit in a useLayoutEffect. The reason for the\n * useLayoutEffect is we do not want to call onInput or onCommit during the render cycle.\n *\n * The timeResetRef is used to track whether the time value has been programmatically changed\n * (i.e., reset) from outside the component.\n *\n * When timeResetRef.current is true, it indicates that the time value has been reset, and the hook\n * uptimes the lastTimeRef an the lastCommittedTimeRef to the new value.\n * The hook checks timeResetRef.current to be false before calling onInput. This prevents onInput\n * from being called when the time value is reset programmatically. Then timeResetRef.current is set to false.\n *\n * timeResetRef.current is set to true in useTimeFieldState.\n */\nconst useTimeFieldCommitInput = ({\n timeResetRef,\n dispatch,\n onCommit,\n onInput,\n state,\n value: currentValue\n}: Props) => {\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 // If the value was programmatically changed, then uptime the\n // last changed and last committed time 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 // Call onCommit, only if the value is different.\n const doCommitIfNeeded = useCallback(() => {\n if (timesAreDifferent(lastCommittedTimeRef.current, state.currentTime)) {\n onCommit?.({ value: state.currentTime });\n lastCommittedTimeRef.current = state.currentTime;\n }\n }, [onCommit, state.currentTime]);\n\n // If you try to call onInput from onChange directly it doesn't work. The value of\n // state.currentTime is from the current render, not the render *after* the dispatch.\n // So wait for the state to finish updating.\n useLayoutEffect(() => {\n // do not call onInput if the time has been reset programmatically\n if (timesAreDifferent(lastTimeRef.current, state.currentTime) && !timeResetRef.current) {\n const frozenTime =\n state.currentTime !== undefined\n ? Object.freeze({ ...state.currentTime })\n : state.currentTime;\n onInput({ value: frozenTime });\n lastTimeRef.current = frozenTime;\n }\n timeResetRef.current = false;\n }, [onInput, state.currentTime, timeResetRef]);\n\n // Check state.isCommitting which is set when we are done updating the state's value\n // on Enter or Blur and ready to call onCommit. We do not want to call onCommit during render,\n // so we use useLayoutEffect. useEffect might trigger this issue - JET-73689 oj-c-input-time-picker onValueChange triggered after button submit function.\n useLayoutEffect(() => {\n if (state.isCommitting) {\n doCommitIfNeeded();\n // This will uptime the state.isCommitting to false.\n dispatch({ actionType: 'committed' });\n }\n }, [dispatch, doCommitIfNeeded, state.isCommitting]);\n\n return;\n};\n\nexport { useTimeFieldCommitInput };\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 { ComponentProps, ContextType, Ref, RefObject, JSX } from 'preact';\nimport { forwardRef } from 'preact/compat';\nimport { useCallback, useImperativeHandle, useMemo, useRef } from 'preact/hooks';\n\nimport type { UnpackSignals } from '@oracle/oraclejet-internal-utilities/attributeUtils';\n\nimport { Label } from '#UNSAFE_Label';\nimport { ReadonlyTextField, ReadonlyTextFieldInput, TextField } from '#UNSAFE_TextField';\nimport { TextFieldContent } from '#UNSAFE_TextField/TextFieldContent';\nimport {\n CompactUserAssistance,\n InlineUserAssistance,\n type UserAssistanceDensityType\n} from '#UNSAFE_UserAssistance';\nimport { useFocusableTextField, type FocusableHandle } from '#hooks/UNSAFE_useFocusableTextField';\nimport { useFormContext } from '#hooks/UNSAFE_useFormContext';\nimport { FormFieldContext } from '#hooks/UNSAFE_useFormFieldContext';\nimport type { FormVariantContext } from '#hooks/UNSAFE_useFormVariantContext';\nimport type { TestIdProps } from '#hooks/UNSAFE_useTestId';\nimport { useTextField } from '#hooks/UNSAFE_useTextField';\nimport { useUser } from '#hooks/UNSAFE_useUser';\nimport type { TextProps } from '#utils/UNSAFE_interpolations/text';\nimport type { Size } from '#utils/UNSAFE_size';\nimport type { LayoutColumnSpan } from '#utils/UNSAFE_styles/Layout';\nimport {\n formatTimeFromMasks,\n getLeadingZeroForHour,\n getTimeMasksFromLocaleAndOptions,\n replaceCustomMasksValuesWithPlaceholders\n} from '#utils/UNSAFE_timeUtils';\nimport type { ValueUpdateDetail } from '#utils/UNSAFE_valueUpdateDetail';\nimport { TimeField } from './TimeField';\nimport type { Time, TimePlaceholders } from './types';\nimport { useTimeFieldState } from './useTimeFieldState';\nimport { mergeProps } from '#utils/UNSAFE_mergeProps';\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'?: UnpackSignals<JSX.AriaAttributes>['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 hide a leading zero in the hour field when the hour is 1-digit, or whether to determine the leading zero by the user's locale.\n * By default, this is determined by the user's locale.\n */\n leadingZeroForHour?: 'show' | 'hide' | 'fromLocale';\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 12-hour clock with a day period or a 24-hour clock.\n * If set to 'fromLocale', the hour clock is determined by the user's locale, unless the masks property is also specified,\n * in which case the hour clock is 12 if the masks property has a dayPeriod (e.g., AM/PM) or 24 if the masks property does not have a dayPeriod.\n */\n hourClock?: '12' | '24' | 'fromLocale';\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 hourClock property is set to '24', an error is thrown\n * because these property values conflict.\n * If the DayPeriodPlaceholder is not in the masks, and the hourClock property is set to '12', 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?: ContextType<typeof FormVariantContext>;\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 hourClock = 'fromLocale',\n isDisabled: propIsDisabled,\n isReadonly: propIsReadonly,\n isRequired,\n isRequiredShown,\n label,\n labelEdge: propLabelEdge,\n labelStartWidth: propLabelStartWidth,\n leadingZeroForHour = 'fromLocale',\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 // JET-72775 - Form control alignment in tables\n // default to 'start' if no text align is set\n const textAlign = propTextAlign ?? formTextAlign ?? 'start';\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, onBlur: inputPropsOnBlur, ...timeFieldProps } = inputProps;\n\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 labelText: labelEdge === 'inside' && !isDisabled ? label : 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 ? (\n // save space for user assistance if density is 'efficient', even though we don't\n // render user assistance for disabled fields\n userAssistanceDensity !== 'efficient' ? undefined : (\n <InlineUserAssistance\n userAssistanceDensity={userAssistanceDensity}\n {...userAssistanceProps}\n />\n )\n ) : isReadonly ? (\n <InlineUserAssistance\n fieldLabel={label}\n messages={messages}\n userAssistanceDensity={userAssistanceDensity}\n {...userAssistanceProps}\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, hourClock);\n\n // hour12 is true or false or undefined in TimeField because it is passed directly to Intl.DateTimeFormat and this is the api for that.\n let hour12: boolean | undefined;\n if (masks !== undefined && hourClock === 'fromLocale') {\n // If we have masks and the hourClock is set to 'fromLocale' which is the default as well, then we look at the masks\n // to set what hour12 we want to pass on to TimeField. If masks include a dayPeriod, then hour12 is true.\n const hasDayPeriod = masks.find((part) => part.type === 'dayPeriod') !== undefined;\n hour12 = hasDayPeriod;\n } else {\n hour12 = hourClock === '12' ? true : hourClock === '24' ? false : undefined;\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 hourClock. 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, hour12);\n\n return placeholderMasks;\n }, [granularity, hour12, 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 resolvedHasLeadingZeroForHour =\n leadingZeroForHour === 'fromLocale'\n ? getLeadingZeroForHour(locale)\n : leadingZeroForHour === 'show';\n\n const { state, dispatch } = useTimeFieldState({\n granularity,\n hasLeadingZeroForHour: resolvedHasLeadingZeroForHour,\n locale,\n timeMasks,\n value\n });\n\n // JET-73689: When we get onFocusOut on the time field, we delegate isCommitting to TimeField.\n // We do not want to commit if we are simply moving between segments.\n const onTimeFieldFocusOut = useCallback(\n (event: FocusEvent) => {\n !(event.currentTarget as HTMLElement).contains(event.relatedTarget as HTMLElement) &&\n dispatch({ actionType: 'commitOnBlur' }); // sets 'isCommitting' state. This might update the state, so we need to wait before calling onCommit.\n },\n [dispatch]\n );\n\n // merge the time field's onblurs.\n const { onBlur: handleTimeFieldBlur } = useMemo(() => {\n return mergeProps({ onBlur: onTimeFieldFocusOut }, { onBlur: inputPropsOnBlur });\n }, [inputPropsOnBlur, onTimeFieldFocusOut]);\n\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 resolvedHasLeadingZeroForHour\n )\n }\n hasEmptyLabel={label === '' && labelEdge === 'none'}\n hasInsideLabel={hasInsideLabel}\n onBlur={inputProps.onBlur}\n onFocus={inputProps.onFocus}\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 dispatch={dispatch}\n fieldRef={enabledElementRef}\n granularity={granularity}\n hasInsideLabel={labelComp !== undefined && labelEdge === 'inside'}\n hasLeadingZeroForHour={resolvedHasLeadingZeroForHour}\n isRequired={isRequired}\n masks={timeMasks}\n onBlur={handleTimeFieldBlur}\n onCommit={onCommit}\n onInput={onInput}\n state={state}\n testId={testId ? testId + '_timeField' : undefined}\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 'hourClock' are provided, it ensures that the 'hourClock' 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 hourClock\n * @throws if there is a conflict between masks and the granularity and hourClock properties.\n */\nconst validateTimeMasksAgainstProperties = (\n masks: TimePlaceholders | undefined,\n granularity: 'minute' | 'second' | 'millisecond',\n hourClock?: '12' | '24' | 'fromLocale'\n) => {\n if (masks === undefined) {\n return;\n }\n // If the user passes in masks and hourClock, we look at masks to see what the hourClock should be.\n // If hourClock is passed in and it is different than what we expect, we throw an error.\n if (hourClock !== undefined && hourClock !== 'fromLocale') {\n const hasDayPeriod = masks.find((part) => part.type === 'dayPeriod') !== undefined;\n if (!hasDayPeriod && hourClock === '12') {\n throw new Error(\n `The masks object does not have a dayPeriod property. hourClock should be set to '24' to match masks.`\n );\n }\n if (hasDayPeriod && hourClock === '24') {\n throw new Error(\n `The masks object does have a dayPeriod property. hourClock should be set to '12' 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","/**\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 } from 'preact/hooks';\nimport type { BCP47Locale } from '#UNSAFE_IntlDateTime';\nimport { timeReducer } from './timeReducer';\n\nimport type { TimeGranularity, TimePlaceholders } from './types';\nimport { TimeField } from './TimeField';\nimport { getTimeFieldInitialState } from './getTimeFieldInitialState';\nimport { useTimeAriaLabels } from './useTimeAriaLabels';\n\ntype TimeFieldType = ComponentProps<typeof TimeField>;\n\ntype UseTimeFieldProps = {\n granularity: TimeGranularity;\n hasLeadingZeroForHour: boolean;\n locale: BCP47Locale;\n timeMasks: TimePlaceholders;\n value?: TimeFieldType['value'];\n};\n\n/**\n * Hook that initializes the time state by calling useReducer.\n * It returns a state and a dispatch method to request changes to that 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 {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' and a 'dispatch' function.\n */\nconst useTimeFieldState = ({\n granularity,\n hasLeadingZeroForHour,\n locale,\n timeMasks,\n value: currentValue\n}: UseTimeFieldProps) => {\n const ariaLabels = useTimeAriaLabels({ locale });\n\n const [state, dispatch] = useReducer(\n timeReducer,\n {\n ariaLabels,\n currentValue,\n hasLeadingZeroForHour,\n granularity,\n locale,\n timeMasks\n },\n getTimeFieldInitialState\n );\n\n return { dispatch, state };\n};\n\nexport { useTimeFieldState };\n"],"names":["LiteralSegment","isHidden","isHighlighted","isPlaceholder","text","isTextOnlyWhitespace","trim","spanClasses","classNames","segmentStyles","literalBase","placeholder","space","highlighted","hidden","notHidden","_jsx","class","children","isLetterOnlyString","input","test","getTextContentFilterOutAriaHidden","elem","getVisibleTextNodes","map","node","textContent","join","setVisibleText","newText","Array","from","childNodes","filter","nodeType","Node","ELEMENT_NODE","getAttribute","preventDefaultHandler","e","preventDefault","isIos","getClientHints","platform","TimeSegment","amPm","ariaLabel","ariaValueMax","ariaValueMin","ariaValueNow","ariaValueText","inputRef","isDisabled","isFieldFocused","isInvalid","isRequired","isSelected","onChange","type","hasDisplayValue","length","rootClasses","base","selected","accessibleTouchTarget","placeholderClasses","emptySegmentValueText","useTranslationBundle","formControl_empty_segment","sRef","useRef","segmentRef","onKeyDown","useCallback","event","key","isSelectAll","isBackspaceOrDelete","isNumberOnlyString","actionType","data","direction","stopPropagation","dayPeriodHandler","ref","compositionRef","updateDayPeriodSegmentState","value","toggleDayPeriodSegmentState","changeDayPeriodIfMatch","matchType","getAmPmMatchType","AM_VALUE","PM_VALUE","onBeforeInput","inputType","current","onInput","useDayPeriodInputHandlers","am","pm","useEffect","focus","valueText","undefined","toString","customDataAttribute","_jsxs","role","autocapitalize","autocorrect","contentEditable","enterkeyhint","inputMode","onCut","onPaste","spellcheck","tabIndex","useTimeFieldHandlers","dispatch","groupRef","isInputFocused","state","tabbableModeProps","tabbableModeIndex","useTabbableMode","anySegmentSelected","segments","some","segment","updatedTabIndex","timeClearedRef","currentTime","Object","keys","action","onClick","segmentType","target","selectAll","isGroupFocus","isCompleteTime","onDoubleClick","onDoubleTap","doubleTapHandlers","useDoubleTap","onSingleTap","isTimeSelected","stopImmediatePropagation","onPointerDown","recentPointerRef","pointerDownTimerRef","clearTimeout","setTimeout","lastInputFocusedRef","useInputMaskSelectFirstHandler","handlers","deviceType","isMobile","timeFieldHandlers","segmentHandlers","timeReducer","updatedSegments","selectFirst","clearTime","orderedSegments","createTimeFieldStateFromUpdatedSegments","updatedSegment","clearSegment","findSegment","createTimeFieldStateFromUpdatedSegment","completeAllSegmentsBasedOnHour","isCommitting","deselectAndComplete","goToEnd","goToHome","doStepOrPage","selectTime","completeAllEmptySegmentsWhenHourHasValue","updatedSelectedNextSegments","selectNext","selectPrevious","selectSegment","newValue","createSegmentFromKeyboardAction","segmentState","isComplete","digitCount","updateSegment","Error","find","isPartialTime","allSegments","seg","autoFillEmptyNonHourSegments","existingSegments","ariaValue","includes","isAutoFilled","currentState","updatedSegmentType","autoAdvance","autoFill","modifiedSegments","replaceTimeSegment","createTimeSegmentStates","actionText","maxValue","minValue","hasLeadingZeros","wasComplete","targetDigitCount","requestedValStr","slice","padStart","finalValStr","withinRange","stringToNumber","finalVal","val","maxVal","numberToString","isSegmentComplete","startsWith","substring","getSelectedSegmentIndex","sel","findIndex","markSelectedSegmentComplete","selectedIndex","checkHourSelected","hourSegment","dayPeriodSegment","hourSegmentState","clearDayPeriodSegmentWhenHourIsEmpty","orderedSegmentsFromCurrentState","getOrderedSegmentsFromState","timeBeforeUpdate","timeAfterUpdate","dayPeriodValue","hourSegmentValue","adjustedHour","getAdjustedH12ToH23","segmentValues","reduce","acc","entries","createTimeFromSegments","useUpdatedValue","hasSegmentsNotDisplayed","displayedTimeSegmentsAreDifferent","isAnySegmentAutoFilled","isTimeAutoFilled","every","adjustTimeSegment","step","min","max","range","newVal","padZero","getAriaValueText","getHomeSegmentValue","getEndSegmentValue","initialStarting","valueNow","currentValue","getPagedSegmentValue","getSteppedSegmentValue","amValue","pmValue","valStr","timeHour12","getTimeFieldInitialState","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","useTimeAriaLabels","useMemo","translations","formControl_hour","formControl_minute","formControl_second","formControl_millisecond","TimeField","describedBy","ariaInvalid","ariaLabelledBy","baseId","fieldRef","hasInsideLabel","masks","onBlur","onCommit","onFocus","testId","textAlign","variant","useUser","announceTimeCleared","inputTimeMask_time_cleared","isFocused","useFormFieldContext","hasValue","classes","useComponentTheme","TextFieldInputRedwoodTheme","styleVariant","isEmbeddedVariant","textarea","prefix","suffix","startContent","endContent","insideLabel","focused","disabled","compClasses","editableSegments","segmentsMap","timeResetRef","lastValueFromParentRef","timesAreDifferent","useTimeReset","lastTimeRef","lastCommittedTimeRef","doCommitIfNeeded","useLayoutEffect","frozenTime","freeze","useTimeFieldCommitInput","formattedTimeStr","formatTimeFromMasks","formattedTimeAriaId","formattedTimeAria","jsx","HiddenAccessible","id","ariaDescribedBy","merge","announceTimeClearedText","announceAutoFilledTime","firstSegmentType","jsxs","onFocusIn","onFocusOut","Flex","wrap","justify","height","align","segmentProps","LiveRegion","InputTimeMask","forwardRef","assistiveText","columnSpan","helpSourceLink","helpSourceText","hourClock","propIsDisabled","isReadonly","propIsReadonly","isRequiredShown","label","labelEdge","propLabelEdge","labelStartWidth","propLabelStartWidth","leadingZeroForHour","mainFieldRef","messages","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","inputPropsOnBlur","timeFieldProps","labelComp","Label","fieldLabelProps","labelText","inlineUserAssistance","InlineUserAssistance","fieldLabel","aRef","anchorRef","compactUserAssistance","CompactUserAssistance","hour12","validateTimeMasksAgainstProperties","replaceCustomMasksValuesWithPlaceholders","getTimeMasksFromLocaleAndOptions","resolvedHasLeadingZeroForHour","getLeadingZeroForHour","useReducer","useTimeFieldState","onTimeFieldFocusOut","currentTarget","contains","relatedTarget","handleTimeFieldBlur","mergeProps","FormFieldContext","Provider","ReadonlyTextField","mainContent","ReadonlyTextFieldInput","as","elementRef","hasEmptyLabel","TextField","hasSecond","hasMillisecond","commonErrorMsg"],"mappings":"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"}
|