UNPKG

alinea

Version:

[![npm](https://img.shields.io/npm/v/alinea.svg)](https://npmjs.org/package/alinea) [![install size](https://packagephobia.com/badge?p=alinea)](https://packagephobia.com/result?p=alinea)

159 lines (157 loc) 4.53 kB
import { unwrap } from "../../chunks/chunk-ZHH24SIG.js"; import { atom } from "../../chunks/chunk-OBOPLPUQ.js"; import { Doc, YMap } from "../../chunks/chunk-OYP4EJOA.js"; import "../../chunks/chunk-O6EXLFU2.js"; import "../../chunks/chunk-U5RRZUYZ.js"; // src/dashboard/atoms/FormAtoms.tsx import { Field, ROOT_KEY, Section, Type, applyEntryData, track } from "alinea/core"; import { entries } from "alinea/core/util/Objects"; import { createContext, useContext, useMemo } from "react"; import { jsx } from "react/jsx-runtime"; var FormAtoms = class { constructor(type, container, options = { readOnly: false }) { this.type = type; this.container = container; this.options = options; for (const section of Type.sections(type)) { for (const [key, field] of entries(Section.fields(section))) { const ref = Field.ref(field); const shape = Field.shape(field); const defaultOptions = Field.options(field); const optionsTracker = track.optionTrackerOf(field); shape.init(container, key); const mutator = shape.mutator(container, key, false); const options2 = optionsTracker ? unwrap( atom((get) => { const tracked = optionsTracker(this.getter(get)); if (tracked instanceof Promise) return tracked.then((partial) => { return { ...defaultOptions, ...partial }; }); return { ...defaultOptions, ...tracked }; }), (prev) => prev ?? defaultOptions ) : atom(defaultOptions); const valueTracker = track.valueTrackerOf(field); const value = this.valueAtom(field, key, valueTracker); this.fieldInfo.set(ref, { key, field, value, mutator, options: options2 }); } } } fieldInfo = /* @__PURE__ */ new Map(); data() { return Type.shape(this.type).fromY(this.container); } getter = (get) => (field) => { const info = this.fieldInfo.get(Field.ref(field)); if (!info) throw new Error(`Field not found: ${Field.label(field)}`); return get(info.value); }; valueAtom(field, key, tracker) { const shape = Field.shape(field); const revision = atom(0); revision.onMount = (setAtom) => { const onChange = () => setAtom((x) => x + 1); const watch = shape.watch(this.container, key); onChange(); return watch(onChange); }; return atom((g) => { g(revision); const current = shape.fromY(this.container.get(key)); const next = tracker ? tracker(this.getter(g)) : current; if (next !== current) shape.applyY(next, this.container, key); return next; }); } fieldByKey(key) { for (const info of this.fieldInfo.values()) if (info.key === key) return info.field; throw new Error(`Field not found: "${key}"`); } keyOf(field) { const res = this.fieldInfo.get(Field.ref(field)); const label = Field.label(field); if (!res) throw new Error(`Field not found: ${label}`); return res.key; } atomsOf(field) { const res = this.fieldInfo.get(Field.ref(field)); const label = Field.label(field); if (!res) throw new Error(`Field not found: ${label}`); return res; } }; var formAtomsContext = createContext(void 0); function useForm(type, options = {}) { return useMemo(() => { const doc = options.doc ?? new Doc(); if (options.initialValue) { applyEntryData(doc, type, { data: options.initialValue }); } return new FormAtoms(type, doc.getMap(ROOT_KEY)); }, [type, options.doc]); } function useFormContext() { const formAtoms = useContext(formAtomsContext); if (!formAtoms) throw new Error("FormAtoms is not provided"); return formAtoms; } function FormProvider({ children, form }) { return /* @__PURE__ */ jsx(formAtomsContext.Provider, { value: form, children }); } function FormRow({ children, field, type, rowId }) { const form = useFormContext(); const rowForm = useMemo(() => { const key = form.keyOf(field); const inner = form.container.get(key); if (rowId) { if (!inner.has(rowId)) inner.set(rowId, new YMap()); } const row = rowId ? inner.get(rowId) : inner; return new FormAtoms(type, row); }, [form, rowId]); return /* @__PURE__ */ jsx(FormProvider, { form: rowForm, children }); } export { FormAtoms, FormProvider, FormRow, useForm, useFormContext };