uncontrollable
Version:
Wrap a controlled react component, to allow specific prop/handler pairs to be uncontrolled
49 lines (47 loc) • 1.54 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.defaultKey = defaultKey;
exports.useUncontrolled = useUncontrolled;
exports.useUncontrolledProp = useUncontrolledProp;
var _react = require("react");
function defaultKey(key) {
return 'default' + key.charAt(0).toUpperCase() + key.substr(1);
}
function useUncontrolledProp(propValue, defaultValue, handler) {
const wasPropRef = (0, _react.useRef)(propValue !== undefined);
const [stateValue, setState] = (0, _react.useState)(defaultValue);
const isProp = propValue !== undefined;
const wasProp = wasPropRef.current;
wasPropRef.current = isProp;
/**
* If a prop switches from controlled to Uncontrolled
* reset its value to the defaultValue
*/
if (!isProp && wasProp && stateValue !== defaultValue) {
setState(defaultValue);
}
return [isProp ? propValue : stateValue, (0, _react.useCallback)((...args) => {
const [value, ...rest] = args;
let returnValue = handler?.(value, ...rest);
setState(value);
return returnValue;
}, [handler])];
}
function useUncontrolled(props, config) {
return Object.keys(config).reduce((result, fieldName) => {
const {
[defaultKey(fieldName)]: defaultValue,
[fieldName]: propsValue,
...rest
} = result;
const handlerName = config[fieldName];
const [value, handler] = useUncontrolledProp(propsValue, defaultValue, props[handlerName]);
return {
...rest,
[fieldName]: value,
[handlerName]: handler
};
}, props);
}