PalmyraForm#
@palmyralabs/rt-forms · src/palmyra/form/PalmyraForm.tsx
Overview#
The root controlled form. Creates a FormManager via useFormManager(props), publishes it through FormManagerContext, forwards a StoreFactory through StoreFactoryContext, and wraps its children in a default FieldGroup name="_default". Field widgets inside the subtree self-register by consuming FieldGroupManagerContext — you never enumerate fields at the prop level.
Use PalmyraForm directly when you need full control of the submit / hydrate flow; for the common patterns, reach for PalmyraNewForm, PalmyraEditForm, or PalmyraViewForm.
Props — IFormOptions#
interface IFormOptions extends IStoreProps<StoreOptions & any> {
children?: any;
formData?: any; // hydrate the form with this value
onValidChange?: (isValid: boolean) => void;
}
interface IStoreProps<T> {
storeFactory?: StoreFactory<any, T>; // usually comes from StoreFactoryContext
storeOptions?: T;
}Ref — IForm#
interface IForm {
getData(): any;
setData(value: any): void;
isValid(): boolean;
}Example#
import { useRef } from 'react';
import { PalmyraForm, type IForm } from '@palmyralabs/rt-forms';
import { TextField } from '@palmyralabs/rt-forms-mantine';
import { Button } from '@mantine/core';
export function ManualUserForm() {
const formRef = useRef<IForm>(null);
const submit = async () => {
if (!formRef.current?.isValid()) return;
const data = formRef.current!.getData();
// hand-rolled submit — skip PalmyraNewForm's automatic save
await fetch('/api/palmyra/user', { method: 'POST', body: JSON.stringify(data) });
};
return (
<>
<PalmyraForm ref={formRef} onValidChange={v => console.log('valid?', v)}>
<TextField attribute="loginName" label="Email" required />
<TextField attribute="firstName" label="First name" />
<TextField attribute="lastName" label="Last name" />
</PalmyraForm>
<Button onClick={submit}>Submit</Button>
</>
);
}