niceform-hook
Version:
Dynamic workhorse for form in react
159 lines (158 loc) • 6.13 kB
JavaScript
import {useController as useController$1,useFormState as useFormState$1,useWatch as useWatch$1}from'react-hook-form';import {jsx}from'react/jsx-runtime';import {createContext as createContext$1,useRef,useEffect,useContext,useState}from'react';function createProvider(ProviderOriginal) {
return ({ value, children }) => {
const valueRef = useRef(value);
const listenersRef = useRef(new Set());
const contextValue = useRef({
value: valueRef,
registerListener: (listener) => {
listenersRef.current.add(listener);
return () => listenersRef.current.delete(listener);
}
});
useEffect(() => {
valueRef.current = value;
listenersRef.current.forEach((listener) => {
listener(value);
});
}, [value]);
return (jsx(ProviderOriginal, { value: contextValue.current, children: children }));
};
}
function createContext(defaultValue) {
const context = createContext$1(defaultValue);
delete context.Consumer;
context.Provider = createProvider(context.Provider);
return context;
}/*
* This code is based on an implementation provided by Luke Edwards
* [https://github.com/lukeed/dequal]
* Copyright (c) Luke Edwards <luke.edwards05@gmail.com> (lukeed.com)
* release v2.0.3
*/
const has = Object.prototype.hasOwnProperty;
function dequalLite(foo, bar) {
let ctor, len;
if (foo === bar)
return true;
if (foo && bar && (ctor = foo.constructor) === bar.constructor) {
if (ctor === Date)
return foo.getTime() === bar.getTime();
if (ctor === RegExp)
return foo.toString() === bar.toString();
if (ctor === Array) {
if ((len = foo.length) === bar.length) {
while (len-- && dequalLite(foo[len], bar[len]))
;
}
return len === -1;
}
if (!ctor || typeof foo === 'object') {
len = 0;
for (ctor in foo) {
if (has.call(foo, ctor) && ++len && !has.call(bar, ctor))
return false;
if (!(ctor in bar) || !dequalLite(foo[ctor], bar[ctor]))
return false;
}
return Object.keys(bar).length === len;
}
}
return foo !== foo && bar !== bar;
}function useContextSelector(context, selector, deepComparison = false) {
const { value, registerListener } = useContext(context);
const selectorRef = useRef(selector);
const [selectedValue, setSelectedValue] = useState(() => selector(value.current));
const _selectedValue = useRef(selectedValue);
_selectedValue.current = selectedValue;
useEffect(() => {
selectorRef.current = selector;
});
useEffect(() => {
const updateValueIfNeeded = (newValue) => {
const newSelectedValue = selectorRef.current(newValue);
const compare = deepComparison ? dequalLite : Object.is;
if (!compare(_selectedValue.current, newSelectedValue)) {
setSelectedValue(() => newSelectedValue);
}
};
const unregisterListener = registerListener(updateValueIfNeeded);
return unregisterListener;
}, [registerListener, value, deepComparison]);
return selectedValue;
}const context = createContext(null);
function useNiceformHookContext(callback, deepComparison = false) {
return useContextSelector(context, callback, deepComparison);
}function useForm() {
return useNiceformHookContext(state => state.form.methods);
}function useController(props) {
const { control } = useForm();
return useController$1({ control, ...props });
}function useFieldState(name) {
const cb = (state) => state.getFieldState(name, state.formState);
const result = useNiceformHookContext(state => {
var _a, _b, _c, _d, _e;
const fieldState = cb(state.form.methods);
return {
/**
* field is not valid.
*
Condition: subscribe to errors.
*/
invalid: fieldState.invalid,
/**
* field is modified.
*
* Condition: subscribe to dirtyFields.
*/
isDirty: fieldState.isDirty,
/**
* field has received a focus and blur event.
*
Condition: subscribe to touchedFields.
*/
isTouched: fieldState.isTouched,
/**
* field error object.
Condition: subscribe to errors.
*/
error: {
/**
* Error type.
*/
type: (_a = fieldState.error) === null || _a === void 0 ? void 0 : _a.type,
root: (_b = fieldState.error) === null || _b === void 0 ? void 0 : _b.root,
/**
* Element reference
*/
ref: (_c = fieldState.error) === null || _c === void 0 ? void 0 : _c.ref,
types: (_d = fieldState.error) === null || _d === void 0 ? void 0 : _d.types,
/**
* Error message
*/
message: (_e = fieldState.error) === null || _e === void 0 ? void 0 : _e.message
}
};
}, true);
return result;
}function useFormState(props) {
const { control } = useForm();
return useFormState$1({ control, ...props });
}/**
* Custom hook to subscribe to field change and isolate re-rendering at the component level.
*
* @remarks
*
* [API](https://react-hook-form.com/api/usewatch) • [Demo](https://codesandbox.io/s/react-hook-form-v7-ts-usewatch-h9i5e)
*
* @example
* ```tsx
* const { watch } = useForm();
* const values = useWatch({
* name: "fieldName"
* })
* ```
*/
function useWatch(props) {
const { control } = useForm();
return useWatch$1({ control, ...props });
}export{useController,useFieldState,useForm,useFormState,useWatch};//# sourceMappingURL=index.esm.mjs.map