@allxsmith/bestax-bulma 5.56.0 → 5.57.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/columns/Column.js +1 -0
- package/dist/esm/columns/Column.js.map +1 -1
- package/dist/esm/columns/Columns.js +1 -0
- package/dist/esm/columns/Columns.js.map +1 -1
- package/dist/esm/components/Avatar.js +1 -0
- package/dist/esm/components/Avatar.js.map +1 -1
- package/dist/esm/components/Avatars.js +1 -0
- package/dist/esm/components/Avatars.js.map +1 -1
- package/dist/esm/components/Badge.js +1 -0
- package/dist/esm/components/Badge.js.map +1 -1
- package/dist/esm/components/Breadcrumb.js +1 -0
- package/dist/esm/components/Breadcrumb.js.map +1 -1
- package/dist/esm/components/Card.js +1 -0
- package/dist/esm/components/Card.js.map +1 -1
- package/dist/esm/components/Carousel.js +1 -0
- package/dist/esm/components/Carousel.js.map +1 -1
- package/dist/esm/components/Collapse.js +1 -0
- package/dist/esm/components/Collapse.js.map +1 -1
- package/dist/esm/components/Collapses.js +1 -0
- package/dist/esm/components/Collapses.js.map +1 -1
- package/dist/esm/components/Command.js +1 -0
- package/dist/esm/components/Command.js.map +1 -1
- package/dist/esm/components/ContextMenu.js +1 -0
- package/dist/esm/components/ContextMenu.js.map +1 -1
- package/dist/esm/components/DataTable.js +1 -0
- package/dist/esm/components/DataTable.js.map +1 -1
- package/dist/esm/components/Dialog.js +1 -0
- package/dist/esm/components/Dialog.js.map +1 -1
- package/dist/esm/components/Dropdown.js +1 -0
- package/dist/esm/components/Dropdown.js.map +1 -1
- package/dist/esm/components/EmptyState.js +1 -0
- package/dist/esm/components/EmptyState.js.map +1 -1
- package/dist/esm/components/HoverCard.js +1 -0
- package/dist/esm/components/HoverCard.js.map +1 -1
- package/dist/esm/components/Loading.js +1 -0
- package/dist/esm/components/Loading.js.map +1 -1
- package/dist/esm/components/Menu.js +1 -0
- package/dist/esm/components/Menu.js.map +1 -1
- package/dist/esm/components/Message.js +1 -0
- package/dist/esm/components/Message.js.map +1 -1
- package/dist/esm/components/Modal.js +1 -0
- package/dist/esm/components/Modal.js.map +1 -1
- package/dist/esm/components/Navbar.js +1 -0
- package/dist/esm/components/Navbar.js.map +1 -1
- package/dist/esm/components/Pagination.js +1 -0
- package/dist/esm/components/Pagination.js.map +1 -1
- package/dist/esm/components/Panel.js +1 -0
- package/dist/esm/components/Panel.js.map +1 -1
- package/dist/esm/components/Popover.js +1 -0
- package/dist/esm/components/Popover.js.map +1 -1
- package/dist/esm/components/Reveal.js +1 -0
- package/dist/esm/components/Reveal.js.map +1 -1
- package/dist/esm/components/ScrollArea.js +1 -0
- package/dist/esm/components/ScrollArea.js.map +1 -1
- package/dist/esm/components/SegmentedControl.js +1 -0
- package/dist/esm/components/SegmentedControl.js.map +1 -1
- package/dist/esm/components/Sidebar.js +1 -0
- package/dist/esm/components/Sidebar.js.map +1 -1
- package/dist/esm/components/Steps.js +1 -0
- package/dist/esm/components/Steps.js.map +1 -1
- package/dist/esm/components/Tabs.js +1 -0
- package/dist/esm/components/Tabs.js.map +1 -1
- package/dist/esm/components/Timeline.js +1 -0
- package/dist/esm/components/Timeline.js.map +1 -1
- package/dist/esm/components/Toast.js +1 -0
- package/dist/esm/components/Toast.js.map +1 -1
- package/dist/esm/components/Tooltip.js +1 -0
- package/dist/esm/components/Tooltip.js.map +1 -1
- package/dist/esm/components/TreeView.js +1 -0
- package/dist/esm/components/TreeView.js.map +1 -1
- package/dist/esm/components/collapsesContext.js +1 -0
- package/dist/esm/components/collapsesContext.js.map +1 -1
- package/dist/esm/components/useDataTable.js +1 -0
- package/dist/esm/components/useDataTable.js.map +1 -1
- package/dist/esm/elements/Block.js +1 -0
- package/dist/esm/elements/Block.js.map +1 -1
- package/dist/esm/elements/Box.js +1 -0
- package/dist/esm/elements/Box.js.map +1 -1
- package/dist/esm/elements/Button.js +1 -0
- package/dist/esm/elements/Button.js.map +1 -1
- package/dist/esm/elements/Buttons.js +1 -0
- package/dist/esm/elements/Buttons.js.map +1 -1
- package/dist/esm/elements/Code.js +1 -0
- package/dist/esm/elements/Code.js.map +1 -1
- package/dist/esm/elements/ColorSwatch.js +1 -0
- package/dist/esm/elements/ColorSwatch.js.map +1 -1
- package/dist/esm/elements/Content.js +1 -0
- package/dist/esm/elements/Content.js.map +1 -1
- package/dist/esm/elements/Delete.js +1 -0
- package/dist/esm/elements/Delete.js.map +1 -1
- package/dist/esm/elements/DescriptionList.js +1 -0
- package/dist/esm/elements/DescriptionList.js.map +1 -1
- package/dist/esm/elements/Divider.js +1 -0
- package/dist/esm/elements/Divider.js.map +1 -1
- package/dist/esm/elements/Emphasis.js +1 -0
- package/dist/esm/elements/Emphasis.js.map +1 -1
- package/dist/esm/elements/Figure.js +1 -0
- package/dist/esm/elements/Figure.js.map +1 -1
- package/dist/esm/elements/Icon.js +1 -0
- package/dist/esm/elements/Icon.js.map +1 -1
- package/dist/esm/elements/IconText.js +1 -0
- package/dist/esm/elements/IconText.js.map +1 -1
- package/dist/esm/elements/Image.js +1 -0
- package/dist/esm/elements/Image.js.map +1 -1
- package/dist/esm/elements/Kbd.js +1 -0
- package/dist/esm/elements/Kbd.js.map +1 -1
- package/dist/esm/elements/Link.js +1 -0
- package/dist/esm/elements/Link.js.map +1 -1
- package/dist/esm/elements/LinkButton.js +1 -0
- package/dist/esm/elements/LinkButton.js.map +1 -1
- package/dist/esm/elements/ListItem.js +1 -0
- package/dist/esm/elements/ListItem.js.map +1 -1
- package/dist/esm/elements/Loader.js +1 -0
- package/dist/esm/elements/Loader.js.map +1 -1
- package/dist/esm/elements/Notification.js +1 -0
- package/dist/esm/elements/Notification.js.map +1 -1
- package/dist/esm/elements/OrderedList.js +1 -0
- package/dist/esm/elements/OrderedList.js.map +1 -1
- package/dist/esm/elements/Paragraph.js +1 -0
- package/dist/esm/elements/Paragraph.js.map +1 -1
- package/dist/esm/elements/Pre.js +1 -0
- package/dist/esm/elements/Pre.js.map +1 -1
- package/dist/esm/elements/Progress.js +1 -0
- package/dist/esm/elements/Progress.js.map +1 -1
- package/dist/esm/elements/RingProgress.js +1 -0
- package/dist/esm/elements/RingProgress.js.map +1 -1
- package/dist/esm/elements/Skeleton.js +1 -0
- package/dist/esm/elements/Skeleton.js.map +1 -1
- package/dist/esm/elements/Span.js +1 -0
- package/dist/esm/elements/Span.js.map +1 -1
- package/dist/esm/elements/Strong.js +1 -0
- package/dist/esm/elements/Strong.js.map +1 -1
- package/dist/esm/elements/SubTitle.js +1 -0
- package/dist/esm/elements/SubTitle.js.map +1 -1
- package/dist/esm/elements/Table.js +1 -0
- package/dist/esm/elements/Table.js.map +1 -1
- package/dist/esm/elements/Tag.js +1 -0
- package/dist/esm/elements/Tag.js.map +1 -1
- package/dist/esm/elements/Tags.js +1 -0
- package/dist/esm/elements/Tags.js.map +1 -1
- package/dist/esm/elements/Tbody.js +1 -0
- package/dist/esm/elements/Tbody.js.map +1 -1
- package/dist/esm/elements/Td.js +1 -0
- package/dist/esm/elements/Td.js.map +1 -1
- package/dist/esm/elements/Tfoot.js +1 -0
- package/dist/esm/elements/Tfoot.js.map +1 -1
- package/dist/esm/elements/Th.js +1 -0
- package/dist/esm/elements/Th.js.map +1 -1
- package/dist/esm/elements/Thead.js +1 -0
- package/dist/esm/elements/Thead.js.map +1 -1
- package/dist/esm/elements/Title.js +1 -0
- package/dist/esm/elements/Title.js.map +1 -1
- package/dist/esm/elements/ToggleButton.js +1 -0
- package/dist/esm/elements/ToggleButton.js.map +1 -1
- package/dist/esm/elements/Tr.js +1 -0
- package/dist/esm/elements/Tr.js.map +1 -1
- package/dist/esm/elements/UnorderedList.js +1 -0
- package/dist/esm/elements/UnorderedList.js.map +1 -1
- package/dist/esm/elements/iconProps.js +1 -0
- package/dist/esm/elements/iconProps.js.map +1 -1
- package/dist/esm/form/Autocomplete.js +1 -0
- package/dist/esm/form/Autocomplete.js.map +1 -1
- package/dist/esm/form/Checkbox.js +1 -0
- package/dist/esm/form/Checkbox.js.map +1 -1
- package/dist/esm/form/CheckboxCard.js +1 -0
- package/dist/esm/form/CheckboxCard.js.map +1 -1
- package/dist/esm/form/Checkboxes.js +1 -0
- package/dist/esm/form/Checkboxes.js.map +1 -1
- package/dist/esm/form/ColorInput.js +1 -0
- package/dist/esm/form/ColorInput.js.map +1 -1
- package/dist/esm/form/ColorInputBase.js +1 -0
- package/dist/esm/form/ColorInputBase.js.map +1 -1
- package/dist/esm/form/ColorPicker.js +1 -0
- package/dist/esm/form/ColorPicker.js.map +1 -1
- package/dist/esm/form/Combobox.js +1 -0
- package/dist/esm/form/Combobox.js.map +1 -1
- package/dist/esm/form/Control.js +1 -0
- package/dist/esm/form/Control.js.map +1 -1
- package/dist/esm/form/DateInput.js +1 -0
- package/dist/esm/form/DateInput.js.map +1 -1
- package/dist/esm/form/DateInputBase.js +1 -0
- package/dist/esm/form/DateInputBase.js.map +1 -1
- package/dist/esm/form/DateRangeInput.js +1 -0
- package/dist/esm/form/DateRangeInput.js.map +1 -1
- package/dist/esm/form/DateRangeInputBase.js +1 -0
- package/dist/esm/form/DateRangeInputBase.js.map +1 -1
- package/dist/esm/form/DateTimeInput.js +1 -0
- package/dist/esm/form/DateTimeInput.js.map +1 -1
- package/dist/esm/form/DateTimeInputBase.js +1 -0
- package/dist/esm/form/DateTimeInputBase.js.map +1 -1
- package/dist/esm/form/Dropzone.js +1 -0
- package/dist/esm/form/Dropzone.js.map +1 -1
- package/dist/esm/form/Field.js +1 -0
- package/dist/esm/form/Field.js.map +1 -1
- package/dist/esm/form/Fieldset.js +1 -0
- package/dist/esm/form/Fieldset.js.map +1 -1
- package/dist/esm/form/File.js +1 -0
- package/dist/esm/form/File.js.map +1 -1
- package/dist/esm/form/FormContext.js +1 -0
- package/dist/esm/form/FormContext.js.map +1 -1
- package/dist/esm/form/Input.js +1 -0
- package/dist/esm/form/Input.js.map +1 -1
- package/dist/esm/form/InputBase.js +1 -0
- package/dist/esm/form/InputBase.js.map +1 -1
- package/dist/esm/form/Numberinput.js +1 -0
- package/dist/esm/form/Numberinput.js.map +1 -1
- package/dist/esm/form/PinInput.js +1 -0
- package/dist/esm/form/PinInput.js.map +1 -1
- package/dist/esm/form/Radio.js +1 -0
- package/dist/esm/form/Radio.js.map +1 -1
- package/dist/esm/form/RadioCard.js +1 -0
- package/dist/esm/form/RadioCard.js.map +1 -1
- package/dist/esm/form/Radios.js +1 -0
- package/dist/esm/form/Radios.js.map +1 -1
- package/dist/esm/form/Rate.js +1 -0
- package/dist/esm/form/Rate.js.map +1 -1
- package/dist/esm/form/Select.js +1 -0
- package/dist/esm/form/Select.js.map +1 -1
- package/dist/esm/form/SelectBase.js +1 -0
- package/dist/esm/form/SelectBase.js.map +1 -1
- package/dist/esm/form/Slider.js +1 -0
- package/dist/esm/form/Slider.js.map +1 -1
- package/dist/esm/form/Switch.js +1 -0
- package/dist/esm/form/Switch.js.map +1 -1
- package/dist/esm/form/Taginput.js +1 -0
- package/dist/esm/form/Taginput.js.map +1 -1
- package/dist/esm/form/TextArea.js +1 -0
- package/dist/esm/form/TextArea.js.map +1 -1
- package/dist/esm/form/TextAreaBase.js +1 -0
- package/dist/esm/form/TextAreaBase.js.map +1 -1
- package/dist/esm/form/TimeInput.js +1 -0
- package/dist/esm/form/TimeInput.js.map +1 -1
- package/dist/esm/form/TimeInputBase.js +1 -0
- package/dist/esm/form/TimeInputBase.js.map +1 -1
- package/dist/esm/form/_colorInternals/EyeDropperButton.js +1 -0
- package/dist/esm/form/_colorInternals/EyeDropperButton.js.map +1 -1
- package/dist/esm/form/_colorInternals/pickerState.js +1 -0
- package/dist/esm/form/_colorInternals/pickerState.js.map +1 -1
- package/dist/esm/form/_pickerInternals/Calendar.js +1 -0
- package/dist/esm/form/_pickerInternals/Calendar.js.map +1 -1
- package/dist/esm/form/_pickerInternals/PickerPopover.js +1 -0
- package/dist/esm/form/_pickerInternals/PickerPopover.js.map +1 -1
- package/dist/esm/form/_pickerInternals/TimeWheels.js +1 -0
- package/dist/esm/form/_pickerInternals/TimeWheels.js.map +1 -1
- package/dist/esm/form/_pickerInternals/useLocaleDefaults.js +1 -0
- package/dist/esm/form/_pickerInternals/useLocaleDefaults.js.map +1 -1
- package/dist/esm/form/_pickerInternals/useNativeMobilePicker.js +1 -0
- package/dist/esm/form/_pickerInternals/useNativeMobilePicker.js.map +1 -1
- package/dist/esm/form/_pickerInternals/useSegmentedEntry.js +1 -0
- package/dist/esm/form/_pickerInternals/useSegmentedEntry.js.map +1 -1
- package/dist/esm/form/controlLoading.js +1 -0
- package/dist/esm/form/controlLoading.js.map +1 -1
- package/dist/esm/form/groupFieldset.js +1 -0
- package/dist/esm/form/groupFieldset.js.map +1 -1
- package/dist/esm/form/useAutoLabelId.js +1 -0
- package/dist/esm/form/useAutoLabelId.js.map +1 -1
- package/dist/esm/grid/Cell.js +1 -0
- package/dist/esm/grid/Cell.js.map +1 -1
- package/dist/esm/grid/Grid.js +1 -0
- package/dist/esm/grid/Grid.js.map +1 -1
- package/dist/esm/helpers/ClientOnly.js +1 -0
- package/dist/esm/helpers/ClientOnly.js.map +1 -1
- package/dist/esm/helpers/Config.js +1 -0
- package/dist/esm/helpers/Config.js.map +1 -1
- package/dist/esm/helpers/LocaleProvider.js +1 -0
- package/dist/esm/helpers/LocaleProvider.js.map +1 -1
- package/dist/esm/helpers/Theme.js +1 -0
- package/dist/esm/helpers/Theme.js.map +1 -1
- package/dist/esm/helpers/flattenChildren.js +1 -0
- package/dist/esm/helpers/flattenChildren.js.map +1 -1
- package/dist/esm/helpers/inertProps.js +1 -0
- package/dist/esm/helpers/inertProps.js.map +1 -1
- package/dist/esm/helpers/localeFormat.js +1 -0
- package/dist/esm/helpers/localeFormat.js.map +1 -1
- package/dist/esm/helpers/overlayStack.js +1 -0
- package/dist/esm/helpers/overlayStack.js.map +1 -1
- package/dist/esm/helpers/portal.js +1 -0
- package/dist/esm/helpers/portal.js.map +1 -1
- package/dist/esm/helpers/scrollLock.js +1 -0
- package/dist/esm/helpers/scrollLock.js.map +1 -1
- package/dist/esm/helpers/statusRegion.js +1 -0
- package/dist/esm/helpers/statusRegion.js.map +1 -1
- package/dist/esm/helpers/typeahead.js +1 -0
- package/dist/esm/helpers/typeahead.js.map +1 -1
- package/dist/esm/helpers/useAnchoredPosition.js +1 -0
- package/dist/esm/helpers/useAnchoredPosition.js.map +1 -1
- package/dist/esm/helpers/useBulmaClasses.js +1 -0
- package/dist/esm/helpers/useBulmaClasses.js.map +1 -1
- package/dist/esm/helpers/useClientLayoutEffect.js +1 -0
- package/dist/esm/helpers/useClientLayoutEffect.js.map +1 -1
- package/dist/esm/helpers/useColorClasses.js +1 -0
- package/dist/esm/helpers/useColorClasses.js.map +1 -1
- package/dist/esm/helpers/useComboboxEngine.js +1 -0
- package/dist/esm/helpers/useComboboxEngine.js.map +1 -1
- package/dist/esm/helpers/useContextMenuTrigger.js +1 -0
- package/dist/esm/helpers/useContextMenuTrigger.js.map +1 -1
- package/dist/esm/helpers/useFlexboxClasses.js +1 -0
- package/dist/esm/helpers/useFlexboxClasses.js.map +1 -1
- package/dist/esm/helpers/useFocusTrap.js +1 -0
- package/dist/esm/helpers/useFocusTrap.js.map +1 -1
- package/dist/esm/helpers/useHoverOpen.js +1 -0
- package/dist/esm/helpers/useHoverOpen.js.map +1 -1
- package/dist/esm/helpers/useInertSiblings.js +1 -0
- package/dist/esm/helpers/useInertSiblings.js.map +1 -1
- package/dist/esm/helpers/useIsHydrated.js +1 -0
- package/dist/esm/helpers/useIsHydrated.js.map +1 -1
- package/dist/esm/helpers/useLatestRef.js +1 -0
- package/dist/esm/helpers/useLatestRef.js.map +1 -1
- package/dist/esm/helpers/useMenuKeys.js +1 -0
- package/dist/esm/helpers/useMenuKeys.js.map +1 -1
- package/dist/esm/helpers/useOtherClasses.js +1 -0
- package/dist/esm/helpers/useOtherClasses.js.map +1 -1
- package/dist/esm/helpers/useSpacingClasses.js +1 -0
- package/dist/esm/helpers/useSpacingClasses.js.map +1 -1
- package/dist/esm/helpers/useTreeView.js +1 -0
- package/dist/esm/helpers/useTreeView.js.map +1 -1
- package/dist/esm/helpers/useTypographyClasses.js +1 -0
- package/dist/esm/helpers/useTypographyClasses.js.map +1 -1
- package/dist/esm/helpers/useVisibilityClasses.js +1 -0
- package/dist/esm/helpers/useVisibilityClasses.js.map +1 -1
- package/dist/esm/layout/Container.js +1 -0
- package/dist/esm/layout/Container.js.map +1 -1
- package/dist/esm/layout/Footer.js +1 -0
- package/dist/esm/layout/Footer.js.map +1 -1
- package/dist/esm/layout/Hero.js +1 -0
- package/dist/esm/layout/Hero.js.map +1 -1
- package/dist/esm/layout/Level.js +1 -0
- package/dist/esm/layout/Level.js.map +1 -1
- package/dist/esm/layout/Media.js +1 -0
- package/dist/esm/layout/Media.js.map +1 -1
- package/dist/esm/layout/Section.js +1 -0
- package/dist/esm/layout/Section.js.map +1 -1
- package/dist/esm/layout/Splitter.js +1 -0
- package/dist/esm/layout/Splitter.js.map +1 -1
- package/package.json +2 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TimeWheels.js","sources":["../../../../src/form/_pickerInternals/TimeWheels.tsx"],"sourcesContent":["/* eslint-disable react-hooks/refs --\n * This wheel/momentum picker intentionally accesses refs during render:\n * - state is mirrored into refs (positionRef, audioTickEnabledRef) so the\n * RAF/drag/tick callbacks read the latest values in lockstep with rendering\n * (refactoring to effect-synced refs would desync drag from the frame);\n * - a MediaQueryList is lazily cached in a ref (reducedMotionMqlRef);\n * - per-column Wheel handle refs build the keyboard focus order.\n * These are deliberate, established patterns; behavior is covered by unit tests\n * and certified interactively in-browser (drag, ticks, keyboard focus nav).\n */\nimport React, {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport {\n classNames,\n prefixedClassNames,\n usePrefixedClassNames,\n} from '../../helpers/classNames';\nimport { useConfig } from '../../helpers/Config';\nimport {\n HourFormat,\n PickerLabels,\n isPopoverToggleKey,\n mergeLabels,\n} from './pickerTypes';\nimport { setTimeOfDay } from './dateUtils';\nimport { tickHaptic as fireTickHaptic } from './haptics';\nimport { playAudioTick, unlockAudioTick } from './audioTick';\n\nexport interface TimeWheelsValue {\n hours: number;\n minutes: number;\n seconds?: number;\n}\n\nexport interface TimeWheelsProps {\n value: TimeWheelsValue;\n onChange: (v: TimeWheelsValue) => void;\n hourFormat?: HourFormat;\n enableSeconds?: boolean;\n /** Step between visible values in the wheel. Default `1`. */\n incrementHours?: number;\n incrementMinutes?: number;\n incrementSeconds?: number;\n unselectableTimes?: (d: Date) => boolean;\n size?: 'small' | 'medium' | 'large';\n color?: 'primary' | 'link' | 'info' | 'success' | 'warning' | 'danger';\n disabled?: boolean;\n className?: string;\n id?: string;\n labels?: PickerLabels;\n /** Number of items visible at once (must be odd). Default 5. */\n visibleCount?: number;\n /** Item height in px. Default 32. */\n itemHeight?: number;\n /**\n * Play a short audible tick on each item crossing. Useful as a fallback on\n * iOS Safari, where there is no web-accessible haptic API. Off by default\n * to avoid surprising users with sound; flip on for iOS-targeted UIs.\n */\n audioTick?: boolean;\n /**\n * Fired when the user presses Enter on a wheel column. The current value is\n * already committed (each wheel-tick calls onChange), so this typically just\n * needs to close the surrounding popover.\n */\n onCommit?: () => void;\n}\n\nconst wrap = (n: number, max: number): number => ((n % max) + max) % max;\n\n/**\n * Walk forward (or backward) from `start` in `step` steps until `test` returns\n * true or we've cycled all `max` candidates. Used to skip past unselectable\n * values without freezing the wheel.\n */\nfunction nextValid(\n start: number,\n step: number,\n max: number,\n test: (n: number) => boolean\n): number {\n let candidate = wrap(start, max);\n for (let i = 0; i < max; i++) {\n if (test(candidate)) return candidate;\n candidate = wrap(candidate + step, max);\n }\n return start;\n}\n\nconst pad2 = (n: number): string => String(n).padStart(2, '0');\n\ninterface WheelHandle {\n focus: () => void;\n /**\n * Begin a drag externally — used by the parent's empty-space forwarder so\n * the user can grab the wheel by touching anywhere in the wheels row, not\n * just on the column itself (matches iOS native picker behavior).\n *\n * The pointer must already be active (i.e., a real `pointerdown` is in\n * flight). We immediately capture the pointer on the wheel root so the\n * existing `onPointerMove` / `onPointerUp` handlers will fire here.\n */\n startDrag: (pointerId: number, clientY: number) => void;\n}\n\ninterface WheelProps<T> {\n values: T[];\n index: number;\n onChange: (nextIndex: number) => void;\n formatLabel: (v: T) => string;\n formatAriaText?: (v: T) => string;\n ariaLabel: string;\n visibleCount: number;\n itemHeight: number;\n disabled?: boolean;\n size?: 'small' | 'medium' | 'large';\n color?: 'primary' | 'link' | 'info' | 'success' | 'warning' | 'danger';\n onFocusPrev?: () => void;\n onFocusNext?: () => void;\n /** Fired when Enter is pressed (current value is already committed live). */\n onCommit?: () => void;\n /**\n * Whether the wheel wraps at the edges. When true, scrolling past the last\n * value rolls back to the first (and vice versa) and neighbouring values\n * are visible above the first / below the last item.\n */\n wrap?: boolean;\n /**\n * Optional predicate. Items for which it returns `true` are rendered with\n * the `disabled` attribute (and visually dimmed via the `:disabled` SCSS\n * rule), giving users a clear cue that the value is blocked. Keyboard /\n * wheel navigation may still pass over these positions, but `onChange`\n * callers (`TimeWheels`) skip them via `nextValid`.\n */\n disabledFor?: (v: T) => boolean;\n /**\n * Play an audible tick on each item crossing. Used as the iOS substitute\n * for haptic feedback; threaded from `TimeWheels.audioTick`.\n */\n audioTick?: boolean;\n}\n\nconst WheelInner = <T,>(\n {\n values,\n index,\n onChange,\n formatLabel,\n formatAriaText,\n ariaLabel,\n visibleCount,\n itemHeight,\n disabled,\n size,\n color,\n onFocusPrev,\n onFocusNext,\n onCommit,\n wrap = false,\n disabledFor,\n audioTick = false,\n }: WheelProps<T>,\n ref: React.Ref<WheelHandle>\n) => {\n const { classPrefix } = useConfig();\n const N = values.length;\n const half = Math.floor(visibleCount / 2);\n const containerHeight = visibleCount * itemHeight;\n // Buffer around the visible window so adjacent items animate in/out smoothly.\n const BUFFER = half + 2;\n\n // Continuous wheel position in units of items. Math.round(position) is the\n // \"active\" virtual index; the fractional part is the drag/momentum offset\n // within an item slot. Using a single float (rather than virtualIdx +\n // dragOffset) keeps drag and tick-update in lockstep so items move with the\n // finger without a 40px overshoot when crossing item boundaries.\n const [position, setPosition] = useState<number>(index);\n const positionRef = useRef<number>(index);\n positionRef.current = position;\n const [isDragging, setIsDragging] = useState(false);\n const rootRef = useRef<HTMLDivElement>(null);\n // Ref to the stationary selection band — populated by the JSX below. The\n // band briefly scales + brightens on each item tick so users perceive a\n // body-felt \"thunk\" even on iOS where no haptic API exists.\n const bandRef = useRef<HTMLDivElement>(null);\n // Cached MediaQueryList for `prefers-reduced-motion`. We read this on\n // every tick to decide whether to fire the band pulse; caching the MQL\n // saves a `matchMedia` call per tick (which can fire at ~20Hz during a\n // momentum flick).\n const reducedMotionMqlRef = useRef<MediaQueryList | null>(null);\n if (\n reducedMotionMqlRef.current === null &&\n typeof window !== 'undefined' &&\n typeof window.matchMedia === 'function'\n ) {\n reducedMotionMqlRef.current = window.matchMedia(\n '(prefers-reduced-motion: reduce)'\n );\n }\n // In-flight band pulse animation (Web Animations API). Tracked so we can\n // cancel on unmount; the WAI's `composite: 'replace'` semantics handle\n // re-trigger automatically without us needing to cancel between ticks.\n const pulseAnimRef = useRef<Animation | null>(null);\n // True while the external `index` prop sync useEffect runs, so we don't\n // fire a haptic blip when the parent updates the value programmatically.\n const isSyncingRef = useRef<boolean>(false);\n\n // Tiny haptic/audio/visual blip per item tick. Haptic uses\n // `navigator.vibrate` where available (Android Chrome / Firefox Android /\n // Samsung Internet); iOS has no web-accessible haptic path as of May\n // 2026, so the optional `audioTick` plays a low-frequency thunk as the\n // closest UX substitute. The visual band-pulse fires on every tick on\n // every platform (gated only by `prefers-reduced-motion`) so the\n // selection band feels reactive — visual reinforcement of the tactile\n // feedback. We skip all three during programmatic prop sync so a parent\n // re-render doesn't blip.\n const audioTickEnabledRef = useRef<boolean>(audioTick);\n audioTickEnabledRef.current = audioTick;\n const playBandPulse = useCallback(() => {\n const el = bandRef.current;\n if (!el || typeof el.animate !== 'function') return;\n if (reducedMotionMqlRef.current?.matches) return;\n // Compound scale + brightness pulse, peaking at 40% through the 110ms\n // duration. `composite: 'replace'` means a re-trigger mid-pulse cleanly\n // restarts rather than queueing — important at fling rates where ticks\n // can fire every ~50ms.\n pulseAnimRef.current = el.animate(\n [\n { transform: 'scale(1)', filter: 'brightness(1)' },\n {\n transform: 'scale(1.04)',\n filter: 'brightness(1.15)',\n offset: 0.4,\n },\n { transform: 'scale(1)', filter: 'brightness(1)' },\n ],\n { duration: 110, easing: 'ease-out', composite: 'replace' }\n );\n }, []);\n const tickFeedback = useCallback(() => {\n /* istanbul ignore next: the sync flag is only true synchronously inside the prop-sync effect, which sets position directly and never routes through commitPosition */\n if (isSyncingRef.current) return;\n fireTickHaptic();\n if (audioTickEnabledRef.current) playAudioTick();\n playBandPulse();\n }, [playBandPulse]);\n const dragStateRef = useRef<{\n pointerId: number | null;\n startY: number;\n startPosition: number;\n captured: boolean;\n samples: { t: number; y: number }[];\n }>({\n pointerId: null,\n startY: 0,\n startPosition: 0,\n captured: false,\n samples: [],\n });\n // RAF id for the in-flight momentum / snap animation, so we can cancel when\n // the user grabs the wheel again or the component unmounts.\n const rafIdRef = useRef<number | null>(null);\n\n const virtualIdx = Math.round(position);\n\n const cancelRaf = useCallback(() => {\n if (rafIdRef.current !== null) {\n cancelAnimationFrame(rafIdRef.current);\n rafIdRef.current = null;\n }\n }, []);\n\n useEffect(\n () => () => {\n cancelRaf();\n // Cancel any in-flight band pulse so it doesn't keep a reference to\n // a detached DOM node. WAI Animation.cancel() is safe to call even\n // if the animation has already finished.\n pulseAnimRef.current?.cancel();\n pulseAnimRef.current = null;\n },\n [cancelRaf]\n );\n\n React.useImperativeHandle(\n ref,\n () => ({\n focus: () => rootRef.current?.focus(),\n startDrag: (pointerId: number, clientY: number) => {\n /* istanbul ignore next: the empty-space forwarder (sole caller) already returns on the same disabled prop */\n if (disabled) return;\n cancelRaf();\n if (audioTickEnabledRef.current) unlockAudioTick();\n const now =\n typeof performance !== 'undefined' ? performance.now() : Date.now();\n dragStateRef.current = {\n pointerId,\n startY: clientY,\n startPosition: positionRef.current,\n // Skip the drag-threshold gate: the parent forwarder has already\n // decided this is a drag (a pointerdown landed on empty space,\n // which has no click target).\n captured: true,\n samples: [{ t: now, y: clientY }],\n };\n try {\n rootRef.current?.setPointerCapture(pointerId);\n } catch {\n // setPointerCapture can throw if the pointer isn't currently\n // active for this element; the existing onPointerMove handler\n // still matches on pointerId so the drag will work either way.\n }\n setIsDragging(true);\n },\n }),\n [disabled, cancelRaf]\n );\n\n // Resolve a virtualIdx into an actual values[] index (modulo wrap if `wrap`).\n const toActual = useCallback(\n (v: number) => {\n if (wrap) return ((v % N) + N) % N;\n return Math.max(0, Math.min(N - 1, v));\n },\n [wrap, N]\n );\n\n const clampPosition = useCallback(\n (p: number) => {\n if (wrap) return p;\n return Math.max(0, Math.min(N - 1, p));\n },\n [wrap, N]\n );\n\n // Update position and fire onChange if the rounded value changed.\n const commitPosition = useCallback(\n (next: number) => {\n const clamped = clampPosition(next);\n const prevRound = Math.round(positionRef.current);\n const nextRound = Math.round(clamped);\n positionRef.current = clamped;\n setPosition(clamped);\n if (nextRound !== prevRound) {\n onChange(toActual(nextRound));\n tickFeedback();\n }\n },\n [clampPosition, onChange, toActual, tickFeedback]\n );\n\n // When the external `index` changes (e.g. from typed input), re-sync\n // position to the closest virtual position that maps to it.\n //\n // Crucial subtlety: this effect re-runs every time the parent value\n // changes — including the round-trip case where the user's own scroll\n // commits a tick → fires onChange → parent re-renders with the new\n // index → here. If we cancelled the in-flight momentum/snap RAF on\n // every such echo, the snap would never get to land on an integer\n // (the user's wheel would stop wherever the last tick fired). So we\n // bail out early when the rounded position already matches the\n // incoming index — the echo case — and only cancel + apply an actual\n // jump when the parent has moved us somewhere we don't already round\n // to.\n useEffect(() => {\n const prev = positionRef.current;\n const wrappedRoundPrev = ((Math.round(prev) % N) + N) % N;\n if (wrappedRoundPrev === index) return;\n cancelRaf();\n isSyncingRef.current = true;\n setPosition(prevPos => {\n if (!wrap) {\n positionRef.current = index;\n return index;\n }\n const wrappedPrev = ((prevPos % N) + N) % N;\n const forward = (index - wrappedPrev + N) % N;\n const backward = forward - N;\n const delta =\n Math.abs(forward) <= Math.abs(backward) ? forward : backward;\n const next = prevPos + delta;\n positionRef.current = next;\n return next;\n });\n isSyncingRef.current = false;\n }, [index, N, wrap, cancelRaf]);\n\n const moveBy = useCallback(\n (delta: number) => {\n if (disabled) return;\n cancelRaf();\n commitPosition(Math.round(positionRef.current) + delta);\n },\n [disabled, cancelRaf, commitPosition]\n );\n\n // The keys are a spinbutton's: up raises the value and down lowers it. The\n // values run down the wheel, so up brings the one below the band into it,\n // the way a drag or a scroll that moves the items up does.\n const onKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n if (isPopoverToggleKey(e)) return;\n switch (e.key) {\n case 'ArrowUp':\n e.preventDefault();\n moveBy(1);\n break;\n case 'ArrowDown':\n e.preventDefault();\n moveBy(-1);\n break;\n case 'PageUp':\n e.preventDefault();\n moveBy(5);\n break;\n case 'PageDown':\n e.preventDefault();\n moveBy(-5);\n break;\n case 'Home':\n e.preventDefault();\n if (disabled) break;\n cancelRaf();\n commitPosition(0);\n break;\n case 'End':\n e.preventDefault();\n if (disabled) break;\n cancelRaf();\n commitPosition(N - 1);\n break;\n case 'ArrowLeft':\n e.preventDefault();\n onFocusPrev?.();\n break;\n case 'ArrowRight':\n e.preventDefault();\n onFocusNext?.();\n break;\n case 'Enter':\n e.preventDefault();\n onCommit?.();\n break;\n }\n },\n [\n moveBy,\n disabled,\n commitPosition,\n cancelRaf,\n N,\n onFocusPrev,\n onFocusNext,\n onCommit,\n ]\n );\n\n // Animate position to the nearest integer with ease-out cubic. Used after a\n // drag / momentum settles, so the wheel always rests aligned to an item.\n const animateSnap = useCallback(() => {\n cancelRaf();\n const start = positionRef.current;\n const target = Math.round(start);\n if (start === target) return;\n const duration = 180;\n const startTime =\n typeof performance !== 'undefined' ? performance.now() : Date.now();\n const tick = (now: number) => {\n const t = Math.min(1, (now - startTime) / duration);\n const eased = 1 - Math.pow(1 - t, 3);\n const next = start + (target - start) * eased;\n commitPosition(next);\n if (t < 1) {\n rafIdRef.current = requestAnimationFrame(tick);\n } else {\n rafIdRef.current = null;\n }\n };\n rafIdRef.current = requestAnimationFrame(tick);\n }, [cancelRaf, commitPosition]);\n\n // Kinetic momentum after a flick. Uses exponential friction so the velocity\n // tapers smoothly. Updates `position` in items/ms; commitPosition handles\n // the onChange ticks as virtualIdx crosses integers.\n const startMomentum = useCallback(\n (initialPxPerMs: number) => {\n cancelRaf();\n // Drag-up (negative dy/dt in screen coords) should INCREASE position\n // (later values come into view), so flip the sign.\n let velocity = -initialPxPerMs / itemHeight; // items / ms\n // Cap initial velocity so a frantic swipe doesn't blast through the\n // whole list. Empirically tuned to match iOS feel.\n const MAX_VEL = 0.05; // items/ms (≈ 50 items/sec)\n if (velocity > MAX_VEL) velocity = MAX_VEL;\n if (velocity < -MAX_VEL) velocity = -MAX_VEL;\n const STOP_VEL = 0.0015; // items/ms (≈ 1.5 items/sec)\n // Friction coefficient per millisecond — chosen so velocity halves\n // every ~120ms.\n const FRICTION_PER_MS = Math.pow(0.5, 1 / 120);\n let lastTime =\n typeof performance !== 'undefined' ? performance.now() : Date.now();\n const tick = (now: number) => {\n const dt = Math.max(1, now - lastTime);\n lastTime = now;\n let next = positionRef.current + velocity * dt;\n // Boundary handling for non-wrapping wheels: clamp and zero the\n // velocity so we don't keep ticking against the wall.\n if (!wrap) {\n if (next <= 0) {\n next = 0;\n velocity = 0;\n } else if (next >= N - 1) {\n next = N - 1;\n velocity = 0;\n }\n }\n commitPosition(next);\n velocity *= Math.pow(FRICTION_PER_MS, dt);\n if (Math.abs(velocity) < STOP_VEL) {\n animateSnap();\n return;\n }\n rafIdRef.current = requestAnimationFrame(tick);\n };\n rafIdRef.current = requestAnimationFrame(tick);\n },\n [cancelRaf, commitPosition, itemHeight, wrap, N, animateSnap]\n );\n\n // Mouse wheel: accumulate deltaY across events and step when the\n // accumulator crosses SCROLL_STEP_PX. Trackpads emit dozens of small\n // events per swipe; without accumulation a single gesture flies the wheel.\n useEffect(() => {\n const el = rootRef.current;\n if (!el || disabled) return undefined;\n const SCROLL_STEP_PX = 60;\n const QUIET_MS = 250;\n let accumulated = 0;\n let resetTimer: ReturnType<typeof setTimeout> | null = null;\n const resetAccumulator = () => {\n accumulated = 0;\n };\n const onWheel = (e: WheelEvent) => {\n e.preventDefault();\n // Reset accumulator if scroll direction reversed mid-gesture.\n if (accumulated !== 0 && Math.sign(accumulated) !== Math.sign(e.deltaY)) {\n accumulated = 0;\n }\n accumulated += e.deltaY;\n while (Math.abs(accumulated) >= SCROLL_STEP_PX) {\n if (accumulated > 0) {\n moveBy(1);\n accumulated -= SCROLL_STEP_PX;\n } else {\n moveBy(-1);\n accumulated += SCROLL_STEP_PX;\n }\n }\n if (resetTimer) clearTimeout(resetTimer);\n resetTimer = setTimeout(resetAccumulator, QUIET_MS);\n };\n el.addEventListener('wheel', onWheel, { passive: false });\n return () => {\n el.removeEventListener('wheel', onWheel);\n if (resetTimer) clearTimeout(resetTimer);\n };\n }, [moveBy, disabled]);\n\n // Pointer drag.\n // We DELAY capturing the pointer until the user moves more than\n // DRAG_THRESHOLD_PX. Without this, capturing on pointerdown would redirect\n // mouseup → wheel root, which suppresses the click event on the item button\n // the user pressed (so single-clicks on neighbouring items would no-op).\n const DRAG_THRESHOLD_PX = 4;\n const onPointerDown = (e: React.PointerEvent<HTMLDivElement>) => {\n if (disabled) return;\n cancelRaf();\n if (audioTickEnabledRef.current) {\n // Resume the AudioContext from inside the user gesture so the first\n // tick of this drag can play (iOS Safari requires this; other browsers\n // are forgiving but it's a cheap idempotent call).\n unlockAudioTick();\n }\n const now =\n typeof performance !== 'undefined' ? performance.now() : Date.now();\n dragStateRef.current = {\n pointerId: e.pointerId,\n startY: e.clientY,\n startPosition: positionRef.current,\n captured: false,\n samples: [{ t: now, y: e.clientY }],\n };\n };\n const onPointerMove = (e: React.PointerEvent<HTMLDivElement>) => {\n const s = dragStateRef.current;\n if (s.pointerId !== e.pointerId) return;\n const dy = e.clientY - s.startY;\n if (!s.captured) {\n if (Math.abs(dy) < DRAG_THRESHOLD_PX) return;\n rootRef.current?.setPointerCapture(e.pointerId);\n s.captured = true;\n setIsDragging(true);\n }\n const now =\n typeof performance !== 'undefined' ? performance.now() : Date.now();\n s.samples.push({ t: now, y: e.clientY });\n // Keep the velocity sample window short so the post-flick velocity\n // reflects the *recent* finger speed, not the whole-drag average.\n const VELOCITY_WINDOW_MS = 100;\n while (s.samples.length > 2 && now - s.samples[0].t > VELOCITY_WINDOW_MS) {\n s.samples.shift();\n }\n // Continuous position: every itemHeight worth of finger drag advances\n // the wheel by 1 unit. Pulling the finger DOWN (positive dy) shows\n // EARLIER values, which means position decreases.\n commitPosition(s.startPosition - dy / itemHeight);\n };\n const onPointerUp = (e: React.PointerEvent<HTMLDivElement>) => {\n const s = dragStateRef.current;\n if (s.pointerId !== e.pointerId) return;\n if (s.captured) {\n rootRef.current?.releasePointerCapture(e.pointerId);\n // Drags don't fire click → focus would be left on whichever child\n // received pointerdown. Pull it back to the wheel root so :focus\n // emphasis still reads correctly after a drag.\n rootRef.current?.focus();\n // Compute fling velocity from the recent sample window.\n const samples = s.samples;\n let pxPerMs = 0;\n if (samples.length >= 2) {\n const first = samples[0];\n const last = samples[samples.length - 1];\n const dt = last.t - first.t;\n if (dt > 0) pxPerMs = (last.y - first.y) / dt;\n }\n // Threshold below which we just snap to the nearest item; above which\n // we kick off momentum.\n const FLING_THRESHOLD = 0.25; // px/ms ≈ 250 px/sec\n if (Math.abs(pxPerMs) > FLING_THRESHOLD) {\n startMomentum(pxPerMs);\n } else {\n animateSnap();\n }\n }\n s.pointerId = null;\n s.captured = false;\n s.samples = [];\n setIsDragging(false);\n };\n\n const rootClass = prefixedClassNames(classPrefix, 'timeinput-wheel', {\n [`is-${color}`]: !!color,\n [`is-${size}`]: !!size,\n 'is-disabled': disabled,\n 'is-dragging': isDragging,\n });\n const itemClass = (selected: boolean) =>\n prefixedClassNames(classPrefix, 'timeinput-wheel-item', {\n 'is-selected': selected,\n [`is-${color}`]: selected && !!color,\n });\n const bandClass = prefixedClassNames(classPrefix, 'timeinput-wheel-band', {\n [`is-${color}`]: !!color,\n });\n\n // Build the buffered window of items to render around the current position.\n const items: { vIdx: number; aIdx: number }[] = [];\n for (let off = -BUFFER; off <= BUFFER; off++) {\n const vIdx = virtualIdx + off;\n if (!wrap && (vIdx < 0 || vIdx >= N)) continue;\n const aIdx = toActual(vIdx);\n items.push({ vIdx, aIdx });\n }\n\n const ariaText = formatAriaText\n ? formatAriaText(values[toActual(virtualIdx)])\n : formatLabel(values[toActual(virtualIdx)]);\n\n // Center of the wheel viewport, in px from the top.\n const centreTop = containerHeight / 2 - itemHeight / 2;\n\n return (\n <div\n ref={rootRef}\n role=\"spinbutton\"\n aria-label={ariaLabel}\n aria-valuemin={0}\n aria-valuemax={N - 1}\n aria-valuenow={toActual(virtualIdx)}\n aria-valuetext={ariaText}\n tabIndex={disabled ? -1 : 0}\n className={rootClass}\n style={{ height: containerHeight }}\n onKeyDown={onKeyDown}\n onPointerDown={onPointerDown}\n onPointerMove={onPointerMove}\n onPointerUp={onPointerUp}\n onPointerCancel={onPointerUp}\n >\n {/* Stationary selection band — sits at the centre of the viewport while\n items slide through it, like the iOS native picker. The ref lets\n `playBandPulse` animate scale + brightness on each item tick. */}\n <div\n ref={bandRef}\n className={bandClass}\n aria-hidden=\"true\"\n style={{\n position: 'absolute',\n left: 0,\n right: 0,\n top: centreTop,\n height: itemHeight,\n pointerEvents: 'none',\n }}\n />\n {items.map(({ vIdx, aIdx }) => {\n // Continuous offset in items: items at the centre have offset ≈ 0;\n // top of viewport is negative, bottom positive.\n const offCentreItems = vIdx - position;\n const top = centreTop + offCentreItems * itemHeight;\n const selected = vIdx === virtualIdx;\n const itemDisabled =\n disabled || (disabledFor ? disabledFor(values[aIdx]) : false);\n return (\n <button\n key={vIdx}\n type=\"button\"\n // A spinbutton owns no options: it states its value through\n // aria-valuetext, so the items are pointer targets only.\n aria-hidden=\"true\"\n tabIndex={-1}\n className={itemClass(selected)}\n style={{\n position: 'absolute',\n left: 0,\n right: 0,\n height: itemHeight,\n top: `${top}px`,\n }}\n disabled={itemDisabled}\n // Keep a press from focusing the item, which assistive technology\n // can't see; the click below hands focus to the wheel instead.\n onMouseDown={e => e.preventDefault()}\n onClick={() => {\n moveBy(vIdx - virtualIdx);\n // Click focuses the <button> child by default; pull focus back\n // to the wheel root so the column emphasis (:focus rules) match.\n rootRef.current?.focus();\n }}\n >\n {formatLabel(values[aIdx])}\n </button>\n );\n })}\n </div>\n );\n};\n\nconst Wheel = React.forwardRef(WheelInner) as <T>(\n props: WheelProps<T> & { ref?: React.Ref<WheelHandle> }\n) => React.ReactElement;\n\nexport const TimeWheels: React.FC<TimeWheelsProps> = ({\n value,\n onChange,\n hourFormat = '24',\n enableSeconds = false,\n incrementHours = 1,\n incrementMinutes = 1,\n incrementSeconds = 1,\n unselectableTimes,\n size,\n color,\n disabled,\n className,\n id,\n labels,\n visibleCount = 5,\n itemHeight = 32,\n audioTick = false,\n onCommit,\n}) => {\n const t = mergeLabels(labels);\n\n const rootClass = usePrefixedClassNames('timeinput', {\n [`is-${color}`]: !!color,\n [`is-${size}`]: !!size,\n 'is-disabled': disabled,\n });\n const wheelsClass = usePrefixedClassNames('timeinput-wheels');\n const sepClass = usePrefixedClassNames('timeinput-separator');\n // Use the prefixed class through the same helper the wheels themselves do,\n // so the selector matches the actual rendered class regardless of whether\n // the consumer configured `classPrefix` via ConfigProvider. Building the\n // selector with `${classPrefix}timeinput-wheel` is wrong when classPrefix\n // is undefined (defaults to the empty prefix) — it would stringify to\n // \"undefinedtimeinput-wheel\".\n const wheelSingleClass = usePrefixedClassNames('timeinput-wheel');\n const wheelsContainerRef = useRef<HTMLDivElement>(null);\n\n const isPm = value.hours >= 12;\n\n const isTimeAllowed = useCallback(\n (h: number, m: number, s: number) => {\n if (!unselectableTimes) return true;\n const probe = setTimeOfDay(new Date(), {\n hours: h,\n minutes: m,\n seconds: s,\n milliseconds: 0,\n });\n return !unselectableTimes(probe);\n },\n [unselectableTimes]\n );\n\n // Per-column \"is this value disabled?\" predicates. We compute them against\n // the current value's other parts, so e.g. a predicate that only blocks\n // 12:00–12:59 leaves all minutes selectable when the user moves the hour\n // off 12. Returning `undefined` (rather than a function) when there is no\n // unselectableTimes lets the Wheel skip the disabled-attribute branch.\n const isHourDisabled = useCallback(\n (display: number) => {\n let h24 = display;\n if (hourFormat === '12') {\n const base = display % 12;\n h24 = isPm ? base + 12 : base;\n }\n return !isTimeAllowed(h24, value.minutes, value.seconds ?? 0);\n },\n [hourFormat, isPm, isTimeAllowed, value.minutes, value.seconds]\n );\n const isMinuteDisabled = useCallback(\n (m: number) => !isTimeAllowed(value.hours, m, value.seconds ?? 0),\n [isTimeAllowed, value.hours, value.seconds]\n );\n const isSecondDisabled = useCallback(\n (s: number) => !isTimeAllowed(value.hours, value.minutes, s),\n [isTimeAllowed, value.hours, value.minutes]\n );\n const hourDisabledFor = unselectableTimes ? isHourDisabled : undefined;\n const minuteDisabledFor = unselectableTimes ? isMinuteDisabled : undefined;\n const secondDisabledFor = unselectableTimes ? isSecondDisabled : undefined;\n\n const commit = useCallback(\n (next: Partial<TimeWheelsValue>) => {\n const merged: TimeWheelsValue = {\n hours: next.hours ?? value.hours,\n minutes: next.minutes ?? value.minutes,\n seconds: enableSeconds\n ? (next.seconds ?? value.seconds ?? 0)\n : undefined,\n };\n if (!isTimeAllowed(merged.hours, merged.minutes, merged.seconds ?? 0)) {\n return;\n }\n onChange(merged);\n },\n [value, enableSeconds, isTimeAllowed, onChange]\n );\n\n // Build the value lists per column.\n const hourValues = useMemo<number[]>(() => {\n const step = Math.max(1, incrementHours);\n if (hourFormat === '12') {\n const out: number[] = [];\n for (let h = 1; h <= 12; h += step) out.push(h);\n return out;\n }\n const out: number[] = [];\n for (let h = 0; h < 24; h += step) out.push(h);\n return out;\n }, [hourFormat, incrementHours]);\n\n const minuteValues = useMemo<number[]>(() => {\n const step = Math.max(1, incrementMinutes);\n const out: number[] = [];\n for (let m = 0; m < 60; m += step) out.push(m);\n return out;\n }, [incrementMinutes]);\n\n const secondValues = useMemo<number[]>(() => {\n const step = Math.max(1, incrementSeconds);\n const out: number[] = [];\n for (let s = 0; s < 60; s += step) out.push(s);\n return out;\n }, [incrementSeconds]);\n\n // Map current value → wheel index.\n const displayedHours =\n hourFormat === '12'\n ? value.hours % 12 === 0\n ? 12\n : value.hours % 12\n : value.hours;\n const hourIndex = Math.max(0, hourValues.indexOf(displayedHours));\n const minuteIndex = Math.max(0, minuteValues.indexOf(value.minutes));\n const secondIndex = Math.max(0, secondValues.indexOf(value.seconds ?? 0));\n const ampmIndex = isPm ? 1 : 0;\n\n // Refs for column focus management.\n const hoursRef = useRef<WheelHandle>(null);\n const minutesRef = useRef<WheelHandle>(null);\n const secondsRef = useRef<WheelHandle>(null);\n const ampmRef = useRef<WheelHandle>(null);\n\n // Build the focus order at runtime.\n const columnOrder: React.RefObject<WheelHandle | null>[] = [];\n columnOrder.push(hoursRef);\n columnOrder.push(minutesRef);\n if (enableSeconds) columnOrder.push(secondsRef);\n if (hourFormat === '12') columnOrder.push(ampmRef);\n const focusAt = (i: number) => columnOrder[i]?.current?.focus();\n const indexOf = (r: React.RefObject<WheelHandle | null>): number =>\n columnOrder.indexOf(r);\n const focusPrevOf = (r: React.RefObject<WheelHandle | null>) => () =>\n focusAt(indexOf(r) - 1);\n const focusNextOf = (r: React.RefObject<WheelHandle | null>) => () =>\n focusAt(indexOf(r) + 1);\n\n // Hour change — translate displayed value back into 24h.\n const onHourIndex = (next: number) => {\n const display =\n hourValues[Math.max(0, Math.min(hourValues.length - 1, next))];\n let next24 = display;\n if (hourFormat === '12') {\n const baseHour = display % 12;\n next24 = isPm ? baseHour + 12 : baseHour;\n }\n // Skip past any blocked hour using nextValid.\n const allowed = nextValid(next24, next24 >= value.hours ? 1 : -1, 24, h =>\n isTimeAllowed(h, value.minutes, value.seconds ?? 0)\n );\n commit({ hours: allowed });\n };\n\n const onMinuteIndex = (next: number) => {\n const m =\n minuteValues[Math.max(0, Math.min(minuteValues.length - 1, next))];\n const allowed = nextValid(m, m >= value.minutes ? 1 : -1, 60, mm =>\n isTimeAllowed(value.hours, mm, value.seconds ?? 0)\n );\n commit({ minutes: allowed });\n };\n\n const onSecondIndex = (next: number) => {\n const s =\n secondValues[Math.max(0, Math.min(secondValues.length - 1, next))];\n const allowed = nextValid(s, s >= (value.seconds ?? 0) ? 1 : -1, 60, ss =>\n isTimeAllowed(value.hours, value.minutes, ss)\n );\n commit({ seconds: allowed });\n };\n\n const onAmpmIndex = (next: number) => {\n if (next === ampmIndex) return;\n commit({ hours: (value.hours + 12) % 24 });\n };\n\n // Forward drags that originate on the empty space inside the wheels row\n // (left of the leftmost wheel, right of the rightmost wheel, on the\n // separator) to whichever wheel column is nearest to the pointer X — so\n // the picker behaves like the iOS native one, where the whole picker\n // surface is grabbable, not just the column itself.\n const onWheelsContainerPointerDown = (\n e: React.PointerEvent<HTMLDivElement>\n ) => {\n if (disabled) return;\n // If the pointerdown landed on a real wheel column, the wheel's own\n // handler takes over — don't double-dispatch.\n if ((e.target as HTMLElement).closest(`.${wheelSingleClass}`)) return;\n const container = wheelsContainerRef.current;\n /* istanbul ignore next: the handler is attached to the very element this ref points to, so it can't be null while events fire */\n if (!container) return;\n const wheels = container.querySelectorAll<HTMLElement>(\n `.${wheelSingleClass}`\n );\n if (wheels.length === 0) return;\n let nearestIdx = 0;\n let nearestDist = Infinity;\n const x = e.clientX;\n wheels.forEach((el, i) => {\n const r = el.getBoundingClientRect();\n const cx = (r.left + r.right) / 2;\n const d = Math.abs(x - cx);\n if (d < nearestDist) {\n nearestDist = d;\n nearestIdx = i;\n }\n });\n columnOrder[nearestIdx]?.current?.startDrag(e.pointerId, e.clientY);\n };\n\n return (\n <div\n id={id}\n className={classNames(rootClass, className)}\n aria-disabled={disabled}\n >\n <div\n className={wheelsClass}\n ref={wheelsContainerRef}\n onPointerDown={onWheelsContainerPointerDown}\n >\n <Wheel\n ref={hoursRef}\n values={hourValues}\n index={hourIndex}\n onChange={onHourIndex}\n formatLabel={pad2}\n ariaLabel={t.hours}\n visibleCount={visibleCount}\n itemHeight={itemHeight}\n disabled={disabled}\n size={size}\n color={color}\n wrap\n onCommit={onCommit}\n onFocusPrev={focusPrevOf(hoursRef)}\n onFocusNext={focusNextOf(hoursRef)}\n disabledFor={hourDisabledFor}\n audioTick={audioTick}\n />\n <div className={sepClass} aria-hidden=\"true\">\n :\n </div>\n <Wheel\n ref={minutesRef}\n values={minuteValues}\n index={minuteIndex}\n onChange={onMinuteIndex}\n formatLabel={pad2}\n ariaLabel={t.minutes}\n visibleCount={visibleCount}\n itemHeight={itemHeight}\n disabled={disabled}\n size={size}\n color={color}\n wrap\n onCommit={onCommit}\n onFocusPrev={focusPrevOf(minutesRef)}\n onFocusNext={focusNextOf(minutesRef)}\n disabledFor={minuteDisabledFor}\n audioTick={audioTick}\n />\n {enableSeconds && (\n <>\n <div className={sepClass} aria-hidden=\"true\">\n :\n </div>\n <Wheel\n ref={secondsRef}\n values={secondValues}\n index={secondIndex}\n onChange={onSecondIndex}\n formatLabel={pad2}\n ariaLabel={t.seconds}\n visibleCount={visibleCount}\n itemHeight={itemHeight}\n disabled={disabled}\n size={size}\n color={color}\n wrap\n onCommit={onCommit}\n onFocusPrev={focusPrevOf(secondsRef)}\n onFocusNext={focusNextOf(secondsRef)}\n disabledFor={secondDisabledFor}\n audioTick={audioTick}\n />\n </>\n )}\n {hourFormat === '12' && (\n <Wheel\n ref={ampmRef}\n values={['AM', 'PM']}\n index={ampmIndex}\n onChange={onAmpmIndex}\n formatLabel={v => v}\n ariaLabel={t.ampm}\n visibleCount={visibleCount}\n itemHeight={itemHeight}\n disabled={disabled}\n size={size}\n color={color}\n onCommit={onCommit}\n onFocusPrev={focusPrevOf(ampmRef)}\n onFocusNext={focusNextOf(ampmRef)}\n audioTick={audioTick}\n />\n )}\n </div>\n </div>\n );\n};\n\nTimeWheels.displayName = 'TimeWheels';\n\nexport default TimeWheels;\n"],"names":["fireTickHaptic","_jsxs","_jsx","_Fragment"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"TimeWheels.js","sources":["../../../../src/form/_pickerInternals/TimeWheels.tsx"],"sourcesContent":["/* eslint-disable react-hooks/refs --\n * This wheel/momentum picker intentionally accesses refs during render:\n * - state is mirrored into refs (positionRef, audioTickEnabledRef) so the\n * RAF/drag/tick callbacks read the latest values in lockstep with rendering\n * (refactoring to effect-synced refs would desync drag from the frame);\n * - a MediaQueryList is lazily cached in a ref (reducedMotionMqlRef);\n * - per-column Wheel handle refs build the keyboard focus order.\n * These are deliberate, established patterns; behavior is covered by unit tests\n * and certified interactively in-browser (drag, ticks, keyboard focus nav).\n */\nimport React, {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport {\n classNames,\n prefixedClassNames,\n usePrefixedClassNames,\n} from '../../helpers/classNames';\nimport { useConfig } from '../../helpers/Config';\nimport {\n HourFormat,\n PickerLabels,\n isPopoverToggleKey,\n mergeLabels,\n} from './pickerTypes';\nimport { setTimeOfDay } from './dateUtils';\nimport { tickHaptic as fireTickHaptic } from './haptics';\nimport { playAudioTick, unlockAudioTick } from './audioTick';\n\nexport interface TimeWheelsValue {\n hours: number;\n minutes: number;\n seconds?: number;\n}\n\nexport interface TimeWheelsProps {\n value: TimeWheelsValue;\n onChange: (v: TimeWheelsValue) => void;\n hourFormat?: HourFormat;\n enableSeconds?: boolean;\n /** Step between visible values in the wheel. Default `1`. */\n incrementHours?: number;\n incrementMinutes?: number;\n incrementSeconds?: number;\n unselectableTimes?: (d: Date) => boolean;\n size?: 'small' | 'medium' | 'large';\n color?: 'primary' | 'link' | 'info' | 'success' | 'warning' | 'danger';\n disabled?: boolean;\n className?: string;\n id?: string;\n labels?: PickerLabels;\n /** Number of items visible at once (must be odd). Default 5. */\n visibleCount?: number;\n /** Item height in px. Default 32. */\n itemHeight?: number;\n /**\n * Play a short audible tick on each item crossing. Useful as a fallback on\n * iOS Safari, where there is no web-accessible haptic API. Off by default\n * to avoid surprising users with sound; flip on for iOS-targeted UIs.\n */\n audioTick?: boolean;\n /**\n * Fired when the user presses Enter on a wheel column. The current value is\n * already committed (each wheel-tick calls onChange), so this typically just\n * needs to close the surrounding popover.\n */\n onCommit?: () => void;\n}\n\nconst wrap = (n: number, max: number): number => ((n % max) + max) % max;\n\n/**\n * Walk forward (or backward) from `start` in `step` steps until `test` returns\n * true or we've cycled all `max` candidates. Used to skip past unselectable\n * values without freezing the wheel.\n */\nfunction nextValid(\n start: number,\n step: number,\n max: number,\n test: (n: number) => boolean\n): number {\n let candidate = wrap(start, max);\n for (let i = 0; i < max; i++) {\n if (test(candidate)) return candidate;\n candidate = wrap(candidate + step, max);\n }\n return start;\n}\n\nconst pad2 = (n: number): string => String(n).padStart(2, '0');\n\ninterface WheelHandle {\n focus: () => void;\n /**\n * Begin a drag externally — used by the parent's empty-space forwarder so\n * the user can grab the wheel by touching anywhere in the wheels row, not\n * just on the column itself (matches iOS native picker behavior).\n *\n * The pointer must already be active (i.e., a real `pointerdown` is in\n * flight). We immediately capture the pointer on the wheel root so the\n * existing `onPointerMove` / `onPointerUp` handlers will fire here.\n */\n startDrag: (pointerId: number, clientY: number) => void;\n}\n\ninterface WheelProps<T> {\n values: T[];\n index: number;\n onChange: (nextIndex: number) => void;\n formatLabel: (v: T) => string;\n formatAriaText?: (v: T) => string;\n ariaLabel: string;\n visibleCount: number;\n itemHeight: number;\n disabled?: boolean;\n size?: 'small' | 'medium' | 'large';\n color?: 'primary' | 'link' | 'info' | 'success' | 'warning' | 'danger';\n onFocusPrev?: () => void;\n onFocusNext?: () => void;\n /** Fired when Enter is pressed (current value is already committed live). */\n onCommit?: () => void;\n /**\n * Whether the wheel wraps at the edges. When true, scrolling past the last\n * value rolls back to the first (and vice versa) and neighbouring values\n * are visible above the first / below the last item.\n */\n wrap?: boolean;\n /**\n * Optional predicate. Items for which it returns `true` are rendered with\n * the `disabled` attribute (and visually dimmed via the `:disabled` SCSS\n * rule), giving users a clear cue that the value is blocked. Keyboard /\n * wheel navigation may still pass over these positions, but `onChange`\n * callers (`TimeWheels`) skip them via `nextValid`.\n */\n disabledFor?: (v: T) => boolean;\n /**\n * Play an audible tick on each item crossing. Used as the iOS substitute\n * for haptic feedback; threaded from `TimeWheels.audioTick`.\n */\n audioTick?: boolean;\n}\n\nconst WheelInner = <T,>(\n {\n values,\n index,\n onChange,\n formatLabel,\n formatAriaText,\n ariaLabel,\n visibleCount,\n itemHeight,\n disabled,\n size,\n color,\n onFocusPrev,\n onFocusNext,\n onCommit,\n wrap = false,\n disabledFor,\n audioTick = false,\n }: WheelProps<T>,\n ref: React.Ref<WheelHandle>\n) => {\n const { classPrefix } = useConfig();\n const N = values.length;\n const half = Math.floor(visibleCount / 2);\n const containerHeight = visibleCount * itemHeight;\n // Buffer around the visible window so adjacent items animate in/out smoothly.\n const BUFFER = half + 2;\n\n // Continuous wheel position in units of items. Math.round(position) is the\n // \"active\" virtual index; the fractional part is the drag/momentum offset\n // within an item slot. Using a single float (rather than virtualIdx +\n // dragOffset) keeps drag and tick-update in lockstep so items move with the\n // finger without a 40px overshoot when crossing item boundaries.\n const [position, setPosition] = useState<number>(index);\n const positionRef = useRef<number>(index);\n positionRef.current = position;\n const [isDragging, setIsDragging] = useState(false);\n const rootRef = useRef<HTMLDivElement>(null);\n // Ref to the stationary selection band — populated by the JSX below. The\n // band briefly scales + brightens on each item tick so users perceive a\n // body-felt \"thunk\" even on iOS where no haptic API exists.\n const bandRef = useRef<HTMLDivElement>(null);\n // Cached MediaQueryList for `prefers-reduced-motion`. We read this on\n // every tick to decide whether to fire the band pulse; caching the MQL\n // saves a `matchMedia` call per tick (which can fire at ~20Hz during a\n // momentum flick).\n const reducedMotionMqlRef = useRef<MediaQueryList | null>(null);\n if (\n reducedMotionMqlRef.current === null &&\n typeof window !== 'undefined' &&\n typeof window.matchMedia === 'function'\n ) {\n reducedMotionMqlRef.current = window.matchMedia(\n '(prefers-reduced-motion: reduce)'\n );\n }\n // In-flight band pulse animation (Web Animations API). Tracked so we can\n // cancel on unmount; the WAI's `composite: 'replace'` semantics handle\n // re-trigger automatically without us needing to cancel between ticks.\n const pulseAnimRef = useRef<Animation | null>(null);\n // True while the external `index` prop sync useEffect runs, so we don't\n // fire a haptic blip when the parent updates the value programmatically.\n const isSyncingRef = useRef<boolean>(false);\n\n // Tiny haptic/audio/visual blip per item tick. Haptic uses\n // `navigator.vibrate` where available (Android Chrome / Firefox Android /\n // Samsung Internet); iOS has no web-accessible haptic path as of May\n // 2026, so the optional `audioTick` plays a low-frequency thunk as the\n // closest UX substitute. The visual band-pulse fires on every tick on\n // every platform (gated only by `prefers-reduced-motion`) so the\n // selection band feels reactive — visual reinforcement of the tactile\n // feedback. We skip all three during programmatic prop sync so a parent\n // re-render doesn't blip.\n const audioTickEnabledRef = useRef<boolean>(audioTick);\n audioTickEnabledRef.current = audioTick;\n const playBandPulse = useCallback(() => {\n const el = bandRef.current;\n if (!el || typeof el.animate !== 'function') return;\n if (reducedMotionMqlRef.current?.matches) return;\n // Compound scale + brightness pulse, peaking at 40% through the 110ms\n // duration. `composite: 'replace'` means a re-trigger mid-pulse cleanly\n // restarts rather than queueing — important at fling rates where ticks\n // can fire every ~50ms.\n pulseAnimRef.current = el.animate(\n [\n { transform: 'scale(1)', filter: 'brightness(1)' },\n {\n transform: 'scale(1.04)',\n filter: 'brightness(1.15)',\n offset: 0.4,\n },\n { transform: 'scale(1)', filter: 'brightness(1)' },\n ],\n { duration: 110, easing: 'ease-out', composite: 'replace' }\n );\n }, []);\n const tickFeedback = useCallback(() => {\n /* istanbul ignore next: the sync flag is only true synchronously inside the prop-sync effect, which sets position directly and never routes through commitPosition */\n if (isSyncingRef.current) return;\n fireTickHaptic();\n if (audioTickEnabledRef.current) playAudioTick();\n playBandPulse();\n }, [playBandPulse]);\n const dragStateRef = useRef<{\n pointerId: number | null;\n startY: number;\n startPosition: number;\n captured: boolean;\n samples: { t: number; y: number }[];\n }>({\n pointerId: null,\n startY: 0,\n startPosition: 0,\n captured: false,\n samples: [],\n });\n // RAF id for the in-flight momentum / snap animation, so we can cancel when\n // the user grabs the wheel again or the component unmounts.\n const rafIdRef = useRef<number | null>(null);\n\n const virtualIdx = Math.round(position);\n\n const cancelRaf = useCallback(() => {\n if (rafIdRef.current !== null) {\n cancelAnimationFrame(rafIdRef.current);\n rafIdRef.current = null;\n }\n }, []);\n\n useEffect(\n () => () => {\n cancelRaf();\n // Cancel any in-flight band pulse so it doesn't keep a reference to\n // a detached DOM node. WAI Animation.cancel() is safe to call even\n // if the animation has already finished.\n pulseAnimRef.current?.cancel();\n pulseAnimRef.current = null;\n },\n [cancelRaf]\n );\n\n React.useImperativeHandle(\n ref,\n () => ({\n focus: () => rootRef.current?.focus(),\n startDrag: (pointerId: number, clientY: number) => {\n /* istanbul ignore next: the empty-space forwarder (sole caller) already returns on the same disabled prop */\n if (disabled) return;\n cancelRaf();\n if (audioTickEnabledRef.current) unlockAudioTick();\n const now =\n typeof performance !== 'undefined' ? performance.now() : Date.now();\n dragStateRef.current = {\n pointerId,\n startY: clientY,\n startPosition: positionRef.current,\n // Skip the drag-threshold gate: the parent forwarder has already\n // decided this is a drag (a pointerdown landed on empty space,\n // which has no click target).\n captured: true,\n samples: [{ t: now, y: clientY }],\n };\n try {\n rootRef.current?.setPointerCapture(pointerId);\n } catch {\n // setPointerCapture can throw if the pointer isn't currently\n // active for this element; the existing onPointerMove handler\n // still matches on pointerId so the drag will work either way.\n }\n setIsDragging(true);\n },\n }),\n [disabled, cancelRaf]\n );\n\n // Resolve a virtualIdx into an actual values[] index (modulo wrap if `wrap`).\n const toActual = useCallback(\n (v: number) => {\n if (wrap) return ((v % N) + N) % N;\n return Math.max(0, Math.min(N - 1, v));\n },\n [wrap, N]\n );\n\n const clampPosition = useCallback(\n (p: number) => {\n if (wrap) return p;\n return Math.max(0, Math.min(N - 1, p));\n },\n [wrap, N]\n );\n\n // Update position and fire onChange if the rounded value changed.\n const commitPosition = useCallback(\n (next: number) => {\n const clamped = clampPosition(next);\n const prevRound = Math.round(positionRef.current);\n const nextRound = Math.round(clamped);\n positionRef.current = clamped;\n setPosition(clamped);\n if (nextRound !== prevRound) {\n onChange(toActual(nextRound));\n tickFeedback();\n }\n },\n [clampPosition, onChange, toActual, tickFeedback]\n );\n\n // When the external `index` changes (e.g. from typed input), re-sync\n // position to the closest virtual position that maps to it.\n //\n // Crucial subtlety: this effect re-runs every time the parent value\n // changes — including the round-trip case where the user's own scroll\n // commits a tick → fires onChange → parent re-renders with the new\n // index → here. If we cancelled the in-flight momentum/snap RAF on\n // every such echo, the snap would never get to land on an integer\n // (the user's wheel would stop wherever the last tick fired). So we\n // bail out early when the rounded position already matches the\n // incoming index — the echo case — and only cancel + apply an actual\n // jump when the parent has moved us somewhere we don't already round\n // to.\n useEffect(() => {\n const prev = positionRef.current;\n const wrappedRoundPrev = ((Math.round(prev) % N) + N) % N;\n if (wrappedRoundPrev === index) return;\n cancelRaf();\n isSyncingRef.current = true;\n setPosition(prevPos => {\n if (!wrap) {\n positionRef.current = index;\n return index;\n }\n const wrappedPrev = ((prevPos % N) + N) % N;\n const forward = (index - wrappedPrev + N) % N;\n const backward = forward - N;\n const delta =\n Math.abs(forward) <= Math.abs(backward) ? forward : backward;\n const next = prevPos + delta;\n positionRef.current = next;\n return next;\n });\n isSyncingRef.current = false;\n }, [index, N, wrap, cancelRaf]);\n\n const moveBy = useCallback(\n (delta: number) => {\n if (disabled) return;\n cancelRaf();\n commitPosition(Math.round(positionRef.current) + delta);\n },\n [disabled, cancelRaf, commitPosition]\n );\n\n // The keys are a spinbutton's: up raises the value and down lowers it. The\n // values run down the wheel, so up brings the one below the band into it,\n // the way a drag or a scroll that moves the items up does.\n const onKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n if (isPopoverToggleKey(e)) return;\n switch (e.key) {\n case 'ArrowUp':\n e.preventDefault();\n moveBy(1);\n break;\n case 'ArrowDown':\n e.preventDefault();\n moveBy(-1);\n break;\n case 'PageUp':\n e.preventDefault();\n moveBy(5);\n break;\n case 'PageDown':\n e.preventDefault();\n moveBy(-5);\n break;\n case 'Home':\n e.preventDefault();\n if (disabled) break;\n cancelRaf();\n commitPosition(0);\n break;\n case 'End':\n e.preventDefault();\n if (disabled) break;\n cancelRaf();\n commitPosition(N - 1);\n break;\n case 'ArrowLeft':\n e.preventDefault();\n onFocusPrev?.();\n break;\n case 'ArrowRight':\n e.preventDefault();\n onFocusNext?.();\n break;\n case 'Enter':\n e.preventDefault();\n onCommit?.();\n break;\n }\n },\n [\n moveBy,\n disabled,\n commitPosition,\n cancelRaf,\n N,\n onFocusPrev,\n onFocusNext,\n onCommit,\n ]\n );\n\n // Animate position to the nearest integer with ease-out cubic. Used after a\n // drag / momentum settles, so the wheel always rests aligned to an item.\n const animateSnap = useCallback(() => {\n cancelRaf();\n const start = positionRef.current;\n const target = Math.round(start);\n if (start === target) return;\n const duration = 180;\n const startTime =\n typeof performance !== 'undefined' ? performance.now() : Date.now();\n const tick = (now: number) => {\n const t = Math.min(1, (now - startTime) / duration);\n const eased = 1 - Math.pow(1 - t, 3);\n const next = start + (target - start) * eased;\n commitPosition(next);\n if (t < 1) {\n rafIdRef.current = requestAnimationFrame(tick);\n } else {\n rafIdRef.current = null;\n }\n };\n rafIdRef.current = requestAnimationFrame(tick);\n }, [cancelRaf, commitPosition]);\n\n // Kinetic momentum after a flick. Uses exponential friction so the velocity\n // tapers smoothly. Updates `position` in items/ms; commitPosition handles\n // the onChange ticks as virtualIdx crosses integers.\n const startMomentum = useCallback(\n (initialPxPerMs: number) => {\n cancelRaf();\n // Drag-up (negative dy/dt in screen coords) should INCREASE position\n // (later values come into view), so flip the sign.\n let velocity = -initialPxPerMs / itemHeight; // items / ms\n // Cap initial velocity so a frantic swipe doesn't blast through the\n // whole list. Empirically tuned to match iOS feel.\n const MAX_VEL = 0.05; // items/ms (≈ 50 items/sec)\n if (velocity > MAX_VEL) velocity = MAX_VEL;\n if (velocity < -MAX_VEL) velocity = -MAX_VEL;\n const STOP_VEL = 0.0015; // items/ms (≈ 1.5 items/sec)\n // Friction coefficient per millisecond — chosen so velocity halves\n // every ~120ms.\n const FRICTION_PER_MS = Math.pow(0.5, 1 / 120);\n let lastTime =\n typeof performance !== 'undefined' ? performance.now() : Date.now();\n const tick = (now: number) => {\n const dt = Math.max(1, now - lastTime);\n lastTime = now;\n let next = positionRef.current + velocity * dt;\n // Boundary handling for non-wrapping wheels: clamp and zero the\n // velocity so we don't keep ticking against the wall.\n if (!wrap) {\n if (next <= 0) {\n next = 0;\n velocity = 0;\n } else if (next >= N - 1) {\n next = N - 1;\n velocity = 0;\n }\n }\n commitPosition(next);\n velocity *= Math.pow(FRICTION_PER_MS, dt);\n if (Math.abs(velocity) < STOP_VEL) {\n animateSnap();\n return;\n }\n rafIdRef.current = requestAnimationFrame(tick);\n };\n rafIdRef.current = requestAnimationFrame(tick);\n },\n [cancelRaf, commitPosition, itemHeight, wrap, N, animateSnap]\n );\n\n // Mouse wheel: accumulate deltaY across events and step when the\n // accumulator crosses SCROLL_STEP_PX. Trackpads emit dozens of small\n // events per swipe; without accumulation a single gesture flies the wheel.\n useEffect(() => {\n const el = rootRef.current;\n if (!el || disabled) return undefined;\n const SCROLL_STEP_PX = 60;\n const QUIET_MS = 250;\n let accumulated = 0;\n let resetTimer: ReturnType<typeof setTimeout> | null = null;\n const resetAccumulator = () => {\n accumulated = 0;\n };\n const onWheel = (e: WheelEvent) => {\n e.preventDefault();\n // Reset accumulator if scroll direction reversed mid-gesture.\n if (accumulated !== 0 && Math.sign(accumulated) !== Math.sign(e.deltaY)) {\n accumulated = 0;\n }\n accumulated += e.deltaY;\n while (Math.abs(accumulated) >= SCROLL_STEP_PX) {\n if (accumulated > 0) {\n moveBy(1);\n accumulated -= SCROLL_STEP_PX;\n } else {\n moveBy(-1);\n accumulated += SCROLL_STEP_PX;\n }\n }\n if (resetTimer) clearTimeout(resetTimer);\n resetTimer = setTimeout(resetAccumulator, QUIET_MS);\n };\n el.addEventListener('wheel', onWheel, { passive: false });\n return () => {\n el.removeEventListener('wheel', onWheel);\n if (resetTimer) clearTimeout(resetTimer);\n };\n }, [moveBy, disabled]);\n\n // Pointer drag.\n // We DELAY capturing the pointer until the user moves more than\n // DRAG_THRESHOLD_PX. Without this, capturing on pointerdown would redirect\n // mouseup → wheel root, which suppresses the click event on the item button\n // the user pressed (so single-clicks on neighbouring items would no-op).\n const DRAG_THRESHOLD_PX = 4;\n const onPointerDown = (e: React.PointerEvent<HTMLDivElement>) => {\n if (disabled) return;\n cancelRaf();\n if (audioTickEnabledRef.current) {\n // Resume the AudioContext from inside the user gesture so the first\n // tick of this drag can play (iOS Safari requires this; other browsers\n // are forgiving but it's a cheap idempotent call).\n unlockAudioTick();\n }\n const now =\n typeof performance !== 'undefined' ? performance.now() : Date.now();\n dragStateRef.current = {\n pointerId: e.pointerId,\n startY: e.clientY,\n startPosition: positionRef.current,\n captured: false,\n samples: [{ t: now, y: e.clientY }],\n };\n };\n const onPointerMove = (e: React.PointerEvent<HTMLDivElement>) => {\n const s = dragStateRef.current;\n if (s.pointerId !== e.pointerId) return;\n const dy = e.clientY - s.startY;\n if (!s.captured) {\n if (Math.abs(dy) < DRAG_THRESHOLD_PX) return;\n rootRef.current?.setPointerCapture(e.pointerId);\n s.captured = true;\n setIsDragging(true);\n }\n const now =\n typeof performance !== 'undefined' ? performance.now() : Date.now();\n s.samples.push({ t: now, y: e.clientY });\n // Keep the velocity sample window short so the post-flick velocity\n // reflects the *recent* finger speed, not the whole-drag average.\n const VELOCITY_WINDOW_MS = 100;\n while (s.samples.length > 2 && now - s.samples[0].t > VELOCITY_WINDOW_MS) {\n s.samples.shift();\n }\n // Continuous position: every itemHeight worth of finger drag advances\n // the wheel by 1 unit. Pulling the finger DOWN (positive dy) shows\n // EARLIER values, which means position decreases.\n commitPosition(s.startPosition - dy / itemHeight);\n };\n const onPointerUp = (e: React.PointerEvent<HTMLDivElement>) => {\n const s = dragStateRef.current;\n if (s.pointerId !== e.pointerId) return;\n if (s.captured) {\n rootRef.current?.releasePointerCapture(e.pointerId);\n // Drags don't fire click → focus would be left on whichever child\n // received pointerdown. Pull it back to the wheel root so :focus\n // emphasis still reads correctly after a drag.\n rootRef.current?.focus();\n // Compute fling velocity from the recent sample window.\n const samples = s.samples;\n let pxPerMs = 0;\n if (samples.length >= 2) {\n const first = samples[0];\n const last = samples[samples.length - 1];\n const dt = last.t - first.t;\n if (dt > 0) pxPerMs = (last.y - first.y) / dt;\n }\n // Threshold below which we just snap to the nearest item; above which\n // we kick off momentum.\n const FLING_THRESHOLD = 0.25; // px/ms ≈ 250 px/sec\n if (Math.abs(pxPerMs) > FLING_THRESHOLD) {\n startMomentum(pxPerMs);\n } else {\n animateSnap();\n }\n }\n s.pointerId = null;\n s.captured = false;\n s.samples = [];\n setIsDragging(false);\n };\n\n const rootClass = prefixedClassNames(classPrefix, 'timeinput-wheel', {\n [`is-${color}`]: !!color,\n [`is-${size}`]: !!size,\n 'is-disabled': disabled,\n 'is-dragging': isDragging,\n });\n const itemClass = (selected: boolean) =>\n prefixedClassNames(classPrefix, 'timeinput-wheel-item', {\n 'is-selected': selected,\n [`is-${color}`]: selected && !!color,\n });\n const bandClass = prefixedClassNames(classPrefix, 'timeinput-wheel-band', {\n [`is-${color}`]: !!color,\n });\n\n // Build the buffered window of items to render around the current position.\n const items: { vIdx: number; aIdx: number }[] = [];\n for (let off = -BUFFER; off <= BUFFER; off++) {\n const vIdx = virtualIdx + off;\n if (!wrap && (vIdx < 0 || vIdx >= N)) continue;\n const aIdx = toActual(vIdx);\n items.push({ vIdx, aIdx });\n }\n\n const ariaText = formatAriaText\n ? formatAriaText(values[toActual(virtualIdx)])\n : formatLabel(values[toActual(virtualIdx)]);\n\n // Center of the wheel viewport, in px from the top.\n const centreTop = containerHeight / 2 - itemHeight / 2;\n\n return (\n <div\n ref={rootRef}\n role=\"spinbutton\"\n aria-label={ariaLabel}\n aria-valuemin={0}\n aria-valuemax={N - 1}\n aria-valuenow={toActual(virtualIdx)}\n aria-valuetext={ariaText}\n tabIndex={disabled ? -1 : 0}\n className={rootClass}\n style={{ height: containerHeight }}\n onKeyDown={onKeyDown}\n onPointerDown={onPointerDown}\n onPointerMove={onPointerMove}\n onPointerUp={onPointerUp}\n onPointerCancel={onPointerUp}\n >\n {/* Stationary selection band — sits at the centre of the viewport while\n items slide through it, like the iOS native picker. The ref lets\n `playBandPulse` animate scale + brightness on each item tick. */}\n <div\n ref={bandRef}\n className={bandClass}\n aria-hidden=\"true\"\n style={{\n position: 'absolute',\n left: 0,\n right: 0,\n top: centreTop,\n height: itemHeight,\n pointerEvents: 'none',\n }}\n />\n {items.map(({ vIdx, aIdx }) => {\n // Continuous offset in items: items at the centre have offset ≈ 0;\n // top of viewport is negative, bottom positive.\n const offCentreItems = vIdx - position;\n const top = centreTop + offCentreItems * itemHeight;\n const selected = vIdx === virtualIdx;\n const itemDisabled =\n disabled || (disabledFor ? disabledFor(values[aIdx]) : false);\n return (\n <button\n key={vIdx}\n type=\"button\"\n // A spinbutton owns no options: it states its value through\n // aria-valuetext, so the items are pointer targets only.\n aria-hidden=\"true\"\n tabIndex={-1}\n className={itemClass(selected)}\n style={{\n position: 'absolute',\n left: 0,\n right: 0,\n height: itemHeight,\n top: `${top}px`,\n }}\n disabled={itemDisabled}\n // Keep a press from focusing the item, which assistive technology\n // can't see; the click below hands focus to the wheel instead.\n onMouseDown={e => e.preventDefault()}\n onClick={() => {\n moveBy(vIdx - virtualIdx);\n // Click focuses the <button> child by default; pull focus back\n // to the wheel root so the column emphasis (:focus rules) match.\n rootRef.current?.focus();\n }}\n >\n {formatLabel(values[aIdx])}\n </button>\n );\n })}\n </div>\n );\n};\n\nconst Wheel = React.forwardRef(WheelInner) as <T>(\n props: WheelProps<T> & { ref?: React.Ref<WheelHandle> }\n) => React.ReactElement;\n\nexport const TimeWheels: React.FC<TimeWheelsProps> = ({\n value,\n onChange,\n hourFormat = '24',\n enableSeconds = false,\n incrementHours = 1,\n incrementMinutes = 1,\n incrementSeconds = 1,\n unselectableTimes,\n size,\n color,\n disabled,\n className,\n id,\n labels,\n visibleCount = 5,\n itemHeight = 32,\n audioTick = false,\n onCommit,\n}) => {\n const t = mergeLabels(labels);\n\n const rootClass = usePrefixedClassNames('timeinput', {\n [`is-${color}`]: !!color,\n [`is-${size}`]: !!size,\n 'is-disabled': disabled,\n });\n const wheelsClass = usePrefixedClassNames('timeinput-wheels');\n const sepClass = usePrefixedClassNames('timeinput-separator');\n // Use the prefixed class through the same helper the wheels themselves do,\n // so the selector matches the actual rendered class regardless of whether\n // the consumer configured `classPrefix` via ConfigProvider. Building the\n // selector with `${classPrefix}timeinput-wheel` is wrong when classPrefix\n // is undefined (defaults to the empty prefix) — it would stringify to\n // \"undefinedtimeinput-wheel\".\n const wheelSingleClass = usePrefixedClassNames('timeinput-wheel');\n const wheelsContainerRef = useRef<HTMLDivElement>(null);\n\n const isPm = value.hours >= 12;\n\n const isTimeAllowed = useCallback(\n (h: number, m: number, s: number) => {\n if (!unselectableTimes) return true;\n const probe = setTimeOfDay(new Date(), {\n hours: h,\n minutes: m,\n seconds: s,\n milliseconds: 0,\n });\n return !unselectableTimes(probe);\n },\n [unselectableTimes]\n );\n\n // Per-column \"is this value disabled?\" predicates. We compute them against\n // the current value's other parts, so e.g. a predicate that only blocks\n // 12:00–12:59 leaves all minutes selectable when the user moves the hour\n // off 12. Returning `undefined` (rather than a function) when there is no\n // unselectableTimes lets the Wheel skip the disabled-attribute branch.\n const isHourDisabled = useCallback(\n (display: number) => {\n let h24 = display;\n if (hourFormat === '12') {\n const base = display % 12;\n h24 = isPm ? base + 12 : base;\n }\n return !isTimeAllowed(h24, value.minutes, value.seconds ?? 0);\n },\n [hourFormat, isPm, isTimeAllowed, value.minutes, value.seconds]\n );\n const isMinuteDisabled = useCallback(\n (m: number) => !isTimeAllowed(value.hours, m, value.seconds ?? 0),\n [isTimeAllowed, value.hours, value.seconds]\n );\n const isSecondDisabled = useCallback(\n (s: number) => !isTimeAllowed(value.hours, value.minutes, s),\n [isTimeAllowed, value.hours, value.minutes]\n );\n const hourDisabledFor = unselectableTimes ? isHourDisabled : undefined;\n const minuteDisabledFor = unselectableTimes ? isMinuteDisabled : undefined;\n const secondDisabledFor = unselectableTimes ? isSecondDisabled : undefined;\n\n const commit = useCallback(\n (next: Partial<TimeWheelsValue>) => {\n const merged: TimeWheelsValue = {\n hours: next.hours ?? value.hours,\n minutes: next.minutes ?? value.minutes,\n seconds: enableSeconds\n ? (next.seconds ?? value.seconds ?? 0)\n : undefined,\n };\n if (!isTimeAllowed(merged.hours, merged.minutes, merged.seconds ?? 0)) {\n return;\n }\n onChange(merged);\n },\n [value, enableSeconds, isTimeAllowed, onChange]\n );\n\n // Build the value lists per column.\n const hourValues = useMemo<number[]>(() => {\n const step = Math.max(1, incrementHours);\n if (hourFormat === '12') {\n const out: number[] = [];\n for (let h = 1; h <= 12; h += step) out.push(h);\n return out;\n }\n const out: number[] = [];\n for (let h = 0; h < 24; h += step) out.push(h);\n return out;\n }, [hourFormat, incrementHours]);\n\n const minuteValues = useMemo<number[]>(() => {\n const step = Math.max(1, incrementMinutes);\n const out: number[] = [];\n for (let m = 0; m < 60; m += step) out.push(m);\n return out;\n }, [incrementMinutes]);\n\n const secondValues = useMemo<number[]>(() => {\n const step = Math.max(1, incrementSeconds);\n const out: number[] = [];\n for (let s = 0; s < 60; s += step) out.push(s);\n return out;\n }, [incrementSeconds]);\n\n // Map current value → wheel index.\n const displayedHours =\n hourFormat === '12'\n ? value.hours % 12 === 0\n ? 12\n : value.hours % 12\n : value.hours;\n const hourIndex = Math.max(0, hourValues.indexOf(displayedHours));\n const minuteIndex = Math.max(0, minuteValues.indexOf(value.minutes));\n const secondIndex = Math.max(0, secondValues.indexOf(value.seconds ?? 0));\n const ampmIndex = isPm ? 1 : 0;\n\n // Refs for column focus management.\n const hoursRef = useRef<WheelHandle>(null);\n const minutesRef = useRef<WheelHandle>(null);\n const secondsRef = useRef<WheelHandle>(null);\n const ampmRef = useRef<WheelHandle>(null);\n\n // Build the focus order at runtime.\n const columnOrder: React.RefObject<WheelHandle | null>[] = [];\n columnOrder.push(hoursRef);\n columnOrder.push(minutesRef);\n if (enableSeconds) columnOrder.push(secondsRef);\n if (hourFormat === '12') columnOrder.push(ampmRef);\n const focusAt = (i: number) => columnOrder[i]?.current?.focus();\n const indexOf = (r: React.RefObject<WheelHandle | null>): number =>\n columnOrder.indexOf(r);\n const focusPrevOf = (r: React.RefObject<WheelHandle | null>) => () =>\n focusAt(indexOf(r) - 1);\n const focusNextOf = (r: React.RefObject<WheelHandle | null>) => () =>\n focusAt(indexOf(r) + 1);\n\n // Hour change — translate displayed value back into 24h.\n const onHourIndex = (next: number) => {\n const display =\n hourValues[Math.max(0, Math.min(hourValues.length - 1, next))];\n let next24 = display;\n if (hourFormat === '12') {\n const baseHour = display % 12;\n next24 = isPm ? baseHour + 12 : baseHour;\n }\n // Skip past any blocked hour using nextValid.\n const allowed = nextValid(next24, next24 >= value.hours ? 1 : -1, 24, h =>\n isTimeAllowed(h, value.minutes, value.seconds ?? 0)\n );\n commit({ hours: allowed });\n };\n\n const onMinuteIndex = (next: number) => {\n const m =\n minuteValues[Math.max(0, Math.min(minuteValues.length - 1, next))];\n const allowed = nextValid(m, m >= value.minutes ? 1 : -1, 60, mm =>\n isTimeAllowed(value.hours, mm, value.seconds ?? 0)\n );\n commit({ minutes: allowed });\n };\n\n const onSecondIndex = (next: number) => {\n const s =\n secondValues[Math.max(0, Math.min(secondValues.length - 1, next))];\n const allowed = nextValid(s, s >= (value.seconds ?? 0) ? 1 : -1, 60, ss =>\n isTimeAllowed(value.hours, value.minutes, ss)\n );\n commit({ seconds: allowed });\n };\n\n const onAmpmIndex = (next: number) => {\n if (next === ampmIndex) return;\n commit({ hours: (value.hours + 12) % 24 });\n };\n\n // Forward drags that originate on the empty space inside the wheels row\n // (left of the leftmost wheel, right of the rightmost wheel, on the\n // separator) to whichever wheel column is nearest to the pointer X — so\n // the picker behaves like the iOS native one, where the whole picker\n // surface is grabbable, not just the column itself.\n const onWheelsContainerPointerDown = (\n e: React.PointerEvent<HTMLDivElement>\n ) => {\n if (disabled) return;\n // If the pointerdown landed on a real wheel column, the wheel's own\n // handler takes over — don't double-dispatch.\n if ((e.target as HTMLElement).closest(`.${wheelSingleClass}`)) return;\n const container = wheelsContainerRef.current;\n /* istanbul ignore next: the handler is attached to the very element this ref points to, so it can't be null while events fire */\n if (!container) return;\n const wheels = container.querySelectorAll<HTMLElement>(\n `.${wheelSingleClass}`\n );\n if (wheels.length === 0) return;\n let nearestIdx = 0;\n let nearestDist = Infinity;\n const x = e.clientX;\n wheels.forEach((el, i) => {\n const r = el.getBoundingClientRect();\n const cx = (r.left + r.right) / 2;\n const d = Math.abs(x - cx);\n if (d < nearestDist) {\n nearestDist = d;\n nearestIdx = i;\n }\n });\n columnOrder[nearestIdx]?.current?.startDrag(e.pointerId, e.clientY);\n };\n\n return (\n <div\n id={id}\n className={classNames(rootClass, className)}\n aria-disabled={disabled}\n >\n <div\n className={wheelsClass}\n ref={wheelsContainerRef}\n onPointerDown={onWheelsContainerPointerDown}\n >\n <Wheel\n ref={hoursRef}\n values={hourValues}\n index={hourIndex}\n onChange={onHourIndex}\n formatLabel={pad2}\n ariaLabel={t.hours}\n visibleCount={visibleCount}\n itemHeight={itemHeight}\n disabled={disabled}\n size={size}\n color={color}\n wrap\n onCommit={onCommit}\n onFocusPrev={focusPrevOf(hoursRef)}\n onFocusNext={focusNextOf(hoursRef)}\n disabledFor={hourDisabledFor}\n audioTick={audioTick}\n />\n <div className={sepClass} aria-hidden=\"true\">\n :\n </div>\n <Wheel\n ref={minutesRef}\n values={minuteValues}\n index={minuteIndex}\n onChange={onMinuteIndex}\n formatLabel={pad2}\n ariaLabel={t.minutes}\n visibleCount={visibleCount}\n itemHeight={itemHeight}\n disabled={disabled}\n size={size}\n color={color}\n wrap\n onCommit={onCommit}\n onFocusPrev={focusPrevOf(minutesRef)}\n onFocusNext={focusNextOf(minutesRef)}\n disabledFor={minuteDisabledFor}\n audioTick={audioTick}\n />\n {enableSeconds && (\n <>\n <div className={sepClass} aria-hidden=\"true\">\n :\n </div>\n <Wheel\n ref={secondsRef}\n values={secondValues}\n index={secondIndex}\n onChange={onSecondIndex}\n formatLabel={pad2}\n ariaLabel={t.seconds}\n visibleCount={visibleCount}\n itemHeight={itemHeight}\n disabled={disabled}\n size={size}\n color={color}\n wrap\n onCommit={onCommit}\n onFocusPrev={focusPrevOf(secondsRef)}\n onFocusNext={focusNextOf(secondsRef)}\n disabledFor={secondDisabledFor}\n audioTick={audioTick}\n />\n </>\n )}\n {hourFormat === '12' && (\n <Wheel\n ref={ampmRef}\n values={['AM', 'PM']}\n index={ampmIndex}\n onChange={onAmpmIndex}\n formatLabel={v => v}\n ariaLabel={t.ampm}\n visibleCount={visibleCount}\n itemHeight={itemHeight}\n disabled={disabled}\n size={size}\n color={color}\n onCommit={onCommit}\n onFocusPrev={focusPrevOf(ampmRef)}\n onFocusNext={focusNextOf(ampmRef)}\n audioTick={audioTick}\n />\n )}\n </div>\n </div>\n );\n};\n\nTimeWheels.displayName = 'TimeWheels';\n\nexport default TimeWheels;\n"],"names":["fireTickHaptic","_jsxs","_jsx","_Fragment"],"mappings":"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"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/* @allxsmith/bestax-bulma — AI agents: see AGENTS.md in the package root, or https://bestax.io/llms.txt */
|
|
2
|
+
'use client';
|
|
2
3
|
import { useMemo } from 'react';
|
|
3
4
|
import { useLocaleScope } from '../../helpers/LocaleProvider.js';
|
|
4
5
|
import { canonicalLocale, localeDirection, localeFirstDay } from '../../helpers/localeInfo.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useLocaleDefaults.js","sources":["../../../../src/form/_pickerInternals/useLocaleDefaults.ts"],"sourcesContent":["import { useMemo } from 'react';\nimport {\n useLocaleScope,\n type PortalLocale,\n} from '../../helpers/LocaleProvider';\nimport {\n canonicalLocale,\n localeDirection,\n localeFirstDay,\n} from '../../helpers/localeInfo';\nimport type { DayOfWeek } from './pickerTypes';\n\n/**\n * A picker's locale: its own `locale`, else the one a `LocaleProvider` around\n * it sets, else `undefined`, which leaves `Intl` to use the runtime's.\n */\nexport function usePickerLocale(own: string | undefined): string | undefined {\n const scope = useLocaleScope();\n return own || scope?.locale;\n}\n\n/** Where a picker's own language and direction go, inside a `LocaleProvider`. */\nexport interface PickerLocaleScope {\n /**\n * The `lang` and `dir` for the picker's root, so what renders inside it,\n * an inline calendar or a popover in place, follows them. Empty unless the\n * picker has a `locale` of its own.\n */\n rootAttrs: { lang?: string; dir?: string };\n /** What its portaled panel carries; unset outside a provider. */\n panel?: PortalLocale;\n}\n\nconst NO_ROOT_ATTRS = {};\n\n/**\n * A picker's language and direction inside a `LocaleProvider`, by the rule a\n * nested provider follows: its `lang` is its own `locale`, else the\n * provider's, and its `dir` is the `dir` passed to it, else its own locale's\n * direction when it has one, else the provider's. Outside a provider it\n * changes nothing. A `locale` `Intl` refuses counts as none here, since the\n * picker's own formatting reports it.\n */\nexport function usePickerLocaleScope(\n ownLocale: string | undefined,\n ownDir: string | undefined\n): PickerLocaleScope {\n const scope = useLocaleScope();\n return useMemo(() => {\n if (!scope) return { rootAttrs: NO_ROOT_ATTRS };\n let own: string | undefined;\n try {\n own = canonicalLocale(ownLocale);\n } catch {\n own = undefined;\n }\n const dir = ownDir || (own ? localeDirection(own) : scope.dir);\n return {\n rootAttrs: own ? { lang: own, dir } : NO_ROOT_ATTRS,\n panel: { locale: own || scope.locale, dir },\n };\n }, [scope, ownLocale, ownDir]);\n}\n\n/**\n * Whether a picker's `dayNames` replace the calendar's own, which `Calendar`\n * does only for a full week of seven.\n */\nexport function hasOwnDayNames(dayNames: string[] | undefined): boolean {\n return dayNames !== undefined && dayNames.length === 7;\n}\n\n/**\n * The day a picker's week starts on: its own `firstDayOfWeek`, else, inside a\n * `LocaleProvider`, the first day of the locale the picker uses, else Sunday.\n * Outside a provider it stays Sunday whatever the locale, as it always has,\n * and so does a picker inside one with no locale from either, since the\n * runtime's own differs between the server and the browser.\n *\n * It also stays Sunday for a picker that brings its own `dayNames`. The\n * calendar shows those exactly as given, in calendar order, and before the\n * provider an unset `firstDayOfWeek` was always Sunday, so names written\n * Sunday first would sit a day or more off their columns if the week moved\n * under them.\n */\nexport function usePickerFirstDayOfWeek(\n own: DayOfWeek | undefined,\n locale: string | undefined,\n hasDayNames: boolean\n): DayOfWeek {\n const inProvider = useLocaleScope() !== null;\n return useMemo(() => {\n if (own !== undefined) return own;\n if (!inProvider || !locale || hasDayNames) return 0;\n try {\n return localeFirstDay(canonicalLocale(locale) as string);\n } catch {\n // A tag Intl refuses: the picker's own formatting says so.\n return 0;\n }\n }, [own, inProvider, locale, hasDayNames]);\n}\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useLocaleDefaults.js","sources":["../../../../src/form/_pickerInternals/useLocaleDefaults.ts"],"sourcesContent":["import { useMemo } from 'react';\nimport {\n useLocaleScope,\n type PortalLocale,\n} from '../../helpers/LocaleProvider';\nimport {\n canonicalLocale,\n localeDirection,\n localeFirstDay,\n} from '../../helpers/localeInfo';\nimport type { DayOfWeek } from './pickerTypes';\n\n/**\n * A picker's locale: its own `locale`, else the one a `LocaleProvider` around\n * it sets, else `undefined`, which leaves `Intl` to use the runtime's.\n */\nexport function usePickerLocale(own: string | undefined): string | undefined {\n const scope = useLocaleScope();\n return own || scope?.locale;\n}\n\n/** Where a picker's own language and direction go, inside a `LocaleProvider`. */\nexport interface PickerLocaleScope {\n /**\n * The `lang` and `dir` for the picker's root, so what renders inside it,\n * an inline calendar or a popover in place, follows them. Empty unless the\n * picker has a `locale` of its own.\n */\n rootAttrs: { lang?: string; dir?: string };\n /** What its portaled panel carries; unset outside a provider. */\n panel?: PortalLocale;\n}\n\nconst NO_ROOT_ATTRS = {};\n\n/**\n * A picker's language and direction inside a `LocaleProvider`, by the rule a\n * nested provider follows: its `lang` is its own `locale`, else the\n * provider's, and its `dir` is the `dir` passed to it, else its own locale's\n * direction when it has one, else the provider's. Outside a provider it\n * changes nothing. A `locale` `Intl` refuses counts as none here, since the\n * picker's own formatting reports it.\n */\nexport function usePickerLocaleScope(\n ownLocale: string | undefined,\n ownDir: string | undefined\n): PickerLocaleScope {\n const scope = useLocaleScope();\n return useMemo(() => {\n if (!scope) return { rootAttrs: NO_ROOT_ATTRS };\n let own: string | undefined;\n try {\n own = canonicalLocale(ownLocale);\n } catch {\n own = undefined;\n }\n const dir = ownDir || (own ? localeDirection(own) : scope.dir);\n return {\n rootAttrs: own ? { lang: own, dir } : NO_ROOT_ATTRS,\n panel: { locale: own || scope.locale, dir },\n };\n }, [scope, ownLocale, ownDir]);\n}\n\n/**\n * Whether a picker's `dayNames` replace the calendar's own, which `Calendar`\n * does only for a full week of seven.\n */\nexport function hasOwnDayNames(dayNames: string[] | undefined): boolean {\n return dayNames !== undefined && dayNames.length === 7;\n}\n\n/**\n * The day a picker's week starts on: its own `firstDayOfWeek`, else, inside a\n * `LocaleProvider`, the first day of the locale the picker uses, else Sunday.\n * Outside a provider it stays Sunday whatever the locale, as it always has,\n * and so does a picker inside one with no locale from either, since the\n * runtime's own differs between the server and the browser.\n *\n * It also stays Sunday for a picker that brings its own `dayNames`. The\n * calendar shows those exactly as given, in calendar order, and before the\n * provider an unset `firstDayOfWeek` was always Sunday, so names written\n * Sunday first would sit a day or more off their columns if the week moved\n * under them.\n */\nexport function usePickerFirstDayOfWeek(\n own: DayOfWeek | undefined,\n locale: string | undefined,\n hasDayNames: boolean\n): DayOfWeek {\n const inProvider = useLocaleScope() !== null;\n return useMemo(() => {\n if (own !== undefined) return own;\n if (!inProvider || !locale || hasDayNames) return 0;\n try {\n return localeFirstDay(canonicalLocale(locale) as string);\n } catch {\n // A tag Intl refuses: the picker's own formatting says so.\n return 0;\n }\n }, [own, inProvider, locale, hasDayNames]);\n}\n"],"names":[],"mappings":";;;;;;AAYA;;;AAGG;AACG,SAAU,eAAe,CAAC,GAAuB,EAAA;AACrD,IAAA,MAAM,KAAK,GAAG,cAAc,EAAE;AAC9B,IAAA,OAAO,GAAG,IAAI,KAAK,EAAE,MAAM;AAC7B;AAcA,MAAM,aAAa,GAAG,EAAE;AAExB;;;;;;;AAOG;AACG,SAAU,oBAAoB,CAClC,SAA6B,EAC7B,MAA0B,EAAA;AAE1B,IAAA,MAAM,KAAK,GAAG,cAAc,EAAE;IAC9B,OAAO,OAAO,CAAC,MAAK;AAClB,QAAA,IAAI,CAAC,KAAK;AAAE,YAAA,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE;AAC/C,QAAA,IAAI,GAAuB;AAC3B,QAAA,IAAI;AACF,YAAA,GAAG,GAAG,eAAe,CAAC,SAAS,CAAC;QAClC;AAAE,QAAA,MAAM;YACN,GAAG,GAAG,SAAS;QACjB;QACA,MAAM,GAAG,GAAG,MAAM,KAAK,GAAG,GAAG,eAAe,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC;QAC9D,OAAO;AACL,YAAA,SAAS,EAAE,GAAG,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,aAAa;YACnD,KAAK,EAAE,EAAE,MAAM,EAAE,GAAG,IAAI,KAAK,CAAC,MAAM,EAAE,GAAG,EAAE;SAC5C;IACH,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;AAChC;AAEA;;;AAGG;AACG,SAAU,cAAc,CAAC,QAA8B,EAAA;IAC3D,OAAO,QAAQ,KAAK,SAAS,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;AACxD;AAEA;;;;;;;;;;;;AAYG;SACa,uBAAuB,CACrC,GAA0B,EAC1B,MAA0B,EAC1B,WAAoB,EAAA;AAEpB,IAAA,MAAM,UAAU,GAAG,cAAc,EAAE,KAAK,IAAI;IAC5C,OAAO,OAAO,CAAC,MAAK;QAClB,IAAI,GAAG,KAAK,SAAS;AAAE,YAAA,OAAO,GAAG;AACjC,QAAA,IAAI,CAAC,UAAU,IAAI,CAAC,MAAM,IAAI,WAAW;AAAE,YAAA,OAAO,CAAC;AACnD,QAAA,IAAI;AACF,YAAA,OAAO,cAAc,CAAC,eAAe,CAAC,MAAM,CAAW,CAAC;QAC1D;AAAE,QAAA,MAAM;;AAEN,YAAA,OAAO,CAAC;QACV;IACF,CAAC,EAAE,CAAC,GAAG,EAAE,UAAU,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC;AAC5C;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useNativeMobilePicker.js","sources":["../../../../src/form/_pickerInternals/useNativeMobilePicker.ts"],"sourcesContent":["import { useEffect, useState } from 'react';\n\nexport interface NativeMobileDetect {\n isCoarsePointer: boolean;\n isSmallViewport: boolean;\n shouldUseNative: boolean;\n}\n\nexport interface UseNativeMobilePickerOptions {\n smallViewportMaxPx?: number;\n /** When set, overrides detection. */\n force?: boolean;\n}\n\nexport function useNativeMobilePicker(\n options: UseNativeMobilePickerOptions = {}\n): NativeMobileDetect {\n const { smallViewportMaxPx = 768, force } = options;\n const [state, setState] = useState<NativeMobileDetect>({\n isCoarsePointer: false,\n isSmallViewport: false,\n shouldUseNative: force === true,\n });\n\n useEffect(() => {\n const isBrowser =\n typeof window !== 'undefined' && typeof window.matchMedia === 'function';\n if (!isBrowser) return undefined;\n const coarse = window.matchMedia('(pointer: coarse)');\n const small = window.matchMedia(`(max-width: ${smallViewportMaxPx}px)`);\n\n const update = () => {\n const isCoarsePointer = coarse.matches;\n const isSmallViewport = small.matches;\n const shouldUseNative =\n force === true\n ? true\n : force === false\n ? false\n : isCoarsePointer && isSmallViewport;\n setState({ isCoarsePointer, isSmallViewport, shouldUseNative });\n };\n\n update();\n const subscribe = (mql: MediaQueryList, fn: () => void) => {\n if (mql.addEventListener) {\n // eslint-disable-next-line @eslint-react/web-api-no-leaked-event-listener -- cleanup returned below and run in the effect teardown\n mql.addEventListener('change', fn);\n return () => mql.removeEventListener('change', fn);\n }\n // Older Safari fallback\n mql.addListener(fn);\n return () => mql.removeListener(fn);\n };\n const unsubCoarse = subscribe(coarse, update);\n const unsubSmall = subscribe(small, update);\n return () => {\n unsubCoarse();\n unsubSmall();\n };\n }, [smallViewportMaxPx, force]);\n\n return state;\n}\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useNativeMobilePicker.js","sources":["../../../../src/form/_pickerInternals/useNativeMobilePicker.ts"],"sourcesContent":["import { useEffect, useState } from 'react';\n\nexport interface NativeMobileDetect {\n isCoarsePointer: boolean;\n isSmallViewport: boolean;\n shouldUseNative: boolean;\n}\n\nexport interface UseNativeMobilePickerOptions {\n smallViewportMaxPx?: number;\n /** When set, overrides detection. */\n force?: boolean;\n}\n\nexport function useNativeMobilePicker(\n options: UseNativeMobilePickerOptions = {}\n): NativeMobileDetect {\n const { smallViewportMaxPx = 768, force } = options;\n const [state, setState] = useState<NativeMobileDetect>({\n isCoarsePointer: false,\n isSmallViewport: false,\n shouldUseNative: force === true,\n });\n\n useEffect(() => {\n const isBrowser =\n typeof window !== 'undefined' && typeof window.matchMedia === 'function';\n if (!isBrowser) return undefined;\n const coarse = window.matchMedia('(pointer: coarse)');\n const small = window.matchMedia(`(max-width: ${smallViewportMaxPx}px)`);\n\n const update = () => {\n const isCoarsePointer = coarse.matches;\n const isSmallViewport = small.matches;\n const shouldUseNative =\n force === true\n ? true\n : force === false\n ? false\n : isCoarsePointer && isSmallViewport;\n setState({ isCoarsePointer, isSmallViewport, shouldUseNative });\n };\n\n update();\n const subscribe = (mql: MediaQueryList, fn: () => void) => {\n if (mql.addEventListener) {\n // eslint-disable-next-line @eslint-react/web-api-no-leaked-event-listener -- cleanup returned below and run in the effect teardown\n mql.addEventListener('change', fn);\n return () => mql.removeEventListener('change', fn);\n }\n // Older Safari fallback\n mql.addListener(fn);\n return () => mql.removeListener(fn);\n };\n const unsubCoarse = subscribe(coarse, update);\n const unsubSmall = subscribe(small, update);\n return () => {\n unsubCoarse();\n unsubSmall();\n };\n }, [smallViewportMaxPx, force]);\n\n return state;\n}\n"],"names":[],"mappings":";;;;AAcM,SAAU,qBAAqB,CACnC,OAAA,GAAwC,EAAE,EAAA;IAE1C,MAAM,EAAE,kBAAkB,GAAG,GAAG,EAAE,KAAK,EAAE,GAAG,OAAO;AACnD,IAAA,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAqB;AACrD,QAAA,eAAe,EAAE,KAAK;AACtB,QAAA,eAAe,EAAE,KAAK;QACtB,eAAe,EAAE,KAAK,KAAK,IAAI;AAChC,KAAA,CAAC;IAEF,SAAS,CAAC,MAAK;AACb,QAAA,MAAM,SAAS,GACb,OAAO,MAAM,KAAK,WAAW,IAAI,OAAO,MAAM,CAAC,UAAU,KAAK,UAAU;AAC1E,QAAA,IAAI,CAAC,SAAS;AAAE,YAAA,OAAO,SAAS;QAChC,MAAM,MAAM,GAAG,MAAM,CAAC,UAAU,CAAC,mBAAmB,CAAC;QACrD,MAAM,KAAK,GAAG,MAAM,CAAC,UAAU,CAAC,CAAA,YAAA,EAAe,kBAAkB,CAAA,GAAA,CAAK,CAAC;QAEvE,MAAM,MAAM,GAAG,MAAK;AAClB,YAAA,MAAM,eAAe,GAAG,MAAM,CAAC,OAAO;AACtC,YAAA,MAAM,eAAe,GAAG,KAAK,CAAC,OAAO;AACrC,YAAA,MAAM,eAAe,GACnB,KAAK,KAAK;AACR,kBAAE;kBACA,KAAK,KAAK;AACV,sBAAE;AACF,sBAAE,eAAe,IAAI,eAAe;YAC1C,QAAQ,CAAC,EAAE,eAAe,EAAE,eAAe,EAAE,eAAe,EAAE,CAAC;AACjE,QAAA,CAAC;AAED,QAAA,MAAM,EAAE;AACR,QAAA,MAAM,SAAS,GAAG,CAAC,GAAmB,EAAE,EAAc,KAAI;AACxD,YAAA,IAAI,GAAG,CAAC,gBAAgB,EAAE;;AAExB,gBAAA,GAAG,CAAC,gBAAgB,CAAC,QAAQ,EAAE,EAAE,CAAC;gBAClC,OAAO,MAAM,GAAG,CAAC,mBAAmB,CAAC,QAAQ,EAAE,EAAE,CAAC;YACpD;;AAEA,YAAA,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC;YACnB,OAAO,MAAM,GAAG,CAAC,cAAc,CAAC,EAAE,CAAC;AACrC,QAAA,CAAC;QACD,MAAM,WAAW,GAAG,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC;QAC7C,MAAM,UAAU,GAAG,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC;AAC3C,QAAA,OAAO,MAAK;AACV,YAAA,WAAW,EAAE;AACb,YAAA,UAAU,EAAE;AACd,QAAA,CAAC;AACH,IAAA,CAAC,EAAE,CAAC,kBAAkB,EAAE,KAAK,CAAC,CAAC;AAE/B,IAAA,OAAO,KAAK;AACd;;"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/* @allxsmith/bestax-bulma — AI agents: see AGENTS.md in the package root, or https://bestax.io/llms.txt */
|
|
2
|
+
'use client';
|
|
2
3
|
import { useMemo, useState, useRef, useCallback, useEffect } from 'react';
|
|
3
4
|
import { useClientLayoutEffect } from '../../helpers/useClientLayoutEffect.js';
|
|
4
5
|
import { isWithin } from './dateUtils.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useSegmentedEntry.js","sources":["../../../../src/form/_pickerInternals/useSegmentedEntry.ts"],"sourcesContent":["import React, {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { useClientLayoutEffect } from '../../helpers/useClientLayoutEffect';\nimport { DateFormatOption } from './formatters';\nimport { isWithin } from './dateUtils';\nimport {\n buildSegmentMap,\n incrementSegmentValue,\n setSegmentValue,\n setAmPm,\n segmentIndexAtCaret,\n SegmentKind,\n SegmentMap,\n} from './segmentMap';\n\n/**\n * Single-character literals that, when typed, jump the caret to the next\n * editable segment — the slash / colon / dash / dot / space separators that\n * appear between date and time tokens. Lets a user type `12/25/2026` or\n * `13:45` straight through, skipping over the format's punctuation.\n */\nconst SEPARATOR_RE = /[/:\\-.\\s]/;\n\nexport interface UseSegmentedEntryParams {\n /** Resolved format actually used to render (the host's default format). */\n format: DateFormatOption;\n /**\n * Segment kinds the caret never stops on: they still render, but arrows,\n * digits and separators pass over them. A month picker skips `'day'` so a\n * format such as `'YYYY-MM-DD'` edits only the year and month. Must be\n * referentially stable. A format left with no editable segment falls back\n * to free-form entry.\n */\n skipKinds?: readonly SegmentKind[];\n /** Current canonical value (controlled or internal). */\n value: Date | null;\n /** Commit a new Date through the host's onChange / internal pipeline. */\n commitValue: (next: Date | null) => void;\n /** Host formatter: formatDate | formatTime | formatDateTime. */\n formatFn: (\n d: Date,\n fmt: DateFormatOption | undefined,\n locale?: string\n ) => string;\n /** Host parser used by the free-form fallback (parseDate / parseTime / custom). */\n tryParse: (s: string) => Date | null;\n /** Host's displayed-text state and setter (the hook drives it during edits). */\n text: string;\n setText: (s: string) => void;\n /**\n * Seed for an empty value when the user starts typing: Time → today at noon,\n * Date → today at 00:00, DateTime → now. Should be referentially stable.\n */\n makeBaseDate: () => Date;\n locale?: string;\n min?: Date;\n max?: Date;\n /**\n * Host-supplied blocking predicate (composed from shouldDisableDate /\n * unselectableDates / unselectableTimes). Checked alongside min/max on\n * every manual-entry commit; return true to reject the candidate value.\n */\n isBlocked?: (d: Date) => boolean;\n /**\n * Rejects a candidate only while the digits typed into its segment leave\n * it unfinished, such as the first digits of a year. The digit stays in\n * the segment and the next one tries again, so a value passing through a\n * candidate it can't commit on the way to one it can costs nothing. A\n * finished segment, an arrow step and parsed text answer to `isBlocked`\n * alone.\n */\n isUnfinishedBlocked?: (d: Date) => boolean;\n disabled?: boolean;\n readOnly?: boolean;\n /** Allow segmented typing. When false, segment mode never engages. */\n editable?: boolean;\n /** Whether a popover exists; gates open-on-focus / click / Alt+ArrowDown. */\n popover?: boolean;\n openOnFocus?: boolean;\n closeOnSelect?: boolean;\n isOpen: boolean;\n /**\n * The host's open-state setter. The hook asks it to open on focus, click\n * or Alt+ArrowDown, but not on the focus the popover's focus trap hands\n * back to the input as it closes, which is not the user arriving.\n */\n setOpen: (next: boolean) => void;\n inputRef: React.RefObject<HTMLInputElement | null>;\n containerRef: React.RefObject<HTMLElement | null>;\n onFocus?: React.FocusEventHandler<HTMLInputElement>;\n onClick?: React.MouseEventHandler<HTMLInputElement>;\n onKeyDown?: React.KeyboardEventHandler<HTMLInputElement>;\n onBlur?: React.FocusEventHandler<HTMLInputElement>;\n}\n\nexport interface UseSegmentedEntryResult {\n segmentMap: SegmentMap | null;\n activeSegmentIdx: number | null;\n /** True when segment typing is available (map + editable + not disabled/readOnly). */\n segmentEditable: boolean;\n /** True when a segment is actively selected. */\n inSegmentMode: boolean;\n /** Spread onto the combobox `<input>`. */\n inputHandlers: {\n onChange: React.ChangeEventHandler<HTMLInputElement>;\n onFocus: React.FocusEventHandler<HTMLInputElement>;\n onClick: React.MouseEventHandler<HTMLInputElement>;\n onKeyDown: React.KeyboardEventHandler<HTMLInputElement>;\n onBlur: React.FocusEventHandler<HTMLInputElement>;\n };\n}\n\n/**\n * Segmented manual keyboard entry for a date / time picker input. Computes a\n * segment map from the token format, tracks the active segment, and returns\n * the full set of `<input>` event handlers — segment-mutating keys (arrows,\n * digits, AM/PM, separators) are handled here, while popover open/close and\n * free-form parse-on-blur/Enter are driven through the host-supplied\n * `setOpen` / `tryParse` / `commitValue` callbacks. When the format is an\n * `Intl` options object or contains variable-width tokens, the segment map is\n * null and the input transparently falls back to free-form text entry.\n */\nexport function useSegmentedEntry(\n params: UseSegmentedEntryParams\n): UseSegmentedEntryResult {\n const {\n format,\n skipKinds,\n value,\n commitValue,\n formatFn,\n tryParse,\n text,\n setText,\n makeBaseDate,\n locale,\n min,\n max,\n isBlocked,\n isUnfinishedBlocked,\n disabled,\n readOnly,\n editable = true,\n popover = true,\n openOnFocus = true,\n closeOnSelect = false,\n isOpen,\n setOpen,\n inputRef,\n containerRef,\n onFocus,\n onClick,\n onKeyDown,\n onBlur,\n } = params;\n\n const segmentMap: SegmentMap | null = useMemo(() => {\n const map = typeof format === 'string' ? buildSegmentMap(format) : null;\n if (!map || !skipKinds) return map;\n const editable = map.editable.filter(\n i => !skipKinds.includes(map.segments[i].kind)\n );\n return editable.length > 0 ? { ...map, editable } : null;\n }, [format, skipKinds]);\n const [activeSegmentIdx, setActiveSegmentIdx] = useState<number | null>(null);\n // Buffer of digits typed within the current segment, cleared on segment\n // change. Kept in a ref because key handlers read+update synchronously\n // within the same event tick.\n const typedDigitsRef = useRef<string>('');\n // The text focus seeded an empty picker with, until the user edits it or\n // leaves.\n const seedRef = useRef<string | null>(null);\n\n // Whether the text is still what the picker put there, so nothing in it was\n // typed: the value's display, or an empty picker's seed until an edit drops\n // it. Against a value it compares text alone, so typing that ends back on\n // the display counts as untouched.\n const isUntouched = useCallback(\n (s: string) =>\n value\n ? s === formatFn(value, format, locale)\n : seedRef.current !== null && s === seedRef.current,\n [value, formatFn, format, locale]\n );\n\n // A seed the popover never turned into a value closes with it, wherever\n // focus goes, so a dismissed empty field stays empty.\n //\n // As the popover closes, its focus trap hands focus back to the input. That\n // focus is not the user arriving: it must not open the popover again under\n // `openOnFocus`, or seed an empty picker. `closingRef` is set in the layout\n // phase of the commit that closes it and cleared by that commit's effects,\n // and React runs a commit's effect cleanups, the trap's among them, before\n // any of its effects, so a focus in between is the one handed back.\n const closingRef = useRef(false);\n const wasOpenRef = useRef(isOpen);\n useClientLayoutEffect(() => {\n if (wasOpenRef.current && !isOpen) {\n closingRef.current = true;\n if (!value && isUntouched(text)) setText('');\n seedRef.current = null;\n }\n wasOpenRef.current = isOpen;\n }, [isOpen, value, isUntouched, text, setText]);\n useEffect(() => {\n closingRef.current = false;\n }, [isOpen]);\n\n // Segment mode is unavailable for disabled / read-only / non-editable\n // pickers and for Intl-options / variable-width formats (segmentMap null).\n const segmentEditable = !!segmentMap && !!editable && !disabled && !readOnly;\n\n // The Date we edit when the user starts without a current value.\n const segmentBaseDate = useCallback(\n (): Date => value ?? makeBaseDate(),\n [value, makeBaseDate]\n );\n\n // Single gate for every manual-entry commit: min/max bounds plus the\n // host's blocking predicate.\n const isAllowed = useCallback(\n (d: Date) => isWithin(d, min, max) && !isBlocked?.(d),\n [min, max, isBlocked]\n );\n\n // Apply a segment-driven date update: commit through the host pipeline (so\n // onChange / controlled mode keep working) and re-render the text so the\n // active selection range stays valid.\n const applyDateFromSegment = useCallback(\n (next: Date) => {\n if (!isAllowed(next)) return;\n commitValue(next);\n setText(formatFn(next, format, locale));\n },\n [commitValue, isAllowed, formatFn, format, locale, setText]\n );\n\n // After every segment-driven change, restore the system selection on the\n // active segment's char range. A layout effect runs synchronously before\n // paint so the user never sees a stray caret position. We deliberately do\n // NOT gate on document.activeElement: when openOnFocus is true the focus\n // trap moves focus into the popover, but setSelectionRange on an unfocused\n // input is well-defined and the selection becomes visible on refocus.\n useClientLayoutEffect(() => {\n if (activeSegmentIdx === null || !segmentMap || !inputRef.current) return;\n const seg = segmentMap.segments[activeSegmentIdx];\n if (!seg) return;\n try {\n inputRef.current.setSelectionRange(seg.start, seg.end);\n } catch {\n // Some read-only inputs reject setSelectionRange; harmless.\n }\n }, [activeSegmentIdx, segmentMap, text, inputRef]);\n\n const moveSegment = useCallback(\n (delta: 1 | -1) => {\n if (!segmentMap || activeSegmentIdx === null) return;\n const pos = segmentMap.editable.indexOf(activeSegmentIdx);\n if (pos < 0) return;\n const nextPos = Math.max(\n 0,\n Math.min(segmentMap.editable.length - 1, pos + delta)\n );\n const nextIdx = segmentMap.editable[nextPos];\n if (nextIdx !== activeSegmentIdx) {\n typedDigitsRef.current = '';\n setActiveSegmentIdx(nextIdx);\n }\n },\n [segmentMap, activeSegmentIdx]\n );\n\n const handleChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n // In segment mode the text is managed programmatically (every edit\n // re-formats from the canonical Date). Browser-issued input events\n // would otherwise clobber it. The free-form path runs only when\n // segment mode is inactive.\n if (activeSegmentIdx !== null && segmentEditable) return;\n seedRef.current = null;\n setText(e.target.value);\n },\n [activeSegmentIdx, segmentEditable, setText]\n );\n\n const handleBlur = useCallback(\n (e: React.FocusEvent<HTMLInputElement>) => {\n // The popover opens on focus by default, and the focus trap moves focus\n // into the popover panel — that fires this blur even though the user is\n // still in the same picker. Only tear down segment state and re-parse\n // when focus has truly left the picker's container.\n const nextFocus = e.relatedTarget as HTMLElement | null;\n const stayingInPicker =\n nextFocus !== null &&\n containerRef.current !== null &&\n containerRef.current.contains(nextFocus);\n if (stayingInPicker) {\n onBlur?.(e);\n return;\n }\n setActiveSegmentIdx(null);\n typedDigitsRef.current = '';\n // Leaving commits only what was typed. Re-parsing the value's display\n // could drop what the format leaves out, such as seconds, and a seed\n // nobody typed over is not the user's date.\n const untouched = isUntouched(text);\n // An open popover keeps an unused seed until it closes, so one portaled\n // outside the picker, whose focus reads as leaving, keeps it as one\n // inside does.\n if (!isOpen) seedRef.current = null;\n if (untouched) {\n if (!value && !isOpen) setText('');\n onBlur?.(e);\n return;\n }\n const parsed = tryParse(text);\n if (parsed && isAllowed(parsed)) {\n commitValue(parsed);\n } else {\n setText(value ? formatFn(value, format, locale) : '');\n }\n onBlur?.(e);\n },\n [\n containerRef,\n isUntouched,\n isOpen,\n tryParse,\n text,\n isAllowed,\n commitValue,\n value,\n formatFn,\n format,\n locale,\n setText,\n onBlur,\n ]\n );\n\n const handleFocus = useCallback(\n (e: React.FocusEvent<HTMLInputElement>) => {\n const handedBack = closingRef.current;\n if (!handedBack && openOnFocus && popover && !disabled && !readOnly) {\n setOpen(true);\n }\n // Enter segment mode: prime an initial value (so editing works even when\n // empty), seed the text, and highlight the first editable segment. The\n // segment base doesn't need the seed, so focus handed back skips it.\n if (segmentEditable && segmentMap) {\n if (!value && !handedBack) {\n const seed = formatFn(makeBaseDate(), format, locale);\n seedRef.current = seed;\n setText(seed);\n }\n typedDigitsRef.current = '';\n setActiveSegmentIdx(segmentMap.editable[0]);\n }\n onFocus?.(e);\n },\n [\n openOnFocus,\n popover,\n disabled,\n readOnly,\n setOpen,\n segmentEditable,\n segmentMap,\n value,\n makeBaseDate,\n formatFn,\n format,\n locale,\n setText,\n onFocus,\n ]\n );\n\n const handleClick = useCallback(\n (e: React.MouseEvent<HTMLInputElement>) => {\n // Clicking the field opens the popover only when `openOnFocus` is on —\n // a click is just a focus. With `openOnFocus={false}` (manual-entry\n // mode) the click positions the caret for typing and the popover is\n // opened explicitly via the right launcher button (or Alt+ArrowDown).\n if (openOnFocus && popover && !disabled && !readOnly) setOpen(true);\n if (segmentEditable && segmentMap && inputRef.current) {\n const caret = inputRef.current.selectionStart ?? 0;\n const idx = segmentIndexAtCaret(segmentMap, caret);\n if (idx !== null && idx !== activeSegmentIdx) {\n typedDigitsRef.current = '';\n setActiveSegmentIdx(idx);\n }\n }\n onClick?.(e);\n },\n [\n openOnFocus,\n popover,\n disabled,\n readOnly,\n setOpen,\n segmentEditable,\n segmentMap,\n inputRef,\n activeSegmentIdx,\n onClick,\n ]\n );\n\n const inSegmentMode =\n segmentEditable && segmentMap !== null && activeSegmentIdx !== null;\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent<HTMLInputElement>) => {\n // Segment-mode key routing comes first. When segment mode isn't engaged\n // (not editable, no map, or no active segment — e.g. after a typed-text\n // fallback), unhandled keys fall through to the popover / free-form\n // handling below.\n if (inSegmentMode && segmentMap && activeSegmentIdx !== null) {\n const seg = segmentMap.segments[activeSegmentIdx];\n const base = segmentBaseDate();\n const isPm = base.getHours() >= 12;\n switch (e.key) {\n case 'ArrowUp':\n case 'ArrowDown':\n e.preventDefault();\n // The plain arrows step the segment, so the popover opens on\n // Alt+ArrowDown and closes on Alt+ArrowUp, as a combobox's does,\n // and neither steps it.\n if (e.altKey) {\n if (e.key === 'ArrowUp') {\n if (isOpen) setOpen(false);\n } else if (!isOpen && popover) {\n setOpen(true);\n }\n return;\n }\n typedDigitsRef.current = '';\n applyDateFromSegment(\n incrementSegmentValue(\n seg,\n base,\n e.key === 'ArrowUp' ? 1 : -1,\n isPm\n )\n );\n return;\n case 'ArrowRight':\n e.preventDefault();\n moveSegment(1);\n return;\n case 'ArrowLeft':\n e.preventDefault();\n moveSegment(-1);\n return;\n case 'Backspace':\n e.preventDefault();\n if (typedDigitsRef.current.length > 0) {\n typedDigitsRef.current = '';\n } else {\n moveSegment(-1);\n }\n return;\n case 'Escape':\n if (isOpen) {\n e.preventDefault();\n setOpen(false);\n }\n return;\n case 'Enter':\n e.preventDefault();\n if (closeOnSelect) setOpen(false);\n return;\n case 'Tab':\n setActiveSegmentIdx(null);\n typedDigitsRef.current = '';\n return;\n default:\n // AM/PM keys.\n if (seg.kind === 'ampm') {\n if (e.key === 'a' || e.key === 'A') {\n e.preventDefault();\n typedDigitsRef.current = '';\n applyDateFromSegment(setAmPm(base, false));\n moveSegment(1);\n return;\n }\n if (e.key === 'p' || e.key === 'P') {\n e.preventDefault();\n typedDigitsRef.current = '';\n applyDateFromSegment(setAmPm(base, true));\n moveSegment(1);\n return;\n }\n }\n // Typing a format separator (/, :, -, ., space) jumps to the next\n // segment, skipping over the literal punctuation.\n if (e.key.length === 1 && SEPARATOR_RE.test(e.key)) {\n e.preventDefault();\n typedDigitsRef.current = '';\n moveSegment(1);\n return;\n }\n // Digit entry for numeric segments.\n if (/^[0-9]$/.test(e.key) && seg.kind !== 'ampm') {\n e.preventDefault();\n const nextBuffer = typedDigitsRef.current + e.key;\n typedDigitsRef.current = nextBuffer;\n const { date, advance } = setSegmentValue(\n seg,\n base,\n nextBuffer,\n isPm\n );\n if (!advance && isUnfinishedBlocked?.(date)) return;\n applyDateFromSegment(date);\n if (advance) {\n typedDigitsRef.current = '';\n moveSegment(1);\n }\n return;\n }\n }\n }\n // ----- free-form / popover key handling -----\n // With no segment to step, ArrowDown opens the popover with or without\n // Alt, unless the field is read-only or disabled, as focus and the\n // launcher don't open it then either. Alt+ArrowUp closes it.\n if (\n e.key === 'ArrowDown' &&\n !isOpen &&\n popover &&\n !disabled &&\n !readOnly\n ) {\n e.preventDefault();\n setOpen(true);\n return;\n }\n if (e.key === 'ArrowUp' && e.altKey && isOpen) {\n e.preventDefault();\n setOpen(false);\n return;\n }\n if (e.key === 'Escape' && isOpen) {\n e.preventDefault();\n setOpen(false);\n return;\n }\n if (e.key === 'Enter') {\n e.preventDefault();\n // Untouched text has nothing to commit, as on leaving, but Enter\n // still confirms what the field shows.\n if (isUntouched(text)) {\n if (closeOnSelect) setOpen(false);\n } else {\n const parsed = tryParse(text);\n if (parsed && isAllowed(parsed)) {\n commitValue(parsed);\n if (closeOnSelect) setOpen(false);\n }\n }\n }\n onKeyDown?.(e);\n },\n [\n inSegmentMode,\n segmentMap,\n activeSegmentIdx,\n segmentBaseDate,\n applyDateFromSegment,\n isUnfinishedBlocked,\n moveSegment,\n isOpen,\n setOpen,\n closeOnSelect,\n popover,\n disabled,\n readOnly,\n isUntouched,\n tryParse,\n text,\n isAllowed,\n commitValue,\n onKeyDown,\n ]\n );\n\n return {\n segmentMap,\n activeSegmentIdx,\n segmentEditable,\n inSegmentMode,\n inputHandlers: {\n onChange: handleChange,\n onFocus: handleFocus,\n onClick: handleClick,\n onKeyDown: handleKeyDown,\n onBlur: handleBlur,\n },\n };\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"useSegmentedEntry.js","sources":["../../../../src/form/_pickerInternals/useSegmentedEntry.ts"],"sourcesContent":["import React, {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { useClientLayoutEffect } from '../../helpers/useClientLayoutEffect';\nimport { DateFormatOption } from './formatters';\nimport { isWithin } from './dateUtils';\nimport {\n buildSegmentMap,\n incrementSegmentValue,\n setSegmentValue,\n setAmPm,\n segmentIndexAtCaret,\n SegmentKind,\n SegmentMap,\n} from './segmentMap';\n\n/**\n * Single-character literals that, when typed, jump the caret to the next\n * editable segment — the slash / colon / dash / dot / space separators that\n * appear between date and time tokens. Lets a user type `12/25/2026` or\n * `13:45` straight through, skipping over the format's punctuation.\n */\nconst SEPARATOR_RE = /[/:\\-.\\s]/;\n\nexport interface UseSegmentedEntryParams {\n /** Resolved format actually used to render (the host's default format). */\n format: DateFormatOption;\n /**\n * Segment kinds the caret never stops on: they still render, but arrows,\n * digits and separators pass over them. A month picker skips `'day'` so a\n * format such as `'YYYY-MM-DD'` edits only the year and month. Must be\n * referentially stable. A format left with no editable segment falls back\n * to free-form entry.\n */\n skipKinds?: readonly SegmentKind[];\n /** Current canonical value (controlled or internal). */\n value: Date | null;\n /** Commit a new Date through the host's onChange / internal pipeline. */\n commitValue: (next: Date | null) => void;\n /** Host formatter: formatDate | formatTime | formatDateTime. */\n formatFn: (\n d: Date,\n fmt: DateFormatOption | undefined,\n locale?: string\n ) => string;\n /** Host parser used by the free-form fallback (parseDate / parseTime / custom). */\n tryParse: (s: string) => Date | null;\n /** Host's displayed-text state and setter (the hook drives it during edits). */\n text: string;\n setText: (s: string) => void;\n /**\n * Seed for an empty value when the user starts typing: Time → today at noon,\n * Date → today at 00:00, DateTime → now. Should be referentially stable.\n */\n makeBaseDate: () => Date;\n locale?: string;\n min?: Date;\n max?: Date;\n /**\n * Host-supplied blocking predicate (composed from shouldDisableDate /\n * unselectableDates / unselectableTimes). Checked alongside min/max on\n * every manual-entry commit; return true to reject the candidate value.\n */\n isBlocked?: (d: Date) => boolean;\n /**\n * Rejects a candidate only while the digits typed into its segment leave\n * it unfinished, such as the first digits of a year. The digit stays in\n * the segment and the next one tries again, so a value passing through a\n * candidate it can't commit on the way to one it can costs nothing. A\n * finished segment, an arrow step and parsed text answer to `isBlocked`\n * alone.\n */\n isUnfinishedBlocked?: (d: Date) => boolean;\n disabled?: boolean;\n readOnly?: boolean;\n /** Allow segmented typing. When false, segment mode never engages. */\n editable?: boolean;\n /** Whether a popover exists; gates open-on-focus / click / Alt+ArrowDown. */\n popover?: boolean;\n openOnFocus?: boolean;\n closeOnSelect?: boolean;\n isOpen: boolean;\n /**\n * The host's open-state setter. The hook asks it to open on focus, click\n * or Alt+ArrowDown, but not on the focus the popover's focus trap hands\n * back to the input as it closes, which is not the user arriving.\n */\n setOpen: (next: boolean) => void;\n inputRef: React.RefObject<HTMLInputElement | null>;\n containerRef: React.RefObject<HTMLElement | null>;\n onFocus?: React.FocusEventHandler<HTMLInputElement>;\n onClick?: React.MouseEventHandler<HTMLInputElement>;\n onKeyDown?: React.KeyboardEventHandler<HTMLInputElement>;\n onBlur?: React.FocusEventHandler<HTMLInputElement>;\n}\n\nexport interface UseSegmentedEntryResult {\n segmentMap: SegmentMap | null;\n activeSegmentIdx: number | null;\n /** True when segment typing is available (map + editable + not disabled/readOnly). */\n segmentEditable: boolean;\n /** True when a segment is actively selected. */\n inSegmentMode: boolean;\n /** Spread onto the combobox `<input>`. */\n inputHandlers: {\n onChange: React.ChangeEventHandler<HTMLInputElement>;\n onFocus: React.FocusEventHandler<HTMLInputElement>;\n onClick: React.MouseEventHandler<HTMLInputElement>;\n onKeyDown: React.KeyboardEventHandler<HTMLInputElement>;\n onBlur: React.FocusEventHandler<HTMLInputElement>;\n };\n}\n\n/**\n * Segmented manual keyboard entry for a date / time picker input. Computes a\n * segment map from the token format, tracks the active segment, and returns\n * the full set of `<input>` event handlers — segment-mutating keys (arrows,\n * digits, AM/PM, separators) are handled here, while popover open/close and\n * free-form parse-on-blur/Enter are driven through the host-supplied\n * `setOpen` / `tryParse` / `commitValue` callbacks. When the format is an\n * `Intl` options object or contains variable-width tokens, the segment map is\n * null and the input transparently falls back to free-form text entry.\n */\nexport function useSegmentedEntry(\n params: UseSegmentedEntryParams\n): UseSegmentedEntryResult {\n const {\n format,\n skipKinds,\n value,\n commitValue,\n formatFn,\n tryParse,\n text,\n setText,\n makeBaseDate,\n locale,\n min,\n max,\n isBlocked,\n isUnfinishedBlocked,\n disabled,\n readOnly,\n editable = true,\n popover = true,\n openOnFocus = true,\n closeOnSelect = false,\n isOpen,\n setOpen,\n inputRef,\n containerRef,\n onFocus,\n onClick,\n onKeyDown,\n onBlur,\n } = params;\n\n const segmentMap: SegmentMap | null = useMemo(() => {\n const map = typeof format === 'string' ? buildSegmentMap(format) : null;\n if (!map || !skipKinds) return map;\n const editable = map.editable.filter(\n i => !skipKinds.includes(map.segments[i].kind)\n );\n return editable.length > 0 ? { ...map, editable } : null;\n }, [format, skipKinds]);\n const [activeSegmentIdx, setActiveSegmentIdx] = useState<number | null>(null);\n // Buffer of digits typed within the current segment, cleared on segment\n // change. Kept in a ref because key handlers read+update synchronously\n // within the same event tick.\n const typedDigitsRef = useRef<string>('');\n // The text focus seeded an empty picker with, until the user edits it or\n // leaves.\n const seedRef = useRef<string | null>(null);\n\n // Whether the text is still what the picker put there, so nothing in it was\n // typed: the value's display, or an empty picker's seed until an edit drops\n // it. Against a value it compares text alone, so typing that ends back on\n // the display counts as untouched.\n const isUntouched = useCallback(\n (s: string) =>\n value\n ? s === formatFn(value, format, locale)\n : seedRef.current !== null && s === seedRef.current,\n [value, formatFn, format, locale]\n );\n\n // A seed the popover never turned into a value closes with it, wherever\n // focus goes, so a dismissed empty field stays empty.\n //\n // As the popover closes, its focus trap hands focus back to the input. That\n // focus is not the user arriving: it must not open the popover again under\n // `openOnFocus`, or seed an empty picker. `closingRef` is set in the layout\n // phase of the commit that closes it and cleared by that commit's effects,\n // and React runs a commit's effect cleanups, the trap's among them, before\n // any of its effects, so a focus in between is the one handed back.\n const closingRef = useRef(false);\n const wasOpenRef = useRef(isOpen);\n useClientLayoutEffect(() => {\n if (wasOpenRef.current && !isOpen) {\n closingRef.current = true;\n if (!value && isUntouched(text)) setText('');\n seedRef.current = null;\n }\n wasOpenRef.current = isOpen;\n }, [isOpen, value, isUntouched, text, setText]);\n useEffect(() => {\n closingRef.current = false;\n }, [isOpen]);\n\n // Segment mode is unavailable for disabled / read-only / non-editable\n // pickers and for Intl-options / variable-width formats (segmentMap null).\n const segmentEditable = !!segmentMap && !!editable && !disabled && !readOnly;\n\n // The Date we edit when the user starts without a current value.\n const segmentBaseDate = useCallback(\n (): Date => value ?? makeBaseDate(),\n [value, makeBaseDate]\n );\n\n // Single gate for every manual-entry commit: min/max bounds plus the\n // host's blocking predicate.\n const isAllowed = useCallback(\n (d: Date) => isWithin(d, min, max) && !isBlocked?.(d),\n [min, max, isBlocked]\n );\n\n // Apply a segment-driven date update: commit through the host pipeline (so\n // onChange / controlled mode keep working) and re-render the text so the\n // active selection range stays valid.\n const applyDateFromSegment = useCallback(\n (next: Date) => {\n if (!isAllowed(next)) return;\n commitValue(next);\n setText(formatFn(next, format, locale));\n },\n [commitValue, isAllowed, formatFn, format, locale, setText]\n );\n\n // After every segment-driven change, restore the system selection on the\n // active segment's char range. A layout effect runs synchronously before\n // paint so the user never sees a stray caret position. We deliberately do\n // NOT gate on document.activeElement: when openOnFocus is true the focus\n // trap moves focus into the popover, but setSelectionRange on an unfocused\n // input is well-defined and the selection becomes visible on refocus.\n useClientLayoutEffect(() => {\n if (activeSegmentIdx === null || !segmentMap || !inputRef.current) return;\n const seg = segmentMap.segments[activeSegmentIdx];\n if (!seg) return;\n try {\n inputRef.current.setSelectionRange(seg.start, seg.end);\n } catch {\n // Some read-only inputs reject setSelectionRange; harmless.\n }\n }, [activeSegmentIdx, segmentMap, text, inputRef]);\n\n const moveSegment = useCallback(\n (delta: 1 | -1) => {\n if (!segmentMap || activeSegmentIdx === null) return;\n const pos = segmentMap.editable.indexOf(activeSegmentIdx);\n if (pos < 0) return;\n const nextPos = Math.max(\n 0,\n Math.min(segmentMap.editable.length - 1, pos + delta)\n );\n const nextIdx = segmentMap.editable[nextPos];\n if (nextIdx !== activeSegmentIdx) {\n typedDigitsRef.current = '';\n setActiveSegmentIdx(nextIdx);\n }\n },\n [segmentMap, activeSegmentIdx]\n );\n\n const handleChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n // In segment mode the text is managed programmatically (every edit\n // re-formats from the canonical Date). Browser-issued input events\n // would otherwise clobber it. The free-form path runs only when\n // segment mode is inactive.\n if (activeSegmentIdx !== null && segmentEditable) return;\n seedRef.current = null;\n setText(e.target.value);\n },\n [activeSegmentIdx, segmentEditable, setText]\n );\n\n const handleBlur = useCallback(\n (e: React.FocusEvent<HTMLInputElement>) => {\n // The popover opens on focus by default, and the focus trap moves focus\n // into the popover panel — that fires this blur even though the user is\n // still in the same picker. Only tear down segment state and re-parse\n // when focus has truly left the picker's container.\n const nextFocus = e.relatedTarget as HTMLElement | null;\n const stayingInPicker =\n nextFocus !== null &&\n containerRef.current !== null &&\n containerRef.current.contains(nextFocus);\n if (stayingInPicker) {\n onBlur?.(e);\n return;\n }\n setActiveSegmentIdx(null);\n typedDigitsRef.current = '';\n // Leaving commits only what was typed. Re-parsing the value's display\n // could drop what the format leaves out, such as seconds, and a seed\n // nobody typed over is not the user's date.\n const untouched = isUntouched(text);\n // An open popover keeps an unused seed until it closes, so one portaled\n // outside the picker, whose focus reads as leaving, keeps it as one\n // inside does.\n if (!isOpen) seedRef.current = null;\n if (untouched) {\n if (!value && !isOpen) setText('');\n onBlur?.(e);\n return;\n }\n const parsed = tryParse(text);\n if (parsed && isAllowed(parsed)) {\n commitValue(parsed);\n } else {\n setText(value ? formatFn(value, format, locale) : '');\n }\n onBlur?.(e);\n },\n [\n containerRef,\n isUntouched,\n isOpen,\n tryParse,\n text,\n isAllowed,\n commitValue,\n value,\n formatFn,\n format,\n locale,\n setText,\n onBlur,\n ]\n );\n\n const handleFocus = useCallback(\n (e: React.FocusEvent<HTMLInputElement>) => {\n const handedBack = closingRef.current;\n if (!handedBack && openOnFocus && popover && !disabled && !readOnly) {\n setOpen(true);\n }\n // Enter segment mode: prime an initial value (so editing works even when\n // empty), seed the text, and highlight the first editable segment. The\n // segment base doesn't need the seed, so focus handed back skips it.\n if (segmentEditable && segmentMap) {\n if (!value && !handedBack) {\n const seed = formatFn(makeBaseDate(), format, locale);\n seedRef.current = seed;\n setText(seed);\n }\n typedDigitsRef.current = '';\n setActiveSegmentIdx(segmentMap.editable[0]);\n }\n onFocus?.(e);\n },\n [\n openOnFocus,\n popover,\n disabled,\n readOnly,\n setOpen,\n segmentEditable,\n segmentMap,\n value,\n makeBaseDate,\n formatFn,\n format,\n locale,\n setText,\n onFocus,\n ]\n );\n\n const handleClick = useCallback(\n (e: React.MouseEvent<HTMLInputElement>) => {\n // Clicking the field opens the popover only when `openOnFocus` is on —\n // a click is just a focus. With `openOnFocus={false}` (manual-entry\n // mode) the click positions the caret for typing and the popover is\n // opened explicitly via the right launcher button (or Alt+ArrowDown).\n if (openOnFocus && popover && !disabled && !readOnly) setOpen(true);\n if (segmentEditable && segmentMap && inputRef.current) {\n const caret = inputRef.current.selectionStart ?? 0;\n const idx = segmentIndexAtCaret(segmentMap, caret);\n if (idx !== null && idx !== activeSegmentIdx) {\n typedDigitsRef.current = '';\n setActiveSegmentIdx(idx);\n }\n }\n onClick?.(e);\n },\n [\n openOnFocus,\n popover,\n disabled,\n readOnly,\n setOpen,\n segmentEditable,\n segmentMap,\n inputRef,\n activeSegmentIdx,\n onClick,\n ]\n );\n\n const inSegmentMode =\n segmentEditable && segmentMap !== null && activeSegmentIdx !== null;\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent<HTMLInputElement>) => {\n // Segment-mode key routing comes first. When segment mode isn't engaged\n // (not editable, no map, or no active segment — e.g. after a typed-text\n // fallback), unhandled keys fall through to the popover / free-form\n // handling below.\n if (inSegmentMode && segmentMap && activeSegmentIdx !== null) {\n const seg = segmentMap.segments[activeSegmentIdx];\n const base = segmentBaseDate();\n const isPm = base.getHours() >= 12;\n switch (e.key) {\n case 'ArrowUp':\n case 'ArrowDown':\n e.preventDefault();\n // The plain arrows step the segment, so the popover opens on\n // Alt+ArrowDown and closes on Alt+ArrowUp, as a combobox's does,\n // and neither steps it.\n if (e.altKey) {\n if (e.key === 'ArrowUp') {\n if (isOpen) setOpen(false);\n } else if (!isOpen && popover) {\n setOpen(true);\n }\n return;\n }\n typedDigitsRef.current = '';\n applyDateFromSegment(\n incrementSegmentValue(\n seg,\n base,\n e.key === 'ArrowUp' ? 1 : -1,\n isPm\n )\n );\n return;\n case 'ArrowRight':\n e.preventDefault();\n moveSegment(1);\n return;\n case 'ArrowLeft':\n e.preventDefault();\n moveSegment(-1);\n return;\n case 'Backspace':\n e.preventDefault();\n if (typedDigitsRef.current.length > 0) {\n typedDigitsRef.current = '';\n } else {\n moveSegment(-1);\n }\n return;\n case 'Escape':\n if (isOpen) {\n e.preventDefault();\n setOpen(false);\n }\n return;\n case 'Enter':\n e.preventDefault();\n if (closeOnSelect) setOpen(false);\n return;\n case 'Tab':\n setActiveSegmentIdx(null);\n typedDigitsRef.current = '';\n return;\n default:\n // AM/PM keys.\n if (seg.kind === 'ampm') {\n if (e.key === 'a' || e.key === 'A') {\n e.preventDefault();\n typedDigitsRef.current = '';\n applyDateFromSegment(setAmPm(base, false));\n moveSegment(1);\n return;\n }\n if (e.key === 'p' || e.key === 'P') {\n e.preventDefault();\n typedDigitsRef.current = '';\n applyDateFromSegment(setAmPm(base, true));\n moveSegment(1);\n return;\n }\n }\n // Typing a format separator (/, :, -, ., space) jumps to the next\n // segment, skipping over the literal punctuation.\n if (e.key.length === 1 && SEPARATOR_RE.test(e.key)) {\n e.preventDefault();\n typedDigitsRef.current = '';\n moveSegment(1);\n return;\n }\n // Digit entry for numeric segments.\n if (/^[0-9]$/.test(e.key) && seg.kind !== 'ampm') {\n e.preventDefault();\n const nextBuffer = typedDigitsRef.current + e.key;\n typedDigitsRef.current = nextBuffer;\n const { date, advance } = setSegmentValue(\n seg,\n base,\n nextBuffer,\n isPm\n );\n if (!advance && isUnfinishedBlocked?.(date)) return;\n applyDateFromSegment(date);\n if (advance) {\n typedDigitsRef.current = '';\n moveSegment(1);\n }\n return;\n }\n }\n }\n // ----- free-form / popover key handling -----\n // With no segment to step, ArrowDown opens the popover with or without\n // Alt, unless the field is read-only or disabled, as focus and the\n // launcher don't open it then either. Alt+ArrowUp closes it.\n if (\n e.key === 'ArrowDown' &&\n !isOpen &&\n popover &&\n !disabled &&\n !readOnly\n ) {\n e.preventDefault();\n setOpen(true);\n return;\n }\n if (e.key === 'ArrowUp' && e.altKey && isOpen) {\n e.preventDefault();\n setOpen(false);\n return;\n }\n if (e.key === 'Escape' && isOpen) {\n e.preventDefault();\n setOpen(false);\n return;\n }\n if (e.key === 'Enter') {\n e.preventDefault();\n // Untouched text has nothing to commit, as on leaving, but Enter\n // still confirms what the field shows.\n if (isUntouched(text)) {\n if (closeOnSelect) setOpen(false);\n } else {\n const parsed = tryParse(text);\n if (parsed && isAllowed(parsed)) {\n commitValue(parsed);\n if (closeOnSelect) setOpen(false);\n }\n }\n }\n onKeyDown?.(e);\n },\n [\n inSegmentMode,\n segmentMap,\n activeSegmentIdx,\n segmentBaseDate,\n applyDateFromSegment,\n isUnfinishedBlocked,\n moveSegment,\n isOpen,\n setOpen,\n closeOnSelect,\n popover,\n disabled,\n readOnly,\n isUntouched,\n tryParse,\n text,\n isAllowed,\n commitValue,\n onKeyDown,\n ]\n );\n\n return {\n segmentMap,\n activeSegmentIdx,\n segmentEditable,\n inSegmentMode,\n inputHandlers: {\n onChange: handleChange,\n onFocus: handleFocus,\n onClick: handleClick,\n onKeyDown: handleKeyDown,\n onBlur: handleBlur,\n },\n };\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"controlLoading.js","sources":["../../../src/form/controlLoading.ts"],"sourcesContent":["import { createContext, useContext } from 'react';\n\n// Whether the nearest enclosing `Control` shows its `isLoading` spinner. The\n// picker bases read it so their right-side launcher gives way to that\n// spinner, which sits at the same edge, whether the `Control` is the one a\n// convenience input renders or one the caller wrapped around the input.\n// Autocomplete reads it for its clear button, which sits there too.\n// Kept apart from `FormContext`, whose contexts only report whether a `Field`\n// or `Control` is present. Internal; not part of the public API.\nconst ControlLoadingContext = createContext(false);\n\n/** Provider for the loading state, used internally by `Control`. */\nexport const ControlLoadingProvider = ControlLoadingContext.Provider;\n\n/** Whether the nearest enclosing `Control` is loading; `false` outside one. */\nexport const useControlLoading = () => useContext(ControlLoadingContext);\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"controlLoading.js","sources":["../../../src/form/controlLoading.ts"],"sourcesContent":["import { createContext, useContext } from 'react';\n\n// Whether the nearest enclosing `Control` shows its `isLoading` spinner. The\n// picker bases read it so their right-side launcher gives way to that\n// spinner, which sits at the same edge, whether the `Control` is the one a\n// convenience input renders or one the caller wrapped around the input.\n// Autocomplete reads it for its clear button, which sits there too.\n// Kept apart from `FormContext`, whose contexts only report whether a `Field`\n// or `Control` is present. Internal; not part of the public API.\nconst ControlLoadingContext = createContext(false);\n\n/** Provider for the loading state, used internally by `Control`. */\nexport const ControlLoadingProvider = ControlLoadingContext.Provider;\n\n/** Whether the nearest enclosing `Control` is loading; `false` outside one. */\nexport const useControlLoading = () => useContext(ControlLoadingContext);\n"],"names":[],"mappings":";;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM,qBAAqB,GAAG,aAAa,CAAC,KAAK,CAAC;AAElD;AACO,MAAM,sBAAsB,GAAG,qBAAqB,CAAC;AAE5D;AACO,MAAM,iBAAiB,GAAG,MAAM,UAAU,CAAC,qBAAqB;;"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/* @allxsmith/bestax-bulma — AI agents: see AGENTS.md in the package root, or https://bestax.io/llms.txt */
|
|
2
|
+
'use client';
|
|
2
3
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
3
4
|
import { usePrefixedClassNames, classNames } from '../helpers/classNames.js';
|
|
4
5
|
import { FieldProvider } from './FormContext.js';
|