UNPKG

@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
/* 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