@fluentui/react-timepicker-compat 0.2.36 → 0.2.38
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/CHANGELOG.md +18 -2
- package/lib/TimePicker.js.map +1 -1
- package/lib/components/TimePicker/TimePicker.js.map +1 -1
- package/lib/components/TimePicker/TimePicker.types.js.map +1 -1
- package/lib/components/TimePicker/index.js.map +1 -1
- package/lib/components/TimePicker/timeMath.js.map +1 -1
- package/lib/components/TimePicker/useTimePicker.js.map +1 -1
- package/lib/components/TimePicker/useTimePickerStyles.styles.js +1 -2
- package/lib/index.js.map +1 -1
- package/lib-commonjs/TimePicker.js.map +1 -1
- package/lib-commonjs/components/TimePicker/TimePicker.js.map +1 -1
- package/lib-commonjs/components/TimePicker/TimePicker.types.js.map +1 -1
- package/lib-commonjs/components/TimePicker/index.js.map +1 -1
- package/lib-commonjs/components/TimePicker/timeMath.js.map +1 -1
- package/lib-commonjs/components/TimePicker/useTimePicker.js.map +1 -1
- package/lib-commonjs/components/TimePicker/useTimePickerStyles.styles.js +1 -1
- package/lib-commonjs/index.js.map +1 -1
- package/package.json +8 -22
package/CHANGELOG.md
CHANGED
|
@@ -1,12 +1,28 @@
|
|
|
1
1
|
# Change Log - @fluentui/react-timepicker-compat
|
|
2
2
|
|
|
3
|
-
This log was last generated on
|
|
3
|
+
This log was last generated on Mon, 11 Nov 2024 10:01:01 GMT and should not be manually modified.
|
|
4
4
|
|
|
5
5
|
<!-- Start content -->
|
|
6
6
|
|
|
7
|
+
## [0.2.37](https://github.com/microsoft/fluentui/tree/@fluentui/react-timepicker-compat_v0.2.37)
|
|
8
|
+
|
|
9
|
+
Mon, 11 Nov 2024 10:01:01 GMT
|
|
10
|
+
[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-timepicker-compat_v0.2.36..@fluentui/react-timepicker-compat_v0.2.37)
|
|
11
|
+
|
|
12
|
+
### Patches
|
|
13
|
+
|
|
14
|
+
- chore: replace npm-scripts and just-scrtips with nx inferred tasks ([PR #33074](https://github.com/microsoft/fluentui/pull/33074) by martinhochel@microsoft.com)
|
|
15
|
+
- Bump @fluentui/keyboard-keys to v9.0.8 ([PR #33238](https://github.com/microsoft/fluentui/pull/33238) by beachball)
|
|
16
|
+
- Bump @fluentui/react-combobox to v9.13.11 ([PR #33238](https://github.com/microsoft/fluentui/pull/33238) by beachball)
|
|
17
|
+
- Bump @fluentui/react-field to v9.1.79 ([PR #33238](https://github.com/microsoft/fluentui/pull/33238) by beachball)
|
|
18
|
+
- Bump @fluentui/react-jsx-runtime to v9.0.46 ([PR #33238](https://github.com/microsoft/fluentui/pull/33238) by beachball)
|
|
19
|
+
- Bump @fluentui/react-shared-contexts to v9.21.0 ([PR #33238](https://github.com/microsoft/fluentui/pull/33238) by beachball)
|
|
20
|
+
- Bump @fluentui/react-theme to v9.1.22 ([PR #33238](https://github.com/microsoft/fluentui/pull/33238) by beachball)
|
|
21
|
+
- Bump @fluentui/react-utilities to v9.18.17 ([PR #33238](https://github.com/microsoft/fluentui/pull/33238) by beachball)
|
|
22
|
+
|
|
7
23
|
## [0.2.36](https://github.com/microsoft/fluentui/tree/@fluentui/react-timepicker-compat_v0.2.36)
|
|
8
24
|
|
|
9
|
-
Tue, 15 Oct 2024 17:
|
|
25
|
+
Tue, 15 Oct 2024 17:17:53 GMT
|
|
10
26
|
[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-timepicker-compat_v0.2.35..@fluentui/react-timepicker-compat_v0.2.36)
|
|
11
27
|
|
|
12
28
|
### Patches
|
package/lib/TimePicker.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["TimePicker.ts"],"sourcesContent":["export * from './components/TimePicker/index';\n"],"names":[],"rangeMappings":"","mappings":"AAAA,cAAc,gCAAgC"}
|
|
1
|
+
{"version":3,"sources":["../src/TimePicker.ts"],"sourcesContent":["export * from './components/TimePicker/index';\n"],"names":[],"rangeMappings":"","mappings":"AAAA,cAAc,gCAAgC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["TimePicker.tsx"],"sourcesContent":["import * as React from 'react';\nimport type { ForwardRefComponent } from '@fluentui/react-utilities';\nimport { useTimePicker_unstable } from './useTimePicker';\nimport { useTimePickerStyles_unstable } from './useTimePickerStyles.styles';\nimport type { TimePickerProps } from './TimePicker.types';\nimport { renderCombobox_unstable, useComboboxContextValues } from '@fluentui/react-combobox';\nimport { useCustomStyleHook_unstable } from '@fluentui/react-shared-contexts';\n\n/**\n * TimePicker Compat component\n */\nexport const TimePicker: ForwardRefComponent<TimePickerProps> = React.forwardRef((props, ref) => {\n const state = useTimePicker_unstable(props, ref);\n\n const contextValues = useComboboxContextValues(state);\n\n useTimePickerStyles_unstable(state);\n useCustomStyleHook_unstable('useTimePickerCompatStyles_unstable')(state);\n\n return renderCombobox_unstable(state, contextValues);\n});\n\nTimePicker.displayName = 'TimePicker';\n"],"names":["React","useTimePicker_unstable","useTimePickerStyles_unstable","renderCombobox_unstable","useComboboxContextValues","useCustomStyleHook_unstable","TimePicker","forwardRef","props","ref","state","contextValues","displayName"],"rangeMappings":";;;;;;;;;;;;;;","mappings":"AAAA,YAAYA,WAAW,QAAQ;AAE/B,SAASC,sBAAsB,QAAQ,kBAAkB;AACzD,SAASC,4BAA4B,QAAQ,+BAA+B;AAE5E,SAASC,uBAAuB,EAAEC,wBAAwB,QAAQ,2BAA2B;AAC7F,SAASC,2BAA2B,QAAQ,kCAAkC;AAE9E;;CAEC,GACD,OAAO,MAAMC,2BAAmDN,MAAMO,UAAU,CAAC,CAACC,OAAOC;IACvF,MAAMC,QAAQT,uBAAuBO,OAAOC;IAE5C,MAAME,gBAAgBP,yBAAyBM;IAE/CR,6BAA6BQ;IAC7BL,4BAA4B,sCAAsCK;IAElE,OAAOP,wBAAwBO,OAAOC;AACxC,GAAG;AAEHL,WAAWM,WAAW,GAAG"}
|
|
1
|
+
{"version":3,"sources":["../src/components/TimePicker/TimePicker.tsx"],"sourcesContent":["import * as React from 'react';\nimport type { ForwardRefComponent } from '@fluentui/react-utilities';\nimport { useTimePicker_unstable } from './useTimePicker';\nimport { useTimePickerStyles_unstable } from './useTimePickerStyles.styles';\nimport type { TimePickerProps } from './TimePicker.types';\nimport { renderCombobox_unstable, useComboboxContextValues } from '@fluentui/react-combobox';\nimport { useCustomStyleHook_unstable } from '@fluentui/react-shared-contexts';\n\n/**\n * TimePicker Compat component\n */\nexport const TimePicker: ForwardRefComponent<TimePickerProps> = React.forwardRef((props, ref) => {\n const state = useTimePicker_unstable(props, ref);\n\n const contextValues = useComboboxContextValues(state);\n\n useTimePickerStyles_unstable(state);\n useCustomStyleHook_unstable('useTimePickerCompatStyles_unstable')(state);\n\n return renderCombobox_unstable(state, contextValues);\n});\n\nTimePicker.displayName = 'TimePicker';\n"],"names":["React","useTimePicker_unstable","useTimePickerStyles_unstable","renderCombobox_unstable","useComboboxContextValues","useCustomStyleHook_unstable","TimePicker","forwardRef","props","ref","state","contextValues","displayName"],"rangeMappings":";;;;;;;;;;;;;;","mappings":"AAAA,YAAYA,WAAW,QAAQ;AAE/B,SAASC,sBAAsB,QAAQ,kBAAkB;AACzD,SAASC,4BAA4B,QAAQ,+BAA+B;AAE5E,SAASC,uBAAuB,EAAEC,wBAAwB,QAAQ,2BAA2B;AAC7F,SAASC,2BAA2B,QAAQ,kCAAkC;AAE9E;;CAEC,GACD,OAAO,MAAMC,2BAAmDN,MAAMO,UAAU,CAAC,CAACC,OAAOC;IACvF,MAAMC,QAAQT,uBAAuBO,OAAOC;IAE5C,MAAME,gBAAgBP,yBAAyBM;IAE/CR,6BAA6BQ;IAC7BL,4BAA4B,sCAAsCK;IAElE,OAAOP,wBAAwBO,OAAOC;AACxC,GAAG;AAEHL,WAAWM,WAAW,GAAG"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["TimePicker.types.ts"],"sourcesContent":["import * as React from 'react';\nimport type { ComboboxSlots, ComboboxState, ComboboxProps, SelectionEvents } from '@fluentui/react-combobox';\nimport type { ComponentProps } from '@fluentui/react-utilities';\n\nexport type Hour =\n | 0\n | 1\n | 2\n | 3\n | 4\n | 5\n | 6\n | 7\n | 8\n | 9\n | 10\n | 11\n | 12\n | 13\n | 14\n | 15\n | 16\n | 17\n | 18\n | 19\n | 20\n | 21\n | 22\n | 23\n | 24;\n\n/**\n * Data structure for rendering options in the TimePicker.\n */\nexport type TimePickerOption = {\n /**\n * The Date object associated with the option.\n */\n date: Date;\n\n /**\n * A unique identifier for the option.\n */\n key: string;\n\n /**\n * The display text for the option within the Combobox dropdown.\n */\n text: string;\n};\n\n/**\n * Error types returned by the `onValidationResult` callback.\n */\nexport type TimePickerErrorType = 'invalid-input' | 'out-of-bounds' | 'required-input';\n\nexport type TimeStringValidationResult = {\n date: Date | null;\n errorType?: TimePickerErrorType;\n};\n\nexport type TimePickerSlots = ComboboxSlots;\n\nexport type TimeSelectionEvents = SelectionEvents | React.FocusEvent<HTMLElement>;\nexport type TimeSelectionData = {\n /**\n * The Date object associated with the selected option. For freeform TimePicker it can also be the Date object parsed from the user input.\n */\n selectedTime: Date | null;\n /**\n * The display text for the selected option. For freeform TimePicker it can also be the value in user input.\n */\n selectedTimeText: string | undefined;\n /**\n * The error type for the selected option.\n */\n errorType: TimePickerErrorType | undefined;\n};\n\nexport type TimeFormatOptions = {\n /**\n * A string value indicating whether the 12-hour format (\"h11\", \"h12\") or the 24-hour format (\"h23\", \"h24\") should be used.\n * - 'h11' and 'h23' start with hour 0 and go up to 11 and 23 respectively.\n * - 'h12' and 'h24' start with hour 1 and go up to 12 and 24 respectively.\n * @default undefined\n */\n hourCycle?: 'h11' | 'h12' | 'h23' | 'h24' | undefined;\n\n /**\n * If true, show seconds in the dropdown options and consider seconds for default validation purposes.\n */\n showSeconds?: boolean;\n};\n\n/**\n * TimePicker Props\n */\nexport type TimePickerProps = Omit<ComponentProps<Partial<ComboboxSlots>, 'input'>, 'children' | 'size'> &\n Pick<\n ComboboxProps,\n | 'appearance'\n | 'clearable'\n | 'defaultOpen'\n | 'defaultValue'\n | 'inlinePopup'\n | 'onOpenChange'\n | 'open'\n | 'placeholder'\n | 'positioning'\n | 'size'\n | 'value'\n | 'mountNode'\n | 'freeform'\n > &\n TimeFormatOptions & {\n /**\n * Start hour (inclusive) for the time range, 0-24.\n */\n startHour?: Hour;\n\n /**\n * End hour (exclusive) for the time range, 0-24.\n */\n endHour?: Hour;\n\n /**\n * Time increment, in minutes, of the options in the dropdown.\n */\n increment?: number;\n\n /**\n * The date in which all dropdown options are based off of.\n */\n dateAnchor?: Date;\n\n /**\n * Currently selected time in the TimePicker.\n */\n selectedTime?: Date | null;\n\n /**\n * Default selected time in the TimePicker, for uncontrolled scenarios.\n */\n defaultSelectedTime?: Date;\n\n /**\n * Callback for when a time selection is made.\n */\n // eslint-disable-next-line @nx/workspace-consistent-callback-type -- can't change type of existing callback\n onTimeChange?: (event: TimeSelectionEvents, data: TimeSelectionData) => void;\n\n /**\n * Customizes the formatting of date strings displayed in dropdown options.\n */\n formatDateToTimeString?: (date: Date) => string;\n\n /**\n * In the freeform TimePicker, customizes the parsing from the input time string into a Date and provides custom validation.\n */\n parseTimeStringToDate?: (time: string | undefined) => TimeStringValidationResult;\n };\n\n/**\n * State used in rendering TimePicker\n */\nexport type TimePickerState = ComboboxState &\n Required<Pick<TimePickerProps, 'freeform' | 'parseTimeStringToDate'>> & {\n /**\n * 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.\n */\n submittedText: string | undefined;\n };\n"],"names":["React"],"rangeMappings":"","mappings":"AAAA,YAAYA,WAAW,QAAQ"}
|
|
1
|
+
{"version":3,"sources":["../src/components/TimePicker/TimePicker.types.ts"],"sourcesContent":["import * as React from 'react';\nimport type { ComboboxSlots, ComboboxState, ComboboxProps, SelectionEvents } from '@fluentui/react-combobox';\nimport type { ComponentProps } from '@fluentui/react-utilities';\n\nexport type Hour =\n | 0\n | 1\n | 2\n | 3\n | 4\n | 5\n | 6\n | 7\n | 8\n | 9\n | 10\n | 11\n | 12\n | 13\n | 14\n | 15\n | 16\n | 17\n | 18\n | 19\n | 20\n | 21\n | 22\n | 23\n | 24;\n\n/**\n * Data structure for rendering options in the TimePicker.\n */\nexport type TimePickerOption = {\n /**\n * The Date object associated with the option.\n */\n date: Date;\n\n /**\n * A unique identifier for the option.\n */\n key: string;\n\n /**\n * The display text for the option within the Combobox dropdown.\n */\n text: string;\n};\n\n/**\n * Error types returned by the `onValidationResult` callback.\n */\nexport type TimePickerErrorType = 'invalid-input' | 'out-of-bounds' | 'required-input';\n\nexport type TimeStringValidationResult = {\n date: Date | null;\n errorType?: TimePickerErrorType;\n};\n\nexport type TimePickerSlots = ComboboxSlots;\n\nexport type TimeSelectionEvents = SelectionEvents | React.FocusEvent<HTMLElement>;\nexport type TimeSelectionData = {\n /**\n * The Date object associated with the selected option. For freeform TimePicker it can also be the Date object parsed from the user input.\n */\n selectedTime: Date | null;\n /**\n * The display text for the selected option. For freeform TimePicker it can also be the value in user input.\n */\n selectedTimeText: string | undefined;\n /**\n * The error type for the selected option.\n */\n errorType: TimePickerErrorType | undefined;\n};\n\nexport type TimeFormatOptions = {\n /**\n * A string value indicating whether the 12-hour format (\"h11\", \"h12\") or the 24-hour format (\"h23\", \"h24\") should be used.\n * - 'h11' and 'h23' start with hour 0 and go up to 11 and 23 respectively.\n * - 'h12' and 'h24' start with hour 1 and go up to 12 and 24 respectively.\n * @default undefined\n */\n hourCycle?: 'h11' | 'h12' | 'h23' | 'h24' | undefined;\n\n /**\n * If true, show seconds in the dropdown options and consider seconds for default validation purposes.\n */\n showSeconds?: boolean;\n};\n\n/**\n * TimePicker Props\n */\nexport type TimePickerProps = Omit<ComponentProps<Partial<ComboboxSlots>, 'input'>, 'children' | 'size'> &\n Pick<\n ComboboxProps,\n | 'appearance'\n | 'clearable'\n | 'defaultOpen'\n | 'defaultValue'\n | 'inlinePopup'\n | 'onOpenChange'\n | 'open'\n | 'placeholder'\n | 'positioning'\n | 'size'\n | 'value'\n | 'mountNode'\n | 'freeform'\n > &\n TimeFormatOptions & {\n /**\n * Start hour (inclusive) for the time range, 0-24.\n */\n startHour?: Hour;\n\n /**\n * End hour (exclusive) for the time range, 0-24.\n */\n endHour?: Hour;\n\n /**\n * Time increment, in minutes, of the options in the dropdown.\n */\n increment?: number;\n\n /**\n * The date in which all dropdown options are based off of.\n */\n dateAnchor?: Date;\n\n /**\n * Currently selected time in the TimePicker.\n */\n selectedTime?: Date | null;\n\n /**\n * Default selected time in the TimePicker, for uncontrolled scenarios.\n */\n defaultSelectedTime?: Date;\n\n /**\n * Callback for when a time selection is made.\n */\n // eslint-disable-next-line @nx/workspace-consistent-callback-type -- can't change type of existing callback\n onTimeChange?: (event: TimeSelectionEvents, data: TimeSelectionData) => void;\n\n /**\n * Customizes the formatting of date strings displayed in dropdown options.\n */\n formatDateToTimeString?: (date: Date) => string;\n\n /**\n * In the freeform TimePicker, customizes the parsing from the input time string into a Date and provides custom validation.\n */\n parseTimeStringToDate?: (time: string | undefined) => TimeStringValidationResult;\n };\n\n/**\n * State used in rendering TimePicker\n */\nexport type TimePickerState = ComboboxState &\n Required<Pick<TimePickerProps, 'freeform' | 'parseTimeStringToDate'>> & {\n /**\n * 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.\n */\n submittedText: string | undefined;\n };\n"],"names":["React"],"rangeMappings":"","mappings":"AAAA,YAAYA,WAAW,QAAQ"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["index.ts"],"sourcesContent":["export * from './TimePicker';\nexport * from './TimePicker.types';\nexport * from './useTimePicker';\nexport * from './useTimePickerStyles.styles';\nexport { formatDateToTimeString } from './timeMath';\n"],"names":["formatDateToTimeString"],"rangeMappings":";;;;","mappings":"AAAA,cAAc,eAAe;AAC7B,cAAc,qBAAqB;AACnC,cAAc,kBAAkB;AAChC,cAAc,+BAA+B;AAC7C,SAASA,sBAAsB,QAAQ,aAAa"}
|
|
1
|
+
{"version":3,"sources":["../src/components/TimePicker/index.ts"],"sourcesContent":["export * from './TimePicker';\nexport * from './TimePicker.types';\nexport * from './useTimePicker';\nexport * from './useTimePickerStyles.styles';\nexport { formatDateToTimeString } from './timeMath';\n"],"names":["formatDateToTimeString"],"rangeMappings":";;;;","mappings":"AAAA,cAAc,eAAe;AAC7B,cAAc,qBAAqB;AACnC,cAAc,kBAAkB;AAChC,cAAc,+BAA+B;AAC7C,SAASA,sBAAsB,QAAQ,aAAa"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["timeMath.ts"],"sourcesContent":["import type { TimeFormatOptions, TimeStringValidationResult } from './TimePicker.types';\n\nfunction isValidDate(date: Date): boolean {\n return !isNaN(date.getTime());\n}\n\n/**\n * Converts a Date object to a string key.\n */\nexport function dateToKey(date: Date | null): string {\n if (!date) {\n return '';\n }\n if (!isValidDate(date)) {\n return 'invalid';\n }\n return date.toISOString();\n}\n\n/**\n * Converts a string key back to a Date object.\n * Returns undefined for keys that don't represent valid dates.\n */\nexport function keyToDate(key: string): Date | null {\n if (key === '' || key === 'invalid') {\n return null;\n }\n const date = new Date(key);\n return isValidDate(date) ? date : null;\n}\n\n/**\n * Formats a Date object into a time string based on provided options.\n *\n * @param date - The Date object to be formatted.\n * @param options - Formatting options. It has two properties:\n * 1. hourCycle (default: undefined): Determines if the time format should be 12-hour or 24-hour.\n * 2. showSeconds (default: false): Determines if the seconds should be included in the formatted string.\n * @returns Formatted time string based on the given options.\n *\n * @example\n * const date = new Date(2023, 9, 6, 23, 45, 12);\n * formatDateToTimeString(date); // Returns \"23:45\" in CET\n * formatDateToTimeString(date, \\{ showSeconds: true \\}); // Returns \"23:45:12\" in CET\n * formatDateToTimeString(date, \\{ hourCycle: 'h12', showSeconds: true \\}); // Returns \"11:45:12 PM\" in CET\n */\nexport function formatDateToTimeString(date: Date, { hourCycle, showSeconds }: TimeFormatOptions = {}): string {\n return date.toLocaleTimeString(undefined, {\n hour: 'numeric',\n hourCycle,\n minute: '2-digit',\n second: showSeconds ? '2-digit' : undefined,\n });\n}\n\n/**\n * Get the start date anchor based on the provided parameters.\n * @example\n * const date = new Date(2023, 9, 6); // October 6, 2023\n * getStartAnchorDate(date, 5); // Returns a date for October 6, 2023, 05:00:00\n */\nexport function getDateStartAnchor(dateAnchor: Date, startHour: number): Date {\n const startDate = new Date(dateAnchor);\n startDate.setHours(startHour, 0, 0, 0);\n return startDate;\n}\n\n/**\n * Get the end date anchor based on the provided parameters.\n * @example\n * const date = new Date(2023, 9, 6); // October 6, 2023\n * getEndAnchorDate(date, 5, 10); // Returns a date for October 6, 2023, 10:00:00\n * getEndAnchorDate(date, 10, 5); // Returns a date for October 7, 2023, 05:00:00 (next day due to hour conditions)\n */\nexport function getDateEndAnchor(dateAnchor: Date, startHour: number, endHour: number): Date {\n const endDate = new Date(dateAnchor);\n if (startHour > endHour || endHour === 24) {\n endDate.setDate(endDate.getDate() + 1);\n }\n endDate.setHours(endHour === 24 ? 0 : endHour, 0, 0, 0);\n return endDate;\n}\n\n/**\n * Generates an array of Date objects between two given Date anchors.\n *\n * @param dateStartAnchor - The starting Date anchor.\n * @param dateEndAnchor - The ending Date anchor.\n * @param increment - The minute increment between each Date in the resulting array.\n * @returns - An array of Date objects.\n *\n * @example\n * const start = new Date(2023, 0, 1, 10, 0); // Jan 1, 2023 10:00:00 AM\n * const end = new Date(2023, 0, 1, 11, 0); // Jan 1, 2023 11:00:00 AM\n * getTimesBetween(start, end, 15); // Returns array with Dates [10:00, 10:15, 10:30, 10:45]\n */\nexport function getTimesBetween(dateStartAnchor: Date, dateEndAnchor: Date, increment: number) {\n if (increment <= 0) {\n // eslint-disable-next-line no-console\n console.error('Increment value should be a positive number.');\n return [];\n }\n\n const result: Date[] = [];\n\n const startDate = new Date(dateStartAnchor);\n while (startDate < dateEndAnchor) {\n result.push(new Date(startDate));\n startDate.setMinutes(startDate.getMinutes() + increment);\n }\n\n return result;\n}\n\nconst REGEX_SHOW_SECONDS_HOUR_12 = /^((1[0-2]|0?[0-9]):([0-5][0-9]):([0-5][0-9])\\s([AaPp][Mm]))$/;\nconst REGEX_HIDE_SECONDS_HOUR_12 = /^((1[0-2]|0?[0-9]):[0-5][0-9]\\s([AaPp][Mm]))$/;\nconst REGEX_SHOW_SECONDS_HOUR_24 = /^([0-1]?[0-9]|2[0-4]):[0-5][0-9]:[0-5][0-9]$/;\nconst REGEX_HIDE_SECONDS_HOUR_24 = /^([0-1]?[0-9]|2[0-4]):[0-5][0-9]$/;\n\n/**\n * Calculates a new date from the user-selected time string based on anchor dates.\n * Returns an object containing a date if the provided time string is valid, and an optional string indicating the type of error.\n *\n * @param time - The time string to be parsed (e.g., \"2:30 PM\", \"15:45:20\").\n * @param dateStartAnchor - The start anchor date.\n * @param dateEndAnchor - The end anchor date.\n * @param timeFormatOptions - format options for the provided time string.\n * @returns An object with either a 'date' or an 'errorType'.\n *\n * @example\n * Input: time=\"2:30 PM\", dateStartAnchor=2023-10-06T12:00:00Z, dateEndAnchor=2023-10-07T12:00:00Z, options={hourCycle: 'h12', showSeconds: false}\n * Output: { date: 2023-10-06T14:30:00Z }\n *\n * Input: time=\"25:30\"\n * Output: { errorType: 'invalid-input' }\n *\n * Input: time=\"1:30 AM\", dateStartAnchor=2023-10-06T03:00:00Z, dateEndAnchor=2023-10-07T03:00:00Z, options={hourCycle: 'h12', showSeconds: false}\n * Output: { date: 2023-10-07T01:30:00Z, errorType: 'out-of-bounds' }\n */\nexport function getDateFromTimeString(\n time: string | undefined,\n dateStartAnchor: Date,\n dateEndAnchor: Date,\n timeFormatOptions: TimeFormatOptions,\n): TimeStringValidationResult {\n if (!time) {\n return { date: null, errorType: 'required-input' };\n }\n\n const { hourCycle, showSeconds } = timeFormatOptions;\n const hour12 = hourCycle === 'h11' || hourCycle === 'h12';\n\n // Determine the regex based on format\n const regex = hour12\n ? showSeconds\n ? REGEX_SHOW_SECONDS_HOUR_12\n : REGEX_HIDE_SECONDS_HOUR_12\n : showSeconds\n ? REGEX_SHOW_SECONDS_HOUR_24\n : REGEX_HIDE_SECONDS_HOUR_24;\n\n if (!regex.test(time)) {\n return { date: null, errorType: 'invalid-input' };\n }\n\n const timeParts = /^(\\d\\d?):(\\d\\d):?(\\d\\d)? ?([ap]m)?/i.exec(time);\n if (!timeParts) {\n return { date: null, errorType: 'invalid-input' };\n }\n\n const [, selectedHours, minutes, seconds, amPm] = timeParts;\n let hours = selectedHours;\n\n // Adjust for 12-hour time format if needed\n if (hour12 && amPm) {\n if (amPm.toLowerCase() === 'pm' && +hours !== 12) {\n hours = (+hours + 12).toString();\n } else if (amPm.toLowerCase() === 'am' && +hours === 12) {\n hours = '0';\n }\n }\n\n const adjustedDate = new Date(dateStartAnchor);\n adjustedDate.setHours(+hours, +minutes, seconds ? +seconds : 0);\n\n // Adjust to the next day if the selected time is before the anchor time\n if (adjustedDate < dateStartAnchor) {\n adjustedDate.setDate(adjustedDate.getDate() + 1);\n }\n\n if (adjustedDate >= dateEndAnchor) {\n return { date: adjustedDate, errorType: 'out-of-bounds' };\n }\n\n return { date: adjustedDate };\n}\n"],"names":["isValidDate","date","isNaN","getTime","dateToKey","toISOString","keyToDate","key","Date","formatDateToTimeString","hourCycle","showSeconds","toLocaleTimeString","undefined","hour","minute","second","getDateStartAnchor","dateAnchor","startHour","startDate","setHours","getDateEndAnchor","endHour","endDate","setDate","getDate","getTimesBetween","dateStartAnchor","dateEndAnchor","increment","console","error","result","push","setMinutes","getMinutes","REGEX_SHOW_SECONDS_HOUR_12","REGEX_HIDE_SECONDS_HOUR_12","REGEX_SHOW_SECONDS_HOUR_24","REGEX_HIDE_SECONDS_HOUR_24","getDateFromTimeString","time","timeFormatOptions","errorType","hour12","regex","test","timeParts","exec","selectedHours","minutes","seconds","amPm","hours","toLowerCase","toString","adjustedDate"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAEA,SAASA,YAAYC,IAAU;IAC7B,OAAO,CAACC,MAAMD,KAAKE,OAAO;AAC5B;AAEA;;CAEC,GACD,OAAO,SAASC,UAAUH,IAAiB;IACzC,IAAI,CAACA,MAAM;QACT,OAAO;IACT;IACA,IAAI,CAACD,YAAYC,OAAO;QACtB,OAAO;IACT;IACA,OAAOA,KAAKI,WAAW;AACzB;AAEA;;;CAGC,GACD,OAAO,SAASC,UAAUC,GAAW;IACnC,IAAIA,QAAQ,MAAMA,QAAQ,WAAW;QACnC,OAAO;IACT;IACA,MAAMN,OAAO,IAAIO,KAAKD;IACtB,OAAOP,YAAYC,QAAQA,OAAO;AACpC;AAEA;;;;;;;;;;;;;;CAcC,GACD,OAAO,SAASQ,uBAAuBR,IAAU,EAAE,EAAES,SAAS,EAAEC,WAAW,EAAqB,GAAG,CAAC,CAAC;IACnG,OAAOV,KAAKW,kBAAkB,CAACC,WAAW;QACxCC,MAAM;QACNJ;QACAK,QAAQ;QACRC,QAAQL,cAAc,YAAYE;IACpC;AACF;AAEA;;;;;CAKC,GACD,OAAO,SAASI,mBAAmBC,UAAgB,EAAEC,SAAiB;IACpE,MAAMC,YAAY,IAAIZ,KAAKU;IAC3BE,UAAUC,QAAQ,CAACF,WAAW,GAAG,GAAG;IACpC,OAAOC;AACT;AAEA;;;;;;CAMC,GACD,OAAO,SAASE,iBAAiBJ,UAAgB,EAAEC,SAAiB,EAAEI,OAAe;IACnF,MAAMC,UAAU,IAAIhB,KAAKU;IACzB,IAAIC,YAAYI,WAAWA,YAAY,IAAI;QACzCC,QAAQC,OAAO,CAACD,QAAQE,OAAO,KAAK;IACtC;IACAF,QAAQH,QAAQ,CAACE,YAAY,KAAK,IAAIA,SAAS,GAAG,GAAG;IACrD,OAAOC;AACT;AAEA;;;;;;;;;;;;CAYC,GACD,OAAO,SAASG,gBAAgBC,eAAqB,EAAEC,aAAmB,EAAEC,SAAiB;IAC3F,IAAIA,aAAa,GAAG;QAClB,sCAAsC;QACtCC,QAAQC,KAAK,CAAC;QACd,OAAO,EAAE;IACX;IAEA,MAAMC,SAAiB,EAAE;IAEzB,MAAMb,YAAY,IAAIZ,KAAKoB;IAC3B,MAAOR,YAAYS,cAAe;QAChCI,OAAOC,IAAI,CAAC,IAAI1B,KAAKY;QACrBA,UAAUe,UAAU,CAACf,UAAUgB,UAAU,KAAKN;IAChD;IAEA,OAAOG;AACT;AAEA,MAAMI,6BAA6B;AACnC,MAAMC,6BAA6B;AACnC,MAAMC,6BAA6B;AACnC,MAAMC,6BAA6B;AAEnC;;;;;;;;;;;;;;;;;;;CAmBC,GACD,OAAO,SAASC,sBACdC,IAAwB,EACxBd,eAAqB,EACrBC,aAAmB,EACnBc,iBAAoC;IAEpC,IAAI,CAACD,MAAM;QACT,OAAO;YAAEzC,MAAM;YAAM2C,WAAW;QAAiB;IACnD;IAEA,MAAM,EAAElC,SAAS,EAAEC,WAAW,EAAE,GAAGgC;IACnC,MAAME,SAASnC,cAAc,SAASA,cAAc;IAEpD,sCAAsC;IACtC,MAAMoC,QAAQD,SACVlC,cACE0B,6BACAC,6BACF3B,cACA4B,6BACAC;IAEJ,IAAI,CAACM,MAAMC,IAAI,CAACL,OAAO;QACrB,OAAO;YAAEzC,MAAM;YAAM2C,WAAW;QAAgB;IAClD;IAEA,MAAMI,YAAY,sCAAsCC,IAAI,CAACP;IAC7D,IAAI,CAACM,WAAW;QACd,OAAO;YAAE/C,MAAM;YAAM2C,WAAW;QAAgB;IAClD;IAEA,MAAM,GAAGM,eAAeC,SAASC,SAASC,KAAK,GAAGL;IAClD,IAAIM,QAAQJ;IAEZ,2CAA2C;IAC3C,IAAIL,UAAUQ,MAAM;QAClB,IAAIA,KAAKE,WAAW,OAAO,QAAQ,CAACD,UAAU,IAAI;YAChDA,QAAQ,AAAC,CAAA,CAACA,QAAQ,EAAC,EAAGE,QAAQ;QAChC,OAAO,IAAIH,KAAKE,WAAW,OAAO,QAAQ,CAACD,UAAU,IAAI;YACvDA,QAAQ;QACV;IACF;IAEA,MAAMG,eAAe,IAAIjD,KAAKoB;IAC9B6B,aAAapC,QAAQ,CAAC,CAACiC,OAAO,CAACH,SAASC,UAAU,CAACA,UAAU;IAE7D,wEAAwE;IACxE,IAAIK,eAAe7B,iBAAiB;QAClC6B,aAAahC,OAAO,CAACgC,aAAa/B,OAAO,KAAK;IAChD;IAEA,IAAI+B,gBAAgB5B,eAAe;QACjC,OAAO;YAAE5B,MAAMwD;YAAcb,WAAW;QAAgB;IAC1D;IAEA,OAAO;QAAE3C,MAAMwD;IAAa;AAC9B"}
|
|
1
|
+
{"version":3,"sources":["../src/components/TimePicker/timeMath.ts"],"sourcesContent":["import type { TimeFormatOptions, TimeStringValidationResult } from './TimePicker.types';\n\nfunction isValidDate(date: Date): boolean {\n return !isNaN(date.getTime());\n}\n\n/**\n * Converts a Date object to a string key.\n */\nexport function dateToKey(date: Date | null): string {\n if (!date) {\n return '';\n }\n if (!isValidDate(date)) {\n return 'invalid';\n }\n return date.toISOString();\n}\n\n/**\n * Converts a string key back to a Date object.\n * Returns undefined for keys that don't represent valid dates.\n */\nexport function keyToDate(key: string): Date | null {\n if (key === '' || key === 'invalid') {\n return null;\n }\n const date = new Date(key);\n return isValidDate(date) ? date : null;\n}\n\n/**\n * Formats a Date object into a time string based on provided options.\n *\n * @param date - The Date object to be formatted.\n * @param options - Formatting options. It has two properties:\n * 1. hourCycle (default: undefined): Determines if the time format should be 12-hour or 24-hour.\n * 2. showSeconds (default: false): Determines if the seconds should be included in the formatted string.\n * @returns Formatted time string based on the given options.\n *\n * @example\n * const date = new Date(2023, 9, 6, 23, 45, 12);\n * formatDateToTimeString(date); // Returns \"23:45\" in CET\n * formatDateToTimeString(date, \\{ showSeconds: true \\}); // Returns \"23:45:12\" in CET\n * formatDateToTimeString(date, \\{ hourCycle: 'h12', showSeconds: true \\}); // Returns \"11:45:12 PM\" in CET\n */\nexport function formatDateToTimeString(date: Date, { hourCycle, showSeconds }: TimeFormatOptions = {}): string {\n return date.toLocaleTimeString(undefined, {\n hour: 'numeric',\n hourCycle,\n minute: '2-digit',\n second: showSeconds ? '2-digit' : undefined,\n });\n}\n\n/**\n * Get the start date anchor based on the provided parameters.\n * @example\n * const date = new Date(2023, 9, 6); // October 6, 2023\n * getStartAnchorDate(date, 5); // Returns a date for October 6, 2023, 05:00:00\n */\nexport function getDateStartAnchor(dateAnchor: Date, startHour: number): Date {\n const startDate = new Date(dateAnchor);\n startDate.setHours(startHour, 0, 0, 0);\n return startDate;\n}\n\n/**\n * Get the end date anchor based on the provided parameters.\n * @example\n * const date = new Date(2023, 9, 6); // October 6, 2023\n * getEndAnchorDate(date, 5, 10); // Returns a date for October 6, 2023, 10:00:00\n * getEndAnchorDate(date, 10, 5); // Returns a date for October 7, 2023, 05:00:00 (next day due to hour conditions)\n */\nexport function getDateEndAnchor(dateAnchor: Date, startHour: number, endHour: number): Date {\n const endDate = new Date(dateAnchor);\n if (startHour > endHour || endHour === 24) {\n endDate.setDate(endDate.getDate() + 1);\n }\n endDate.setHours(endHour === 24 ? 0 : endHour, 0, 0, 0);\n return endDate;\n}\n\n/**\n * Generates an array of Date objects between two given Date anchors.\n *\n * @param dateStartAnchor - The starting Date anchor.\n * @param dateEndAnchor - The ending Date anchor.\n * @param increment - The minute increment between each Date in the resulting array.\n * @returns - An array of Date objects.\n *\n * @example\n * const start = new Date(2023, 0, 1, 10, 0); // Jan 1, 2023 10:00:00 AM\n * const end = new Date(2023, 0, 1, 11, 0); // Jan 1, 2023 11:00:00 AM\n * getTimesBetween(start, end, 15); // Returns array with Dates [10:00, 10:15, 10:30, 10:45]\n */\nexport function getTimesBetween(dateStartAnchor: Date, dateEndAnchor: Date, increment: number) {\n if (increment <= 0) {\n // eslint-disable-next-line no-console\n console.error('Increment value should be a positive number.');\n return [];\n }\n\n const result: Date[] = [];\n\n const startDate = new Date(dateStartAnchor);\n while (startDate < dateEndAnchor) {\n result.push(new Date(startDate));\n startDate.setMinutes(startDate.getMinutes() + increment);\n }\n\n return result;\n}\n\nconst REGEX_SHOW_SECONDS_HOUR_12 = /^((1[0-2]|0?[0-9]):([0-5][0-9]):([0-5][0-9])\\s([AaPp][Mm]))$/;\nconst REGEX_HIDE_SECONDS_HOUR_12 = /^((1[0-2]|0?[0-9]):[0-5][0-9]\\s([AaPp][Mm]))$/;\nconst REGEX_SHOW_SECONDS_HOUR_24 = /^([0-1]?[0-9]|2[0-4]):[0-5][0-9]:[0-5][0-9]$/;\nconst REGEX_HIDE_SECONDS_HOUR_24 = /^([0-1]?[0-9]|2[0-4]):[0-5][0-9]$/;\n\n/**\n * Calculates a new date from the user-selected time string based on anchor dates.\n * Returns an object containing a date if the provided time string is valid, and an optional string indicating the type of error.\n *\n * @param time - The time string to be parsed (e.g., \"2:30 PM\", \"15:45:20\").\n * @param dateStartAnchor - The start anchor date.\n * @param dateEndAnchor - The end anchor date.\n * @param timeFormatOptions - format options for the provided time string.\n * @returns An object with either a 'date' or an 'errorType'.\n *\n * @example\n * Input: time=\"2:30 PM\", dateStartAnchor=2023-10-06T12:00:00Z, dateEndAnchor=2023-10-07T12:00:00Z, options={hourCycle: 'h12', showSeconds: false}\n * Output: { date: 2023-10-06T14:30:00Z }\n *\n * Input: time=\"25:30\"\n * Output: { errorType: 'invalid-input' }\n *\n * Input: time=\"1:30 AM\", dateStartAnchor=2023-10-06T03:00:00Z, dateEndAnchor=2023-10-07T03:00:00Z, options={hourCycle: 'h12', showSeconds: false}\n * Output: { date: 2023-10-07T01:30:00Z, errorType: 'out-of-bounds' }\n */\nexport function getDateFromTimeString(\n time: string | undefined,\n dateStartAnchor: Date,\n dateEndAnchor: Date,\n timeFormatOptions: TimeFormatOptions,\n): TimeStringValidationResult {\n if (!time) {\n return { date: null, errorType: 'required-input' };\n }\n\n const { hourCycle, showSeconds } = timeFormatOptions;\n const hour12 = hourCycle === 'h11' || hourCycle === 'h12';\n\n // Determine the regex based on format\n const regex = hour12\n ? showSeconds\n ? REGEX_SHOW_SECONDS_HOUR_12\n : REGEX_HIDE_SECONDS_HOUR_12\n : showSeconds\n ? REGEX_SHOW_SECONDS_HOUR_24\n : REGEX_HIDE_SECONDS_HOUR_24;\n\n if (!regex.test(time)) {\n return { date: null, errorType: 'invalid-input' };\n }\n\n const timeParts = /^(\\d\\d?):(\\d\\d):?(\\d\\d)? ?([ap]m)?/i.exec(time);\n if (!timeParts) {\n return { date: null, errorType: 'invalid-input' };\n }\n\n const [, selectedHours, minutes, seconds, amPm] = timeParts;\n let hours = selectedHours;\n\n // Adjust for 12-hour time format if needed\n if (hour12 && amPm) {\n if (amPm.toLowerCase() === 'pm' && +hours !== 12) {\n hours = (+hours + 12).toString();\n } else if (amPm.toLowerCase() === 'am' && +hours === 12) {\n hours = '0';\n }\n }\n\n const adjustedDate = new Date(dateStartAnchor);\n adjustedDate.setHours(+hours, +minutes, seconds ? +seconds : 0);\n\n // Adjust to the next day if the selected time is before the anchor time\n if (adjustedDate < dateStartAnchor) {\n adjustedDate.setDate(adjustedDate.getDate() + 1);\n }\n\n if (adjustedDate >= dateEndAnchor) {\n return { date: adjustedDate, errorType: 'out-of-bounds' };\n }\n\n return { date: adjustedDate };\n}\n"],"names":["isValidDate","date","isNaN","getTime","dateToKey","toISOString","keyToDate","key","Date","formatDateToTimeString","hourCycle","showSeconds","toLocaleTimeString","undefined","hour","minute","second","getDateStartAnchor","dateAnchor","startHour","startDate","setHours","getDateEndAnchor","endHour","endDate","setDate","getDate","getTimesBetween","dateStartAnchor","dateEndAnchor","increment","console","error","result","push","setMinutes","getMinutes","REGEX_SHOW_SECONDS_HOUR_12","REGEX_HIDE_SECONDS_HOUR_12","REGEX_SHOW_SECONDS_HOUR_24","REGEX_HIDE_SECONDS_HOUR_24","getDateFromTimeString","time","timeFormatOptions","errorType","hour12","regex","test","timeParts","exec","selectedHours","minutes","seconds","amPm","hours","toLowerCase","toString","adjustedDate"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["useTimePicker.tsx"],"sourcesContent":["import * as React from 'react';\nimport {\n elementContains,\n mergeCallbacks,\n useControllableState,\n useEventCallback,\n useId,\n useMergedRefs,\n} from '@fluentui/react-utilities';\nimport { Enter } from '@fluentui/keyboard-keys';\nimport type { Hour, TimePickerOption, TimePickerProps, TimePickerState, TimeSelectionData } from './TimePicker.types';\nimport { ComboboxProps, useCombobox_unstable, Option } from '@fluentui/react-combobox';\nimport { useFieldContext_unstable as useFieldContext } from '@fluentui/react-field';\nimport {\n dateToKey,\n keyToDate,\n formatDateToTimeString as defaultFormatDateToTimeString,\n getDateStartAnchor,\n getDateEndAnchor,\n getTimesBetween,\n getDateFromTimeString,\n} from './timeMath';\n\n/**\n * Create the state required to render TimePicker.\n *\n * The returned state can be modified with hooks such as useTimePickerStyles_unstable,\n * before being passed to renderTimePicker_unstable.\n *\n * @param props - props from this instance of TimePicker\n * @param ref - reference to root HTMLElement of TimePicker\n */\nexport const useTimePicker_unstable = (props: TimePickerProps, ref: React.Ref<HTMLInputElement>): TimePickerState => {\n const {\n dateAnchor: dateAnchorInProps,\n defaultSelectedTime: defaultSelectedTimeInProps,\n endHour = 24,\n formatDateToTimeString = defaultFormatDateToTimeString,\n hourCycle,\n increment = 30,\n onTimeChange,\n selectedTime: selectedTimeInProps,\n showSeconds = false,\n startHour = 0,\n parseTimeStringToDate: parseTimeStringToDateInProps,\n ...rest\n } = props;\n const { freeform = false } = rest;\n\n const { dateStartAnchor, dateEndAnchor } = useStableDateAnchor(\n dateAnchorInProps ?? selectedTimeInProps ?? defaultSelectedTimeInProps,\n startHour,\n endHour,\n );\n\n const options: TimePickerOption[] = React.useMemo(\n () =>\n getTimesBetween(dateStartAnchor, dateEndAnchor, increment).map(time => ({\n date: time,\n key: dateToKey(time),\n text: formatDateToTimeString(time, { showSeconds, hourCycle }),\n })),\n [dateEndAnchor, dateStartAnchor, formatDateToTimeString, hourCycle, increment, showSeconds],\n );\n\n const [selectedTime, setSelectedTime] = useControllableState<Date | null>({\n state: selectedTimeInProps,\n defaultState: defaultSelectedTimeInProps,\n initialState: null,\n });\n\n const [submittedText, setSubmittedText] = React.useState<string | undefined>(undefined);\n\n const selectTime: TimePickerProps['onTimeChange'] = useEventCallback((e, data) => {\n setSelectedTime(data.selectedTime);\n setSubmittedText(data.selectedTimeText);\n onTimeChange?.(e, data);\n });\n\n const selectedOptions = React.useMemo(() => {\n const selectedTimeKey = dateToKey(selectedTime);\n const selectedOption = options.find(date => date.key === selectedTimeKey);\n return selectedOption ? [selectedOption.key] : [];\n }, [options, selectedTime]);\n\n const clearIconRef = React.useRef<HTMLSpanElement>(null);\n const handleOptionSelect: ComboboxProps['onOptionSelect'] = useEventCallback((e, data) => {\n if (\n freeform &&\n data.optionValue === undefined &&\n !(rest.clearable && e.type === 'click' && e.currentTarget === clearIconRef.current)\n ) {\n // Combobox clears selection when input value not matching any option; but we allow this case in freeform TimePicker.\n return;\n }\n const timeSelectionData: TimeSelectionData = {\n selectedTime: keyToDate(data.optionValue ?? ''),\n selectedTimeText: data.optionText,\n errorType: undefined,\n };\n selectTime(e, timeSelectionData);\n });\n\n const baseState = useCombobox_unstable(\n {\n autoComplete: 'off',\n ...rest,\n selectedOptions,\n onOptionSelect: handleOptionSelect,\n children: options.map(date => (\n <Option key={date.key} value={date.key}>\n {date.text}\n </Option>\n )),\n },\n ref,\n );\n\n const defaultParseTimeStringToDate = React.useCallback(\n (time: string | undefined) =>\n getDateFromTimeString(time, dateStartAnchor, dateEndAnchor, { hourCycle, showSeconds }),\n [dateEndAnchor, dateStartAnchor, hourCycle, showSeconds],\n );\n\n const mergedClearIconRef = useMergedRefs(baseState.clearIcon?.ref, clearIconRef);\n const state: TimePickerState = {\n ...baseState,\n clearIcon: baseState.clearIcon\n ? {\n ...baseState.clearIcon,\n ref: mergedClearIconRef,\n }\n : undefined,\n freeform,\n parseTimeStringToDate: parseTimeStringToDateInProps ?? defaultParseTimeStringToDate,\n submittedText,\n };\n\n useDefaultChevronIconLabel(state);\n useSelectTimeFromValue(state, selectTime);\n\n return state;\n};\n\n/**\n * Provides stable start and end date anchors based on the provided date and time parameters.\n * The hook ensures that the memoization remains consistent even if new Date objects representing the same date are provided.\n */\nconst useStableDateAnchor = (providedDate: Date | undefined, startHour: Hour, endHour: Hour) => {\n const [fallbackDateAnchor] = React.useState(() => new Date());\n\n const providedDateKey = dateToKey(providedDate ?? null);\n\n return React.useMemo(() => {\n const dateAnchor = providedDate ?? fallbackDateAnchor;\n\n const dateStartAnchor = getDateStartAnchor(dateAnchor, startHour);\n const dateEndAnchor = getDateEndAnchor(dateAnchor, startHour, endHour);\n\n return { dateStartAnchor, dateEndAnchor };\n // `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.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [endHour, fallbackDateAnchor, providedDateKey, startHour]);\n};\n\n/**\n * Mimics the behavior of the browser's change event for a freeform TimePicker.\n * The provided callback is called when input changed and:\n * - Enter/Tab key is pressed on the input.\n * - TimePicker loses focus, signifying a possible change.\n */\nconst useSelectTimeFromValue = (state: TimePickerState, callback: TimePickerProps['onTimeChange']) => {\n const { getOptionById, freeform, parseTimeStringToDate, submittedText, value, activeDescendantController } = state;\n const getActiveOption = React.useCallback(() => {\n const activeOptionId = activeDescendantController.active();\n return activeOptionId ? getOptionById(activeOptionId) : null;\n }, [activeDescendantController, getOptionById]);\n\n // Base Combobox has activeOption default to first option in dropdown even if it doesn't match input value, and Enter key will select it.\n // This effect ensures that the activeOption is cleared when the input doesn't match any option.\n // This behavior is specific to a freeform TimePicker where the input value is treated as a valid time even if it's not in the dropdown.\n React.useEffect(() => {\n if (freeform && value) {\n const activeOption = getActiveOption();\n if (!activeOption) {\n return;\n }\n\n const valueMatchesActiveOption = activeOption.text.toLowerCase().indexOf(value.toLowerCase()) === 0;\n if (!valueMatchesActiveOption) {\n activeDescendantController.blur();\n }\n }\n }, [freeform, value, activeDescendantController, getActiveOption]);\n\n const selectTimeFromValue = useEventCallback(\n (e: React.KeyboardEvent<HTMLInputElement> | React.FocusEvent<HTMLInputElement>) => {\n if (!freeform) {\n return;\n }\n\n const { date: selectedTime, errorType } = parseTimeStringToDate(value);\n\n // Only triggers callback when the text in input has changed.\n if (submittedText !== value) {\n callback?.(e, { selectedTime, selectedTimeText: value, errorType });\n }\n },\n );\n\n const handleKeyDown: ComboboxProps['onKeyDown'] = useEventCallback(e => {\n const activeOption = getActiveOption();\n if (!activeOption && e.key === Enter) {\n selectTimeFromValue(e);\n }\n });\n state.root.onKeyDown = mergeCallbacks(handleKeyDown, state.root.onKeyDown);\n\n const rootRef = React.useRef<HTMLDivElement>(null);\n state.root.ref = useMergedRefs(state.root.ref, rootRef);\n\n if (state.listbox) {\n state.listbox.tabIndex = -1; // allows it to be the relatedTarget of a blur event.\n }\n\n if (state.expandIcon) {\n state.expandIcon.tabIndex = -1; // allows it to be the relatedTarget of a blur event.\n }\n\n const handleInputBlur = useEventCallback((e: React.FocusEvent<HTMLInputElement>) => {\n const isOutside = e.relatedTarget ? !elementContains(rootRef.current, e.relatedTarget) : true;\n if (isOutside) {\n selectTimeFromValue(e);\n }\n });\n state.input.onBlur = mergeCallbacks(handleInputBlur, state.input.onBlur);\n};\n\n/**\n * Provides a default aria-labelledby for the chevron icon if the TimePicker is wrapped in a Field.\n */\nconst useDefaultChevronIconLabel = (state: TimePickerState) => {\n const fieldContext = useFieldContext();\n const chevronDefaultId = useId('timepicker-chevron-');\n const defaultLabelFromCombobox = 'Open';\n\n if (fieldContext?.labelId && state.expandIcon?.['aria-label'] === defaultLabelFromCombobox) {\n const chevronId = state.expandIcon.id ?? chevronDefaultId;\n state.expandIcon['aria-labelledby'] = `${chevronId} ${fieldContext.labelId}`;\n }\n};\n"],"names":["React","elementContains","mergeCallbacks","useControllableState","useEventCallback","useId","useMergedRefs","Enter","useCombobox_unstable","Option","useFieldContext_unstable","useFieldContext","dateToKey","keyToDate","formatDateToTimeString","defaultFormatDateToTimeString","getDateStartAnchor","getDateEndAnchor","getTimesBetween","getDateFromTimeString","useTimePicker_unstable","props","ref","baseState","dateAnchor","dateAnchorInProps","defaultSelectedTime","defaultSelectedTimeInProps","endHour","hourCycle","increment","onTimeChange","selectedTime","selectedTimeInProps","showSeconds","startHour","parseTimeStringToDate","parseTimeStringToDateInProps","rest","freeform","dateStartAnchor","dateEndAnchor","useStableDateAnchor","options","useMemo","map","time","date","key","text","setSelectedTime","state","defaultState","initialState","submittedText","setSubmittedText","useState","undefined","selectTime","e","data","selectedTimeText","selectedOptions","selectedTimeKey","selectedOption","find","clearIconRef","useRef","handleOptionSelect","optionValue","clearable","type","currentTarget","current","timeSelectionData","optionText","errorType","autoComplete","onOptionSelect","children","value","defaultParseTimeStringToDate","useCallback","mergedClearIconRef","clearIcon","useDefaultChevronIconLabel","useSelectTimeFromValue","providedDate","fallbackDateAnchor","Date","providedDateKey","callback","getOptionById","activeDescendantController","getActiveOption","activeOptionId","active","useEffect","activeOption","valueMatchesActiveOption","toLowerCase","indexOf","blur","selectTimeFromValue","handleKeyDown","root","onKeyDown","rootRef","listbox","tabIndex","expandIcon","handleInputBlur","isOutside","relatedTarget","input","onBlur","fieldContext","chevronDefaultId","defaultLabelFromCombobox","labelId","chevronId","id"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../src/components/TimePicker/useTimePicker.tsx"],"sourcesContent":["import * as React from 'react';\nimport {\n elementContains,\n mergeCallbacks,\n useControllableState,\n useEventCallback,\n useId,\n useMergedRefs,\n} from '@fluentui/react-utilities';\nimport { Enter } from '@fluentui/keyboard-keys';\nimport type { Hour, TimePickerOption, TimePickerProps, TimePickerState, TimeSelectionData } from './TimePicker.types';\nimport { ComboboxProps, useCombobox_unstable, Option } from '@fluentui/react-combobox';\nimport { useFieldContext_unstable as useFieldContext } from '@fluentui/react-field';\nimport {\n dateToKey,\n keyToDate,\n formatDateToTimeString as defaultFormatDateToTimeString,\n getDateStartAnchor,\n getDateEndAnchor,\n getTimesBetween,\n getDateFromTimeString,\n} from './timeMath';\n\n/**\n * Create the state required to render TimePicker.\n *\n * The returned state can be modified with hooks such as useTimePickerStyles_unstable,\n * before being passed to renderTimePicker_unstable.\n *\n * @param props - props from this instance of TimePicker\n * @param ref - reference to root HTMLElement of TimePicker\n */\nexport const useTimePicker_unstable = (props: TimePickerProps, ref: React.Ref<HTMLInputElement>): TimePickerState => {\n const {\n dateAnchor: dateAnchorInProps,\n defaultSelectedTime: defaultSelectedTimeInProps,\n endHour = 24,\n formatDateToTimeString = defaultFormatDateToTimeString,\n hourCycle,\n increment = 30,\n onTimeChange,\n selectedTime: selectedTimeInProps,\n showSeconds = false,\n startHour = 0,\n parseTimeStringToDate: parseTimeStringToDateInProps,\n ...rest\n } = props;\n const { freeform = false } = rest;\n\n const { dateStartAnchor, dateEndAnchor } = useStableDateAnchor(\n dateAnchorInProps ?? selectedTimeInProps ?? defaultSelectedTimeInProps,\n startHour,\n endHour,\n );\n\n const options: TimePickerOption[] = React.useMemo(\n () =>\n getTimesBetween(dateStartAnchor, dateEndAnchor, increment).map(time => ({\n date: time,\n key: dateToKey(time),\n text: formatDateToTimeString(time, { showSeconds, hourCycle }),\n })),\n [dateEndAnchor, dateStartAnchor, formatDateToTimeString, hourCycle, increment, showSeconds],\n );\n\n const [selectedTime, setSelectedTime] = useControllableState<Date | null>({\n state: selectedTimeInProps,\n defaultState: defaultSelectedTimeInProps,\n initialState: null,\n });\n\n const [submittedText, setSubmittedText] = React.useState<string | undefined>(undefined);\n\n const selectTime: TimePickerProps['onTimeChange'] = useEventCallback((e, data) => {\n setSelectedTime(data.selectedTime);\n setSubmittedText(data.selectedTimeText);\n onTimeChange?.(e, data);\n });\n\n const selectedOptions = React.useMemo(() => {\n const selectedTimeKey = dateToKey(selectedTime);\n const selectedOption = options.find(date => date.key === selectedTimeKey);\n return selectedOption ? [selectedOption.key] : [];\n }, [options, selectedTime]);\n\n const clearIconRef = React.useRef<HTMLSpanElement>(null);\n const handleOptionSelect: ComboboxProps['onOptionSelect'] = useEventCallback((e, data) => {\n if (\n freeform &&\n data.optionValue === undefined &&\n !(rest.clearable && e.type === 'click' && e.currentTarget === clearIconRef.current)\n ) {\n // Combobox clears selection when input value not matching any option; but we allow this case in freeform TimePicker.\n return;\n }\n const timeSelectionData: TimeSelectionData = {\n selectedTime: keyToDate(data.optionValue ?? ''),\n selectedTimeText: data.optionText,\n errorType: undefined,\n };\n selectTime(e, timeSelectionData);\n });\n\n const baseState = useCombobox_unstable(\n {\n autoComplete: 'off',\n ...rest,\n selectedOptions,\n onOptionSelect: handleOptionSelect,\n children: options.map(date => (\n <Option key={date.key} value={date.key}>\n {date.text}\n </Option>\n )),\n },\n ref,\n );\n\n const defaultParseTimeStringToDate = React.useCallback(\n (time: string | undefined) =>\n getDateFromTimeString(time, dateStartAnchor, dateEndAnchor, { hourCycle, showSeconds }),\n [dateEndAnchor, dateStartAnchor, hourCycle, showSeconds],\n );\n\n const mergedClearIconRef = useMergedRefs(baseState.clearIcon?.ref, clearIconRef);\n const state: TimePickerState = {\n ...baseState,\n clearIcon: baseState.clearIcon\n ? {\n ...baseState.clearIcon,\n ref: mergedClearIconRef,\n }\n : undefined,\n freeform,\n parseTimeStringToDate: parseTimeStringToDateInProps ?? defaultParseTimeStringToDate,\n submittedText,\n };\n\n useDefaultChevronIconLabel(state);\n useSelectTimeFromValue(state, selectTime);\n\n return state;\n};\n\n/**\n * Provides stable start and end date anchors based on the provided date and time parameters.\n * The hook ensures that the memoization remains consistent even if new Date objects representing the same date are provided.\n */\nconst useStableDateAnchor = (providedDate: Date | undefined, startHour: Hour, endHour: Hour) => {\n const [fallbackDateAnchor] = React.useState(() => new Date());\n\n const providedDateKey = dateToKey(providedDate ?? null);\n\n return React.useMemo(() => {\n const dateAnchor = providedDate ?? fallbackDateAnchor;\n\n const dateStartAnchor = getDateStartAnchor(dateAnchor, startHour);\n const dateEndAnchor = getDateEndAnchor(dateAnchor, startHour, endHour);\n\n return { dateStartAnchor, dateEndAnchor };\n // `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.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [endHour, fallbackDateAnchor, providedDateKey, startHour]);\n};\n\n/**\n * Mimics the behavior of the browser's change event for a freeform TimePicker.\n * The provided callback is called when input changed and:\n * - Enter/Tab key is pressed on the input.\n * - TimePicker loses focus, signifying a possible change.\n */\nconst useSelectTimeFromValue = (state: TimePickerState, callback: TimePickerProps['onTimeChange']) => {\n const { getOptionById, freeform, parseTimeStringToDate, submittedText, value, activeDescendantController } = state;\n const getActiveOption = React.useCallback(() => {\n const activeOptionId = activeDescendantController.active();\n return activeOptionId ? getOptionById(activeOptionId) : null;\n }, [activeDescendantController, getOptionById]);\n\n // Base Combobox has activeOption default to first option in dropdown even if it doesn't match input value, and Enter key will select it.\n // This effect ensures that the activeOption is cleared when the input doesn't match any option.\n // This behavior is specific to a freeform TimePicker where the input value is treated as a valid time even if it's not in the dropdown.\n React.useEffect(() => {\n if (freeform && value) {\n const activeOption = getActiveOption();\n if (!activeOption) {\n return;\n }\n\n const valueMatchesActiveOption = activeOption.text.toLowerCase().indexOf(value.toLowerCase()) === 0;\n if (!valueMatchesActiveOption) {\n activeDescendantController.blur();\n }\n }\n }, [freeform, value, activeDescendantController, getActiveOption]);\n\n const selectTimeFromValue = useEventCallback(\n (e: React.KeyboardEvent<HTMLInputElement> | React.FocusEvent<HTMLInputElement>) => {\n if (!freeform) {\n return;\n }\n\n const { date: selectedTime, errorType } = parseTimeStringToDate(value);\n\n // Only triggers callback when the text in input has changed.\n if (submittedText !== value) {\n callback?.(e, { selectedTime, selectedTimeText: value, errorType });\n }\n },\n );\n\n const handleKeyDown: ComboboxProps['onKeyDown'] = useEventCallback(e => {\n const activeOption = getActiveOption();\n if (!activeOption && e.key === Enter) {\n selectTimeFromValue(e);\n }\n });\n state.root.onKeyDown = mergeCallbacks(handleKeyDown, state.root.onKeyDown);\n\n const rootRef = React.useRef<HTMLDivElement>(null);\n state.root.ref = useMergedRefs(state.root.ref, rootRef);\n\n if (state.listbox) {\n state.listbox.tabIndex = -1; // allows it to be the relatedTarget of a blur event.\n }\n\n if (state.expandIcon) {\n state.expandIcon.tabIndex = -1; // allows it to be the relatedTarget of a blur event.\n }\n\n const handleInputBlur = useEventCallback((e: React.FocusEvent<HTMLInputElement>) => {\n const isOutside = e.relatedTarget ? !elementContains(rootRef.current, e.relatedTarget) : true;\n if (isOutside) {\n selectTimeFromValue(e);\n }\n });\n state.input.onBlur = mergeCallbacks(handleInputBlur, state.input.onBlur);\n};\n\n/**\n * Provides a default aria-labelledby for the chevron icon if the TimePicker is wrapped in a Field.\n */\nconst useDefaultChevronIconLabel = (state: TimePickerState) => {\n const fieldContext = useFieldContext();\n const chevronDefaultId = useId('timepicker-chevron-');\n const defaultLabelFromCombobox = 'Open';\n\n if (fieldContext?.labelId && state.expandIcon?.['aria-label'] === defaultLabelFromCombobox) {\n const chevronId = state.expandIcon.id ?? chevronDefaultId;\n state.expandIcon['aria-labelledby'] = `${chevronId} ${fieldContext.labelId}`;\n }\n};\n"],"names":["React","elementContains","mergeCallbacks","useControllableState","useEventCallback","useId","useMergedRefs","Enter","useCombobox_unstable","Option","useFieldContext_unstable","useFieldContext","dateToKey","keyToDate","formatDateToTimeString","defaultFormatDateToTimeString","getDateStartAnchor","getDateEndAnchor","getTimesBetween","getDateFromTimeString","useTimePicker_unstable","props","ref","baseState","dateAnchor","dateAnchorInProps","defaultSelectedTime","defaultSelectedTimeInProps","endHour","hourCycle","increment","onTimeChange","selectedTime","selectedTimeInProps","showSeconds","startHour","parseTimeStringToDate","parseTimeStringToDateInProps","rest","freeform","dateStartAnchor","dateEndAnchor","useStableDateAnchor","options","useMemo","map","time","date","key","text","setSelectedTime","state","defaultState","initialState","submittedText","setSubmittedText","useState","undefined","selectTime","e","data","selectedTimeText","selectedOptions","selectedTimeKey","selectedOption","find","clearIconRef","useRef","handleOptionSelect","optionValue","clearable","type","currentTarget","current","timeSelectionData","optionText","errorType","autoComplete","onOptionSelect","children","value","defaultParseTimeStringToDate","useCallback","mergedClearIconRef","clearIcon","useDefaultChevronIconLabel","useSelectTimeFromValue","providedDate","fallbackDateAnchor","Date","providedDateKey","callback","getOptionById","activeDescendantController","getActiveOption","activeOptionId","active","useEffect","activeOption","valueMatchesActiveOption","toLowerCase","indexOf","blur","selectTimeFromValue","handleKeyDown","root","onKeyDown","rootRef","listbox","tabIndex","expandIcon","handleInputBlur","isOutside","relatedTarget","input","onBlur","fieldContext","chevronDefaultId","defaultLabelFromCombobox","labelId","chevronId","id"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
|
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["index.ts"],"sourcesContent":["export {\n TimePicker,\n timePickerClassNames,\n useTimePickerStyles_unstable,\n useTimePicker_unstable,\n formatDateToTimeString,\n} from './TimePicker';\nexport type {\n TimePickerProps,\n TimePickerSlots,\n TimePickerState,\n TimeSelectionData,\n TimeSelectionEvents,\n TimePickerErrorType,\n} from './TimePicker';\n"],"names":["TimePicker","timePickerClassNames","useTimePickerStyles_unstable","useTimePicker_unstable","formatDateToTimeString"],"rangeMappings":"","mappings":"AAAA,SACEA,UAAU,EACVC,oBAAoB,EACpBC,4BAA4B,EAC5BC,sBAAsB,EACtBC,sBAAsB,QACjB,eAAe"}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["export {\n TimePicker,\n timePickerClassNames,\n useTimePickerStyles_unstable,\n useTimePicker_unstable,\n formatDateToTimeString,\n} from './TimePicker';\nexport type {\n TimePickerProps,\n TimePickerSlots,\n TimePickerState,\n TimeSelectionData,\n TimeSelectionEvents,\n TimePickerErrorType,\n} from './TimePicker';\n"],"names":["TimePicker","timePickerClassNames","useTimePickerStyles_unstable","useTimePicker_unstable","formatDateToTimeString"],"rangeMappings":"","mappings":"AAAA,SACEA,UAAU,EACVC,oBAAoB,EACpBC,4BAA4B,EAC5BC,sBAAsB,EACtBC,sBAAsB,QACjB,eAAe"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["TimePicker.ts"],"sourcesContent":["export * from './components/TimePicker/index';\n"],"names":[],"rangeMappings":";;;;;","mappings":";;;;;uBAAc"}
|
|
1
|
+
{"version":3,"sources":["../src/TimePicker.ts"],"sourcesContent":["export * from './components/TimePicker/index';\n"],"names":[],"rangeMappings":";;;;;","mappings":";;;;;uBAAc"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["TimePicker.tsx"],"sourcesContent":["import * as React from 'react';\nimport type { ForwardRefComponent } from '@fluentui/react-utilities';\nimport { useTimePicker_unstable } from './useTimePicker';\nimport { useTimePickerStyles_unstable } from './useTimePickerStyles.styles';\nimport type { TimePickerProps } from './TimePicker.types';\nimport { renderCombobox_unstable, useComboboxContextValues } from '@fluentui/react-combobox';\nimport { useCustomStyleHook_unstable } from '@fluentui/react-shared-contexts';\n\n/**\n * TimePicker Compat component\n */\nexport const TimePicker: ForwardRefComponent<TimePickerProps> = React.forwardRef((props, ref) => {\n const state = useTimePicker_unstable(props, ref);\n\n const contextValues = useComboboxContextValues(state);\n\n useTimePickerStyles_unstable(state);\n useCustomStyleHook_unstable('useTimePickerCompatStyles_unstable')(state);\n\n return renderCombobox_unstable(state, contextValues);\n});\n\nTimePicker.displayName = 'TimePicker';\n"],"names":["TimePicker","React","forwardRef","props","ref","state","useTimePicker_unstable","contextValues","useComboboxContextValues","useTimePickerStyles_unstable","useCustomStyleHook_unstable","renderCombobox_unstable","displayName"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;","mappings":";;;;+BAWaA;;;eAAAA;;;;iEAXU;+BAEgB;2CACM;+BAEqB;qCACtB;AAKrC,MAAMA,aAAAA,WAAAA,GAAmDC,OAAMC,UAAU,CAAC,CAACC,OAAOC;IACvF,MAAMC,QAAQC,IAAAA,qCAAAA,EAAuBH,OAAOC;IAE5C,MAAMG,gBAAgBC,IAAAA,uCAAAA,EAAyBH;IAE/CI,IAAAA,uDAAAA,EAA6BJ;IAC7BK,IAAAA,gDAAAA,EAA4B,sCAAsCL;IAElE,OAAOM,IAAAA,sCAAAA,EAAwBN,OAAOE;AACxC;AAEAP,WAAWY,WAAW,GAAG"}
|
|
1
|
+
{"version":3,"sources":["../src/components/TimePicker/TimePicker.tsx"],"sourcesContent":["import * as React from 'react';\nimport type { ForwardRefComponent } from '@fluentui/react-utilities';\nimport { useTimePicker_unstable } from './useTimePicker';\nimport { useTimePickerStyles_unstable } from './useTimePickerStyles.styles';\nimport type { TimePickerProps } from './TimePicker.types';\nimport { renderCombobox_unstable, useComboboxContextValues } from '@fluentui/react-combobox';\nimport { useCustomStyleHook_unstable } from '@fluentui/react-shared-contexts';\n\n/**\n * TimePicker Compat component\n */\nexport const TimePicker: ForwardRefComponent<TimePickerProps> = React.forwardRef((props, ref) => {\n const state = useTimePicker_unstable(props, ref);\n\n const contextValues = useComboboxContextValues(state);\n\n useTimePickerStyles_unstable(state);\n useCustomStyleHook_unstable('useTimePickerCompatStyles_unstable')(state);\n\n return renderCombobox_unstable(state, contextValues);\n});\n\nTimePicker.displayName = 'TimePicker';\n"],"names":["TimePicker","React","forwardRef","props","ref","state","useTimePicker_unstable","contextValues","useComboboxContextValues","useTimePickerStyles_unstable","useCustomStyleHook_unstable","renderCombobox_unstable","displayName"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;","mappings":";;;;+BAWaA;;;eAAAA;;;;iEAXU;+BAEgB;2CACM;+BAEqB;qCACtB;AAKrC,MAAMA,aAAAA,WAAAA,GAAmDC,OAAMC,UAAU,CAAC,CAACC,OAAOC;IACvF,MAAMC,QAAQC,IAAAA,qCAAAA,EAAuBH,OAAOC;IAE5C,MAAMG,gBAAgBC,IAAAA,uCAAAA,EAAyBH;IAE/CI,IAAAA,uDAAAA,EAA6BJ;IAC7BK,IAAAA,gDAAAA,EAA4B,sCAAsCL;IAElE,OAAOM,IAAAA,sCAAAA,EAAwBN,OAAOE;AACxC;AAEAP,WAAWY,WAAW,GAAG"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["TimePicker.types.ts"],"sourcesContent":["import * as React from 'react';\nimport type { ComboboxSlots, ComboboxState, ComboboxProps, SelectionEvents } from '@fluentui/react-combobox';\nimport type { ComponentProps } from '@fluentui/react-utilities';\n\nexport type Hour =\n | 0\n | 1\n | 2\n | 3\n | 4\n | 5\n | 6\n | 7\n | 8\n | 9\n | 10\n | 11\n | 12\n | 13\n | 14\n | 15\n | 16\n | 17\n | 18\n | 19\n | 20\n | 21\n | 22\n | 23\n | 24;\n\n/**\n * Data structure for rendering options in the TimePicker.\n */\nexport type TimePickerOption = {\n /**\n * The Date object associated with the option.\n */\n date: Date;\n\n /**\n * A unique identifier for the option.\n */\n key: string;\n\n /**\n * The display text for the option within the Combobox dropdown.\n */\n text: string;\n};\n\n/**\n * Error types returned by the `onValidationResult` callback.\n */\nexport type TimePickerErrorType = 'invalid-input' | 'out-of-bounds' | 'required-input';\n\nexport type TimeStringValidationResult = {\n date: Date | null;\n errorType?: TimePickerErrorType;\n};\n\nexport type TimePickerSlots = ComboboxSlots;\n\nexport type TimeSelectionEvents = SelectionEvents | React.FocusEvent<HTMLElement>;\nexport type TimeSelectionData = {\n /**\n * The Date object associated with the selected option. For freeform TimePicker it can also be the Date object parsed from the user input.\n */\n selectedTime: Date | null;\n /**\n * The display text for the selected option. For freeform TimePicker it can also be the value in user input.\n */\n selectedTimeText: string | undefined;\n /**\n * The error type for the selected option.\n */\n errorType: TimePickerErrorType | undefined;\n};\n\nexport type TimeFormatOptions = {\n /**\n * A string value indicating whether the 12-hour format (\"h11\", \"h12\") or the 24-hour format (\"h23\", \"h24\") should be used.\n * - 'h11' and 'h23' start with hour 0 and go up to 11 and 23 respectively.\n * - 'h12' and 'h24' start with hour 1 and go up to 12 and 24 respectively.\n * @default undefined\n */\n hourCycle?: 'h11' | 'h12' | 'h23' | 'h24' | undefined;\n\n /**\n * If true, show seconds in the dropdown options and consider seconds for default validation purposes.\n */\n showSeconds?: boolean;\n};\n\n/**\n * TimePicker Props\n */\nexport type TimePickerProps = Omit<ComponentProps<Partial<ComboboxSlots>, 'input'>, 'children' | 'size'> &\n Pick<\n ComboboxProps,\n | 'appearance'\n | 'clearable'\n | 'defaultOpen'\n | 'defaultValue'\n | 'inlinePopup'\n | 'onOpenChange'\n | 'open'\n | 'placeholder'\n | 'positioning'\n | 'size'\n | 'value'\n | 'mountNode'\n | 'freeform'\n > &\n TimeFormatOptions & {\n /**\n * Start hour (inclusive) for the time range, 0-24.\n */\n startHour?: Hour;\n\n /**\n * End hour (exclusive) for the time range, 0-24.\n */\n endHour?: Hour;\n\n /**\n * Time increment, in minutes, of the options in the dropdown.\n */\n increment?: number;\n\n /**\n * The date in which all dropdown options are based off of.\n */\n dateAnchor?: Date;\n\n /**\n * Currently selected time in the TimePicker.\n */\n selectedTime?: Date | null;\n\n /**\n * Default selected time in the TimePicker, for uncontrolled scenarios.\n */\n defaultSelectedTime?: Date;\n\n /**\n * Callback for when a time selection is made.\n */\n // eslint-disable-next-line @nx/workspace-consistent-callback-type -- can't change type of existing callback\n onTimeChange?: (event: TimeSelectionEvents, data: TimeSelectionData) => void;\n\n /**\n * Customizes the formatting of date strings displayed in dropdown options.\n */\n formatDateToTimeString?: (date: Date) => string;\n\n /**\n * In the freeform TimePicker, customizes the parsing from the input time string into a Date and provides custom validation.\n */\n parseTimeStringToDate?: (time: string | undefined) => TimeStringValidationResult;\n };\n\n/**\n * State used in rendering TimePicker\n */\nexport type TimePickerState = ComboboxState &\n Required<Pick<TimePickerProps, 'freeform' | 'parseTimeStringToDate'>> & {\n /**\n * 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.\n */\n submittedText: string | undefined;\n };\n"],"names":[],"rangeMappings":";;;;;","mappings":";;;;;iEAAuB"}
|
|
1
|
+
{"version":3,"sources":["../src/components/TimePicker/TimePicker.types.ts"],"sourcesContent":["import * as React from 'react';\nimport type { ComboboxSlots, ComboboxState, ComboboxProps, SelectionEvents } from '@fluentui/react-combobox';\nimport type { ComponentProps } from '@fluentui/react-utilities';\n\nexport type Hour =\n | 0\n | 1\n | 2\n | 3\n | 4\n | 5\n | 6\n | 7\n | 8\n | 9\n | 10\n | 11\n | 12\n | 13\n | 14\n | 15\n | 16\n | 17\n | 18\n | 19\n | 20\n | 21\n | 22\n | 23\n | 24;\n\n/**\n * Data structure for rendering options in the TimePicker.\n */\nexport type TimePickerOption = {\n /**\n * The Date object associated with the option.\n */\n date: Date;\n\n /**\n * A unique identifier for the option.\n */\n key: string;\n\n /**\n * The display text for the option within the Combobox dropdown.\n */\n text: string;\n};\n\n/**\n * Error types returned by the `onValidationResult` callback.\n */\nexport type TimePickerErrorType = 'invalid-input' | 'out-of-bounds' | 'required-input';\n\nexport type TimeStringValidationResult = {\n date: Date | null;\n errorType?: TimePickerErrorType;\n};\n\nexport type TimePickerSlots = ComboboxSlots;\n\nexport type TimeSelectionEvents = SelectionEvents | React.FocusEvent<HTMLElement>;\nexport type TimeSelectionData = {\n /**\n * The Date object associated with the selected option. For freeform TimePicker it can also be the Date object parsed from the user input.\n */\n selectedTime: Date | null;\n /**\n * The display text for the selected option. For freeform TimePicker it can also be the value in user input.\n */\n selectedTimeText: string | undefined;\n /**\n * The error type for the selected option.\n */\n errorType: TimePickerErrorType | undefined;\n};\n\nexport type TimeFormatOptions = {\n /**\n * A string value indicating whether the 12-hour format (\"h11\", \"h12\") or the 24-hour format (\"h23\", \"h24\") should be used.\n * - 'h11' and 'h23' start with hour 0 and go up to 11 and 23 respectively.\n * - 'h12' and 'h24' start with hour 1 and go up to 12 and 24 respectively.\n * @default undefined\n */\n hourCycle?: 'h11' | 'h12' | 'h23' | 'h24' | undefined;\n\n /**\n * If true, show seconds in the dropdown options and consider seconds for default validation purposes.\n */\n showSeconds?: boolean;\n};\n\n/**\n * TimePicker Props\n */\nexport type TimePickerProps = Omit<ComponentProps<Partial<ComboboxSlots>, 'input'>, 'children' | 'size'> &\n Pick<\n ComboboxProps,\n | 'appearance'\n | 'clearable'\n | 'defaultOpen'\n | 'defaultValue'\n | 'inlinePopup'\n | 'onOpenChange'\n | 'open'\n | 'placeholder'\n | 'positioning'\n | 'size'\n | 'value'\n | 'mountNode'\n | 'freeform'\n > &\n TimeFormatOptions & {\n /**\n * Start hour (inclusive) for the time range, 0-24.\n */\n startHour?: Hour;\n\n /**\n * End hour (exclusive) for the time range, 0-24.\n */\n endHour?: Hour;\n\n /**\n * Time increment, in minutes, of the options in the dropdown.\n */\n increment?: number;\n\n /**\n * The date in which all dropdown options are based off of.\n */\n dateAnchor?: Date;\n\n /**\n * Currently selected time in the TimePicker.\n */\n selectedTime?: Date | null;\n\n /**\n * Default selected time in the TimePicker, for uncontrolled scenarios.\n */\n defaultSelectedTime?: Date;\n\n /**\n * Callback for when a time selection is made.\n */\n // eslint-disable-next-line @nx/workspace-consistent-callback-type -- can't change type of existing callback\n onTimeChange?: (event: TimeSelectionEvents, data: TimeSelectionData) => void;\n\n /**\n * Customizes the formatting of date strings displayed in dropdown options.\n */\n formatDateToTimeString?: (date: Date) => string;\n\n /**\n * In the freeform TimePicker, customizes the parsing from the input time string into a Date and provides custom validation.\n */\n parseTimeStringToDate?: (time: string | undefined) => TimeStringValidationResult;\n };\n\n/**\n * State used in rendering TimePicker\n */\nexport type TimePickerState = ComboboxState &\n Required<Pick<TimePickerProps, 'freeform' | 'parseTimeStringToDate'>> & {\n /**\n * 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.\n */\n submittedText: string | undefined;\n };\n"],"names":[],"rangeMappings":";;;;;","mappings":";;;;;iEAAuB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["index.ts"],"sourcesContent":["export * from './TimePicker';\nexport * from './TimePicker.types';\nexport * from './useTimePicker';\nexport * from './useTimePickerStyles.styles';\nexport { formatDateToTimeString } from './timeMath';\n"],"names":["formatDateToTimeString"],"rangeMappings":";;;;;;;;;;;;;;;","mappings":";;;;+BAISA;;;eAAAA,gCAAsB;;;;uBAJjB;uBACA;uBACA;uBACA;0BACyB"}
|
|
1
|
+
{"version":3,"sources":["../src/components/TimePicker/index.ts"],"sourcesContent":["export * from './TimePicker';\nexport * from './TimePicker.types';\nexport * from './useTimePicker';\nexport * from './useTimePickerStyles.styles';\nexport { formatDateToTimeString } from './timeMath';\n"],"names":["formatDateToTimeString"],"rangeMappings":";;;;;;;;;;;;;;;","mappings":";;;;+BAISA;;;eAAAA,gCAAsB;;;;uBAJjB;uBACA;uBACA;uBACA;0BACyB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["timeMath.ts"],"sourcesContent":["import type { TimeFormatOptions, TimeStringValidationResult } from './TimePicker.types';\n\nfunction isValidDate(date: Date): boolean {\n return !isNaN(date.getTime());\n}\n\n/**\n * Converts a Date object to a string key.\n */\nexport function dateToKey(date: Date | null): string {\n if (!date) {\n return '';\n }\n if (!isValidDate(date)) {\n return 'invalid';\n }\n return date.toISOString();\n}\n\n/**\n * Converts a string key back to a Date object.\n * Returns undefined for keys that don't represent valid dates.\n */\nexport function keyToDate(key: string): Date | null {\n if (key === '' || key === 'invalid') {\n return null;\n }\n const date = new Date(key);\n return isValidDate(date) ? date : null;\n}\n\n/**\n * Formats a Date object into a time string based on provided options.\n *\n * @param date - The Date object to be formatted.\n * @param options - Formatting options. It has two properties:\n * 1. hourCycle (default: undefined): Determines if the time format should be 12-hour or 24-hour.\n * 2. showSeconds (default: false): Determines if the seconds should be included in the formatted string.\n * @returns Formatted time string based on the given options.\n *\n * @example\n * const date = new Date(2023, 9, 6, 23, 45, 12);\n * formatDateToTimeString(date); // Returns \"23:45\" in CET\n * formatDateToTimeString(date, \\{ showSeconds: true \\}); // Returns \"23:45:12\" in CET\n * formatDateToTimeString(date, \\{ hourCycle: 'h12', showSeconds: true \\}); // Returns \"11:45:12 PM\" in CET\n */\nexport function formatDateToTimeString(date: Date, { hourCycle, showSeconds }: TimeFormatOptions = {}): string {\n return date.toLocaleTimeString(undefined, {\n hour: 'numeric',\n hourCycle,\n minute: '2-digit',\n second: showSeconds ? '2-digit' : undefined,\n });\n}\n\n/**\n * Get the start date anchor based on the provided parameters.\n * @example\n * const date = new Date(2023, 9, 6); // October 6, 2023\n * getStartAnchorDate(date, 5); // Returns a date for October 6, 2023, 05:00:00\n */\nexport function getDateStartAnchor(dateAnchor: Date, startHour: number): Date {\n const startDate = new Date(dateAnchor);\n startDate.setHours(startHour, 0, 0, 0);\n return startDate;\n}\n\n/**\n * Get the end date anchor based on the provided parameters.\n * @example\n * const date = new Date(2023, 9, 6); // October 6, 2023\n * getEndAnchorDate(date, 5, 10); // Returns a date for October 6, 2023, 10:00:00\n * getEndAnchorDate(date, 10, 5); // Returns a date for October 7, 2023, 05:00:00 (next day due to hour conditions)\n */\nexport function getDateEndAnchor(dateAnchor: Date, startHour: number, endHour: number): Date {\n const endDate = new Date(dateAnchor);\n if (startHour > endHour || endHour === 24) {\n endDate.setDate(endDate.getDate() + 1);\n }\n endDate.setHours(endHour === 24 ? 0 : endHour, 0, 0, 0);\n return endDate;\n}\n\n/**\n * Generates an array of Date objects between two given Date anchors.\n *\n * @param dateStartAnchor - The starting Date anchor.\n * @param dateEndAnchor - The ending Date anchor.\n * @param increment - The minute increment between each Date in the resulting array.\n * @returns - An array of Date objects.\n *\n * @example\n * const start = new Date(2023, 0, 1, 10, 0); // Jan 1, 2023 10:00:00 AM\n * const end = new Date(2023, 0, 1, 11, 0); // Jan 1, 2023 11:00:00 AM\n * getTimesBetween(start, end, 15); // Returns array with Dates [10:00, 10:15, 10:30, 10:45]\n */\nexport function getTimesBetween(dateStartAnchor: Date, dateEndAnchor: Date, increment: number) {\n if (increment <= 0) {\n // eslint-disable-next-line no-console\n console.error('Increment value should be a positive number.');\n return [];\n }\n\n const result: Date[] = [];\n\n const startDate = new Date(dateStartAnchor);\n while (startDate < dateEndAnchor) {\n result.push(new Date(startDate));\n startDate.setMinutes(startDate.getMinutes() + increment);\n }\n\n return result;\n}\n\nconst REGEX_SHOW_SECONDS_HOUR_12 = /^((1[0-2]|0?[0-9]):([0-5][0-9]):([0-5][0-9])\\s([AaPp][Mm]))$/;\nconst REGEX_HIDE_SECONDS_HOUR_12 = /^((1[0-2]|0?[0-9]):[0-5][0-9]\\s([AaPp][Mm]))$/;\nconst REGEX_SHOW_SECONDS_HOUR_24 = /^([0-1]?[0-9]|2[0-4]):[0-5][0-9]:[0-5][0-9]$/;\nconst REGEX_HIDE_SECONDS_HOUR_24 = /^([0-1]?[0-9]|2[0-4]):[0-5][0-9]$/;\n\n/**\n * Calculates a new date from the user-selected time string based on anchor dates.\n * Returns an object containing a date if the provided time string is valid, and an optional string indicating the type of error.\n *\n * @param time - The time string to be parsed (e.g., \"2:30 PM\", \"15:45:20\").\n * @param dateStartAnchor - The start anchor date.\n * @param dateEndAnchor - The end anchor date.\n * @param timeFormatOptions - format options for the provided time string.\n * @returns An object with either a 'date' or an 'errorType'.\n *\n * @example\n * Input: time=\"2:30 PM\", dateStartAnchor=2023-10-06T12:00:00Z, dateEndAnchor=2023-10-07T12:00:00Z, options={hourCycle: 'h12', showSeconds: false}\n * Output: { date: 2023-10-06T14:30:00Z }\n *\n * Input: time=\"25:30\"\n * Output: { errorType: 'invalid-input' }\n *\n * Input: time=\"1:30 AM\", dateStartAnchor=2023-10-06T03:00:00Z, dateEndAnchor=2023-10-07T03:00:00Z, options={hourCycle: 'h12', showSeconds: false}\n * Output: { date: 2023-10-07T01:30:00Z, errorType: 'out-of-bounds' }\n */\nexport function getDateFromTimeString(\n time: string | undefined,\n dateStartAnchor: Date,\n dateEndAnchor: Date,\n timeFormatOptions: TimeFormatOptions,\n): TimeStringValidationResult {\n if (!time) {\n return { date: null, errorType: 'required-input' };\n }\n\n const { hourCycle, showSeconds } = timeFormatOptions;\n const hour12 = hourCycle === 'h11' || hourCycle === 'h12';\n\n // Determine the regex based on format\n const regex = hour12\n ? showSeconds\n ? REGEX_SHOW_SECONDS_HOUR_12\n : REGEX_HIDE_SECONDS_HOUR_12\n : showSeconds\n ? REGEX_SHOW_SECONDS_HOUR_24\n : REGEX_HIDE_SECONDS_HOUR_24;\n\n if (!regex.test(time)) {\n return { date: null, errorType: 'invalid-input' };\n }\n\n const timeParts = /^(\\d\\d?):(\\d\\d):?(\\d\\d)? ?([ap]m)?/i.exec(time);\n if (!timeParts) {\n return { date: null, errorType: 'invalid-input' };\n }\n\n const [, selectedHours, minutes, seconds, amPm] = timeParts;\n let hours = selectedHours;\n\n // Adjust for 12-hour time format if needed\n if (hour12 && amPm) {\n if (amPm.toLowerCase() === 'pm' && +hours !== 12) {\n hours = (+hours + 12).toString();\n } else if (amPm.toLowerCase() === 'am' && +hours === 12) {\n hours = '0';\n }\n }\n\n const adjustedDate = new Date(dateStartAnchor);\n adjustedDate.setHours(+hours, +minutes, seconds ? +seconds : 0);\n\n // Adjust to the next day if the selected time is before the anchor time\n if (adjustedDate < dateStartAnchor) {\n adjustedDate.setDate(adjustedDate.getDate() + 1);\n }\n\n if (adjustedDate >= dateEndAnchor) {\n return { date: adjustedDate, errorType: 'out-of-bounds' };\n }\n\n return { date: adjustedDate };\n}\n"],"names":["dateToKey","formatDateToTimeString","getDateEndAnchor","getDateFromTimeString","getDateStartAnchor","getTimesBetween","keyToDate","isValidDate","date","isNaN","getTime","toISOString","key","Date","hourCycle","showSeconds","toLocaleTimeString","undefined","hour","minute","second","dateAnchor","startHour","startDate","setHours","endHour","endDate","setDate","getDate","dateStartAnchor","dateEndAnchor","increment","console","error","result","push","setMinutes","getMinutes","REGEX_SHOW_SECONDS_HOUR_12","REGEX_HIDE_SECONDS_HOUR_12","REGEX_SHOW_SECONDS_HOUR_24","REGEX_HIDE_SECONDS_HOUR_24","time","timeFormatOptions","errorType","hour12","regex","test","timeParts","exec","selectedHours","minutes","seconds","amPm","hours","toLowerCase","toString","adjustedDate"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../src/components/TimePicker/timeMath.ts"],"sourcesContent":["import type { TimeFormatOptions, TimeStringValidationResult } from './TimePicker.types';\n\nfunction isValidDate(date: Date): boolean {\n return !isNaN(date.getTime());\n}\n\n/**\n * Converts a Date object to a string key.\n */\nexport function dateToKey(date: Date | null): string {\n if (!date) {\n return '';\n }\n if (!isValidDate(date)) {\n return 'invalid';\n }\n return date.toISOString();\n}\n\n/**\n * Converts a string key back to a Date object.\n * Returns undefined for keys that don't represent valid dates.\n */\nexport function keyToDate(key: string): Date | null {\n if (key === '' || key === 'invalid') {\n return null;\n }\n const date = new Date(key);\n return isValidDate(date) ? date : null;\n}\n\n/**\n * Formats a Date object into a time string based on provided options.\n *\n * @param date - The Date object to be formatted.\n * @param options - Formatting options. It has two properties:\n * 1. hourCycle (default: undefined): Determines if the time format should be 12-hour or 24-hour.\n * 2. showSeconds (default: false): Determines if the seconds should be included in the formatted string.\n * @returns Formatted time string based on the given options.\n *\n * @example\n * const date = new Date(2023, 9, 6, 23, 45, 12);\n * formatDateToTimeString(date); // Returns \"23:45\" in CET\n * formatDateToTimeString(date, \\{ showSeconds: true \\}); // Returns \"23:45:12\" in CET\n * formatDateToTimeString(date, \\{ hourCycle: 'h12', showSeconds: true \\}); // Returns \"11:45:12 PM\" in CET\n */\nexport function formatDateToTimeString(date: Date, { hourCycle, showSeconds }: TimeFormatOptions = {}): string {\n return date.toLocaleTimeString(undefined, {\n hour: 'numeric',\n hourCycle,\n minute: '2-digit',\n second: showSeconds ? '2-digit' : undefined,\n });\n}\n\n/**\n * Get the start date anchor based on the provided parameters.\n * @example\n * const date = new Date(2023, 9, 6); // October 6, 2023\n * getStartAnchorDate(date, 5); // Returns a date for October 6, 2023, 05:00:00\n */\nexport function getDateStartAnchor(dateAnchor: Date, startHour: number): Date {\n const startDate = new Date(dateAnchor);\n startDate.setHours(startHour, 0, 0, 0);\n return startDate;\n}\n\n/**\n * Get the end date anchor based on the provided parameters.\n * @example\n * const date = new Date(2023, 9, 6); // October 6, 2023\n * getEndAnchorDate(date, 5, 10); // Returns a date for October 6, 2023, 10:00:00\n * getEndAnchorDate(date, 10, 5); // Returns a date for October 7, 2023, 05:00:00 (next day due to hour conditions)\n */\nexport function getDateEndAnchor(dateAnchor: Date, startHour: number, endHour: number): Date {\n const endDate = new Date(dateAnchor);\n if (startHour > endHour || endHour === 24) {\n endDate.setDate(endDate.getDate() + 1);\n }\n endDate.setHours(endHour === 24 ? 0 : endHour, 0, 0, 0);\n return endDate;\n}\n\n/**\n * Generates an array of Date objects between two given Date anchors.\n *\n * @param dateStartAnchor - The starting Date anchor.\n * @param dateEndAnchor - The ending Date anchor.\n * @param increment - The minute increment between each Date in the resulting array.\n * @returns - An array of Date objects.\n *\n * @example\n * const start = new Date(2023, 0, 1, 10, 0); // Jan 1, 2023 10:00:00 AM\n * const end = new Date(2023, 0, 1, 11, 0); // Jan 1, 2023 11:00:00 AM\n * getTimesBetween(start, end, 15); // Returns array with Dates [10:00, 10:15, 10:30, 10:45]\n */\nexport function getTimesBetween(dateStartAnchor: Date, dateEndAnchor: Date, increment: number) {\n if (increment <= 0) {\n // eslint-disable-next-line no-console\n console.error('Increment value should be a positive number.');\n return [];\n }\n\n const result: Date[] = [];\n\n const startDate = new Date(dateStartAnchor);\n while (startDate < dateEndAnchor) {\n result.push(new Date(startDate));\n startDate.setMinutes(startDate.getMinutes() + increment);\n }\n\n return result;\n}\n\nconst REGEX_SHOW_SECONDS_HOUR_12 = /^((1[0-2]|0?[0-9]):([0-5][0-9]):([0-5][0-9])\\s([AaPp][Mm]))$/;\nconst REGEX_HIDE_SECONDS_HOUR_12 = /^((1[0-2]|0?[0-9]):[0-5][0-9]\\s([AaPp][Mm]))$/;\nconst REGEX_SHOW_SECONDS_HOUR_24 = /^([0-1]?[0-9]|2[0-4]):[0-5][0-9]:[0-5][0-9]$/;\nconst REGEX_HIDE_SECONDS_HOUR_24 = /^([0-1]?[0-9]|2[0-4]):[0-5][0-9]$/;\n\n/**\n * Calculates a new date from the user-selected time string based on anchor dates.\n * Returns an object containing a date if the provided time string is valid, and an optional string indicating the type of error.\n *\n * @param time - The time string to be parsed (e.g., \"2:30 PM\", \"15:45:20\").\n * @param dateStartAnchor - The start anchor date.\n * @param dateEndAnchor - The end anchor date.\n * @param timeFormatOptions - format options for the provided time string.\n * @returns An object with either a 'date' or an 'errorType'.\n *\n * @example\n * Input: time=\"2:30 PM\", dateStartAnchor=2023-10-06T12:00:00Z, dateEndAnchor=2023-10-07T12:00:00Z, options={hourCycle: 'h12', showSeconds: false}\n * Output: { date: 2023-10-06T14:30:00Z }\n *\n * Input: time=\"25:30\"\n * Output: { errorType: 'invalid-input' }\n *\n * Input: time=\"1:30 AM\", dateStartAnchor=2023-10-06T03:00:00Z, dateEndAnchor=2023-10-07T03:00:00Z, options={hourCycle: 'h12', showSeconds: false}\n * Output: { date: 2023-10-07T01:30:00Z, errorType: 'out-of-bounds' }\n */\nexport function getDateFromTimeString(\n time: string | undefined,\n dateStartAnchor: Date,\n dateEndAnchor: Date,\n timeFormatOptions: TimeFormatOptions,\n): TimeStringValidationResult {\n if (!time) {\n return { date: null, errorType: 'required-input' };\n }\n\n const { hourCycle, showSeconds } = timeFormatOptions;\n const hour12 = hourCycle === 'h11' || hourCycle === 'h12';\n\n // Determine the regex based on format\n const regex = hour12\n ? showSeconds\n ? REGEX_SHOW_SECONDS_HOUR_12\n : REGEX_HIDE_SECONDS_HOUR_12\n : showSeconds\n ? REGEX_SHOW_SECONDS_HOUR_24\n : REGEX_HIDE_SECONDS_HOUR_24;\n\n if (!regex.test(time)) {\n return { date: null, errorType: 'invalid-input' };\n }\n\n const timeParts = /^(\\d\\d?):(\\d\\d):?(\\d\\d)? ?([ap]m)?/i.exec(time);\n if (!timeParts) {\n return { date: null, errorType: 'invalid-input' };\n }\n\n const [, selectedHours, minutes, seconds, amPm] = timeParts;\n let hours = selectedHours;\n\n // Adjust for 12-hour time format if needed\n if (hour12 && amPm) {\n if (amPm.toLowerCase() === 'pm' && +hours !== 12) {\n hours = (+hours + 12).toString();\n } else if (amPm.toLowerCase() === 'am' && +hours === 12) {\n hours = '0';\n }\n }\n\n const adjustedDate = new Date(dateStartAnchor);\n adjustedDate.setHours(+hours, +minutes, seconds ? +seconds : 0);\n\n // Adjust to the next day if the selected time is before the anchor time\n if (adjustedDate < dateStartAnchor) {\n adjustedDate.setDate(adjustedDate.getDate() + 1);\n }\n\n if (adjustedDate >= dateEndAnchor) {\n return { date: adjustedDate, errorType: 'out-of-bounds' };\n }\n\n return { date: adjustedDate };\n}\n"],"names":["dateToKey","formatDateToTimeString","getDateEndAnchor","getDateFromTimeString","getDateStartAnchor","getTimesBetween","keyToDate","isValidDate","date","isNaN","getTime","toISOString","key","Date","hourCycle","showSeconds","toLocaleTimeString","undefined","hour","minute","second","dateAnchor","startHour","startDate","setHours","endHour","endDate","setDate","getDate","dateStartAnchor","dateEndAnchor","increment","console","error","result","push","setMinutes","getMinutes","REGEX_SHOW_SECONDS_HOUR_12","REGEX_HIDE_SECONDS_HOUR_12","REGEX_SHOW_SECONDS_HOUR_24","REGEX_HIDE_SECONDS_HOUR_24","time","timeFormatOptions","errorType","hour12","regex","test","timeParts","exec","selectedHours","minutes","seconds","amPm","hours","toLowerCase","toString","adjustedDate"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["useTimePicker.tsx"],"sourcesContent":["import * as React from 'react';\nimport {\n elementContains,\n mergeCallbacks,\n useControllableState,\n useEventCallback,\n useId,\n useMergedRefs,\n} from '@fluentui/react-utilities';\nimport { Enter } from '@fluentui/keyboard-keys';\nimport type { Hour, TimePickerOption, TimePickerProps, TimePickerState, TimeSelectionData } from './TimePicker.types';\nimport { ComboboxProps, useCombobox_unstable, Option } from '@fluentui/react-combobox';\nimport { useFieldContext_unstable as useFieldContext } from '@fluentui/react-field';\nimport {\n dateToKey,\n keyToDate,\n formatDateToTimeString as defaultFormatDateToTimeString,\n getDateStartAnchor,\n getDateEndAnchor,\n getTimesBetween,\n getDateFromTimeString,\n} from './timeMath';\n\n/**\n * Create the state required to render TimePicker.\n *\n * The returned state can be modified with hooks such as useTimePickerStyles_unstable,\n * before being passed to renderTimePicker_unstable.\n *\n * @param props - props from this instance of TimePicker\n * @param ref - reference to root HTMLElement of TimePicker\n */\nexport const useTimePicker_unstable = (props: TimePickerProps, ref: React.Ref<HTMLInputElement>): TimePickerState => {\n const {\n dateAnchor: dateAnchorInProps,\n defaultSelectedTime: defaultSelectedTimeInProps,\n endHour = 24,\n formatDateToTimeString = defaultFormatDateToTimeString,\n hourCycle,\n increment = 30,\n onTimeChange,\n selectedTime: selectedTimeInProps,\n showSeconds = false,\n startHour = 0,\n parseTimeStringToDate: parseTimeStringToDateInProps,\n ...rest\n } = props;\n const { freeform = false } = rest;\n\n const { dateStartAnchor, dateEndAnchor } = useStableDateAnchor(\n dateAnchorInProps ?? selectedTimeInProps ?? defaultSelectedTimeInProps,\n startHour,\n endHour,\n );\n\n const options: TimePickerOption[] = React.useMemo(\n () =>\n getTimesBetween(dateStartAnchor, dateEndAnchor, increment).map(time => ({\n date: time,\n key: dateToKey(time),\n text: formatDateToTimeString(time, { showSeconds, hourCycle }),\n })),\n [dateEndAnchor, dateStartAnchor, formatDateToTimeString, hourCycle, increment, showSeconds],\n );\n\n const [selectedTime, setSelectedTime] = useControllableState<Date | null>({\n state: selectedTimeInProps,\n defaultState: defaultSelectedTimeInProps,\n initialState: null,\n });\n\n const [submittedText, setSubmittedText] = React.useState<string | undefined>(undefined);\n\n const selectTime: TimePickerProps['onTimeChange'] = useEventCallback((e, data) => {\n setSelectedTime(data.selectedTime);\n setSubmittedText(data.selectedTimeText);\n onTimeChange?.(e, data);\n });\n\n const selectedOptions = React.useMemo(() => {\n const selectedTimeKey = dateToKey(selectedTime);\n const selectedOption = options.find(date => date.key === selectedTimeKey);\n return selectedOption ? [selectedOption.key] : [];\n }, [options, selectedTime]);\n\n const clearIconRef = React.useRef<HTMLSpanElement>(null);\n const handleOptionSelect: ComboboxProps['onOptionSelect'] = useEventCallback((e, data) => {\n if (\n freeform &&\n data.optionValue === undefined &&\n !(rest.clearable && e.type === 'click' && e.currentTarget === clearIconRef.current)\n ) {\n // Combobox clears selection when input value not matching any option; but we allow this case in freeform TimePicker.\n return;\n }\n const timeSelectionData: TimeSelectionData = {\n selectedTime: keyToDate(data.optionValue ?? ''),\n selectedTimeText: data.optionText,\n errorType: undefined,\n };\n selectTime(e, timeSelectionData);\n });\n\n const baseState = useCombobox_unstable(\n {\n autoComplete: 'off',\n ...rest,\n selectedOptions,\n onOptionSelect: handleOptionSelect,\n children: options.map(date => (\n <Option key={date.key} value={date.key}>\n {date.text}\n </Option>\n )),\n },\n ref,\n );\n\n const defaultParseTimeStringToDate = React.useCallback(\n (time: string | undefined) =>\n getDateFromTimeString(time, dateStartAnchor, dateEndAnchor, { hourCycle, showSeconds }),\n [dateEndAnchor, dateStartAnchor, hourCycle, showSeconds],\n );\n\n const mergedClearIconRef = useMergedRefs(baseState.clearIcon?.ref, clearIconRef);\n const state: TimePickerState = {\n ...baseState,\n clearIcon: baseState.clearIcon\n ? {\n ...baseState.clearIcon,\n ref: mergedClearIconRef,\n }\n : undefined,\n freeform,\n parseTimeStringToDate: parseTimeStringToDateInProps ?? defaultParseTimeStringToDate,\n submittedText,\n };\n\n useDefaultChevronIconLabel(state);\n useSelectTimeFromValue(state, selectTime);\n\n return state;\n};\n\n/**\n * Provides stable start and end date anchors based on the provided date and time parameters.\n * The hook ensures that the memoization remains consistent even if new Date objects representing the same date are provided.\n */\nconst useStableDateAnchor = (providedDate: Date | undefined, startHour: Hour, endHour: Hour) => {\n const [fallbackDateAnchor] = React.useState(() => new Date());\n\n const providedDateKey = dateToKey(providedDate ?? null);\n\n return React.useMemo(() => {\n const dateAnchor = providedDate ?? fallbackDateAnchor;\n\n const dateStartAnchor = getDateStartAnchor(dateAnchor, startHour);\n const dateEndAnchor = getDateEndAnchor(dateAnchor, startHour, endHour);\n\n return { dateStartAnchor, dateEndAnchor };\n // `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.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [endHour, fallbackDateAnchor, providedDateKey, startHour]);\n};\n\n/**\n * Mimics the behavior of the browser's change event for a freeform TimePicker.\n * The provided callback is called when input changed and:\n * - Enter/Tab key is pressed on the input.\n * - TimePicker loses focus, signifying a possible change.\n */\nconst useSelectTimeFromValue = (state: TimePickerState, callback: TimePickerProps['onTimeChange']) => {\n const { getOptionById, freeform, parseTimeStringToDate, submittedText, value, activeDescendantController } = state;\n const getActiveOption = React.useCallback(() => {\n const activeOptionId = activeDescendantController.active();\n return activeOptionId ? getOptionById(activeOptionId) : null;\n }, [activeDescendantController, getOptionById]);\n\n // Base Combobox has activeOption default to first option in dropdown even if it doesn't match input value, and Enter key will select it.\n // This effect ensures that the activeOption is cleared when the input doesn't match any option.\n // This behavior is specific to a freeform TimePicker where the input value is treated as a valid time even if it's not in the dropdown.\n React.useEffect(() => {\n if (freeform && value) {\n const activeOption = getActiveOption();\n if (!activeOption) {\n return;\n }\n\n const valueMatchesActiveOption = activeOption.text.toLowerCase().indexOf(value.toLowerCase()) === 0;\n if (!valueMatchesActiveOption) {\n activeDescendantController.blur();\n }\n }\n }, [freeform, value, activeDescendantController, getActiveOption]);\n\n const selectTimeFromValue = useEventCallback(\n (e: React.KeyboardEvent<HTMLInputElement> | React.FocusEvent<HTMLInputElement>) => {\n if (!freeform) {\n return;\n }\n\n const { date: selectedTime, errorType } = parseTimeStringToDate(value);\n\n // Only triggers callback when the text in input has changed.\n if (submittedText !== value) {\n callback?.(e, { selectedTime, selectedTimeText: value, errorType });\n }\n },\n );\n\n const handleKeyDown: ComboboxProps['onKeyDown'] = useEventCallback(e => {\n const activeOption = getActiveOption();\n if (!activeOption && e.key === Enter) {\n selectTimeFromValue(e);\n }\n });\n state.root.onKeyDown = mergeCallbacks(handleKeyDown, state.root.onKeyDown);\n\n const rootRef = React.useRef<HTMLDivElement>(null);\n state.root.ref = useMergedRefs(state.root.ref, rootRef);\n\n if (state.listbox) {\n state.listbox.tabIndex = -1; // allows it to be the relatedTarget of a blur event.\n }\n\n if (state.expandIcon) {\n state.expandIcon.tabIndex = -1; // allows it to be the relatedTarget of a blur event.\n }\n\n const handleInputBlur = useEventCallback((e: React.FocusEvent<HTMLInputElement>) => {\n const isOutside = e.relatedTarget ? !elementContains(rootRef.current, e.relatedTarget) : true;\n if (isOutside) {\n selectTimeFromValue(e);\n }\n });\n state.input.onBlur = mergeCallbacks(handleInputBlur, state.input.onBlur);\n};\n\n/**\n * Provides a default aria-labelledby for the chevron icon if the TimePicker is wrapped in a Field.\n */\nconst useDefaultChevronIconLabel = (state: TimePickerState) => {\n const fieldContext = useFieldContext();\n const chevronDefaultId = useId('timepicker-chevron-');\n const defaultLabelFromCombobox = 'Open';\n\n if (fieldContext?.labelId && state.expandIcon?.['aria-label'] === defaultLabelFromCombobox) {\n const chevronId = state.expandIcon.id ?? chevronDefaultId;\n state.expandIcon['aria-labelledby'] = `${chevronId} ${fieldContext.labelId}`;\n }\n};\n"],"names":["useTimePicker_unstable","props","ref","baseState","dateAnchor","dateAnchorInProps","defaultSelectedTime","defaultSelectedTimeInProps","endHour","formatDateToTimeString","defaultFormatDateToTimeString","hourCycle","increment","onTimeChange","selectedTime","selectedTimeInProps","showSeconds","startHour","parseTimeStringToDate","parseTimeStringToDateInProps","rest","freeform","dateStartAnchor","dateEndAnchor","useStableDateAnchor","options","React","useMemo","getTimesBetween","map","time","date","key","dateToKey","text","setSelectedTime","useControllableState","state","defaultState","initialState","submittedText","setSubmittedText","useState","undefined","selectTime","useEventCallback","e","data","selectedTimeText","selectedOptions","selectedTimeKey","selectedOption","find","clearIconRef","useRef","handleOptionSelect","optionValue","clearable","type","currentTarget","current","timeSelectionData","keyToDate","optionText","errorType","useCombobox_unstable","autoComplete","onOptionSelect","children","createElement","Option","value","defaultParseTimeStringToDate","useCallback","getDateFromTimeString","mergedClearIconRef","useMergedRefs","clearIcon","useDefaultChevronIconLabel","useSelectTimeFromValue","providedDate","fallbackDateAnchor","Date","providedDateKey","getDateStartAnchor","getDateEndAnchor","callback","getOptionById","activeDescendantController","getActiveOption","activeOptionId","active","useEffect","activeOption","valueMatchesActiveOption","toLowerCase","indexOf","blur","selectTimeFromValue","handleKeyDown","Enter","root","onKeyDown","mergeCallbacks","rootRef","listbox","tabIndex","expandIcon","handleInputBlur","isOutside","relatedTarget","elementContains","input","onBlur","fieldContext","useFieldContext","chevronDefaultId","useId","defaultLabelFromCombobox","labelId","chevronId","id"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../src/components/TimePicker/useTimePicker.tsx"],"sourcesContent":["import * as React from 'react';\nimport {\n elementContains,\n mergeCallbacks,\n useControllableState,\n useEventCallback,\n useId,\n useMergedRefs,\n} from '@fluentui/react-utilities';\nimport { Enter } from '@fluentui/keyboard-keys';\nimport type { Hour, TimePickerOption, TimePickerProps, TimePickerState, TimeSelectionData } from './TimePicker.types';\nimport { ComboboxProps, useCombobox_unstable, Option } from '@fluentui/react-combobox';\nimport { useFieldContext_unstable as useFieldContext } from '@fluentui/react-field';\nimport {\n dateToKey,\n keyToDate,\n formatDateToTimeString as defaultFormatDateToTimeString,\n getDateStartAnchor,\n getDateEndAnchor,\n getTimesBetween,\n getDateFromTimeString,\n} from './timeMath';\n\n/**\n * Create the state required to render TimePicker.\n *\n * The returned state can be modified with hooks such as useTimePickerStyles_unstable,\n * before being passed to renderTimePicker_unstable.\n *\n * @param props - props from this instance of TimePicker\n * @param ref - reference to root HTMLElement of TimePicker\n */\nexport const useTimePicker_unstable = (props: TimePickerProps, ref: React.Ref<HTMLInputElement>): TimePickerState => {\n const {\n dateAnchor: dateAnchorInProps,\n defaultSelectedTime: defaultSelectedTimeInProps,\n endHour = 24,\n formatDateToTimeString = defaultFormatDateToTimeString,\n hourCycle,\n increment = 30,\n onTimeChange,\n selectedTime: selectedTimeInProps,\n showSeconds = false,\n startHour = 0,\n parseTimeStringToDate: parseTimeStringToDateInProps,\n ...rest\n } = props;\n const { freeform = false } = rest;\n\n const { dateStartAnchor, dateEndAnchor } = useStableDateAnchor(\n dateAnchorInProps ?? selectedTimeInProps ?? defaultSelectedTimeInProps,\n startHour,\n endHour,\n );\n\n const options: TimePickerOption[] = React.useMemo(\n () =>\n getTimesBetween(dateStartAnchor, dateEndAnchor, increment).map(time => ({\n date: time,\n key: dateToKey(time),\n text: formatDateToTimeString(time, { showSeconds, hourCycle }),\n })),\n [dateEndAnchor, dateStartAnchor, formatDateToTimeString, hourCycle, increment, showSeconds],\n );\n\n const [selectedTime, setSelectedTime] = useControllableState<Date | null>({\n state: selectedTimeInProps,\n defaultState: defaultSelectedTimeInProps,\n initialState: null,\n });\n\n const [submittedText, setSubmittedText] = React.useState<string | undefined>(undefined);\n\n const selectTime: TimePickerProps['onTimeChange'] = useEventCallback((e, data) => {\n setSelectedTime(data.selectedTime);\n setSubmittedText(data.selectedTimeText);\n onTimeChange?.(e, data);\n });\n\n const selectedOptions = React.useMemo(() => {\n const selectedTimeKey = dateToKey(selectedTime);\n const selectedOption = options.find(date => date.key === selectedTimeKey);\n return selectedOption ? [selectedOption.key] : [];\n }, [options, selectedTime]);\n\n const clearIconRef = React.useRef<HTMLSpanElement>(null);\n const handleOptionSelect: ComboboxProps['onOptionSelect'] = useEventCallback((e, data) => {\n if (\n freeform &&\n data.optionValue === undefined &&\n !(rest.clearable && e.type === 'click' && e.currentTarget === clearIconRef.current)\n ) {\n // Combobox clears selection when input value not matching any option; but we allow this case in freeform TimePicker.\n return;\n }\n const timeSelectionData: TimeSelectionData = {\n selectedTime: keyToDate(data.optionValue ?? ''),\n selectedTimeText: data.optionText,\n errorType: undefined,\n };\n selectTime(e, timeSelectionData);\n });\n\n const baseState = useCombobox_unstable(\n {\n autoComplete: 'off',\n ...rest,\n selectedOptions,\n onOptionSelect: handleOptionSelect,\n children: options.map(date => (\n <Option key={date.key} value={date.key}>\n {date.text}\n </Option>\n )),\n },\n ref,\n );\n\n const defaultParseTimeStringToDate = React.useCallback(\n (time: string | undefined) =>\n getDateFromTimeString(time, dateStartAnchor, dateEndAnchor, { hourCycle, showSeconds }),\n [dateEndAnchor, dateStartAnchor, hourCycle, showSeconds],\n );\n\n const mergedClearIconRef = useMergedRefs(baseState.clearIcon?.ref, clearIconRef);\n const state: TimePickerState = {\n ...baseState,\n clearIcon: baseState.clearIcon\n ? {\n ...baseState.clearIcon,\n ref: mergedClearIconRef,\n }\n : undefined,\n freeform,\n parseTimeStringToDate: parseTimeStringToDateInProps ?? defaultParseTimeStringToDate,\n submittedText,\n };\n\n useDefaultChevronIconLabel(state);\n useSelectTimeFromValue(state, selectTime);\n\n return state;\n};\n\n/**\n * Provides stable start and end date anchors based on the provided date and time parameters.\n * The hook ensures that the memoization remains consistent even if new Date objects representing the same date are provided.\n */\nconst useStableDateAnchor = (providedDate: Date | undefined, startHour: Hour, endHour: Hour) => {\n const [fallbackDateAnchor] = React.useState(() => new Date());\n\n const providedDateKey = dateToKey(providedDate ?? null);\n\n return React.useMemo(() => {\n const dateAnchor = providedDate ?? fallbackDateAnchor;\n\n const dateStartAnchor = getDateStartAnchor(dateAnchor, startHour);\n const dateEndAnchor = getDateEndAnchor(dateAnchor, startHour, endHour);\n\n return { dateStartAnchor, dateEndAnchor };\n // `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.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [endHour, fallbackDateAnchor, providedDateKey, startHour]);\n};\n\n/**\n * Mimics the behavior of the browser's change event for a freeform TimePicker.\n * The provided callback is called when input changed and:\n * - Enter/Tab key is pressed on the input.\n * - TimePicker loses focus, signifying a possible change.\n */\nconst useSelectTimeFromValue = (state: TimePickerState, callback: TimePickerProps['onTimeChange']) => {\n const { getOptionById, freeform, parseTimeStringToDate, submittedText, value, activeDescendantController } = state;\n const getActiveOption = React.useCallback(() => {\n const activeOptionId = activeDescendantController.active();\n return activeOptionId ? getOptionById(activeOptionId) : null;\n }, [activeDescendantController, getOptionById]);\n\n // Base Combobox has activeOption default to first option in dropdown even if it doesn't match input value, and Enter key will select it.\n // This effect ensures that the activeOption is cleared when the input doesn't match any option.\n // This behavior is specific to a freeform TimePicker where the input value is treated as a valid time even if it's not in the dropdown.\n React.useEffect(() => {\n if (freeform && value) {\n const activeOption = getActiveOption();\n if (!activeOption) {\n return;\n }\n\n const valueMatchesActiveOption = activeOption.text.toLowerCase().indexOf(value.toLowerCase()) === 0;\n if (!valueMatchesActiveOption) {\n activeDescendantController.blur();\n }\n }\n }, [freeform, value, activeDescendantController, getActiveOption]);\n\n const selectTimeFromValue = useEventCallback(\n (e: React.KeyboardEvent<HTMLInputElement> | React.FocusEvent<HTMLInputElement>) => {\n if (!freeform) {\n return;\n }\n\n const { date: selectedTime, errorType } = parseTimeStringToDate(value);\n\n // Only triggers callback when the text in input has changed.\n if (submittedText !== value) {\n callback?.(e, { selectedTime, selectedTimeText: value, errorType });\n }\n },\n );\n\n const handleKeyDown: ComboboxProps['onKeyDown'] = useEventCallback(e => {\n const activeOption = getActiveOption();\n if (!activeOption && e.key === Enter) {\n selectTimeFromValue(e);\n }\n });\n state.root.onKeyDown = mergeCallbacks(handleKeyDown, state.root.onKeyDown);\n\n const rootRef = React.useRef<HTMLDivElement>(null);\n state.root.ref = useMergedRefs(state.root.ref, rootRef);\n\n if (state.listbox) {\n state.listbox.tabIndex = -1; // allows it to be the relatedTarget of a blur event.\n }\n\n if (state.expandIcon) {\n state.expandIcon.tabIndex = -1; // allows it to be the relatedTarget of a blur event.\n }\n\n const handleInputBlur = useEventCallback((e: React.FocusEvent<HTMLInputElement>) => {\n const isOutside = e.relatedTarget ? !elementContains(rootRef.current, e.relatedTarget) : true;\n if (isOutside) {\n selectTimeFromValue(e);\n }\n });\n state.input.onBlur = mergeCallbacks(handleInputBlur, state.input.onBlur);\n};\n\n/**\n * Provides a default aria-labelledby for the chevron icon if the TimePicker is wrapped in a Field.\n */\nconst useDefaultChevronIconLabel = (state: TimePickerState) => {\n const fieldContext = useFieldContext();\n const chevronDefaultId = useId('timepicker-chevron-');\n const defaultLabelFromCombobox = 'Open';\n\n if (fieldContext?.labelId && state.expandIcon?.['aria-label'] === defaultLabelFromCombobox) {\n const chevronId = state.expandIcon.id ?? chevronDefaultId;\n state.expandIcon['aria-labelledby'] = `${chevronId} ${fieldContext.labelId}`;\n }\n};\n"],"names":["useTimePicker_unstable","props","ref","baseState","dateAnchor","dateAnchorInProps","defaultSelectedTime","defaultSelectedTimeInProps","endHour","formatDateToTimeString","defaultFormatDateToTimeString","hourCycle","increment","onTimeChange","selectedTime","selectedTimeInProps","showSeconds","startHour","parseTimeStringToDate","parseTimeStringToDateInProps","rest","freeform","dateStartAnchor","dateEndAnchor","useStableDateAnchor","options","React","useMemo","getTimesBetween","map","time","date","key","dateToKey","text","setSelectedTime","useControllableState","state","defaultState","initialState","submittedText","setSubmittedText","useState","undefined","selectTime","useEventCallback","e","data","selectedTimeText","selectedOptions","selectedTimeKey","selectedOption","find","clearIconRef","useRef","handleOptionSelect","optionValue","clearable","type","currentTarget","current","timeSelectionData","keyToDate","optionText","errorType","useCombobox_unstable","autoComplete","onOptionSelect","children","createElement","Option","value","defaultParseTimeStringToDate","useCallback","getDateFromTimeString","mergedClearIconRef","useMergedRefs","clearIcon","useDefaultChevronIconLabel","useSelectTimeFromValue","providedDate","fallbackDateAnchor","Date","providedDateKey","getDateStartAnchor","getDateEndAnchor","callback","getOptionById","activeDescendantController","getActiveOption","activeOptionId","active","useEffect","activeOption","valueMatchesActiveOption","toLowerCase","indexOf","blur","selectTimeFromValue","handleKeyDown","Enter","root","onKeyDown","mergeCallbacks","rootRef","listbox","tabIndex","expandIcon","handleInputBlur","isOutside","relatedTarget","elementContains","input","onBlur","fieldContext","useFieldContext","chevronDefaultId","useId","defaultLabelFromCombobox","labelId","chevronId","id"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["index.ts"],"sourcesContent":["export {\n TimePicker,\n timePickerClassNames,\n useTimePickerStyles_unstable,\n useTimePicker_unstable,\n formatDateToTimeString,\n} from './TimePicker';\nexport type {\n TimePickerProps,\n TimePickerSlots,\n TimePickerState,\n TimeSelectionData,\n TimeSelectionEvents,\n TimePickerErrorType,\n} from './TimePicker';\n"],"names":["TimePicker","formatDateToTimeString","timePickerClassNames","useTimePickerStyles_unstable","useTimePicker_unstable"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":";;;;;;;;;;;IACEA,UAAU;eAAVA,sBAAU;;IAIVC,sBAAsB;eAAtBA,kCAAsB;;IAHtBC,oBAAoB;eAApBA,gCAAoB;;IACpBC,4BAA4B;eAA5BA,wCAA4B;;IAC5BC,sBAAsB;eAAtBA,kCAAsB;;;4BAEjB"}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["export {\n TimePicker,\n timePickerClassNames,\n useTimePickerStyles_unstable,\n useTimePicker_unstable,\n formatDateToTimeString,\n} from './TimePicker';\nexport type {\n TimePickerProps,\n TimePickerSlots,\n TimePickerState,\n TimeSelectionData,\n TimeSelectionEvents,\n TimePickerErrorType,\n} from './TimePicker';\n"],"names":["TimePicker","formatDateToTimeString","timePickerClassNames","useTimePickerStyles_unstable","useTimePicker_unstable"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":";;;;;;;;;;;IACEA,UAAU;eAAVA,sBAAU;;IAIVC,sBAAsB;eAAtBA,kCAAsB;;IAHtBC,oBAAoB;eAApBA,gCAAoB;;IACpBC,4BAA4B;eAA5BA,wCAA4B;;IAC5BC,sBAAsB;eAAtBA,kCAAsB;;;4BAEjB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fluentui/react-timepicker-compat",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.38",
|
|
4
4
|
"description": "Fluent UI TimePicker Compat Component",
|
|
5
5
|
"main": "lib-commonjs/index.js",
|
|
6
6
|
"module": "lib/index.js",
|
|
@@ -17,19 +17,6 @@
|
|
|
17
17
|
"url": "https://github.com/microsoft/fluentui"
|
|
18
18
|
},
|
|
19
19
|
"license": "MIT",
|
|
20
|
-
"scripts": {
|
|
21
|
-
"build": "just-scripts build",
|
|
22
|
-
"bundle-size": "monosize measure",
|
|
23
|
-
"clean": "just-scripts clean",
|
|
24
|
-
"e2e": "cypress run --component",
|
|
25
|
-
"e2e:local": "cypress open --component",
|
|
26
|
-
"generate-api": "just-scripts generate-api",
|
|
27
|
-
"lint": "just-scripts lint",
|
|
28
|
-
"start": "yarn storybook",
|
|
29
|
-
"storybook": "yarn --cwd ../stories storybook",
|
|
30
|
-
"test": "jest --passWithNoTests",
|
|
31
|
-
"type-check": "just-scripts type-check"
|
|
32
|
-
},
|
|
33
20
|
"devDependencies": {
|
|
34
21
|
"@fluentui/react-provider": "*",
|
|
35
22
|
"@fluentui/react-components": "*",
|
|
@@ -37,17 +24,16 @@
|
|
|
37
24
|
"@fluentui/react-conformance": "*",
|
|
38
25
|
"@fluentui/react-conformance-griffel": "*",
|
|
39
26
|
"@fluentui/scripts-api-extractor": "*",
|
|
40
|
-
"@fluentui/scripts-tasks": "*",
|
|
41
27
|
"@fluentui/scripts-cypress": "*"
|
|
42
28
|
},
|
|
43
29
|
"dependencies": {
|
|
44
|
-
"@fluentui/keyboard-keys": "^9.0.
|
|
45
|
-
"@fluentui/react-combobox": "^9.13.
|
|
46
|
-
"@fluentui/react-field": "^9.1.
|
|
47
|
-
"@fluentui/react-jsx-runtime": "^9.0.
|
|
48
|
-
"@fluentui/react-shared-contexts": "^9.
|
|
49
|
-
"@fluentui/react-theme": "^9.1.
|
|
50
|
-
"@fluentui/react-utilities": "^9.18.
|
|
30
|
+
"@fluentui/keyboard-keys": "^9.0.8",
|
|
31
|
+
"@fluentui/react-combobox": "^9.13.11",
|
|
32
|
+
"@fluentui/react-field": "^9.1.79",
|
|
33
|
+
"@fluentui/react-jsx-runtime": "^9.0.46",
|
|
34
|
+
"@fluentui/react-shared-contexts": "^9.21.0",
|
|
35
|
+
"@fluentui/react-theme": "^9.1.22",
|
|
36
|
+
"@fluentui/react-utilities": "^9.18.17",
|
|
51
37
|
"@griffel/react": "^1.5.22",
|
|
52
38
|
"@swc/helpers": "^0.5.1"
|
|
53
39
|
},
|