@renderlesskit/react
Version:
Collection of headless components/hooks that are accessible, composable, customizable from low level to build your own UI & Design System powered by Reakit
60 lines (58 loc) • 2.51 kB
JavaScript
/* eslint-disable react-hooks/exhaustive-deps */
import * as React from "react";
import { runIfFn, warn } from "@chakra-ui/utils";
export function useControllableProp(prop, state) {
var {
current: isControlled
} = React.useRef(prop !== undefined);
var value = isControlled && typeof prop !== "undefined" ? prop : state;
return [isControlled, value];
}
var defaultPropsMap = {
value: "value",
defaultValue: "defaultValue",
onChange: "onChange"
};
/**
* React hook for using controlling component state.
* @param props
*/
export function useControllableState(props) {
var {
value: valueProp,
defaultValue,
onChange,
name = "Component",
propsMap = defaultPropsMap
} = props;
var [valueState, setValue] = React.useState(defaultValue);
var {
current: isControlled
} = React.useRef(valueProp !== undefined); // don't switch from controlled to uncontrolled
React.useEffect(() => {
var nextIsControlled = valueProp !== undefined;
var nextMode = nextIsControlled ? "a controlled" : "an uncontrolled";
var mode = isControlled ? "a controlled" : "an uncontrolled";
warn({
condition: isControlled !== nextIsControlled,
message: "Warning: ".concat(name, " is changing from ").concat(mode, " to ").concat(nextMode, " component. ") + "Components should not switch from controlled to uncontrolled (or vice versa). " + "Use the '".concat(propsMap.value, "' with an '").concat(propsMap.onChange, "' handler. ") + "If you want an uncontrolled component, remove the ".concat(propsMap.value, " prop and use '").concat(propsMap.defaultValue, "' instead. \"") + "More info: https://fb.me/react-controlled-components"
});
}, [valueProp, isControlled, name]);
var {
current: initialDefaultValue
} = React.useRef(defaultValue);
React.useEffect(() => {
warn({
condition: initialDefaultValue !== defaultValue,
message: "Warning: A component is changing the default value of an uncontrolled ".concat(name, " after being initialized. ") + "To suppress this warning opt to use a controlled ".concat(name, ".")
});
}, [JSON.stringify(defaultValue)]);
var value = isControlled ? valueProp : valueState;
var updateValue = React.useCallback(next => {
var nextValue = runIfFn(next, value);
if (!isControlled) setValue(nextValue);
onChange === null || onChange === void 0 ? void 0 : onChange(nextValue);
}, [onChange, value]);
return [value, updateValue];
}
//# sourceMappingURL=useControllableState.js.map