160 lines
4.3 KiB
JavaScript
160 lines
4.3 KiB
JavaScript
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
|
|
const _excluded = ["className", "sx"];
|
|
import * as React from 'react';
|
|
import useEnhancedEffect from '@mui/utils/useEnhancedEffect';
|
|
import useEventCallback from '@mui/utils/useEventCallback';
|
|
import { useViews } from '../useViews';
|
|
import { isTimeView } from '../../utils/time-utils';
|
|
|
|
/**
|
|
* Props used to handle the views that are common to all pickers.
|
|
*/
|
|
|
|
/**
|
|
* Props used to handle the views of the pickers.
|
|
*/
|
|
|
|
/**
|
|
* Props used to handle the value of the pickers.
|
|
*/
|
|
|
|
/**
|
|
* Manage the views of all the pickers:
|
|
* - Handles the view switch
|
|
* - Handles the switch between UI views and field views
|
|
* - Handles the focus management when switching views
|
|
*/
|
|
export const usePickerViews = ({
|
|
props,
|
|
propsFromPickerValue,
|
|
additionalViewProps,
|
|
inputRef,
|
|
autoFocusView
|
|
}) => {
|
|
const {
|
|
onChange,
|
|
open,
|
|
onSelectedSectionsChange,
|
|
onClose
|
|
} = propsFromPickerValue;
|
|
const {
|
|
view: inView,
|
|
views,
|
|
openTo,
|
|
onViewChange,
|
|
viewRenderers,
|
|
timezone
|
|
} = props;
|
|
const propsToForwardToView = _objectWithoutPropertiesLoose(props, _excluded);
|
|
const {
|
|
view,
|
|
setView,
|
|
defaultView,
|
|
focusedView,
|
|
setFocusedView,
|
|
setValueAndGoToNextView
|
|
} = useViews({
|
|
view: inView,
|
|
views,
|
|
openTo,
|
|
onChange,
|
|
onViewChange,
|
|
autoFocus: autoFocusView
|
|
});
|
|
const {
|
|
hasUIView,
|
|
viewModeLookup
|
|
} = React.useMemo(() => views.reduce((acc, viewForReduce) => {
|
|
let viewMode;
|
|
if (viewRenderers[viewForReduce] != null) {
|
|
viewMode = 'UI';
|
|
} else {
|
|
viewMode = 'field';
|
|
}
|
|
acc.viewModeLookup[viewForReduce] = viewMode;
|
|
if (viewMode === 'UI') {
|
|
acc.hasUIView = true;
|
|
}
|
|
return acc;
|
|
}, {
|
|
hasUIView: false,
|
|
viewModeLookup: {}
|
|
}), [viewRenderers, views]);
|
|
const timeViewsCount = React.useMemo(() => views.reduce((acc, viewForReduce) => {
|
|
if (viewRenderers[viewForReduce] != null && isTimeView(viewForReduce)) {
|
|
return acc + 1;
|
|
}
|
|
return acc;
|
|
}, 0), [viewRenderers, views]);
|
|
const currentViewMode = viewModeLookup[view];
|
|
const shouldRestoreFocus = useEventCallback(() => currentViewMode === 'UI');
|
|
const [popperView, setPopperView] = React.useState(currentViewMode === 'UI' ? view : null);
|
|
if (popperView !== view && viewModeLookup[view] === 'UI') {
|
|
setPopperView(view);
|
|
}
|
|
useEnhancedEffect(() => {
|
|
// Handle case of `DateTimePicker` without time renderers
|
|
if (currentViewMode === 'field' && open) {
|
|
onClose();
|
|
setTimeout(() => {
|
|
// focusing the input before the range selection is done
|
|
// calling `onSelectedSectionsChange` outside of timeout results in an inconsistent behavior between Safari And Chrome
|
|
inputRef == null || inputRef.current.focus();
|
|
onSelectedSectionsChange(view);
|
|
});
|
|
}
|
|
}, [view]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
|
|
useEnhancedEffect(() => {
|
|
if (!open) {
|
|
return;
|
|
}
|
|
let newView = view;
|
|
|
|
// If the current view is a field view, go to the last popper view
|
|
if (currentViewMode === 'field' && popperView != null) {
|
|
newView = popperView;
|
|
}
|
|
|
|
// If the current view is not the default view and both are UI views
|
|
if (newView !== defaultView && viewModeLookup[newView] === 'UI' && viewModeLookup[defaultView] === 'UI') {
|
|
newView = defaultView;
|
|
}
|
|
if (newView !== view) {
|
|
setView(newView);
|
|
}
|
|
setFocusedView(newView, true);
|
|
}, [open]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
|
|
const layoutProps = {
|
|
views,
|
|
view: popperView,
|
|
onViewChange: setView
|
|
};
|
|
return {
|
|
hasUIView,
|
|
shouldRestoreFocus,
|
|
layoutProps,
|
|
renderCurrentView: () => {
|
|
if (popperView == null) {
|
|
return null;
|
|
}
|
|
const renderer = viewRenderers[popperView];
|
|
if (renderer == null) {
|
|
return null;
|
|
}
|
|
return renderer(_extends({}, propsToForwardToView, additionalViewProps, propsFromPickerValue, {
|
|
views,
|
|
timezone,
|
|
onChange: setValueAndGoToNextView,
|
|
view: popperView,
|
|
onViewChange: setView,
|
|
focusedView,
|
|
onFocusedViewChange: setFocusedView,
|
|
showViewSwitcher: timeViewsCount > 1,
|
|
timeViewsCount
|
|
}));
|
|
}
|
|
};
|
|
}; |