From bf076fa99236e81d5f44beea77abc38c890bcea3 Mon Sep 17 00:00:00 2001 From: YuanboXue-Amber Date: Mon, 30 Oct 2023 17:11:08 +0100 Subject: [PATCH 1/9] onTimeSelect => onTimeChange --- .../components/TimePicker/TimePicker.test.tsx | 24 +++++++++---------- .../components/TimePicker/TimePicker.types.ts | 2 +- .../components/TimePicker/useTimePicker.tsx | 10 ++++---- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/packages/react-components/react-timepicker-compat-preview/src/components/TimePicker/TimePicker.test.tsx b/packages/react-components/react-timepicker-compat-preview/src/components/TimePicker/TimePicker.test.tsx index e441946b1d60d1..1b0a394f4da7a0 100644 --- a/packages/react-components/react-timepicker-compat-preview/src/components/TimePicker/TimePicker.test.tsx +++ b/packages/react-components/react-timepicker-compat-preview/src/components/TimePicker/TimePicker.test.tsx @@ -49,9 +49,9 @@ describe('TimePicker', () => { it('shows controlled time correctly', () => { const TestExample = () => { const [selectedTime, setSelectedTime] = React.useState(dateAnchor); - const onTimeSelect: TimePickerProps['onTimeSelect'] = (_e, data) => setSelectedTime(data.selectedTime); + const onTimeChange: TimePickerProps['onTimeChange'] = (_e, data) => setSelectedTime(data.selectedTime); return ( - + ); }; @@ -70,7 +70,7 @@ describe('TimePicker', () => { const ControlledFreeFormExample = () => { const [selectedTime, setSelectedTime] = React.useState(dateAnchor); - const onTimeSelect: TimePickerProps['onTimeSelect'] = (e, data) => { + const onTimeChange: TimePickerProps['onTimeChange'] = (e, data) => { handleTimeSelect(e, data); setSelectedTime(data.selectedTime); }; @@ -80,13 +80,13 @@ describe('TimePicker', () => { dateAnchor={dateAnchor} startHour={10} selectedTime={selectedTime} - onTimeSelect={onTimeSelect} + onTimeChange={onTimeChange} /> ); }; const UnControlledFreeFormExample = () => ( - + ); beforeEach(() => { @@ -130,12 +130,12 @@ describe('TimePicker', () => { name | Component ${'uncontrolled'} | ${UnControlledFreeFormExample} ${'controlled'} | ${ControlledFreeFormExample} - `('$name - trigger onTimeSelect only when value change', ({ Component }) => { + `('$name - trigger onTimeChange only when value change', ({ Component }) => { const { getByRole, getAllByRole } = render(); const input = getByRole('combobox'); - // Call onTimeSelect when select an option + // Call onTimeChange when select an option userEvent.click(input); userEvent.click(getAllByRole('option')[1]); expect(handleTimeSelect).toHaveBeenCalledTimes(1); @@ -145,11 +145,11 @@ describe('TimePicker', () => { ); handleTimeSelect.mockClear(); - // Do not call onTimeSelect on Enter when the value remains the same + // Do not call onTimeChange on Enter when the value remains the same fireEvent.keyDown(input, { key: 'Enter', code: 'Enter' }); expect(handleTimeSelect).toHaveBeenCalledTimes(0); - // Call onTimeSelect on Enter when the value changes + // Call onTimeChange on Enter when the value changes userEvent.type(input, '111{enter}'); expect(handleTimeSelect).toHaveBeenCalledTimes(1); expect(handleTimeSelect).toHaveBeenCalledWith( @@ -162,18 +162,18 @@ describe('TimePicker', () => { name | Component ${'uncontrolled'} | ${UnControlledFreeFormExample} ${'controlled'} | ${ControlledFreeFormExample} - `('$name - trigger onTimeSelect on blur when value change', ({ Component }) => { + `('$name - trigger onTimeChange on blur when value change', ({ Component }) => { const { getByRole } = render(); const input = getByRole('combobox'); const expandIcon = getByRole('button'); - // Do not call onTimeSelect when clicking dropdown icon + // Do not call onTimeChange when clicking dropdown icon userEvent.type(input, '111'); userEvent.click(expandIcon); expect(handleTimeSelect).toHaveBeenCalledTimes(0); - // Call onTimeSelect on focus lose + // Call onTimeChange on focus lose userEvent.tab(); expect(handleTimeSelect).toHaveBeenCalledWith( expect.anything(), diff --git a/packages/react-components/react-timepicker-compat-preview/src/components/TimePicker/TimePicker.types.ts b/packages/react-components/react-timepicker-compat-preview/src/components/TimePicker/TimePicker.types.ts index 540efaf33f725f..4a6614d59cf9a9 100644 --- a/packages/react-components/react-timepicker-compat-preview/src/components/TimePicker/TimePicker.types.ts +++ b/packages/react-components/react-timepicker-compat-preview/src/components/TimePicker/TimePicker.types.ts @@ -138,7 +138,7 @@ export type TimePickerProps = Omit< /** * Callback for when a time selection is made. */ - onTimeSelect?: (event: TimeSelectionEvents, data: TimeSelectionData) => void; + onTimeChange?: (event: TimeSelectionEvents, data: TimeSelectionData) => void; /** * Custom the date strings displayed in dropdown options. diff --git a/packages/react-components/react-timepicker-compat-preview/src/components/TimePicker/useTimePicker.tsx b/packages/react-components/react-timepicker-compat-preview/src/components/TimePicker/useTimePicker.tsx index 3b02d39e68abb7..825e65bae70de4 100644 --- a/packages/react-components/react-timepicker-compat-preview/src/components/TimePicker/useTimePicker.tsx +++ b/packages/react-components/react-timepicker-compat-preview/src/components/TimePicker/useTimePicker.tsx @@ -32,7 +32,7 @@ export const useTimePicker_unstable = (props: TimePickerProps, ref: React.Ref(undefined); - const selectTime: TimePickerProps['onTimeSelect'] = React.useCallback( + const selectTime: TimePickerProps['onTimeChange'] = React.useCallback( (e, data) => { setSelectedTime(data.selectedTime); setSubmittedText(data.selectedTimeText); - onTimeSelect?.(e, data); + onTimeChange?.(e, data); }, - [onTimeSelect, setSelectedTime], + [onTimeChange, setSelectedTime], ); const selectedOptions = React.useMemo(() => { @@ -163,7 +163,7 @@ const useStableDateAnchor = (providedDate: Date | undefined, startHour: Hour, en * - Enter/Tab key is pressed on the input. * - TimePicker loses focus, signifying a possible change. */ -const useSelectTimeFromValue = (state: TimePickerState, callback: TimePickerProps['onTimeSelect']) => { +const useSelectTimeFromValue = (state: TimePickerState, callback: TimePickerProps['onTimeChange']) => { const { activeOption, freeform, validateFreeFormTime, submittedText, setActiveOption, value } = state; // Base Combobox has activeOption default to first option in dropdown even if it doesn't match input value, and Enter key will select it. From 56329ec4d0d077a97134dce3a06a1f50f6d4160f Mon Sep 17 00:00:00 2001 From: YuanboXue-Amber Date: Mon, 30 Oct 2023 17:33:27 +0100 Subject: [PATCH 2/9] pick from combobox props instead of omit --- .../components/TimePicker/TimePicker.types.ts | 30 ++++++++++++------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/packages/react-components/react-timepicker-compat-preview/src/components/TimePicker/TimePicker.types.ts b/packages/react-components/react-timepicker-compat-preview/src/components/TimePicker/TimePicker.types.ts index 4a6614d59cf9a9..079ef996ff6418 100644 --- a/packages/react-components/react-timepicker-compat-preview/src/components/TimePicker/TimePicker.types.ts +++ b/packages/react-components/react-timepicker-compat-preview/src/components/TimePicker/TimePicker.types.ts @@ -94,15 +94,25 @@ export type TimeFormatOptions = { /** * TimePicker Props */ -export type TimePickerProps = Omit< +export type TimePickerProps = Pick< ComboboxProps, - // Omit children as TimePicker has predefined children - | 'children' - // Omit selection props as TimePicker has `selectedTime` props - | 'defaultSelectedOptions' - | 'multiselect' - | 'onOptionSelect' - | 'selectedOptions' + | 'root' + | 'expandIcon' + | 'input' + | 'listbox' + | 'as' + | 'appearance' + | 'defaultOpen' + | 'defaultValue' + | 'inlinePopup' + | 'onOpenChange' + | 'open' + | 'placeholder' + | 'positioning' + | 'size' + | 'value' + | 'mountNode' + | 'freeform' > & TimeFormatOptions & { /** @@ -148,14 +158,14 @@ export type TimePickerProps = Omit< /** * Custom validation for the input time string from user in freeform TimePicker. */ - validateFreeFormTime?: (time: string | undefined) => TimeStringValidationResult; + formatTimeStringToDate?: (time: string | undefined) => TimeStringValidationResult; }; /** * State used in rendering TimePicker */ export type TimePickerState = ComboboxState & - Required> & { + Required> & { /** * Submitted text from the input field. It is used to determine if the input value has changed when user submit a new value on Enter or blur from input. */ From 3ec168b59a05d32c959b92482749810b40b9e233 Mon Sep 17 00:00:00 2001 From: YuanboXue-Amber Date: Mon, 30 Oct 2023 17:45:53 +0100 Subject: [PATCH 3/9] validateFreeFormTime => formatTimeStringToDate --- .../components/TimePicker/useTimePicker.tsx | 28 ++++++++----------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/packages/react-components/react-timepicker-compat-preview/src/components/TimePicker/useTimePicker.tsx b/packages/react-components/react-timepicker-compat-preview/src/components/TimePicker/useTimePicker.tsx index 825e65bae70de4..ac1073baee43d5 100644 --- a/packages/react-components/react-timepicker-compat-preview/src/components/TimePicker/useTimePicker.tsx +++ b/packages/react-components/react-timepicker-compat-preview/src/components/TimePicker/useTimePicker.tsx @@ -29,14 +29,14 @@ export const useTimePicker_unstable = (props: TimePickerProps, ref: React.Ref - formatDateToTimeString - ? formatDateToTimeString(dateTime) - : defaultFormatDateToTimeString(dateTime, { showSeconds, hourCycle }), - [hourCycle, formatDateToTimeString, showSeconds], - ); const options: TimePickerOption[] = React.useMemo( () => getTimesBetween(dateStartAnchor, dateEndAnchor, increment).map(time => ({ date: time, key: dateToKey(time), - text: dateToText(time), + text: formatDateToTimeString(time, { showSeconds, hourCycle }), })), - [dateStartAnchor, dateEndAnchor, increment, dateToText], + [dateEndAnchor, dateStartAnchor, formatDateToTimeString, hourCycle, increment, showSeconds], ); const [selectedTime, setSelectedTime] = useControllableState({ @@ -82,7 +75,8 @@ export const useTimePicker_unstable = (props: TimePickerProps, ref: React.Ref { - const selectedOption = options.find(date => date.key === dateToKey(selectedTime)); + const selectedTimeKey = dateToKey(selectedTime); + const selectedOption = options.find(date => date.key === selectedTimeKey); return selectedOption ? [selectedOption.key] : []; }, [options, selectedTime]); @@ -116,7 +110,7 @@ export const useTimePicker_unstable = (props: TimePickerProps, ref: React.Ref getDateFromTimeString(time, dateStartAnchor, dateEndAnchor, { hourCycle, showSeconds }), [dateEndAnchor, dateStartAnchor, hourCycle, showSeconds], @@ -125,7 +119,7 @@ export const useTimePicker_unstable = (props: TimePickerProps, ref: React.Ref { - const { activeOption, freeform, validateFreeFormTime, submittedText, setActiveOption, value } = state; + const { activeOption, freeform, formatTimeStringToDate, submittedText, setActiveOption, value } = state; // Base Combobox has activeOption default to first option in dropdown even if it doesn't match input value, and Enter key will select it. // This effect ensures that the activeOption is cleared when the input doesn't match any option. @@ -186,14 +180,14 @@ const useSelectTimeFromValue = (state: TimePickerState, callback: TimePickerProp return; } - const { date: selectedTime, error } = validateFreeFormTime(value); + const { date: selectedTime, error } = formatTimeStringToDate(value); // Only triggers callback when the text in input has changed. if (submittedText !== value) { callback?.(e, { selectedTime, selectedTimeText: value, error }); } }, - [callback, freeform, submittedText, validateFreeFormTime, value], + [callback, freeform, submittedText, formatTimeStringToDate, value], ); const handleKeyDown: ComboboxProps['onKeyDown'] = React.useCallback( From eda4fdc9368f7de454473bfd191343082bf7ddf5 Mon Sep 17 00:00:00 2001 From: YuanboXue-Amber Date: Mon, 30 Oct 2023 17:50:16 +0100 Subject: [PATCH 4/9] api --- .../etc/react-timepicker-compat-preview.api.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/react-components/react-timepicker-compat-preview/etc/react-timepicker-compat-preview.api.md b/packages/react-components/react-timepicker-compat-preview/etc/react-timepicker-compat-preview.api.md index ffbb0b7da62923..df2c6568e8f2c1 100644 --- a/packages/react-components/react-timepicker-compat-preview/etc/react-timepicker-compat-preview.api.md +++ b/packages/react-components/react-timepicker-compat-preview/etc/react-timepicker-compat-preview.api.md @@ -19,23 +19,23 @@ export const TimePicker: ForwardRefComponent; export const timePickerClassNames: SlotClassNames; // @public -export type TimePickerProps = Omit & TimeFormatOptions & { +export type TimePickerProps = Pick & TimeFormatOptions & { startHour?: Hour; endHour?: Hour; increment?: number; dateAnchor?: Date; selectedTime?: Date | null; defaultSelectedTime?: Date; - onTimeSelect?: (event: TimeSelectionEvents, data: TimeSelectionData) => void; + onTimeChange?: (event: TimeSelectionEvents, data: TimeSelectionData) => void; formatDateToTimeString?: (date: Date) => string; - validateFreeFormTime?: (time: string | undefined) => TimeStringValidationResult; + formatTimeStringToDate?: (time: string | undefined) => TimeStringValidationResult; }; // @public (undocumented) export type TimePickerSlots = ComboboxSlots; // @public -export type TimePickerState = ComboboxState & Required> & { +export type TimePickerState = ComboboxState & Required> & { submittedText: string | undefined; }; From c26b914ee6c6b372258ff9d253642a997c9844c4 Mon Sep 17 00:00:00 2001 From: YuanboXue-Amber Date: Mon, 30 Oct 2023 17:56:48 +0100 Subject: [PATCH 5/9] memo --- .../components/TimePicker/useTimePicker.tsx | 22 +++++++++---------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/packages/react-components/react-timepicker-compat-preview/src/components/TimePicker/useTimePicker.tsx b/packages/react-components/react-timepicker-compat-preview/src/components/TimePicker/useTimePicker.tsx index ac1073baee43d5..0b59c4dd4a4772 100644 --- a/packages/react-components/react-timepicker-compat-preview/src/components/TimePicker/useTimePicker.tsx +++ b/packages/react-components/react-timepicker-compat-preview/src/components/TimePicker/useTimePicker.tsx @@ -135,20 +135,18 @@ export const useTimePicker_unstable = (props: TimePickerProps, ref: React.Ref { const [fallbackDateAnchor] = React.useState(() => new Date()); - // Convert the Date object to a stable key representation. This ensures that the memoization remains stable when a new Date object representing the same date is passed in. - const dateAnchorKey = dateToKey(providedDate ?? null); - const dateAnchor = React.useMemo( - () => keyToDate(dateAnchorKey) ?? fallbackDateAnchor, - [dateAnchorKey, fallbackDateAnchor], - ); + const providedDateKey = dateToKey(providedDate ?? null); - const dateStartAnchor = React.useMemo(() => getDateStartAnchor(dateAnchor, startHour), [dateAnchor, startHour]); - const dateEndAnchor = React.useMemo( - () => getDateEndAnchor(dateAnchor, startHour, endHour), - [dateAnchor, endHour, startHour], - ); + return React.useMemo(() => { + const dateAnchor = providedDate ?? fallbackDateAnchor; + + const dateStartAnchor = getDateStartAnchor(dateAnchor, startHour); + const dateEndAnchor = getDateEndAnchor(dateAnchor, startHour, endHour); - return { dateStartAnchor, dateEndAnchor }; + return { dateStartAnchor, dateEndAnchor }; + // `providedDate`'s stable key representation is used as dependency instead of the Date object. This ensures that the memoization remains stable when a new Date object representing the same date is passed in. + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [endHour, fallbackDateAnchor, providedDateKey, startHour]); }; /** From b52235417a952dfde548ea6fd9fe577a1493d6cb Mon Sep 17 00:00:00 2001 From: YuanboXue-Amber Date: Tue, 31 Oct 2023 10:19:25 +0100 Subject: [PATCH 6/9] type --- .../react-timepicker-compat-preview.api.md | 3 +- .../components/TimePicker/TimePicker.types.ts | 37 +++++++++---------- 2 files changed, 19 insertions(+), 21 deletions(-) diff --git a/packages/react-components/react-timepicker-compat-preview/etc/react-timepicker-compat-preview.api.md b/packages/react-components/react-timepicker-compat-preview/etc/react-timepicker-compat-preview.api.md index df2c6568e8f2c1..5a671c38dd3788 100644 --- a/packages/react-components/react-timepicker-compat-preview/etc/react-timepicker-compat-preview.api.md +++ b/packages/react-components/react-timepicker-compat-preview/etc/react-timepicker-compat-preview.api.md @@ -7,6 +7,7 @@ import type { ComboboxProps } from '@fluentui/react-combobox'; import type { ComboboxSlots } from '@fluentui/react-combobox'; import type { ComboboxState } from '@fluentui/react-combobox'; +import { ComponentProps } from '@fluentui/react-utilities'; import type { ForwardRefComponent } from '@fluentui/react-utilities'; import * as React_2 from 'react'; import type { SelectionEvents } from '@fluentui/react-combobox'; @@ -19,7 +20,7 @@ export const TimePicker: ForwardRefComponent; export const timePickerClassNames: SlotClassNames; // @public -export type TimePickerProps = Pick & TimeFormatOptions & { +export type TimePickerProps = Omit, 'input'>, 'children' | 'size'> & Pick & TimeFormatOptions & { startHour?: Hour; endHour?: Hour; increment?: number; diff --git a/packages/react-components/react-timepicker-compat-preview/src/components/TimePicker/TimePicker.types.ts b/packages/react-components/react-timepicker-compat-preview/src/components/TimePicker/TimePicker.types.ts index 079ef996ff6418..d27a3aa8135b52 100644 --- a/packages/react-components/react-timepicker-compat-preview/src/components/TimePicker/TimePicker.types.ts +++ b/packages/react-components/react-timepicker-compat-preview/src/components/TimePicker/TimePicker.types.ts @@ -1,5 +1,6 @@ import * as React from 'react'; import type { ComboboxSlots, ComboboxState, ComboboxProps, SelectionEvents } from '@fluentui/react-combobox'; +import { ComponentProps } from '@fluentui/react-utilities'; export type Hour = | 0 @@ -94,26 +95,22 @@ export type TimeFormatOptions = { /** * TimePicker Props */ -export type TimePickerProps = Pick< - ComboboxProps, - | 'root' - | 'expandIcon' - | 'input' - | 'listbox' - | 'as' - | 'appearance' - | 'defaultOpen' - | 'defaultValue' - | 'inlinePopup' - | 'onOpenChange' - | 'open' - | 'placeholder' - | 'positioning' - | 'size' - | 'value' - | 'mountNode' - | 'freeform' -> & +export type TimePickerProps = Omit, 'input'>, 'children' | 'size'> & + Pick< + ComboboxProps, + | 'appearance' + | 'defaultOpen' + | 'defaultValue' + | 'inlinePopup' + | 'onOpenChange' + | 'open' + | 'placeholder' + | 'positioning' + | 'size' + | 'value' + | 'mountNode' + | 'freeform' + > & TimeFormatOptions & { /** * Start hour (inclusive) for the time range, 0-24. From d479e6e9b945cb4714e3a1dc55208bc6f51a87ba Mon Sep 17 00:00:00 2001 From: YuanboXue-Amber Date: Tue, 31 Oct 2023 10:25:38 +0100 Subject: [PATCH 7/9] update comment --- .../src/components/TimePicker/TimePicker.types.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/react-components/react-timepicker-compat-preview/src/components/TimePicker/TimePicker.types.ts b/packages/react-components/react-timepicker-compat-preview/src/components/TimePicker/TimePicker.types.ts index d27a3aa8135b52..84893e206a6840 100644 --- a/packages/react-components/react-timepicker-compat-preview/src/components/TimePicker/TimePicker.types.ts +++ b/packages/react-components/react-timepicker-compat-preview/src/components/TimePicker/TimePicker.types.ts @@ -148,12 +148,12 @@ export type TimePickerProps = Omit, 'input onTimeChange?: (event: TimeSelectionEvents, data: TimeSelectionData) => void; /** - * Custom the date strings displayed in dropdown options. + * Customizes the formatting of date strings displayed in dropdown options. */ formatDateToTimeString?: (date: Date) => string; /** - * Custom validation for the input time string from user in freeform TimePicker. + * In the freeform TimePicker, customizes the parsing from the input time string into a Date and provides custom validation. */ formatTimeStringToDate?: (time: string | undefined) => TimeStringValidationResult; }; From ad11db3e7e6972215b0a968b2b1be5bb047fc5ae Mon Sep 17 00:00:00 2001 From: Amber Date: Tue, 31 Oct 2023 14:39:24 +0100 Subject: [PATCH 8/9] Update packages/react-components/react-timepicker-compat-preview/src/components/TimePicker/TimePicker.types.ts Co-authored-by: Oleksandr Fediashov --- .../src/components/TimePicker/TimePicker.types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-components/react-timepicker-compat-preview/src/components/TimePicker/TimePicker.types.ts b/packages/react-components/react-timepicker-compat-preview/src/components/TimePicker/TimePicker.types.ts index 84893e206a6840..b33ec8530e0dc5 100644 --- a/packages/react-components/react-timepicker-compat-preview/src/components/TimePicker/TimePicker.types.ts +++ b/packages/react-components/react-timepicker-compat-preview/src/components/TimePicker/TimePicker.types.ts @@ -1,6 +1,6 @@ import * as React from 'react'; import type { ComboboxSlots, ComboboxState, ComboboxProps, SelectionEvents } from '@fluentui/react-combobox'; -import { ComponentProps } from '@fluentui/react-utilities'; +import type { ComponentProps } from '@fluentui/react-utilities'; export type Hour = | 0 From 3899b3dc91d255ff706c2c54c916d72bf96d8519 Mon Sep 17 00:00:00 2001 From: YuanboXue-Amber Date: Tue, 31 Oct 2023 15:16:41 +0100 Subject: [PATCH 9/9] rename error to errorType --- .../etc/react-timepicker-compat-preview.api.md | 4 ++-- .../components/TimePicker/TimePicker.test.tsx | 6 +++--- .../components/TimePicker/TimePicker.types.ts | 4 ++-- .../src/components/TimePicker/timeMath.test.ts | 18 +++++++++--------- .../src/components/TimePicker/timeMath.ts | 16 ++++++++-------- .../components/TimePicker/useTimePicker.tsx | 6 +++--- 6 files changed, 27 insertions(+), 27 deletions(-) diff --git a/packages/react-components/react-timepicker-compat-preview/etc/react-timepicker-compat-preview.api.md b/packages/react-components/react-timepicker-compat-preview/etc/react-timepicker-compat-preview.api.md index 5a671c38dd3788..7ea556bbba333e 100644 --- a/packages/react-components/react-timepicker-compat-preview/etc/react-timepicker-compat-preview.api.md +++ b/packages/react-components/react-timepicker-compat-preview/etc/react-timepicker-compat-preview.api.md @@ -7,7 +7,7 @@ import type { ComboboxProps } from '@fluentui/react-combobox'; import type { ComboboxSlots } from '@fluentui/react-combobox'; import type { ComboboxState } from '@fluentui/react-combobox'; -import { ComponentProps } from '@fluentui/react-utilities'; +import type { ComponentProps } from '@fluentui/react-utilities'; import type { ForwardRefComponent } from '@fluentui/react-utilities'; import * as React_2 from 'react'; import type { SelectionEvents } from '@fluentui/react-combobox'; @@ -44,7 +44,7 @@ export type TimePickerState = ComboboxState & Required { expect(handleTimeSelect).toHaveBeenCalledTimes(1); expect(handleTimeSelect).toHaveBeenCalledWith( expect.anything(), - expect.objectContaining({ selectedTime: null, selectedTimeText: '111', error: 'invalid-input' }), + expect.objectContaining({ selectedTime: null, selectedTimeText: '111', errorType: 'invalid-input' }), ); }, ); @@ -122,7 +122,7 @@ describe('TimePicker', () => { expect(handleTimeSelect).toHaveBeenCalledTimes(1); expect(handleTimeSelect).toHaveBeenCalledWith( expect.anything(), - expect.objectContaining({ selectedTimeText: '11:00', error: undefined }), + expect.objectContaining({ selectedTimeText: '11:00', errorType: undefined }), ); }); @@ -154,7 +154,7 @@ describe('TimePicker', () => { expect(handleTimeSelect).toHaveBeenCalledTimes(1); expect(handleTimeSelect).toHaveBeenCalledWith( expect.anything(), - expect.objectContaining({ selectedTimeText: '10:30111', error: 'invalid-input' }), + expect.objectContaining({ selectedTimeText: '10:30111', errorType: 'invalid-input' }), ); }); diff --git a/packages/react-components/react-timepicker-compat-preview/src/components/TimePicker/TimePicker.types.ts b/packages/react-components/react-timepicker-compat-preview/src/components/TimePicker/TimePicker.types.ts index b33ec8530e0dc5..7510e1afafa8cd 100644 --- a/packages/react-components/react-timepicker-compat-preview/src/components/TimePicker/TimePicker.types.ts +++ b/packages/react-components/react-timepicker-compat-preview/src/components/TimePicker/TimePicker.types.ts @@ -56,7 +56,7 @@ export type TimePickerErrorType = 'invalid-input' | 'out-of-bounds' | 'required- export type TimeStringValidationResult = { date: Date | null; - error?: TimePickerErrorType; + errorType?: TimePickerErrorType; }; export type TimePickerSlots = ComboboxSlots; @@ -74,7 +74,7 @@ export type TimeSelectionData = { /** * The error type for the selected option. */ - error: TimePickerErrorType | undefined; + errorType: TimePickerErrorType | undefined; }; export type TimeFormatOptions = { diff --git a/packages/react-components/react-timepicker-compat-preview/src/components/TimePicker/timeMath.test.ts b/packages/react-components/react-timepicker-compat-preview/src/components/TimePicker/timeMath.test.ts index e5af1f193ba33e..83ccd84d519ae2 100644 --- a/packages/react-components/react-timepicker-compat-preview/src/components/TimePicker/timeMath.test.ts +++ b/packages/react-components/react-timepicker-compat-preview/src/components/TimePicker/timeMath.test.ts @@ -160,22 +160,22 @@ describe('Time Utilities', () => { }); expect(result.date?.getHours()).toBe(14); expect(result.date?.getMinutes()).toBe(30); - expect(result.error).toBeUndefined(); + expect(result.errorType).toBeUndefined(); }); - it('returns an error when no time string is provided', () => { + it('returns an errorType when no time string is provided', () => { const result = getDateFromTimeString(undefined, dateStartAnchor, dateEndAnchor, {}); expect(result.date).toBeNull(); - expect(result.error).toBe('required-input'); + expect(result.errorType).toBe('required-input'); }); - it('returns an error for an invalid time string', () => { + it('returns an errorType for an invalid time string', () => { const result = getDateFromTimeString('25:30', dateStartAnchor, dateEndAnchor, {}); expect(result.date).toBeNull(); - expect(result.error).toBe('invalid-input'); + expect(result.errorType).toBe('invalid-input'); }); - it('returns a date in the next day and an out-of-bounds error when the time is before the dateStartAnchor', () => { + it('returns a date in the next day and an out-of-bounds errorType when the time is before the dateStartAnchor', () => { const result = getDateFromTimeString('11:30 AM', dateStartAnchor, new Date('November 25, 2023 13:00:00'), { hourCycle: 'h11', showSeconds: false, @@ -183,17 +183,17 @@ describe('Time Utilities', () => { expect(result.date?.getDate()).toBe(26); expect(result.date?.getHours()).toBe(11); expect(result.date?.getMinutes()).toBe(30); - expect(result.error).toBe('out-of-bounds'); + expect(result.errorType).toBe('out-of-bounds'); }); - it('returns an out-of-bounds error when the time is same as the dateEndAnchor', () => { + it('returns an out-of-bounds errorType when the time is same as the dateEndAnchor', () => { const result = getDateFromTimeString('1:00 PM', dateStartAnchor, new Date('November 25, 2023 13:00:00'), { hourCycle: 'h11', showSeconds: false, }); expect(result.date?.getHours()).toBe(13); expect(result.date?.getMinutes()).toBe(0); - expect(result.error).toBe('out-of-bounds'); + expect(result.errorType).toBe('out-of-bounds'); }); }); }); diff --git a/packages/react-components/react-timepicker-compat-preview/src/components/TimePicker/timeMath.ts b/packages/react-components/react-timepicker-compat-preview/src/components/TimePicker/timeMath.ts index 398c09a1d9eee7..383bd80c4b31c9 100644 --- a/packages/react-components/react-timepicker-compat-preview/src/components/TimePicker/timeMath.ts +++ b/packages/react-components/react-timepicker-compat-preview/src/components/TimePicker/timeMath.ts @@ -119,23 +119,23 @@ const REGEX_HIDE_SECONDS_HOUR_24 = /^([0-1]?[0-9]|2[0-4]):[0-5][0-9]$/; /** * Calculates a new date from the user-selected time string based on anchor dates. - * Returns an object containing a date if the provided time string is valid, and an optional error message indicating the type of error. + * Returns an object containing a date if the provided time string is valid, and an optional string indicating the type of error. * * @param time - The time string to be parsed (e.g., "2:30 PM", "15:45:20"). * @param dateStartAnchor - The start anchor date. * @param dateEndAnchor - The end anchor date. * @param timeFormatOptions - format options for the provided time string. - * @returns An object with either a 'date' or an 'error'. + * @returns An object with either a 'date' or an 'errorType'. * * @example * Input: time="2:30 PM", dateStartAnchor=2023-10-06T12:00:00Z, dateEndAnchor=2023-10-07T12:00:00Z, options={hourCycle: 'h12', showSeconds: false} * Output: { date: 2023-10-06T14:30:00Z } * * Input: time="25:30" - * Output: { error: 'invalid-input' } + * Output: { errorType: 'invalid-input' } * * Input: time="1:30 AM", dateStartAnchor=2023-10-06T03:00:00Z, dateEndAnchor=2023-10-07T03:00:00Z, options={hourCycle: 'h12', showSeconds: false} - * Output: { date: 2023-10-07T01:30:00Z, error: 'out-of-bounds' } + * Output: { date: 2023-10-07T01:30:00Z, errorType: 'out-of-bounds' } */ export function getDateFromTimeString( time: string | undefined, @@ -144,7 +144,7 @@ export function getDateFromTimeString( timeFormatOptions: TimeFormatOptions, ): TimeStringValidationResult { if (!time) { - return { date: null, error: 'required-input' }; + return { date: null, errorType: 'required-input' }; } const { hourCycle, showSeconds } = timeFormatOptions; @@ -160,12 +160,12 @@ export function getDateFromTimeString( : REGEX_HIDE_SECONDS_HOUR_24; if (!regex.test(time)) { - return { date: null, error: 'invalid-input' }; + return { date: null, errorType: 'invalid-input' }; } const timeParts = /^(\d\d?):(\d\d):?(\d\d)? ?([ap]m)?/i.exec(time); if (!timeParts) { - return { date: null, error: 'invalid-input' }; + return { date: null, errorType: 'invalid-input' }; } const [, selectedHours, minutes, seconds, amPm] = timeParts; @@ -189,7 +189,7 @@ export function getDateFromTimeString( } if (adjustedDate >= dateEndAnchor) { - return { date: adjustedDate, error: 'out-of-bounds' }; + return { date: adjustedDate, errorType: 'out-of-bounds' }; } return { date: adjustedDate }; diff --git a/packages/react-components/react-timepicker-compat-preview/src/components/TimePicker/useTimePicker.tsx b/packages/react-components/react-timepicker-compat-preview/src/components/TimePicker/useTimePicker.tsx index 0b59c4dd4a4772..84ae8a71490c33 100644 --- a/packages/react-components/react-timepicker-compat-preview/src/components/TimePicker/useTimePicker.tsx +++ b/packages/react-components/react-timepicker-compat-preview/src/components/TimePicker/useTimePicker.tsx @@ -89,7 +89,7 @@ export const useTimePicker_unstable = (props: TimePickerProps, ref: React.Ref