UNPKG

@hookform/lenses

Version:

Type-safe lenses for React Hook Form that enable precise control over nested form state. Build reusable form components with composable operations, array handling, and full TypeScript support.

231 lines (227 loc) 7.33 kB
"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/index.ts var index_exports = {}; __export(index_exports, { LensCore: () => LensCore, LensesStorage: () => LensesStorage, useLens: () => useLens }); module.exports = __toCommonJS(index_exports); // src/LensCore.ts var import_react_hook_form = require("react-hook-form"); var LensCore = class _LensCore { constructor(control, path, cache) { this.control = control; this.path = path; this.cache = cache; } static create(control, cache) { return new _LensCore(control, "", cache); } focus(prop) { var _a, _b, _c, _d, _e, _f; const propString = prop.toString(); const nestedPath = this.path ? `${this.path}.${propString}` : propString; const fromCache = (_a = this.cache) == null ? void 0 : _a.get(nestedPath); if (fromCache) { return fromCache; } if (Array.isArray(this.override)) { const [template] = this.override; const result2 = new _LensCore(this.control, nestedPath, this.cache); result2.isArrayItemReflection = true; result2.override = template; (_b = this.cache) == null ? void 0 : _b.set(result2, nestedPath); return result2; } else if (this.override) { const overriddenLens = (0, import_react_hook_form.get)(this.override, propString); if (!overriddenLens) { const result2 = new _LensCore(this.control, nestedPath, this.cache); (_c = this.cache) == null ? void 0 : _c.set(result2, nestedPath); return result2; } if (this.isArrayItemReflection) { const arrayItemNestedPath = `${this.path}.${overriddenLens.path}`; const result2 = new _LensCore(this.control, arrayItemNestedPath, this.cache); (_d = this.cache) == null ? void 0 : _d.set(result2, arrayItemNestedPath); return result2; } else { (_e = this.cache) == null ? void 0 : _e.set(overriddenLens, nestedPath); return overriddenLens; } } const result = new _LensCore(this.control, nestedPath, this.cache); (_f = this.cache) == null ? void 0 : _f.set(result, nestedPath); return result; } reflect(getter) { var _a, _b, _c; const fromCache = (_a = this.cache) == null ? void 0 : _a.get(this.path, getter); if (fromCache) { return fromCache; } const template = new _LensCore(this.control, this.path, this.cache); const dictionary = new Proxy( {}, { get: (target, prop) => { if (typeof prop === "string") { return template.focus(prop); } return target; } } ); const override = getter(dictionary, template); if (Array.isArray(override)) { const result = new _LensCore(this.control, this.path, this.cache); template.path = ""; result.override = getter(dictionary, template); (_b = this.cache) == null ? void 0 : _b.set(result, this.path, getter); return result; } else { template.override = override; template.path = this.path; (_c = this.cache) == null ? void 0 : _c.set(template, this.path, getter); return template; } } map(fields, mapper) { return fields.map((value, index, array) => { const item = this.focus(index.toString()); const res = mapper(value, item, index, array, this); return res; }); } interop(cb) { var _a; if (cb) { return cb(this.control, this.path); } (_a = this.interopCache) != null ? _a : this.interopCache = { control: this.control, name: this.path, ...this.override ? { getTransformer: this.getTransformer.bind(this), setTransformer: this.setTransformer.bind(this) } : {} }; return this.interopCache; } getTransformer(value) { const [template] = Array.isArray(this.override) ? this.override : [this.override]; if (!value || !template) { return value; } const newValue = {}; Object.entries(template).forEach(([key, valueTemplate]) => { const restructuredLens = valueTemplate; if (!restructuredLens) { return; } const v = (0, import_react_hook_form.get)(value, restructuredLens.path); (0, import_react_hook_form.set)(newValue, key, v); }); return newValue; } setTransformer(value) { const [template] = Array.isArray(this.override) ? this.override : [this.override]; if (!value || !template) { return value; } const newValue = {}; Object.entries(value).forEach(([key, value2]) => { const restructuredLens = template[key]; if (!restructuredLens) { return; } (0, import_react_hook_form.set)(newValue, restructuredLens.path, value2); }); return newValue; } }; // src/LensesStorage.ts var LensesStorage = class { constructor(control) { var _a, _b, _c; this.cache = /* @__PURE__ */ new Map(); (_c = (_b = (_a = control == null ? void 0 : control._subjects) == null ? void 0 : _a.values) == null ? void 0 : _b.subscribe) == null ? void 0 : _c.call(_b, { next: () => { control._names.unMount.forEach((name) => { this.delete(name); }); } }); } get(path, complexKey) { const cached = this.cache.get(path); if (cached) { if (complexKey) { return cached.complex.get(complexKey); } return cached.plain; } return void 0; } set(lens, path, complexKey) { let cached = this.cache.get(path); if (!cached) { cached = { complex: /* @__PURE__ */ new WeakMap() }; this.cache.set(path, cached); } if (complexKey) { cached.complex.set(complexKey, lens); } else { cached.plain = lens; } } has(path, complexKey) { var _a, _b; if (complexKey) { return (_b = (_a = this.cache.get(path)) == null ? void 0 : _a.complex.has(complexKey)) != null ? _b : false; } return this.cache.has(path); } delete(path) { for (const key of this.cache.keys()) { if (key.startsWith(path)) { this.cache.delete(key); } } } clear() { this.cache.clear(); } }; // src/useLens.ts var import_react = require("react"); function useLens(props, deps = []) { return (0, import_react.useMemo)(() => { const cache = new LensesStorage(props.control); const lens = LensCore.create(props.control, cache); return lens; }, [props.control, ...deps]); } // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { LensCore, LensesStorage, useLens }); //# sourceMappingURL=index.cjs.map