@formhaus/react 0.3.1 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +85 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -0
- package/package.json +2 -2
package/README.md
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# @formhaus/react
|
|
2
|
+
|
|
3
|
+
React adapter for [Formhaus](https://github.com/ignsm/formhaus). Renders forms from a JSON definition with native HTML inputs by default. Drop in your own components via a `components` prop.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @formhaus/core @formhaus/react
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Requires React ≥18 and Node ≥18.
|
|
12
|
+
|
|
13
|
+
## Generating a definition
|
|
14
|
+
|
|
15
|
+
Write the form JSON by hand, or use the [`/formhaus-create-form`](https://formhaus.dev/guide/formhaus-create-form.html) Claude Code skill to generate it from a text description, a CSV table, or a screenshot of an existing form.
|
|
16
|
+
|
|
17
|
+
## Usage
|
|
18
|
+
|
|
19
|
+
```tsx
|
|
20
|
+
import { FormRenderer } from '@formhaus/react';
|
|
21
|
+
import definition from './contact-form.json';
|
|
22
|
+
|
|
23
|
+
export function ContactPage() {
|
|
24
|
+
async function handleSubmit(values: Record<string, unknown>) {
|
|
25
|
+
await fetch('/api/contact', {
|
|
26
|
+
method: 'POST',
|
|
27
|
+
body: JSON.stringify(values),
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return <FormRenderer definition={definition} onSubmit={handleSubmit} />;
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Custom components
|
|
36
|
+
|
|
37
|
+
Swap native HTML for your own UI kit:
|
|
38
|
+
|
|
39
|
+
```tsx
|
|
40
|
+
import type { FieldComponentMap, FieldComponentProps } from '@formhaus/react';
|
|
41
|
+
|
|
42
|
+
function MyInput({ field, value, error, onChange, onBlur }: FieldComponentProps) {
|
|
43
|
+
return (
|
|
44
|
+
<div>
|
|
45
|
+
<label>{field.label}</label>
|
|
46
|
+
<input
|
|
47
|
+
value={value as string}
|
|
48
|
+
onChange={(e) => onChange(e.target.value)}
|
|
49
|
+
onBlur={onBlur}
|
|
50
|
+
/>
|
|
51
|
+
{error && <span className="error">{error}</span>}
|
|
52
|
+
</div>
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const components: FieldComponentMap = { text: MyInput, email: MyInput };
|
|
57
|
+
|
|
58
|
+
<FormRenderer definition={definition} onSubmit={handleSubmit} components={components} />;
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Unmapped field types fall back to native HTML.
|
|
62
|
+
|
|
63
|
+
## Server-side rendering
|
|
64
|
+
|
|
65
|
+
`FormRenderer` is SSR-safe. It works with Next.js static and dynamic prerender, plus React's `renderToString`, with no `next/dynamic` wrapper required.
|
|
66
|
+
|
|
67
|
+
## Optional baseline styles
|
|
68
|
+
|
|
69
|
+
By default the React adapter renders unstyled HTML. For a sensible starting look (padding, focus states, error colour, button styles) import the shared stylesheet:
|
|
70
|
+
|
|
71
|
+
```ts
|
|
72
|
+
import '@formhaus/core/style.css';
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Theme via CSS custom properties (`--fh-color-primary`, `--fh-radius`, `--fh-gap`, etc.). If you bring your own components via the `components` prop (MUI, Tailwind, shadcn), the stylesheet doesn't apply to those.
|
|
76
|
+
|
|
77
|
+
## Docs
|
|
78
|
+
|
|
79
|
+
- Full guide and API reference: https://formhaus.dev
|
|
80
|
+
- Live playground: https://formhaus.dev/playground.html
|
|
81
|
+
- Source and issues: https://github.com/ignsm/formhaus
|
|
82
|
+
|
|
83
|
+
## License
|
|
84
|
+
|
|
85
|
+
MIT
|
package/dist/index.d.ts
CHANGED
|
@@ -65,4 +65,4 @@ declare function FormStepProgress({ current, total, stepTitle, stepDescription,
|
|
|
65
65
|
|
|
66
66
|
declare function useFormEngine(definition: FormDefinition, initialValues?: Record<string, unknown>, options?: FormEngineOptions): FormEngine;
|
|
67
67
|
|
|
68
|
-
export { type FieldComponentMap, type FieldComponentProps, FormActions, type FormActionsProps, FormRenderer, type FormRendererProps, FormStepProgress, type FormStepProgressProps, useFormEngine };
|
|
68
|
+
export { type FieldComponentMap, type FieldComponentProps, FormActions, type FormActionsProps, FormRenderer, type FormRendererProps, FormStepProgress, type FormStepProgressProps, type OptionsProvider, useFormEngine };
|
package/dist/index.js
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
import {useRef,useSyncExternalStore,useEffect,useState}from'react';import {FormEngine,evaluateCondition}from'@formhaus/core';import {jsxs,jsx}from'react/jsx-runtime';function ke(e,r,t){return t?true:!e?.disabled||e.disabled.length===0?false:e.disabled.every(i=>evaluateCondition(i,r))}function A({submitAction:e,backAction:r,cancelAction:t,isFirstStep:i,isLastStep:a,isMultiStep:s,loading:c,values:p={},onSubmit:l,onNext:n,onPrev:d,onCancel:u,primaryLabel:f,showBack:h,backLabel:y,onPrimary:b}){let o=h??(s&&!i&&r!==false),F=y??(typeof r=="object"?r?.label??"Back":"Back"),$=f??(s&&!a?"Continue":e?.label??"Submit"),O=ke(s&&!a?void 0:e,p,c);function E(){b?b():s&&!a?n():l();}return jsxs("div",{className:"fh-form-actions",children:[jsxs("div",{className:"fh-form-actions__secondary",children:[o&&jsx("button",{type:"button",className:"fh-form-actions__button fh-form-actions__button--text",disabled:c,onClick:d,children:F}),t&&jsx("button",{type:"button",className:"fh-form-actions__button fh-form-actions__button--text",disabled:c,onClick:u,children:t.label})]}),jsx("button",{type:"button",className:"fh-form-actions__button fh-form-actions__button--primary",disabled:O,"aria-busy":c,onClick:E,children:$})]})}function z({field:e,value:r,error:t,loading:i,disabled:a,onChange:s,onBlur:c,onFocus:p}){let l=e.key,n=`${e.key}-helper`,d=`${e.key}-error`,u=t?d:e.helperText?n:void 0;return jsxs("div",{className:"fh-field fh-field--checkbox",children:[jsxs("div",{className:"fh-field__checkbox-wrapper",children:[jsx("input",{id:l,type:"checkbox",className:"fh-field__checkbox",checked:!!r,disabled:a||i,"aria-invalid":!!t,"aria-describedby":u,onChange:f=>s(f.target.checked),onBlur:c,onFocus:p}),e.label&&jsx("label",{className:"fh-field__label",htmlFor:l,children:e.label})]}),t&&jsx("p",{id:d,className:"fh-field__error",role:"alert",children:t}),!t&&e.helperText&&jsx("p",{id:n,className:"fh-field__helper",children:e.helperText})]})}function J({field:e,value:r,error:t,loading:i,disabled:a,onChange:s,onBlur:c,onFocus:p}){let l=e.key,n=`${e.key}-helper`,d=`${e.key}-error`,u=t?d:e.helperText?n:void 0;return jsxs("div",{className:"fh-field",children:[e.label&&jsxs("label",{className:"fh-field__label",htmlFor:l,children:[e.label,e.validation?.required&&jsx("span",{className:"fh-field__required","aria-hidden":"true",children:" *"})]}),jsx("input",{id:l,type:"date",className:"fh-field__input fh-field__input--date",value:String(r??""),disabled:a||i,"aria-invalid":!!t,"aria-describedby":u,onChange:f=>s(f.target.value),onBlur:c,onFocus:p}),t&&jsx("p",{id:d,className:"fh-field__error",role:"alert",children:t}),!t&&e.helperText&&jsx("p",{id:n,className:"fh-field__helper",children:e.helperText})]})}function X({field:e,error:r,loading:t,disabled:i,onChange:a,onBlur:s,onFocus:c}){let p=e.key,l=`${e.key}-helper`,n=`${e.key}-error`,d=r?n:e.helperText?l:void 0;return jsxs("div",{className:"fh-field",children:[e.label&&jsxs("label",{className:"fh-field__label",htmlFor:p,children:[e.label,e.validation?.required&&jsx("span",{className:"fh-field__required","aria-hidden":"true",children:" *"})]}),jsx("input",{id:p,type:"file",className:"fh-field__input fh-field__input--file",accept:e.accept,disabled:i||t,"aria-invalid":!!r,"aria-describedby":d,onChange:u=>{let f=u.target.files;a(f&&f.length>0?f[0]:null);},onBlur:s,onFocus:c}),r&&jsx("p",{id:n,className:"fh-field__error",role:"alert",children:r}),!r&&e.helperText&&jsx("p",{id:l,className:"fh-field__helper",children:e.helperText})]})}function Z({field:e,value:r,error:t,loading:i,disabled:a,onChange:s,onBlur:c,onFocus:p}){let l=e.key,n=`${e.key}-helper`,d=`${e.key}-error`,u=t?d:e.helperText?n:void 0,f=e.options??[],h=Array.isArray(r)?r:[];function y(b){let o=h.includes(b)?h.filter(F=>F!==b):[...h,b];s(o);}return jsxs("fieldset",{className:"fh-field fh-field--multiselect","aria-invalid":!!t||void 0,"aria-describedby":u,children:[e.label&&jsx("legend",{className:"fh-field__label",children:e.label}),jsx("div",{className:"fh-field__multiselect-group",children:f.map(b=>{let o=`${l}-${b.value}`;return jsxs("div",{className:"fh-field__multiselect-option",children:[jsx("input",{id:o,type:"checkbox",className:"fh-field__checkbox",checked:h.includes(b.value),disabled:a||i,onChange:()=>y(b.value),onBlur:c,onFocus:p}),jsx("label",{className:"fh-field__multiselect-label",htmlFor:o,children:b.label})]},b.value)})}),t&&jsx("p",{id:d,className:"fh-field__error",role:"alert",children:t}),!t&&e.helperText&&jsx("p",{id:n,className:"fh-field__helper",children:e.helperText})]})}function ee({field:e,value:r,error:t,loading:i,disabled:a,onChange:s,onBlur:c,onFocus:p}){let l=e.key,n=`${e.key}-helper`,d=`${e.key}-error`,u=t?d:e.helperText?n:void 0,f=e.options??[];return jsxs("fieldset",{className:"fh-field fh-field--radio","aria-invalid":!!t||void 0,"aria-describedby":u,children:[e.label&&jsx("legend",{className:"fh-field__label",children:e.label}),jsx("div",{className:"fh-field__radio-group",children:f.map(h=>{let y=`${l}-${h.value}`;return jsxs("div",{className:"fh-field__radio-option",children:[jsx("input",{id:y,type:"radio",className:"fh-field__radio",name:l,value:h.value,checked:String(r)===String(h.value),disabled:a||i,onChange:()=>s(h.value),onBlur:c,onFocus:p}),jsx("label",{className:"fh-field__radio-label",htmlFor:y,children:h.label})]},h.value)})}),t&&jsx("p",{id:d,className:"fh-field__error",role:"alert",children:t}),!t&&e.helperText&&jsx("p",{id:n,className:"fh-field__helper",children:e.helperText})]})}function te({field:e,value:r,error:t,loading:i,disabled:a,onChange:s,onBlur:c,onFocus:p}){let l=e.key,n=`${e.key}-helper`,d=`${e.key}-error`,u=t?d:e.helperText?n:void 0,f=e.options??[];return jsxs("div",{className:"fh-field",children:[e.label&&jsxs("label",{className:"fh-field__label",htmlFor:l,children:[e.label,e.validation?.required&&jsx("span",{className:"fh-field__required","aria-hidden":"true",children:" *"})]}),jsxs("select",{id:l,className:"fh-field__input fh-field__input--select",value:r??"",disabled:a||i,"aria-invalid":!!t,"aria-describedby":u,onChange:h=>s(h.target.value),onBlur:c,onFocus:p,children:[e.placeholder&&jsx("option",{value:"",disabled:true,children:e.placeholder}),f.map(h=>jsx("option",{value:h.value,children:h.label},h.value))]}),t&&jsx("p",{id:d,className:"fh-field__error",role:"alert",children:t}),!t&&e.helperText&&jsx("p",{id:n,className:"fh-field__helper",children:e.helperText})]})}function re({field:e,value:r,error:t,loading:i,disabled:a,onChange:s,onBlur:c,onFocus:p}){let l=e.key,n=`${e.key}-helper`,d=`${e.key}-error`,u=t?d:e.helperText?n:void 0;return jsxs("div",{className:"fh-field fh-field--switch",children:[jsxs("div",{className:"fh-field__switch-wrapper",children:[jsx("input",{id:l,type:"checkbox",role:"switch",className:"fh-field__switch",checked:!!r,disabled:a||i,"aria-invalid":!!t,"aria-describedby":u,onChange:f=>s(f.target.checked),onBlur:c,onFocus:p}),e.label&&jsx("label",{className:"fh-field__label",htmlFor:l,children:e.label})]}),t&&jsx("p",{id:d,className:"fh-field__error",role:"alert",children:t}),!t&&e.helperText&&jsx("p",{id:n,className:"fh-field__helper",children:e.helperText})]})}function k({field:e,value:r,error:t,loading:i,disabled:a,onChange:s,onBlur:c,onFocus:p}){let l=e.key,n=`${e.key}-helper`,d=`${e.key}-error`,u=t?d:e.helperText?n:void 0,f=y=>{let b=y.target.value;s(e.type==="number"?Number(b):b);},h=e.type==="email"?"email":e.type==="phone"?"tel":e.type==="number"?"number":e.type==="password"?"password":"text";return jsxs("div",{className:"fh-field",children:[e.label&&jsxs("label",{className:"fh-field__label",htmlFor:l,children:[e.label,e.validation?.required&&jsx("span",{className:"fh-field__required","aria-hidden":"true",children:" *"})]}),jsx("input",{id:l,type:h,className:"fh-field__input",value:r!=null?String(r):"",placeholder:e.placeholder??e.mask,disabled:a||i,"aria-invalid":!!t,"aria-describedby":u,onChange:f,onBlur:c,onFocus:p}),t&&jsx("p",{id:d,className:"fh-field__error",role:"alert",children:t}),!t&&e.helperText&&jsx("p",{id:n,className:"fh-field__helper",children:e.helperText})]})}function le({field:e,value:r,error:t,loading:i,disabled:a,onChange:s,onBlur:c,onFocus:p}){let l=e.key,n=`${e.key}-helper`,d=`${e.key}-error`,u=t?d:e.helperText?n:void 0;return jsxs("div",{className:"fh-field",children:[e.label&&jsxs("label",{className:"fh-field__label",htmlFor:l,children:[e.label,e.validation?.required&&jsx("span",{className:"fh-field__required","aria-hidden":"true",children:" *"})]}),jsx("textarea",{id:l,className:"fh-field__input fh-field__input--textarea",value:r??"",placeholder:e.placeholder,rows:e.rows??3,disabled:a||i,"aria-invalid":!!t,"aria-describedby":u,onChange:f=>s(f.target.value),onBlur:c,onFocus:p}),t&&jsx("p",{id:d,className:"fh-field__error",role:"alert",children:t}),!t&&e.helperText&&jsx("p",{id:n,className:"fh-field__helper",children:e.helperText})]})}var Ne={text:k,email:k,phone:k,number:k,password:k,select:te,multiselect:Z,checkbox:z,radio:ee,switch:re,file:X,date:J,textarea:le};function ie({field:e,value:r,error:t,loading:i,disabled:a,components:s,onChange:c,onBlur:p,onFocus:l}){let n=s?.[e.type]??Ne[e.type];return n?jsx(n,{field:e,value:r,error:t,loading:i,disabled:a,onChange:c,onBlur:p,onFocus:l}):jsxs("div",{children:["Unsupported field type: ",e.type]})}function K({current:e,total:r,stepTitle:t,stepDescription:i}){let a=e/r*100;return jsxs("div",{className:"fh-step-progress",children:[jsx("div",{className:"fh-step-progress__bar",children:jsx("div",{className:"fh-step-progress__fill",style:{width:`${a}%`}})}),jsx("div",{className:"fh-step-progress__info",children:jsxs("span",{className:"fh-step-progress__counter",children:["Step ",e," of ",r]})}),t&&jsx("h3",{className:"fh-step-progress__title",children:t}),i&&jsx("p",{className:"fh-step-progress__description",children:i})]})}function pe(e,r,t){let[i,a]=useState({}),s=useRef(new Map);return useEffect(()=>{if(!t)return;let c=false;for(let p of e){if(!p.optionsFrom)continue;let l=t[p.optionsFrom];if(!l)continue;let n=(p.optionsDependsOn??[]).map(u=>r[u]).join("|");if(s.current.get(p.key)===n)continue;s.current.set(p.key,n);let d=l(r);Array.isArray(d)?c||a(u=>({...u,[p.key]:d})):d.then(u=>{c||a(f=>({...f,[p.key]:u}));}).catch(()=>{s.current.delete(p.key);});}return ()=>{c=true;}},[e,r,t]),i}function U(e,r,t){let i=useRef(null),a=useRef(e.id);(i.current===null||a.current!==e.id)&&(i.current=new FormEngine(e,r,t),a.current=e.id);let s=i.current;return useSyncExternalStore(s.subscribe.bind(s),s.getSnapshot.bind(s)),s}function Re({definition:e,initialValues:r,onSubmit:t,onCancel:i,onStepChange:a,onFieldChange:s,validators:c,onStepValidate:p,errors:l,loading:n=false,components:d,optionsProviders:u,ActionsComponent:f,ProgressComponent:h,onAnalyticsEvent:y}){let o=U(e,r,{validators:c,onStepValidate:p}),F=pe(o.visibleFields,o.values,u);useEffect(()=>{l&&o.setErrors(l);},[l,o]);function $(m,_){o.setValue(m,_),s?.(m,_,o.values);}function O(m){y?.({type:"field_focused",fieldKey:m});}function E(m){y?.({type:"field_blurred",fieldKey:m,hasValue:o.values[m]!==void 0&&o.values[m]!==""});}function D(m){m.preventDefault();let _=o.validate();for(let[Fe,ve]of Object.entries(_))y?.({type:"field_error",fieldKey:Fe,error:ve});if(Object.keys(_).length>0)return;let S=o.getSubmitValues();y?.({type:"form_submitted",fieldCount:Object.keys(S).length}),t(S);}async function V(){let m=o.currentStep;await o.nextStepAsync()&&(m&&y?.({type:"step_completed",stepId:m.id}),o.currentStep&&(a?.(o.currentStep.id,"next"),y?.({type:"step_viewed",stepId:o.currentStep.id,stepIndex:o.currentStepIndex})));}function ce(){o.prevStep(),o.currentStep&&a?.(o.currentStep.id,"back");}function me(){i?.();}let ue=h??K,fe=f??A,L=o.isLastStep||!o.isMultiStep,he=o.isMultiStep&&!L?o.currentStep?.next?.label??"Continue":e.submit?.label??"Submit",be=o.isMultiStep&&!o.isFirstStep&&o.currentStep?.back!==false,ye=typeof o.currentStep?.back=="object"?o.currentStep.back.label??"Back":"Back";async function _e(){o.isMultiStep&&!L?await V():D({preventDefault:()=>{}});}return jsxs("form",{className:"fh-form",onSubmit:D,children:[o.isMultiStep&&jsx(ue,{current:o.progress.current,total:o.progress.total,stepTitle:o.currentStep?.title,stepDescription:o.currentStep?.description}),jsx("div",{className:"fh-form__fields",children:o.visibleFields.map(m=>{let _=F[m.key]?{...m,options:F[m.key]}:m;return jsx(ie,{field:_,value:o.values[m.key],error:o.errors[m.key],loading:o.fieldLoading[m.key],disabled:n,components:d,onChange:S=>$(m.key,S),onBlur:()=>E(m.key),onFocus:()=>O(m.key)},m.key)})}),o.topLevelErrors.length>0&&jsx("div",{className:"fh-form__top-errors",children:o.topLevelErrors.map(m=>jsx("p",{className:"fh-form__top-error",children:m},m))}),jsx(fe,{submitAction:e.submit,backAction:o.currentStep?.back,cancelAction:e.cancel,isFirstStep:o.isFirstStep,isLastStep:L,isMultiStep:o.isMultiStep,loading:n||o.stepValidating,values:o.values,onSubmit:()=>D({preventDefault:()=>{}}),onNext:V,onPrev:ce,onCancel:me,primaryLabel:he,showBack:be,backLabel:ye,onPrimary:_e})]})}export{A as FormActions,Re as FormRenderer,K as FormStepProgress,U as useFormEngine};
|
|
1
|
+
import {memo,useCallback,useSyncExternalStore,useState,useRef,useEffect}from'react';import {evaluateCondition,FormEngine}from'@formhaus/core';import {jsx,jsxs}from'react/jsx-runtime';function we(e,r,o){return o?true:!e?.disabled||e.disabled.length===0?false:e.disabled.every(n=>evaluateCondition(n,r))}function A({submitAction:e,backAction:r,cancelAction:o,isFirstStep:n,isLastStep:i,isMultiStep:p,loading:a,values:d={},onSubmit:l,onNext:t,onPrev:s,onCancel:m,primaryLabel:c,showBack:u,backLabel:h,onPrimary:b}){let f=u??(p&&!n&&r!==false),_=h??(typeof r=="object"?r?.label??"Back":"Back"),R=c??(p&&!i?"Continue":e?.label??"Submit"),$=we(p&&!i?void 0:e,d,a);function C(){b?b():p&&!i?t():l();}return jsxs("div",{className:"fh-form-actions",children:[jsxs("div",{className:"fh-form-actions__secondary",children:[f&&jsx("button",{type:"button",className:"fh-form-actions__button fh-form-actions__button--text",disabled:a,onClick:s,children:_}),o&&jsx("button",{type:"button",className:"fh-form-actions__button fh-form-actions__button--text",disabled:a,onClick:m,children:o.label})]}),jsx("button",{type:"button",className:"fh-form-actions__button fh-form-actions__button--primary",disabled:$,"aria-busy":a,onClick:C,children:R})]})}function w(e){let r=useCallback(n=>e.subscribe(n),[e]),o=useCallback(()=>e.getSnapshot(),[e]);useSyncExternalStore(r,o,o);}function E(e){let r=useCallback(n=>e.subscribeStructure(n),[e]),o=useCallback(()=>e.getStructureSnapshot(),[e]);useSyncExternalStore(r,o,o);}function X({engine:e,definition:r,loading:o,ActionsComponent:n,onSubmit:i,onNext:p,onPrev:a,onCancel:d}){w(e);let l=n??A,t=e.isLastStep||!e.isMultiStep,s=e.isMultiStep&&!t?e.currentStep?.next?.label??"Continue":r.submit?.label??"Submit",m=e.isMultiStep&&!e.isFirstStep&&e.currentStep?.back!==false,c=typeof e.currentStep?.back=="object"?e.currentStep.back.label??"Back":"Back",u=useCallback(async()=>{e.isMultiStep&&!t?await p():i();},[e,t,p,i]);return jsx(l,{submitAction:r.submit,backAction:e.currentStep?.back,cancelAction:r.cancel,isFirstStep:e.isFirstStep,isLastStep:t,isMultiStep:e.isMultiStep,loading:o||e.stepValidating,values:e.values,onSubmit:i,onNext:p,onPrev:a,onCancel:d,primaryLabel:s,showBack:m,backLabel:c,onPrimary:u})}function v({field:e,inputId:r}){return e.label?jsxs("label",{className:"fh-field__label",htmlFor:r,children:[e.label,e.validation?.required&&jsx("span",{className:"fh-field__required","aria-hidden":"true",children:" *"})]}):null}function F({error:e,helperText:r,errorId:o,helperId:n}){return e?jsx("p",{id:o,className:"fh-field__error",role:"alert",children:e}):r?jsx("p",{id:n,className:"fh-field__helper",children:r}):null}function Z({field:e,value:r,error:o,loading:n,disabled:i,onChange:p,onBlur:a,onFocus:d}){let l=e.key,t=`${e.key}-list`,s=`${e.key}-helper`,m=`${e.key}-error`,c=o?m:e.helperText?s:void 0,u=e.options??[];return jsxs("div",{className:"fh-field",children:[jsx(v,{field:e,inputId:l}),jsx("input",{id:l,type:"text",list:t,className:"fh-field__input fh-field__input--autocomplete",value:r??"",placeholder:e.placeholder,disabled:i||n,"aria-invalid":!!o,"aria-describedby":c,autoComplete:"off",onChange:h=>p(h.target.value),onBlur:a,onFocus:d}),jsx("datalist",{id:t,children:u.map(h=>jsx("option",{value:h.value,children:h.label},h.value))}),jsx(F,{error:o,helperText:e.helperText,errorId:m,helperId:s})]})}function ee({field:e,value:r,error:o,loading:n,disabled:i,onChange:p,onBlur:a,onFocus:d}){let l=e.key,t=`${e.key}-helper`,s=`${e.key}-error`,m=o?s:e.helperText?t:void 0;return jsxs("div",{className:"fh-field fh-field--checkbox",children:[jsxs("div",{className:"fh-field__checkbox-wrapper",children:[jsx("input",{id:l,type:"checkbox",className:"fh-field__checkbox",checked:!!r,disabled:i||n,"aria-invalid":!!o,"aria-describedby":m,onChange:c=>p(c.target.checked),onBlur:a,onFocus:d}),e.label&&jsx("label",{className:"fh-field__label",htmlFor:l,children:e.label})]}),jsx(F,{error:o,helperText:e.helperText,errorId:s,helperId:t})]})}function oe({field:e,value:r,error:o,loading:n,disabled:i,onChange:p,onBlur:a,onFocus:d}){let l=e.key,t=`${e.key}-helper`,s=`${e.key}-error`,m=o?s:e.helperText?t:void 0;return jsxs("div",{className:"fh-field",children:[jsx(v,{field:e,inputId:l}),jsx("input",{id:l,type:"date",className:"fh-field__input fh-field__input--date",value:String(r??""),disabled:i||n,"aria-invalid":!!o,"aria-describedby":m,onChange:c=>p(c.target.value),onBlur:a,onFocus:d}),jsx(F,{error:o,helperText:e.helperText,errorId:s,helperId:t})]})}function re({field:e,value:r,error:o,loading:n,disabled:i,onChange:p,onBlur:a,onFocus:d}){let l=e.key,t=`${e.key}-helper`,s=`${e.key}-error`,m=o?s:e.helperText?t:void 0;return jsxs("div",{className:"fh-field",children:[jsx(v,{field:e,inputId:l}),jsx("input",{id:l,type:"datetime-local",className:"fh-field__input fh-field__input--datetime",value:String(r??""),disabled:i||n,"aria-invalid":!!o,"aria-describedby":m,onChange:c=>p(c.target.value),onBlur:a,onFocus:d}),jsx(F,{error:o,helperText:e.helperText,errorId:s,helperId:t})]})}function te({field:e,error:r,loading:o,disabled:n,onChange:i,onBlur:p,onFocus:a}){let d=e.key,l=`${e.key}-helper`,t=`${e.key}-error`,s=r?t:e.helperText?l:void 0;return jsxs("div",{className:"fh-field",children:[jsx(v,{field:e,inputId:d}),jsx("input",{id:d,type:"file",className:"fh-field__input fh-field__input--file",accept:e.accept,disabled:n||o,"aria-invalid":!!r,"aria-describedby":s,onChange:m=>{let c=m.target.files;i(c&&c.length>0?c[0]:null);},onBlur:p,onFocus:a}),jsx(F,{error:r,helperText:e.helperText,errorId:t,helperId:l})]})}function se({field:e,value:r,error:o,loading:n,disabled:i,onChange:p,onBlur:a,onFocus:d}){let l=e.key,t=`${e.key}-helper`,s=`${e.key}-error`,m=o?s:e.helperText?t:void 0,c=e.options??[],u=Array.isArray(r)?r:[];function h(b){let f=u.includes(b)?u.filter(_=>_!==b):[...u,b];p(f);}return jsxs("fieldset",{className:"fh-field fh-field--multiselect","aria-invalid":!!o||void 0,"aria-describedby":m,children:[e.label&&jsx("legend",{className:"fh-field__label",children:e.label}),jsx("div",{className:"fh-field__multiselect-group",children:c.map(b=>{let f=`${l}-${b.value}`;return jsxs("div",{className:"fh-field__multiselect-option",children:[jsx("input",{id:f,type:"checkbox",className:"fh-field__checkbox",checked:u.includes(b.value),disabled:i||n,onChange:()=>h(b.value),onBlur:a,onFocus:d}),jsx("label",{className:"fh-field__multiselect-label",htmlFor:f,children:b.label})]},b.value)})}),jsx(F,{error:o,helperText:e.helperText,errorId:s,helperId:t})]})}function le({field:e,value:r,error:o,loading:n,disabled:i,onChange:p,onBlur:a,onFocus:d}){let l=e.key,t=`${e.key}-helper`,s=`${e.key}-error`,m=o?s:e.helperText?t:void 0,c=e.options??[];return jsxs("fieldset",{className:"fh-field fh-field--radio","aria-invalid":!!o||void 0,"aria-describedby":m,children:[e.label&&jsx("legend",{className:"fh-field__label",children:e.label}),jsx("div",{className:"fh-field__radio-group",children:c.map(u=>{let h=`${l}-${u.value}`;return jsxs("div",{className:"fh-field__radio-option",children:[jsx("input",{id:h,type:"radio",className:"fh-field__radio",name:l,value:u.value,checked:String(r)===String(u.value),disabled:i||n,onChange:()=>p(u.value),onBlur:a,onFocus:d}),jsx("label",{className:"fh-field__radio-label",htmlFor:h,children:u.label})]},u.value)})}),jsx(F,{error:o,helperText:e.helperText,errorId:s,helperId:t})]})}function ae({field:e,value:r,error:o,loading:n,disabled:i,onChange:p,onBlur:a,onFocus:d}){let l=e.key,t=`${e.key}-helper`,s=`${e.key}-error`,m=o?s:e.helperText?t:void 0,c=e.options??[];return jsxs("div",{className:"fh-field",children:[jsx(v,{field:e,inputId:l}),jsxs("select",{id:l,className:"fh-field__input fh-field__input--select",value:r??"",disabled:i||n,"aria-invalid":!!o,"aria-describedby":m,onChange:u=>p(u.target.value),onBlur:a,onFocus:d,children:[e.placeholder&&jsx("option",{value:"",disabled:true,children:e.placeholder}),c.map(u=>jsx("option",{value:u.value,children:u.label},u.value))]}),jsx(F,{error:o,helperText:e.helperText,errorId:s,helperId:t})]})}function me({field:e,value:r,error:o,loading:n,disabled:i,onChange:p,onBlur:a,onFocus:d}){let l=e.key,t=`${e.key}-helper`,s=`${e.key}-error`,m=o?s:e.helperText?t:void 0;return jsxs("div",{className:"fh-field fh-field--switch",children:[jsxs("div",{className:"fh-field__switch-wrapper",children:[jsx("input",{id:l,type:"checkbox",role:"switch",className:"fh-field__switch",checked:!!r,disabled:i||n,"aria-invalid":!!o,"aria-describedby":m,onChange:c=>p(c.target.checked),onBlur:a,onFocus:d}),e.label&&jsx("label",{className:"fh-field__label",htmlFor:l,children:e.label})]}),jsx(F,{error:o,helperText:e.helperText,errorId:s,helperId:t})]})}function k({field:e,value:r,error:o,loading:n,disabled:i,onChange:p,onBlur:a,onFocus:d}){let l=e.key,t=`${e.key}-helper`,s=`${e.key}-error`,m=o?s:e.helperText?t:void 0,c=h=>{let b=h.target.value;p(e.type==="number"&&b!==""?Number(b):b);},u=e.type==="email"?"email":e.type==="phone"?"tel":e.type==="number"?"number":e.type==="password"?"password":"text";return jsxs("div",{className:"fh-field",children:[jsx(v,{field:e,inputId:l}),jsx("input",{id:l,type:u,className:"fh-field__input",value:r!=null?String(r):"",placeholder:e.placeholder??e.mask,disabled:i||n,"aria-invalid":!!o,"aria-describedby":m,onChange:c,onBlur:a,onFocus:d}),jsx(F,{error:o,helperText:e.helperText,errorId:s,helperId:t})]})}var Ve=3;function ce({field:e,value:r,error:o,loading:n,disabled:i,onChange:p,onBlur:a,onFocus:d}){let l=e.key,t=`${e.key}-helper`,s=`${e.key}-error`,m=o?s:e.helperText?t:void 0;return jsxs("div",{className:"fh-field",children:[jsx(v,{field:e,inputId:l}),jsx("textarea",{id:l,className:"fh-field__input fh-field__input--textarea",value:r??"",placeholder:e.placeholder,rows:e.rows??Ve,disabled:i||n,"aria-invalid":!!o,"aria-describedby":m,onChange:c=>p(c.target.value),onBlur:a,onFocus:d}),jsx(F,{error:o,helperText:e.helperText,errorId:s,helperId:t})]})}var Ke={text:k,email:k,phone:k,number:k,password:k,select:ae,autocomplete:Z,multiselect:se,checkbox:ee,radio:le,switch:me,file:te,date:oe,datetime:re,textarea:ce};function ue({field:e,value:r,error:o,loading:n,disabled:i,components:p,onChange:a,onBlur:d,onFocus:l}){let t=p?.[e.type]??Ke[e.type];return t?jsx(t,{field:e,value:r,error:o,loading:n,disabled:i,onChange:a,onBlur:d,onFocus:l}):jsxs("div",{children:["Unsupported field type: ",e.type]})}var fe=memo(function({engine:r,field:o,options:n,disabled:i,components:p,onChange:a,onBlur:d,onFocus:l}){let t=useCallback(b=>r.subscribeField(o.key,b),[r,o.key]),s=useCallback(()=>r.getFieldSnapshot(o.key),[r,o.key]);useSyncExternalStore(t,s,s);let m=useCallback(b=>a(o.key,b),[o.key,a]),c=useCallback(()=>d(o.key),[o.key,d]),u=useCallback(()=>l(o.key),[o.key,l]),h=n?{...o,options:n}:o;return jsx(ue,{field:h,value:r.values[o.key],error:r.errors[o.key],loading:r.fieldLoading[o.key],disabled:i,components:p,onChange:m,onBlur:c,onFocus:u})});function Ze(e,r){return e?.length===r.length&&e.every((o,n)=>o.value===r[n].value&&o.label===r[n].label)}function he(e,r,o){let[n,i]=useState({}),p=useRef(new Map);return useEffect(()=>{if(!o){i(t=>Object.keys(t).length>0?{}:t);return}let a=true,d=[],l=(t,s)=>{a&&i(m=>Ze(m[t],s)?m:{...m,[t]:s});};for(let t of e){if(!t.optionsFrom)continue;let s=o[t.optionsFrom];if(!s)continue;let m=()=>{let c=(p.current.get(t.key)??0)+1;p.current.set(t.key,c);try{let u=s(r.values);if(Array.isArray(u)){l(t.key,u);return}u.then(h=>{p.current.get(t.key)===c&&l(t.key,h);}).catch(()=>{});}catch{}};m();for(let c of new Set(t.optionsDependsOn??[]))d.push(r.subscribeField(c,m));}return ()=>{a=false;for(let t of d)t();}},[r,e,o]),n}var be=memo(function({engine:r,loading:o,components:n,optionsProviders:i,onChange:p,onBlur:a,onFocus:d}){E(r);let l=r.visibleFields,t=he(l,r,i);return jsx("div",{className:"fh-form__fields",children:l.map(s=>jsx(fe,{engine:r,field:s,options:t[s.key]??s.options,disabled:o,components:n,onChange:p,onBlur:a,onFocus:d},s.key))})});function z({current:e,total:r,stepTitle:o,stepDescription:n}){let i=e/r*100;return jsxs("div",{className:"fh-step-progress",children:[jsx("div",{className:"fh-step-progress__bar",children:jsx("div",{className:"fh-step-progress__fill",style:{width:`${i}%`}})}),jsx("div",{className:"fh-step-progress__info",children:jsxs("span",{className:"fh-step-progress__counter",children:["Step ",e," of ",r]})}),o&&jsx("h3",{className:"fh-step-progress__title",children:o}),n&&jsx("p",{className:"fh-step-progress__description",children:n})]})}function ve({engine:e,ProgressComponent:r}){return E(e),e.isMultiStep?jsx(r??z,{current:e.progress.current,total:e.progress.total,stepTitle:e.currentStep?.title,stepDescription:e.currentStep?.description}):null}function ke({engine:e}){return w(e),e.topLevelErrors.length===0?null:jsx("div",{className:"fh-form__top-errors",children:e.topLevelErrors.map(r=>jsx("p",{className:"fh-form__top-error",children:r},r))})}function G(e,r,o){let n=useRef(null),i=useRef(e.id);return (n.current===null||i.current!==e.id)&&(n.current=new FormEngine(e,r,o),i.current=e.id),n.current}function to(e,r,o){let n=G(e,r,o),i=useCallback(a=>n.subscribe(a),[n]),p=useCallback(()=>n.getSnapshot(),[n]);return useSyncExternalStore(i,p,p),n}function so({definition:e,initialValues:r,onSubmit:o,onCancel:n,onStepChange:i,onFieldChange:p,validators:a,onStepValidate:d,errors:l,loading:t=false,components:s,optionsProviders:m,ActionsComponent:c,ProgressComponent:u,onAnalyticsEvent:h}){let f=G(e,r,{validators:a,onStepValidate:d});useEffect(()=>{l&&f.setErrors(l);},[l,f]);let _=useCallback((y,P)=>{f.setValue(y,P),p?.(y,P,f.values);},[f,p]),R=useCallback(y=>{h?.({type:"field_focused",fieldKey:y});},[h]),$=useCallback(y=>{h?.({type:"field_blurred",fieldKey:y,hasValue:f.values[y]!==void 0&&f.values[y]!==""});},[f,h]),C=useCallback(()=>{let y=f.validate();for(let[Ne,Te]of Object.entries(y))h?.({type:"field_error",fieldKey:Ne,error:Te});if(Object.keys(y).length>0)return;let P=f.getSubmitValues();h?.({type:"form_submitted",fieldCount:Object.keys(P).length}),o(P);},[f,h,o]),Pe=useCallback(y=>{y.preventDefault(),C();},[C]),Ie=useCallback(async()=>{let y=f.currentStep;await f.nextStepAsync()&&(y&&h?.({type:"step_completed",stepId:y.id}),f.currentStep&&(i?.(f.currentStep.id,"next"),h?.({type:"step_viewed",stepId:f.currentStep.id,stepIndex:f.currentStepIndex})));},[f,h,i]),Se=useCallback(()=>{f.prevStep(),f.currentStep&&i?.(f.currentStep.id,"back");},[f,i]),xe=useCallback(()=>n?.(),[n]);return jsxs("form",{className:"fh-form",onSubmit:Pe,children:[jsx(ve,{engine:f,ProgressComponent:u}),jsx(be,{engine:f,loading:t,components:s,optionsProviders:m,onChange:_,onBlur:$,onFocus:R},e.id),jsx(ke,{engine:f}),jsx(X,{engine:f,definition:e,loading:t,ActionsComponent:c,onSubmit:C,onNext:Ie,onPrev:Se,onCancel:xe})]})}export{A as FormActions,so as FormRenderer,z as FormStepProgress,to as useFormEngine};//# sourceMappingURL=index.js.map
|
|
2
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/FormActions.tsx","../src/hooks/useEngineSnapshot.ts","../src/FormActionsController.tsx","../src/fields/FieldLabel.tsx","../src/fields/FieldMessage.tsx","../src/fields/AutocompleteField.tsx","../src/fields/CheckboxField.tsx","../src/fields/DateField.tsx","../src/fields/DateTimeField.tsx","../src/fields/FileField.tsx","../src/fields/MultiselectField.tsx","../src/fields/RadioField.tsx","../src/fields/SelectField.tsx","../src/fields/SwitchField.tsx","../src/fields/TextField.tsx","../src/fields/TextareaField.tsx","../src/FormField.tsx","../src/FormFieldController.tsx","../src/hooks/useFieldOptions.ts","../src/FormFieldsController.tsx","../src/FormStepProgress.tsx","../src/FormProgressController.tsx","../src/FormTopLevelErrors.tsx","../src/hooks/useFormEngine.ts","../src/FormRenderer.tsx"],"names":["isActionDisabled","action","values","loading","c","evaluateCondition","FormActions","submitAction","backAction","cancelAction","isFirstStep","isLastStep","isMultiStep","onSubmit","onNext","onPrev","onCancel","primaryLabelProp","showBackProp","backLabelProp","onPrimaryProp","showBack","backLabel","primaryLabel","primaryDisabled","handlePrimary","jsxs","jsx","useFormSnapshot","engine","subscribe","useCallback","listener","getSnapshot","useSyncExternalStore","useStructureSnapshot","FormActionsController","definition","ActionsComponent","Actions","FieldLabel","field","inputId","FieldMessage","error","helperText","errorId","helperId","AutocompleteField","value","disabled","onChange","onBlur","onFocus","listId","describedBy","options","e","opt","CheckboxField","DateField","DateTimeField","FileField","files","MultiselectField","groupId","selected","handleToggle","optValue","next","v","optionId","RadioField","SelectField","SwitchField","TextField","handleChange","inputType","DEFAULT_ROWS","TextareaField","defaultComponents","FormField","components","Component","FormFieldController","memo","handleBlur","handleFocus","fieldWithOptions","areOptionsEqual","previous","option","index","useFieldOptions","fields","providers","resolved","setResolved","useState","requestVersions","useRef","useEffect","active","unsubscribers","commit","fieldKey","provider","resolve","requestVersion","result","dependency","unsubscribe","FormFieldsController","optionsProviders","resolvedOptions","FormStepProgress","current","total","stepTitle","stepDescription","percent","FormProgressController","ProgressComponent","FormTopLevelErrors","useFormEngineStore","initialValues","engineRef","definitionIdRef","FormEngine","useFormEngine","FormRenderer","onStepChange","onFieldChange","validators","onStepValidate","externalErrors","onAnalyticsEvent","handleFieldUpdate","key","handleFieldFocus","handleFieldBlur","submit","errors","message","handleSubmit","event","handleNext","previousStep","handlePrev","handleCancel"],"mappings":"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","file":"index.js","sourcesContent":["import { evaluateCondition } from '@formhaus/core';\nimport type { FormAction } from '@formhaus/core';\nimport type { FormActionsProps } from './types';\n\nfunction isActionDisabled(\n action: FormAction | undefined,\n values: Record<string, unknown>,\n loading?: boolean,\n): boolean {\n if (loading) return true;\n if (!action?.disabled || action.disabled.length === 0) return false;\n return action.disabled.every((c) => evaluateCondition(c, values));\n}\n\nexport function FormActions({\n submitAction,\n backAction,\n cancelAction,\n isFirstStep,\n isLastStep,\n isMultiStep,\n loading,\n values = {},\n onSubmit,\n onNext,\n onPrev,\n onCancel,\n primaryLabel: primaryLabelProp,\n showBack: showBackProp,\n backLabel: backLabelProp,\n onPrimary: onPrimaryProp,\n}: FormActionsProps) {\n const showBack = showBackProp ?? (isMultiStep && !isFirstStep && backAction !== false);\n const backLabel = backLabelProp ?? (typeof backAction === 'object' ? (backAction?.label ?? 'Back') : 'Back');\n const primaryLabel = primaryLabelProp ?? (isMultiStep && !isLastStep ? 'Continue' : (submitAction?.label ?? 'Submit'));\n\n const primaryDisabled = isActionDisabled(\n isMultiStep && !isLastStep ? undefined : submitAction,\n values,\n loading,\n );\n\n function handlePrimary() {\n if (onPrimaryProp) {\n onPrimaryProp();\n } else if (isMultiStep && !isLastStep) {\n onNext();\n } else {\n onSubmit();\n }\n }\n\n return (\n <div className=\"fh-form-actions\">\n <div className=\"fh-form-actions__secondary\">\n {showBack && (\n <button\n type=\"button\"\n className=\"fh-form-actions__button fh-form-actions__button--text\"\n disabled={loading}\n onClick={onPrev}\n >\n {backLabel}\n </button>\n )}\n {cancelAction && (\n <button\n type=\"button\"\n className=\"fh-form-actions__button fh-form-actions__button--text\"\n disabled={loading}\n onClick={onCancel}\n >\n {cancelAction.label}\n </button>\n )}\n </div>\n <button\n type=\"button\"\n className=\"fh-form-actions__button fh-form-actions__button--primary\"\n disabled={primaryDisabled}\n aria-busy={loading}\n onClick={handlePrimary}\n >\n {primaryLabel}\n </button>\n </div>\n );\n}\n","import type { FormEngine } from '@formhaus/core';\nimport { useCallback, useSyncExternalStore } from 'react';\n\nexport function useFormSnapshot(engine: FormEngine): void {\n const subscribe = useCallback((listener: () => void) => engine.subscribe(listener), [engine]);\n const getSnapshot = useCallback(() => engine.getSnapshot(), [engine]);\n useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n}\n\nexport function useStructureSnapshot(engine: FormEngine): void {\n const subscribe = useCallback(\n (listener: () => void) => engine.subscribeStructure(listener),\n [engine],\n );\n const getSnapshot = useCallback(() => engine.getStructureSnapshot(), [engine]);\n useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n}\n","import type { FormEngine } from '@formhaus/core';\nimport { useCallback } from 'react';\nimport { FormActions } from './FormActions';\nimport { useFormSnapshot } from './hooks/useEngineSnapshot';\nimport type { FormRendererProps } from './types';\n\ninterface FormActionsControllerProps {\n engine: FormEngine;\n definition: FormRendererProps['definition'];\n loading: boolean;\n ActionsComponent: FormRendererProps['ActionsComponent'];\n onSubmit: () => void;\n onNext: () => Promise<void>;\n onPrev: () => void;\n onCancel: () => void;\n}\n\nexport function FormActionsController({\n engine,\n definition,\n loading,\n ActionsComponent,\n onSubmit,\n onNext,\n onPrev,\n onCancel,\n}: FormActionsControllerProps) {\n useFormSnapshot(engine);\n const Actions = ActionsComponent ?? FormActions;\n const isLastStep = engine.isLastStep || !engine.isMultiStep;\n const primaryLabel = engine.isMultiStep && !isLastStep\n ? (engine.currentStep?.next?.label ?? 'Continue')\n : (definition.submit?.label ?? 'Submit');\n const showBack = engine.isMultiStep && !engine.isFirstStep && engine.currentStep?.back !== false;\n const backLabel = typeof engine.currentStep?.back === 'object'\n ? (engine.currentStep.back.label ?? 'Back')\n : 'Back';\n const handlePrimary = useCallback(async () => {\n if (engine.isMultiStep && !isLastStep) await onNext();\n else onSubmit();\n }, [engine, isLastStep, onNext, onSubmit]);\n\n return (\n <Actions\n submitAction={definition.submit}\n backAction={engine.currentStep?.back}\n cancelAction={definition.cancel}\n isFirstStep={engine.isFirstStep}\n isLastStep={isLastStep}\n isMultiStep={engine.isMultiStep}\n loading={loading || engine.stepValidating}\n values={engine.values}\n onSubmit={onSubmit}\n onNext={onNext}\n onPrev={onPrev}\n onCancel={onCancel}\n primaryLabel={primaryLabel}\n showBack={showBack}\n backLabel={backLabel}\n onPrimary={handlePrimary}\n />\n );\n}\n","import type { FormField } from '@formhaus/core';\n\ninterface FieldLabelProps {\n field: FormField;\n inputId: string;\n}\n\nexport function FieldLabel({ field, inputId }: FieldLabelProps) {\n if (!field.label) return null;\n return (\n <label className=\"fh-field__label\" htmlFor={inputId}>\n {field.label}\n {field.validation?.required && (\n <span className=\"fh-field__required\" aria-hidden=\"true\"> *</span>\n )}\n </label>\n );\n}\n","interface FieldMessageProps {\n error?: string;\n helperText?: string;\n errorId: string;\n helperId: string;\n}\n\nexport function FieldMessage({ error, helperText, errorId, helperId }: FieldMessageProps) {\n if (error) {\n return <p id={errorId} className=\"fh-field__error\" role=\"alert\">{error}</p>;\n }\n if (helperText) {\n return <p id={helperId} className=\"fh-field__helper\">{helperText}</p>;\n }\n return null;\n}\n","import type { FieldComponentProps } from '../types';\nimport { FieldLabel } from './FieldLabel';\nimport { FieldMessage } from './FieldMessage';\n\nexport function AutocompleteField({\n field,\n value,\n error,\n loading,\n disabled,\n onChange,\n onBlur,\n onFocus,\n}: FieldComponentProps) {\n const inputId = field.key;\n const listId = `${field.key}-list`;\n const helperId = `${field.key}-helper`;\n const errorId = `${field.key}-error`;\n const describedBy = error ? errorId : field.helperText ? helperId : undefined;\n const options = field.options ?? [];\n\n return (\n <div className=\"fh-field\">\n <FieldLabel field={field} inputId={inputId} />\n <input\n id={inputId}\n type=\"text\"\n list={listId}\n className=\"fh-field__input fh-field__input--autocomplete\"\n value={(value as string) ?? ''}\n placeholder={field.placeholder}\n disabled={disabled || loading}\n aria-invalid={!!error}\n aria-describedby={describedBy}\n autoComplete=\"off\"\n onChange={(e) => onChange(e.target.value)}\n onBlur={onBlur}\n onFocus={onFocus}\n />\n <datalist id={listId}>\n {options.map((opt) => (\n <option key={opt.value} value={opt.value}>\n {opt.label}\n </option>\n ))}\n </datalist>\n <FieldMessage error={error} helperText={field.helperText} errorId={errorId} helperId={helperId} />\n </div>\n );\n}\n","import type { FieldComponentProps } from '../types';\nimport { FieldMessage } from './FieldMessage';\n\nexport function CheckboxField({\n field,\n value,\n error,\n loading,\n disabled,\n onChange,\n onBlur,\n onFocus,\n}: FieldComponentProps) {\n const inputId = field.key;\n const helperId = `${field.key}-helper`;\n const errorId = `${field.key}-error`;\n const describedBy = error ? errorId : field.helperText ? helperId : undefined;\n\n return (\n <div className=\"fh-field fh-field--checkbox\">\n <div className=\"fh-field__checkbox-wrapper\">\n <input\n id={inputId}\n type=\"checkbox\"\n className=\"fh-field__checkbox\"\n checked={!!value}\n disabled={disabled || loading}\n aria-invalid={!!error}\n aria-describedby={describedBy}\n onChange={(e) => onChange(e.target.checked)}\n onBlur={onBlur}\n onFocus={onFocus}\n />\n {field.label && (\n <label className=\"fh-field__label\" htmlFor={inputId}>\n {field.label}\n </label>\n )}\n </div>\n <FieldMessage error={error} helperText={field.helperText} errorId={errorId} helperId={helperId} />\n </div>\n );\n}\n","import type { FieldComponentProps } from '../types';\nimport { FieldLabel } from './FieldLabel';\nimport { FieldMessage } from './FieldMessage';\n\nexport function DateField({\n field,\n value,\n error,\n loading,\n disabled,\n onChange,\n onBlur,\n onFocus,\n}: FieldComponentProps) {\n const inputId = field.key;\n const helperId = `${field.key}-helper`;\n const errorId = `${field.key}-error`;\n const describedBy = error ? errorId : field.helperText ? helperId : undefined;\n\n return (\n <div className=\"fh-field\">\n <FieldLabel field={field} inputId={inputId} />\n <input\n id={inputId}\n type=\"date\"\n className=\"fh-field__input fh-field__input--date\"\n value={String(value ?? '')}\n disabled={disabled || loading}\n aria-invalid={!!error}\n aria-describedby={describedBy}\n onChange={(e) => onChange(e.target.value)}\n onBlur={onBlur}\n onFocus={onFocus}\n />\n <FieldMessage error={error} helperText={field.helperText} errorId={errorId} helperId={helperId} />\n </div>\n );\n}\n","import type { FieldComponentProps } from '../types';\nimport { FieldLabel } from './FieldLabel';\nimport { FieldMessage } from './FieldMessage';\n\nexport function DateTimeField({\n field,\n value,\n error,\n loading,\n disabled,\n onChange,\n onBlur,\n onFocus,\n}: FieldComponentProps) {\n const inputId = field.key;\n const helperId = `${field.key}-helper`;\n const errorId = `${field.key}-error`;\n const describedBy = error ? errorId : field.helperText ? helperId : undefined;\n\n return (\n <div className=\"fh-field\">\n <FieldLabel field={field} inputId={inputId} />\n <input\n id={inputId}\n type=\"datetime-local\"\n className=\"fh-field__input fh-field__input--datetime\"\n value={String(value ?? '')}\n disabled={disabled || loading}\n aria-invalid={!!error}\n aria-describedby={describedBy}\n onChange={(e) => onChange(e.target.value)}\n onBlur={onBlur}\n onFocus={onFocus}\n />\n <FieldMessage error={error} helperText={field.helperText} errorId={errorId} helperId={helperId} />\n </div>\n );\n}\n","import type { FieldComponentProps } from '../types';\nimport { FieldLabel } from './FieldLabel';\nimport { FieldMessage } from './FieldMessage';\n\nexport function FileField({\n field,\n error,\n loading,\n disabled,\n onChange,\n onBlur,\n onFocus,\n}: FieldComponentProps) {\n const inputId = field.key;\n const helperId = `${field.key}-helper`;\n const errorId = `${field.key}-error`;\n const describedBy = error ? errorId : field.helperText ? helperId : undefined;\n\n return (\n <div className=\"fh-field\">\n <FieldLabel field={field} inputId={inputId} />\n <input\n id={inputId}\n type=\"file\"\n className=\"fh-field__input fh-field__input--file\"\n accept={field.accept}\n disabled={disabled || loading}\n aria-invalid={!!error}\n aria-describedby={describedBy}\n onChange={(e) => {\n const files = e.target.files;\n onChange(files && files.length > 0 ? files[0] : null);\n }}\n onBlur={onBlur}\n onFocus={onFocus}\n />\n <FieldMessage error={error} helperText={field.helperText} errorId={errorId} helperId={helperId} />\n </div>\n );\n}\n","import type { FieldComponentProps } from '../types';\nimport { FieldMessage } from './FieldMessage';\n\nexport function MultiselectField({\n field,\n value,\n error,\n loading,\n disabled,\n onChange,\n onBlur,\n onFocus,\n}: FieldComponentProps) {\n const groupId = field.key;\n const helperId = `${field.key}-helper`;\n const errorId = `${field.key}-error`;\n const describedBy = error ? errorId : field.helperText ? helperId : undefined;\n const options = field.options ?? [];\n const selected = Array.isArray(value) ? (value as (string | number)[]) : [];\n\n function handleToggle(optValue: string) {\n const next = selected.includes(optValue)\n ? selected.filter((v) => v !== optValue)\n : [...selected, optValue];\n onChange(next);\n }\n\n return (\n <fieldset\n className=\"fh-field fh-field--multiselect\"\n aria-invalid={!!error || undefined}\n aria-describedby={describedBy}\n >\n {field.label && <legend className=\"fh-field__label\">{field.label}</legend>}\n <div className=\"fh-field__multiselect-group\">\n {options.map((opt) => {\n const optionId = `${groupId}-${opt.value}`;\n return (\n <div key={opt.value} className=\"fh-field__multiselect-option\">\n <input\n id={optionId}\n type=\"checkbox\"\n className=\"fh-field__checkbox\"\n checked={selected.includes(opt.value)}\n disabled={disabled || loading}\n onChange={() => handleToggle(opt.value)}\n onBlur={onBlur}\n onFocus={onFocus}\n />\n <label className=\"fh-field__multiselect-label\" htmlFor={optionId}>\n {opt.label}\n </label>\n </div>\n );\n })}\n </div>\n <FieldMessage error={error} helperText={field.helperText} errorId={errorId} helperId={helperId} />\n </fieldset>\n );\n}\n","import type { FieldComponentProps } from '../types';\nimport { FieldMessage } from './FieldMessage';\n\nexport function RadioField({\n field,\n value,\n error,\n loading,\n disabled,\n onChange,\n onBlur,\n onFocus,\n}: FieldComponentProps) {\n const groupId = field.key;\n const helperId = `${field.key}-helper`;\n const errorId = `${field.key}-error`;\n const describedBy = error ? errorId : field.helperText ? helperId : undefined;\n const options = field.options ?? [];\n\n return (\n <fieldset\n className=\"fh-field fh-field--radio\"\n aria-invalid={!!error || undefined}\n aria-describedby={describedBy}\n >\n {field.label && <legend className=\"fh-field__label\">{field.label}</legend>}\n <div className=\"fh-field__radio-group\">\n {options.map((opt) => {\n const optionId = `${groupId}-${opt.value}`;\n return (\n <div key={opt.value} className=\"fh-field__radio-option\">\n <input\n id={optionId}\n type=\"radio\"\n className=\"fh-field__radio\"\n name={groupId}\n value={opt.value}\n checked={String(value) === String(opt.value)}\n disabled={disabled || loading}\n onChange={() => onChange(opt.value)}\n onBlur={onBlur}\n onFocus={onFocus}\n />\n <label className=\"fh-field__radio-label\" htmlFor={optionId}>\n {opt.label}\n </label>\n </div>\n );\n })}\n </div>\n <FieldMessage error={error} helperText={field.helperText} errorId={errorId} helperId={helperId} />\n </fieldset>\n );\n}\n","import type { FieldComponentProps } from '../types';\nimport { FieldLabel } from './FieldLabel';\nimport { FieldMessage } from './FieldMessage';\n\nexport function SelectField({\n field,\n value,\n error,\n loading,\n disabled,\n onChange,\n onBlur,\n onFocus,\n}: FieldComponentProps) {\n const inputId = field.key;\n const helperId = `${field.key}-helper`;\n const errorId = `${field.key}-error`;\n const describedBy = error ? errorId : field.helperText ? helperId : undefined;\n const options = field.options ?? [];\n\n return (\n <div className=\"fh-field\">\n <FieldLabel field={field} inputId={inputId} />\n <select\n id={inputId}\n className=\"fh-field__input fh-field__input--select\"\n value={(value as string) ?? ''}\n disabled={disabled || loading}\n aria-invalid={!!error}\n aria-describedby={describedBy}\n onChange={(e) => onChange(e.target.value)}\n onBlur={onBlur}\n onFocus={onFocus}\n >\n {field.placeholder && (\n <option value=\"\" disabled>\n {field.placeholder}\n </option>\n )}\n {options.map((opt) => (\n <option key={opt.value} value={opt.value}>\n {opt.label}\n </option>\n ))}\n </select>\n <FieldMessage error={error} helperText={field.helperText} errorId={errorId} helperId={helperId} />\n </div>\n );\n}\n","import type { FieldComponentProps } from '../types';\nimport { FieldMessage } from './FieldMessage';\n\nexport function SwitchField({\n field,\n value,\n error,\n loading,\n disabled,\n onChange,\n onBlur,\n onFocus,\n}: FieldComponentProps) {\n const inputId = field.key;\n const helperId = `${field.key}-helper`;\n const errorId = `${field.key}-error`;\n const describedBy = error ? errorId : field.helperText ? helperId : undefined;\n\n return (\n <div className=\"fh-field fh-field--switch\">\n <div className=\"fh-field__switch-wrapper\">\n <input\n id={inputId}\n type=\"checkbox\"\n role=\"switch\"\n className=\"fh-field__switch\"\n checked={!!value}\n disabled={disabled || loading}\n aria-invalid={!!error}\n aria-describedby={describedBy}\n onChange={(e) => onChange(e.target.checked)}\n onBlur={onBlur}\n onFocus={onFocus}\n />\n {field.label && (\n <label className=\"fh-field__label\" htmlFor={inputId}>\n {field.label}\n </label>\n )}\n </div>\n <FieldMessage error={error} helperText={field.helperText} errorId={errorId} helperId={helperId} />\n </div>\n );\n}\n","import type { FieldComponentProps } from '../types';\nimport { FieldLabel } from './FieldLabel';\nimport { FieldMessage } from './FieldMessage';\n\nexport function TextField({\n field,\n value,\n error,\n loading,\n disabled,\n onChange,\n onBlur,\n onFocus,\n}: FieldComponentProps) {\n const inputId = field.key;\n const helperId = `${field.key}-helper`;\n const errorId = `${field.key}-error`;\n const describedBy = error ? errorId : field.helperText ? helperId : undefined;\n\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const v = e.target.value;\n onChange(field.type === 'number' && v !== '' ? Number(v) : v);\n };\n\n const inputType =\n field.type === 'email'\n ? 'email'\n : field.type === 'phone'\n ? 'tel'\n : field.type === 'number'\n ? 'number'\n : field.type === 'password'\n ? 'password'\n : 'text';\n\n return (\n <div className=\"fh-field\">\n <FieldLabel field={field} inputId={inputId} />\n <input\n id={inputId}\n type={inputType}\n className=\"fh-field__input\"\n value={value != null ? String(value) : ''}\n placeholder={field.placeholder ?? field.mask}\n disabled={disabled || loading}\n aria-invalid={!!error}\n aria-describedby={describedBy}\n onChange={handleChange}\n onBlur={onBlur}\n onFocus={onFocus}\n />\n <FieldMessage error={error} helperText={field.helperText} errorId={errorId} helperId={helperId} />\n </div>\n );\n}\n","import type { FieldComponentProps } from '../types';\nimport { FieldLabel } from './FieldLabel';\nimport { FieldMessage } from './FieldMessage';\n\nconst DEFAULT_ROWS = 3;\n\nexport function TextareaField({\n field,\n value,\n error,\n loading,\n disabled,\n onChange,\n onBlur,\n onFocus,\n}: FieldComponentProps) {\n const inputId = field.key;\n const helperId = `${field.key}-helper`;\n const errorId = `${field.key}-error`;\n const describedBy = error ? errorId : field.helperText ? helperId : undefined;\n\n return (\n <div className=\"fh-field\">\n <FieldLabel field={field} inputId={inputId} />\n <textarea\n id={inputId}\n className=\"fh-field__input fh-field__input--textarea\"\n value={(value as string) ?? ''}\n placeholder={field.placeholder}\n rows={field.rows ?? DEFAULT_ROWS}\n disabled={disabled || loading}\n aria-invalid={!!error}\n aria-describedby={describedBy}\n onChange={(e) => onChange(e.target.value)}\n onBlur={onBlur}\n onFocus={onFocus}\n />\n <FieldMessage error={error} helperText={field.helperText} errorId={errorId} helperId={helperId} />\n </div>\n );\n}\n","import type { DefaultFieldType, FormField as FormFieldType } from '@formhaus/core';\nimport type { ComponentType } from 'react';\nimport { AutocompleteField } from './fields/AutocompleteField';\nimport { CheckboxField } from './fields/CheckboxField';\nimport { DateField } from './fields/DateField';\nimport { DateTimeField } from './fields/DateTimeField';\nimport { FileField } from './fields/FileField';\nimport { MultiselectField } from './fields/MultiselectField';\nimport { RadioField } from './fields/RadioField';\nimport { SelectField } from './fields/SelectField';\nimport { SwitchField } from './fields/SwitchField';\nimport { TextField } from './fields/TextField';\nimport { TextareaField } from './fields/TextareaField';\nimport type { FieldComponentMap, FieldComponentProps } from './types';\n\nconst defaultComponents: Record<DefaultFieldType, ComponentType<FieldComponentProps>> = {\n text: TextField,\n email: TextField,\n phone: TextField,\n number: TextField,\n password: TextField,\n select: SelectField,\n autocomplete: AutocompleteField,\n multiselect: MultiselectField,\n checkbox: CheckboxField,\n radio: RadioField,\n switch: SwitchField,\n file: FileField,\n date: DateField,\n datetime: DateTimeField,\n textarea: TextareaField,\n};\n\ninterface FormFieldProps {\n field: FormFieldType;\n value: unknown;\n error?: string;\n loading?: boolean;\n disabled?: boolean;\n components?: FieldComponentMap;\n onChange: (value: unknown) => void;\n onBlur: () => void;\n onFocus?: () => void;\n}\n\nexport function FormField({\n field,\n value,\n error,\n loading,\n disabled,\n components,\n onChange,\n onBlur,\n onFocus,\n}: FormFieldProps) {\n const Component = components?.[field.type] ?? (defaultComponents as Record<string, ComponentType<FieldComponentProps>>)[field.type];\n\n if (!Component) {\n return <div>Unsupported field type: {field.type}</div>;\n }\n\n return (\n <Component\n field={field}\n value={value}\n error={error}\n loading={loading}\n disabled={disabled}\n onChange={onChange}\n onBlur={onBlur}\n onFocus={onFocus}\n />\n );\n}\n","import type { FieldOption, FormEngine, FormField as FormFieldType } from '@formhaus/core';\nimport { memo, useCallback, useSyncExternalStore } from 'react';\nimport { FormField } from './FormField';\nimport type { FieldComponentMap } from './types';\n\ninterface FormFieldControllerProps {\n engine: FormEngine;\n field: FormFieldType;\n options?: FieldOption[];\n disabled?: boolean;\n components?: FieldComponentMap;\n onChange: (key: string, value: unknown) => void;\n onBlur: (key: string) => void;\n onFocus: (key: string) => void;\n}\n\nexport const FormFieldController = memo(function FormFieldController({\n engine,\n field,\n options,\n disabled,\n components,\n onChange,\n onBlur,\n onFocus,\n}: FormFieldControllerProps) {\n const subscribe = useCallback(\n (listener: () => void) => engine.subscribeField(field.key, listener),\n [engine, field.key],\n );\n const getSnapshot = useCallback(\n () => engine.getFieldSnapshot(field.key),\n [engine, field.key],\n );\n\n useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n\n const handleChange = useCallback(\n (value: unknown) => onChange(field.key, value),\n [field.key, onChange],\n );\n const handleBlur = useCallback(() => onBlur(field.key), [field.key, onBlur]);\n const handleFocus = useCallback(() => onFocus(field.key), [field.key, onFocus]);\n const fieldWithOptions = options ? { ...field, options } : field;\n\n return (\n <FormField\n field={fieldWithOptions}\n value={engine.values[field.key]}\n error={engine.errors[field.key]}\n loading={engine.fieldLoading[field.key]}\n disabled={disabled}\n components={components}\n onChange={handleChange}\n onBlur={handleBlur}\n onFocus={handleFocus}\n />\n );\n});\n","import type { FieldOption, FormEngine, FormField } from '@formhaus/core';\nimport { useEffect, useRef, useState } from 'react';\nimport type { OptionsProvider } from '../types';\n\nfunction areOptionsEqual(previous: FieldOption[] | undefined, next: FieldOption[]): boolean {\n return previous?.length === next.length && previous.every((option, index) => (\n option.value === next[index].value && option.label === next[index].label\n ));\n}\n\nexport function useFieldOptions(\n fields: FormField[],\n engine: FormEngine,\n providers?: Record<string, OptionsProvider>,\n): Record<string, FieldOption[]> {\n const [resolved, setResolved] = useState<Record<string, FieldOption[]>>({});\n const requestVersions = useRef<Map<string, number>>(new Map());\n\n useEffect(() => {\n if (!providers) {\n setResolved((previous) => (\n Object.keys(previous).length > 0 ? {} : previous\n ));\n return;\n }\n\n let active = true;\n const unsubscribers: (() => void)[] = [];\n\n const commit = (fieldKey: string, options: FieldOption[]) => {\n if (!active) return;\n setResolved((previous) => {\n if (areOptionsEqual(previous[fieldKey], options)) return previous;\n return { ...previous, [fieldKey]: options };\n });\n };\n\n for (const field of fields) {\n if (!field.optionsFrom) continue;\n\n const provider = providers[field.optionsFrom];\n if (!provider) continue;\n\n const resolve = () => {\n const requestVersion = (requestVersions.current.get(field.key) ?? 0) + 1;\n requestVersions.current.set(field.key, requestVersion);\n\n try {\n const result = provider(engine.values);\n if (Array.isArray(result)) {\n commit(field.key, result);\n return;\n }\n\n result\n .then((options) => {\n if (requestVersions.current.get(field.key) === requestVersion) {\n commit(field.key, options);\n }\n })\n .catch(() => {});\n } catch {\n // Retry when a dependency changes.\n }\n };\n\n resolve();\n for (const dependency of new Set(field.optionsDependsOn ?? [])) {\n unsubscribers.push(engine.subscribeField(dependency, resolve));\n }\n }\n\n return () => {\n active = false;\n for (const unsubscribe of unsubscribers) unsubscribe();\n };\n }, [engine, fields, providers]);\n\n return resolved;\n}\n","import type { FormEngine } from '@formhaus/core';\nimport { memo } from 'react';\nimport { FormFieldController } from './FormFieldController';\nimport { useStructureSnapshot } from './hooks/useEngineSnapshot';\nimport { useFieldOptions } from './hooks/useFieldOptions';\nimport type { FieldComponentMap, OptionsProvider } from './types';\n\ninterface FormFieldsControllerProps {\n engine: FormEngine;\n loading: boolean;\n components?: FieldComponentMap;\n optionsProviders?: Record<string, OptionsProvider>;\n onChange: (key: string, value: unknown) => void;\n onBlur: (key: string) => void;\n onFocus: (key: string) => void;\n}\n\nexport const FormFieldsController = memo(function FormFieldsController({\n engine,\n loading,\n components,\n optionsProviders,\n onChange,\n onBlur,\n onFocus,\n}: FormFieldsControllerProps) {\n useStructureSnapshot(engine);\n const fields = engine.visibleFields;\n const resolvedOptions = useFieldOptions(fields, engine, optionsProviders);\n\n return (\n <div className=\"fh-form__fields\">\n {fields.map((field) => (\n <FormFieldController\n key={field.key}\n engine={engine}\n field={field}\n options={resolvedOptions[field.key] ?? field.options}\n disabled={loading}\n components={components}\n onChange={onChange}\n onBlur={onBlur}\n onFocus={onFocus}\n />\n ))}\n </div>\n );\n});\n","import type { FormStepProgressProps } from './types';\n\nexport function FormStepProgress({\n current,\n total,\n stepTitle,\n stepDescription,\n}: FormStepProgressProps) {\n const percent = (current / total) * 100;\n\n return (\n <div className=\"fh-step-progress\">\n <div className=\"fh-step-progress__bar\">\n <div className=\"fh-step-progress__fill\" style={{ width: `${percent}%` }} />\n </div>\n <div className=\"fh-step-progress__info\">\n <span className=\"fh-step-progress__counter\">\n Step {current} of {total}\n </span>\n </div>\n {stepTitle && <h3 className=\"fh-step-progress__title\">{stepTitle}</h3>}\n {stepDescription && <p className=\"fh-step-progress__description\">{stepDescription}</p>}\n </div>\n );\n}\n","import type { FormEngine } from '@formhaus/core';\nimport { FormStepProgress } from './FormStepProgress';\nimport { useStructureSnapshot } from './hooks/useEngineSnapshot';\nimport type { FormRendererProps } from './types';\n\ninterface FormProgressControllerProps {\n engine: FormEngine;\n ProgressComponent: FormRendererProps['ProgressComponent'];\n}\n\nexport function FormProgressController({\n engine,\n ProgressComponent,\n}: FormProgressControllerProps) {\n useStructureSnapshot(engine);\n if (!engine.isMultiStep) return null;\n\n const Progress = ProgressComponent ?? FormStepProgress;\n return (\n <Progress\n current={engine.progress.current}\n total={engine.progress.total}\n stepTitle={engine.currentStep?.title}\n stepDescription={engine.currentStep?.description}\n />\n );\n}\n","import type { FormEngine } from '@formhaus/core';\nimport { useFormSnapshot } from './hooks/useEngineSnapshot';\n\nexport function FormTopLevelErrors({ engine }: { engine: FormEngine }) {\n useFormSnapshot(engine);\n if (engine.topLevelErrors.length === 0) return null;\n\n return (\n <div className=\"fh-form__top-errors\">\n {engine.topLevelErrors.map((error) => (\n <p key={error} className=\"fh-form__top-error\">\n {error}\n </p>\n ))}\n </div>\n );\n}\n","import { FormEngine, type FormEngineOptions, type FormDefinition } from '@formhaus/core';\nimport { useCallback, useRef, useSyncExternalStore } from 'react';\n\nexport function useFormEngineStore(\n definition: FormDefinition,\n initialValues?: Record<string, unknown>,\n options?: FormEngineOptions,\n): FormEngine {\n const engineRef = useRef<FormEngine | null>(null);\n const definitionIdRef = useRef<string>(definition.id);\n\n if (engineRef.current === null || definitionIdRef.current !== definition.id) {\n engineRef.current = new FormEngine(definition, initialValues, options);\n definitionIdRef.current = definition.id;\n }\n\n return engineRef.current;\n}\n\nexport function useFormEngine(\n definition: FormDefinition,\n initialValues?: Record<string, unknown>,\n options?: FormEngineOptions,\n): FormEngine {\n const engine = useFormEngineStore(definition, initialValues, options);\n\n const subscribe = useCallback((listener: () => void) => engine.subscribe(listener), [engine]);\n const getSnapshot = useCallback(() => engine.getSnapshot(), [engine]);\n\n useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n\n return engine;\n}\n","import type { FormEngineOptions } from '@formhaus/core';\nimport { useCallback, useEffect } from 'react';\nimport { FormActionsController } from './FormActionsController';\nimport { FormFieldsController } from './FormFieldsController';\nimport { FormProgressController } from './FormProgressController';\nimport { FormTopLevelErrors } from './FormTopLevelErrors';\nimport { useFormEngineStore } from './hooks/useFormEngine';\nimport type { FormRendererProps } from './types';\n\nexport function FormRenderer({\n definition,\n initialValues,\n onSubmit,\n onCancel,\n onStepChange,\n onFieldChange,\n validators,\n onStepValidate,\n errors: externalErrors,\n loading = false,\n components,\n optionsProviders,\n ActionsComponent,\n ProgressComponent,\n onAnalyticsEvent,\n}: FormRendererProps) {\n const engineOptions: FormEngineOptions = { validators, onStepValidate };\n const engine = useFormEngineStore(definition, initialValues, engineOptions);\n\n useEffect(() => {\n if (externalErrors) engine.setErrors(externalErrors);\n }, [externalErrors, engine]);\n\n const handleFieldUpdate = useCallback((key: string, value: unknown) => {\n engine.setValue(key, value);\n onFieldChange?.(key, value, engine.values);\n }, [engine, onFieldChange]);\n\n const handleFieldFocus = useCallback((key: string) => {\n onAnalyticsEvent?.({ type: 'field_focused', fieldKey: key });\n }, [onAnalyticsEvent]);\n\n const handleFieldBlur = useCallback((key: string) => {\n onAnalyticsEvent?.({\n type: 'field_blurred',\n fieldKey: key,\n hasValue: engine.values[key] !== undefined && engine.values[key] !== '',\n });\n }, [engine, onAnalyticsEvent]);\n\n const submit = useCallback(() => {\n const errors = engine.validate();\n for (const [key, message] of Object.entries(errors)) {\n onAnalyticsEvent?.({ type: 'field_error', fieldKey: key, error: message });\n }\n if (Object.keys(errors).length > 0) return;\n const values = engine.getSubmitValues();\n onAnalyticsEvent?.({ type: 'form_submitted', fieldCount: Object.keys(values).length });\n onSubmit(values);\n }, [engine, onAnalyticsEvent, onSubmit]);\n\n const handleSubmit = useCallback((event: React.FormEvent) => {\n event.preventDefault();\n submit();\n }, [submit]);\n\n const handleNext = useCallback(async () => {\n const previousStep = engine.currentStep;\n if (!await engine.nextStepAsync()) return;\n if (previousStep) {\n onAnalyticsEvent?.({ type: 'step_completed', stepId: previousStep.id });\n }\n if (!engine.currentStep) return;\n onStepChange?.(engine.currentStep.id, 'next');\n onAnalyticsEvent?.({\n type: 'step_viewed',\n stepId: engine.currentStep.id,\n stepIndex: engine.currentStepIndex,\n });\n }, [engine, onAnalyticsEvent, onStepChange]);\n\n const handlePrev = useCallback(() => {\n engine.prevStep();\n if (engine.currentStep) onStepChange?.(engine.currentStep.id, 'back');\n }, [engine, onStepChange]);\n\n const handleCancel = useCallback(() => onCancel?.(), [onCancel]);\n\n return (\n <form className=\"fh-form\" onSubmit={handleSubmit}>\n <FormProgressController engine={engine} ProgressComponent={ProgressComponent} />\n <FormFieldsController\n key={definition.id}\n engine={engine}\n loading={loading}\n components={components}\n optionsProviders={optionsProviders}\n onChange={handleFieldUpdate}\n onBlur={handleFieldBlur}\n onFocus={handleFieldFocus}\n />\n <FormTopLevelErrors engine={engine} />\n <FormActionsController\n engine={engine}\n definition={definition}\n loading={loading}\n ActionsComponent={ActionsComponent}\n onSubmit={submit}\n onNext={handleNext}\n onPrev={handlePrev}\n onCancel={handleCancel}\n />\n </form>\n );\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@formhaus/react",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "React components for Formhaus forms. Define a form once in JSON, render with native HTML or your own components.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"dist"
|
|
18
18
|
],
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@formhaus/core": "0.
|
|
20
|
+
"@formhaus/core": "0.5.0"
|
|
21
21
|
},
|
|
22
22
|
"peerDependencies": {
|
|
23
23
|
"react": ">=18.0.0"
|