diff --git a/packages/fluentui/CHANGELOG.md b/packages/fluentui/CHANGELOG.md index 1eb7881cf83358..dd07189e7c946f 100644 --- a/packages/fluentui/CHANGELOG.md +++ b/packages/fluentui/CHANGELOG.md @@ -18,6 +18,9 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm ## [Unreleased] +### Fixes +- `Datepicker`: add onCalendarOpenStateChange prop. @jurokapsiar ([#28136](https://github.com/microsoft/fluentui/pull/28136)) + ## [v0.66.4](https://github.com/microsoft/fluentui/tree/@fluentui/react-northstar_v0.66.4) (2023-03-10) [Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-northstar_v0.66.3..@fluentui/react-northstar_v0.66.4) diff --git a/packages/fluentui/docs/src/examples/components/Datepicker/Types/DatepickerExampleOpen.shorthand.tsx b/packages/fluentui/docs/src/examples/components/Datepicker/Types/DatepickerExampleOpen.shorthand.tsx index cf9926bb91c882..1ee55b7d13f917 100644 --- a/packages/fluentui/docs/src/examples/components/Datepicker/Types/DatepickerExampleOpen.shorthand.tsx +++ b/packages/fluentui/docs/src/examples/components/Datepicker/Types/DatepickerExampleOpen.shorthand.tsx @@ -3,9 +3,13 @@ import * as React from 'react'; import { Datepicker } from '@fluentui/react-northstar'; const DatepickerExampleOpen = () => { - const [open] = useBooleanKnob({ name: 'open' }); - - return ; + const [open, setOpen] = useBooleanKnob({ name: 'open' }); + return ( + setOpen(calendarOpenState)} + /> + ); }; export default DatepickerExampleOpen; diff --git a/packages/fluentui/react-northstar/src/components/Datepicker/Datepicker.tsx b/packages/fluentui/react-northstar/src/components/Datepicker/Datepicker.tsx index 9f2fc59d0dcb49..42540f07835676 100644 --- a/packages/fluentui/react-northstar/src/components/Datepicker/Datepicker.tsx +++ b/packages/fluentui/react-northstar/src/components/Datepicker/Datepicker.tsx @@ -100,6 +100,14 @@ export interface DatepickerProps extends UIComponentProps, Partial; + /** Initial 'selectedDate' value. */ defaultSelectedDate?: Date; @@ -253,6 +261,21 @@ export const Datepicker = React.forwardRef((pro : '', ); + const trySetOpenState = ( + newValue: boolean, + event: + | React.SyntheticEvent + | React.KeyboardEvent + | React.MouseEvent + | KeyboardEvent + | MouseEvent + | TouchEvent + | WheelEvent, + ) => { + setOpenState(newValue); + _.invoke(props, 'onCalendarOpenStateChange', event, { ...props, ...{ calendarOpenState: newValue } }); + }; + const calendarOptions: IDayGridOptions = { selectedDate, navigatedDate: !!selectedDate && !error ? selectedDate : props.today ?? new Date(), @@ -274,10 +297,10 @@ export const Datepicker = React.forwardRef((pro actionHandlers: { open: e => { if (allowManualInput) { - setOpenState(!openState); + trySetOpenState(!openState, e); } else { // Keep popup open in case we can only enter the date through calendar. - setOpenState(true); + trySetOpenState(true, e); } e.preventDefault(); @@ -309,7 +332,7 @@ export const Datepicker = React.forwardRef((pro onDateChange: (e, itemProps) => { const targetDay = itemProps.value; setSelectedDate(targetDay.originalDate); - setOpenState(false); + trySetOpenState(false, e); setError(''); setFormattedDate(valueFormatter(targetDay.originalDate)); @@ -325,10 +348,10 @@ export const Datepicker = React.forwardRef((pro const overrideInputProps = (predefinedProps: InputProps): InputProps => ({ onClick: (e): void => { if (allowManualInput) { - setOpenState(!openState); + trySetOpenState(!openState, e); } else { // Keep popup open in case we can only enter the date through calendar. - setOpenState(true); + trySetOpenState(true, e); } _.invoke(predefinedProps, 'onClick', e, predefinedProps); @@ -415,7 +438,7 @@ export const Datepicker = React.forwardRef((pro onOpenChange: (e, { open }) => { // In case the event is a click on input, we ignore such events as it should be directly handled by input. if (!(e.type === 'click' && e.target === inputRef?.current)) { - setOpenState(open); + trySetOpenState(open, e); _.invoke(predefinedProps, 'onOpenChange', e, { open }); } }, @@ -454,6 +477,7 @@ Datepicker.propTypes = { fallbackToLastCorrectDateOnBlur: PropTypes.bool, defaultCalendarOpenState: PropTypes.bool, calendarOpenState: PropTypes.bool, + onCalendarOpenStateChange: PropTypes.func, selectedDate: PropTypes.instanceOf(Date), defaultSelectedDate: PropTypes.instanceOf(Date),