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.

197 lines (193 loc) 6.58 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, cache, settings = {}) { this.control = control; this.settings = settings; this.cache = cache; } static create(control, cache) { return new _LensCore(control, cache); } focus(propPath) { var _a, _b, _c, _d, _e, _f, _g; let nestedPath = this.settings.propPath === void 0 ? propPath : `${this.settings.propPath}.${propPath}`; if (this.settings.lensesMap) { if (Array.isArray(this.settings.lensesMap)) { const arrayReflectMapper = (0, import_react_hook_form.get)(this.settings.lensesMap[0], propPath); if (arrayReflectMapper) { const reflectedPropPath = (_a = arrayReflectMapper.settings.propPath) == null ? void 0 : _a.slice(`${this.settings.restructureSourcePath}.`.length); if (reflectedPropPath) { nestedPath = `${this.settings.propPath}.${reflectedPropPath}`; if (!((_b = this.cache) == null ? void 0 : _b.has(nestedPath))) { const newLens = new _LensCore(arrayReflectMapper.control, arrayReflectMapper.cache, { ...arrayReflectMapper.settings, propPath: nestedPath }); (_c = this.cache) == null ? void 0 : _c.set(newLens, nestedPath); } const focusedLens2 = (_d = this.cache) == null ? void 0 : _d.get(nestedPath); if (!focusedLens2) { throw new Error(`There is no focused lens: ${nestedPath}`); } return focusedLens2; } } } else { const result = (0, import_react_hook_form.get)(this.settings.lensesMap, propPath); if (result) { return result; } } } if (!((_e = this.cache) == null ? void 0 : _e.has(nestedPath))) { const newLens = new _LensCore(this.control, this.cache, { propPath: nestedPath, lensesMap: this.settings.lensesMap, restructureSourcePath: this.settings.restructureSourcePath }); (_f = this.cache) == null ? void 0 : _f.set(newLens, nestedPath); } const focusedLens = (_g = this.cache) == null ? void 0 : _g.get(nestedPath); if (!focusedLens) { throw new Error(`There is no focused lens: ${nestedPath}`); } return focusedLens; } reflect(getter) { var _a, _b, _c, _d; const fromCache = (_b = this.cache) == null ? void 0 : _b.get((_a = this.settings.propPath) != null ? _a : "", getter); if (fromCache) { return fromCache; } const proxy = new Proxy( {}, { get: (target, prop) => { if (typeof prop === "string") { return this.focus(prop); } return target; } } ); const focusContext = getter(proxy, this); const newLens = new _LensCore(this.control, this.cache, { lensesMap: focusContext, propPath: this.settings.propPath, restructureSourcePath: this.settings.propPath }); (_d = this.cache) == null ? void 0 : _d.set(newLens, (_c = this.settings.propPath) != null ? _c : "", getter); return newLens; } map(fields, mapper) { if (!this.settings.propPath) { throw new Error(`There is no prop name in this lens: ${this.settings.propPath}`); } return fields.map((value, index, array) => { const item = this.focus(index.toString()); const res = mapper(value, item, index, array, this); return res; }); } interop(cb) { return cb ? cb(this.control, this.settings.propPath, this) : { control: this.control, name: this.settings.propPath, lens: this }; } }; // 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(propPath, complexKey) { const cached = this.cache.get(propPath); if (cached) { if (complexKey) { return cached.complex.get(complexKey); } return cached.plain; } return void 0; } set(lens, propPath, complexKey) { let cached = this.cache.get(propPath); if (!cached) { cached = { complex: /* @__PURE__ */ new WeakMap() }; this.cache.set(propPath, cached); } if (complexKey) { cached.complex.set(complexKey, lens); } else { cached.plain = lens; } } has(propPath, complexKey) { var _a, _b; if (complexKey) { return (_b = (_a = this.cache.get(propPath)) == null ? void 0 : _a.complex.has(complexKey)) != null ? _b : false; } return this.cache.has(propPath); } delete(propPath) { for (const key of this.cache.keys()) { if (key.startsWith(propPath)) { 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