137 lines
No EOL
5.4 KiB
JavaScript
137 lines
No EOL
5.4 KiB
JavaScript
"use strict";
|
|
'use client';
|
|
|
|
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
|
|
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
exports.useViews = useViews;
|
|
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
|
|
var React = _interopRequireWildcard(require("react"));
|
|
var _useEventCallback = _interopRequireDefault(require("@mui/utils/useEventCallback"));
|
|
var _useControlled = _interopRequireDefault(require("@mui/utils/useControlled"));
|
|
var _createStepNavigation = require("../utils/createStepNavigation");
|
|
let warnedOnceNotValidView = false;
|
|
function useViews({
|
|
onChange,
|
|
onViewChange,
|
|
openTo,
|
|
view: inView,
|
|
views,
|
|
autoFocus,
|
|
focusedView: inFocusedView,
|
|
onFocusedViewChange,
|
|
getStepNavigation
|
|
}) {
|
|
if (process.env.NODE_ENV !== 'production') {
|
|
if (!warnedOnceNotValidView) {
|
|
if (inView != null && !views.includes(inView)) {
|
|
console.warn(`MUI X: \`view="${inView}"\` is not a valid prop.`, `It must be an element of \`views=["${views.join('", "')}"]\`.`);
|
|
warnedOnceNotValidView = true;
|
|
}
|
|
if (inView == null && openTo != null && !views.includes(openTo)) {
|
|
console.warn(`MUI X: \`openTo="${openTo}"\` is not a valid prop.`, `It must be an element of \`views=["${views.join('", "')}"]\`.`);
|
|
warnedOnceNotValidView = true;
|
|
}
|
|
}
|
|
}
|
|
const previousOpenTo = React.useRef(openTo);
|
|
const previousViews = React.useRef(views);
|
|
const defaultView = React.useRef(views.includes(openTo) ? openTo : views[0]);
|
|
const [view, setView] = (0, _useControlled.default)({
|
|
name: 'useViews',
|
|
state: 'view',
|
|
controlled: inView,
|
|
default: defaultView.current
|
|
});
|
|
const defaultFocusedView = React.useRef(autoFocus ? view : null);
|
|
const [focusedView, setFocusedView] = (0, _useControlled.default)({
|
|
name: 'useViews',
|
|
state: 'focusedView',
|
|
controlled: inFocusedView,
|
|
default: defaultFocusedView.current
|
|
});
|
|
const stepNavigation = getStepNavigation ? getStepNavigation({
|
|
setView,
|
|
view,
|
|
defaultView: defaultView.current,
|
|
views
|
|
}) : _createStepNavigation.DEFAULT_STEP_NAVIGATION;
|
|
React.useEffect(() => {
|
|
// Update the current view when `openTo` or `views` props change
|
|
if (previousOpenTo.current && previousOpenTo.current !== openTo || previousViews.current && previousViews.current.some(previousView => !views.includes(previousView))) {
|
|
setView(views.includes(openTo) ? openTo : views[0]);
|
|
previousViews.current = views;
|
|
previousOpenTo.current = openTo;
|
|
}
|
|
}, [openTo, setView, view, views]);
|
|
const viewIndex = views.indexOf(view);
|
|
const previousView = views[viewIndex - 1] ?? null;
|
|
const nextView = views[viewIndex + 1] ?? null;
|
|
const handleFocusedViewChange = (0, _useEventCallback.default)((viewToFocus, hasFocus) => {
|
|
if (hasFocus) {
|
|
// Focus event
|
|
setFocusedView(viewToFocus);
|
|
} else {
|
|
// Blur event
|
|
setFocusedView(prevFocusedView => viewToFocus === prevFocusedView ? null : prevFocusedView // If false the blur is due to view switching
|
|
);
|
|
}
|
|
onFocusedViewChange?.(viewToFocus, hasFocus);
|
|
});
|
|
const handleChangeView = (0, _useEventCallback.default)(newView => {
|
|
// always keep the focused view in sync
|
|
handleFocusedViewChange(newView, true);
|
|
if (newView === view) {
|
|
return;
|
|
}
|
|
setView(newView);
|
|
if (onViewChange) {
|
|
onViewChange(newView);
|
|
}
|
|
});
|
|
const goToNextView = (0, _useEventCallback.default)(() => {
|
|
if (nextView) {
|
|
handleChangeView(nextView);
|
|
}
|
|
});
|
|
const setValueAndGoToNextView = (0, _useEventCallback.default)((value, currentViewSelectionState, selectedView) => {
|
|
const isSelectionFinishedOnCurrentView = currentViewSelectionState === 'finish';
|
|
const hasMoreViews = selectedView ?
|
|
// handles case like `DateTimePicker`, where a view might return a `finish` selection state
|
|
// but when it's not the final view given all `views` -> overall selection state should be `partial`.
|
|
views.indexOf(selectedView) < views.length - 1 : Boolean(nextView);
|
|
const globalSelectionState = isSelectionFinishedOnCurrentView && hasMoreViews ? 'partial' : currentViewSelectionState;
|
|
onChange(value, globalSelectionState, selectedView);
|
|
|
|
// The selected view can be different from the active view,
|
|
// This can happen if multiple views are displayed, like in `DesktopDateTimePicker` or `MultiSectionDigitalClock`.
|
|
let currentView = null;
|
|
if (selectedView != null && selectedView !== view) {
|
|
currentView = selectedView;
|
|
} else if (isSelectionFinishedOnCurrentView) {
|
|
currentView = view;
|
|
}
|
|
if (currentView == null) {
|
|
return;
|
|
}
|
|
const viewToNavigateTo = views[views.indexOf(currentView) + 1];
|
|
if (viewToNavigateTo == null || !stepNavigation.areViewsInSameStep(currentView, viewToNavigateTo)) {
|
|
return;
|
|
}
|
|
handleChangeView(viewToNavigateTo);
|
|
});
|
|
return (0, _extends2.default)({}, stepNavigation, {
|
|
view,
|
|
setView: handleChangeView,
|
|
focusedView,
|
|
setFocusedView: handleFocusedViewChange,
|
|
nextView,
|
|
previousView,
|
|
// Always return up-to-date default view instead of the initial one (i.e. defaultView.current)
|
|
defaultView: views.includes(openTo) ? openTo : views[0],
|
|
goToNextView,
|
|
setValueAndGoToNextView
|
|
});
|
|
} |