@mui/x-charts
Version:
The community edition of the Charts components (MUI X).
73 lines (69 loc) • 3.54 kB
JavaScript
;
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.useChartModels = void 0;
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var React = _interopRequireWildcard(require("react"));
/**
* Implements the same behavior as `useControlled` but for several models.
* The controlled models are never stored in the state, and the state is only updated if the model is not controlled.
*/
const useChartModels = (plugins, props) => {
const modelsRef = React.useRef({});
const [modelsState, setModelsState] = React.useState(() => {
const initialState = {};
plugins.forEach(plugin => {
if (plugin.models) {
Object.entries(plugin.models).forEach(([modelName, modelInitializer]) => {
modelsRef.current[modelName] = {
isControlled: props[modelName] !== undefined,
getDefaultValue: modelInitializer.getDefaultValue
};
initialState[modelName] = modelInitializer.getDefaultValue(props);
});
}
});
return initialState;
});
const models = Object.fromEntries(Object.entries(modelsRef.current).map(([modelName, model]) => {
const value = props[modelName] ?? modelsState[modelName];
return [modelName, {
value,
setControlledValue: newValue => {
if (!model.isControlled) {
setModelsState(prevState => (0, _extends2.default)({}, prevState, {
[modelName]: typeof newValue === 'function' ? newValue(value) : newValue
}));
}
},
isControlled: modelsRef.current[modelName].isControlled
}];
}));
// We know that `modelsRef` do not vary across renders.
if (process.env.NODE_ENV !== 'production') {
Object.entries(modelsRef.current).forEach(([modelName, model]) => {
const controlled = props[modelName];
const newDefaultValue = model.getDefaultValue(props);
/* eslint-disable react-hooks/rules-of-hooks, react-hooks/exhaustive-deps, react-compiler/react-compiler */
React.useEffect(() => {
if (model.isControlled !== (controlled !== undefined)) {
console.error([`MUI X Charts: A component is changing the ${model.isControlled ? '' : 'un'}controlled ${modelName} state of Chart to be ${model.isControlled ? 'un' : ''}controlled.`, 'Elements should not switch from uncontrolled to controlled (or vice versa).', `Decide between using a controlled or uncontrolled ${modelName} ` + 'element for the lifetime of the component.', "The nature of the state is determined during the first render. It's considered controlled if the value is not `undefined`.", 'More info: https://fb.me/react-controlled-components'].join('\n'));
}
}, [controlled]);
const {
current: defaultValue
} = React.useRef(newDefaultValue);
React.useEffect(() => {
if (!model.isControlled && defaultValue !== newDefaultValue) {
console.error([`MUI X Charts: A component is changing the default ${modelName} state of an uncontrolled Chart after being initialized. ` + `To suppress this warning opt to use a controlled Chart.`].join('\n'));
}
}, [JSON.stringify(newDefaultValue)]);
});
}
/* eslint-enable react-hooks/rules-of-hooks, react-hooks/exhaustive-deps */
return models;
};
exports.useChartModels = useChartModels;