@contractspec/lib.contracts-runtime-client-react 3.8.5 → 3.9.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.
@@ -1,362 +1,2 @@
1
1
  // @bun
2
- var __require = import.meta.require;
3
-
4
- // src/form-render.impl.tsx
5
- import {
6
- buildZodWithRelations,
7
- evalPredicate
8
- } from "@contractspec/lib.contracts-spec/forms";
9
- import { zodResolver } from "@hookform/resolvers/zod";
10
- import React, { useEffect, useMemo, useState } from "react";
11
- import {
12
- Controller,
13
- useFieldArray,
14
- useForm
15
- } from "react-hook-form";
16
- import { jsxDEV, Fragment } from "react/jsx-dev-runtime";
17
- "use client";
18
- function toOptionsArray(src) {
19
- if (!src)
20
- return;
21
- if (Array.isArray(src))
22
- return { kind: "static", options: src };
23
- return src;
24
- }
25
- function getAtPath(values, path) {
26
- if (!path)
27
- return;
28
- const segs = path.replace(/\[(\d+)\]/g, ".$1").split(".").filter(Boolean);
29
- let cur = values;
30
- for (const s of segs) {
31
- if (cur == null)
32
- return;
33
- cur = cur[s];
34
- }
35
- return cur;
36
- }
37
- function makeDepsKey(values, deps) {
38
- if (!deps || deps.length === 0)
39
- return "[]";
40
- try {
41
- return JSON.stringify(deps.map((d) => getAtPath(values, d)));
42
- } catch {
43
- return "[]";
44
- }
45
- }
46
- function useResolvedOptions(values, source, resolvers) {
47
- const [opts, setOpts] = useState([]);
48
- const depKey = useMemo(() => {
49
- if (!source)
50
- return "nil";
51
- if (source.kind === "static")
52
- return JSON.stringify(source.options ?? []);
53
- return makeDepsKey(values, source.deps);
54
- }, [source, values]);
55
- useEffect(() => {
56
- let mounted = true;
57
- const run = async () => {
58
- if (!source)
59
- return setOpts([]);
60
- if (source.kind === "static")
61
- return setOpts([...source.options ?? []]);
62
- const fn = resolvers?.[source.resolverKey];
63
- if (!fn)
64
- return setOpts([]);
65
- const res = await fn(values, source.args);
66
- if (mounted)
67
- setOpts([...res ?? []]);
68
- };
69
- run();
70
- return () => {
71
- mounted = false;
72
- };
73
- }, [
74
- depKey,
75
- source && source.kind === "resolver" ? source.resolverKey : undefined
76
- ]);
77
- return opts;
78
- }
79
- function fieldPath(parent, name, arrayIndex) {
80
- if (!name)
81
- return parent ?? "";
82
- const child = typeof arrayIndex === "number" ? `${name.replace(/^\$index$/, String(arrayIndex))}` : name;
83
- return parent ? `${parent}${typeof arrayIndex === "number" ? `.${arrayIndex}` : ""}.${child}`.replace(/\.+/g, ".") : child;
84
- }
85
- function createFormRenderer(base) {
86
- const conf = base;
87
- const { driver } = conf;
88
- function InternalForm(props) {
89
- const { spec, options, merged } = props;
90
- const baseZod = useMemo(() => buildZodWithRelations(spec), [spec]);
91
- const form = useForm({
92
- ...merged.formOptions,
93
- resolver: zodResolver(baseZod),
94
- defaultValues: options?.defaultValues
95
- });
96
- const values = form.watch();
97
- const renderOne = (f, parent, arrayIndex) => {
98
- const DriverField = driver.Field;
99
- const DriverLabel = driver.FieldLabel;
100
- const DriverDesc = driver.FieldDescription;
101
- const DriverError = driver.FieldError;
102
- const name = fieldPath(parent, f.name, arrayIndex);
103
- const visible = evalPredicate(values, f.visibleWhen);
104
- const enabled = evalPredicate(values, f.enabledWhen);
105
- const invalid = Boolean(form.getFieldState(name)?.invalid);
106
- if (!visible)
107
- return null;
108
- const id = name?.replace(/\./g, "-");
109
- const commonWrapProps = {
110
- "data-invalid": invalid,
111
- hidden: !visible,
112
- disabled: !enabled
113
- };
114
- const labelNode = f.labelI18n ? /* @__PURE__ */ jsxDEV(DriverLabel, {
115
- htmlFor: id,
116
- children: f.labelI18n
117
- }, undefined, false, undefined, this) : null;
118
- const descNode = f.descriptionI18n ? /* @__PURE__ */ jsxDEV(DriverDesc, {
119
- children: f.descriptionI18n
120
- }, undefined, false, undefined, this) : null;
121
- if (f.kind === "group") {
122
- const children = f.fields.map((c, i) => /* @__PURE__ */ jsxDEV(React.Fragment, {
123
- children: renderOne(c, name, arrayIndex)
124
- }, `${name}-${i}`, false, undefined, this));
125
- return /* @__PURE__ */ jsxDEV(DriverField, {
126
- ...commonWrapProps,
127
- children: [
128
- labelNode,
129
- children,
130
- descNode
131
- ]
132
- }, undefined, true, undefined, this);
133
- }
134
- if (f.kind === "array") {
135
- return renderArray(f, parent);
136
- }
137
- return /* @__PURE__ */ jsxDEV(Controller, {
138
- name,
139
- control: form.control,
140
- render: ({ field, fieldState }) => {
141
- const err = fieldState.error ? [fieldState.error] : [];
142
- const ariaInvalid = fieldState.invalid || undefined;
143
- if (f.kind === "text") {
144
- const textField = f;
145
- const Input = driver.Input;
146
- return /* @__PURE__ */ jsxDEV(DriverField, {
147
- ...commonWrapProps,
148
- children: [
149
- labelNode,
150
- /* @__PURE__ */ jsxDEV(Input, {
151
- id,
152
- "aria-invalid": ariaInvalid,
153
- placeholder: f.placeholderI18n,
154
- autoComplete: textField.autoComplete,
155
- inputMode: textField.inputMode,
156
- maxLength: textField.maxLength,
157
- minLength: textField.minLength,
158
- disabled: !enabled,
159
- ...field,
160
- ...f.uiProps
161
- }, undefined, false, undefined, this),
162
- descNode,
163
- fieldState.invalid ? /* @__PURE__ */ jsxDEV(DriverError, {
164
- errors: err
165
- }, undefined, false, undefined, this) : null
166
- ]
167
- }, undefined, true, undefined, this);
168
- }
169
- if (f.kind === "textarea") {
170
- const textareaField = f;
171
- const Textarea = driver.Textarea;
172
- return /* @__PURE__ */ jsxDEV(DriverField, {
173
- ...commonWrapProps,
174
- children: [
175
- labelNode,
176
- /* @__PURE__ */ jsxDEV(Textarea, {
177
- id,
178
- "aria-invalid": ariaInvalid,
179
- placeholder: f.placeholderI18n,
180
- rows: textareaField.rows,
181
- maxLength: textareaField.maxLength,
182
- disabled: !enabled,
183
- ...field,
184
- ...f.uiProps
185
- }, undefined, false, undefined, this),
186
- descNode,
187
- fieldState.invalid ? /* @__PURE__ */ jsxDEV(DriverError, {
188
- errors: err
189
- }, undefined, false, undefined, this) : null
190
- ]
191
- }, undefined, true, undefined, this);
192
- }
193
- if (f.kind === "select") {
194
- const selectField = f;
195
- const Select = driver.Select;
196
- const src = toOptionsArray(selectField.options);
197
- const opts = useResolvedOptions(values, src, merged.resolvers);
198
- return /* @__PURE__ */ jsxDEV(DriverField, {
199
- ...commonWrapProps,
200
- children: [
201
- labelNode,
202
- /* @__PURE__ */ jsxDEV(Select, {
203
- id,
204
- name,
205
- "aria-invalid": ariaInvalid,
206
- disabled: !enabled,
207
- value: field.value,
208
- onChange: (v) => field.onChange(v),
209
- options: opts,
210
- ...f.uiProps
211
- }, undefined, false, undefined, this),
212
- descNode,
213
- fieldState.invalid ? /* @__PURE__ */ jsxDEV(DriverError, {
214
- errors: err
215
- }, undefined, false, undefined, this) : null
216
- ]
217
- }, undefined, true, undefined, this);
218
- }
219
- if (f.kind === "checkbox") {
220
- const Checkbox = driver.Checkbox;
221
- return /* @__PURE__ */ jsxDEV(DriverField, {
222
- ...commonWrapProps,
223
- children: [
224
- labelNode,
225
- /* @__PURE__ */ jsxDEV(Checkbox, {
226
- id,
227
- name,
228
- disabled: !enabled,
229
- checked: !!field.value,
230
- onCheckedChange: (v) => field.onChange(v),
231
- ...f.uiProps
232
- }, undefined, false, undefined, this),
233
- descNode,
234
- fieldState.invalid ? /* @__PURE__ */ jsxDEV(DriverError, {
235
- errors: err
236
- }, undefined, false, undefined, this) : null
237
- ]
238
- }, undefined, true, undefined, this);
239
- }
240
- if (f.kind === "radio") {
241
- const radioField = f;
242
- const RadioGroup = driver.RadioGroup;
243
- const src = toOptionsArray(radioField.options);
244
- const opts = useResolvedOptions(values, src, merged.resolvers);
245
- return /* @__PURE__ */ jsxDEV(DriverField, {
246
- ...commonWrapProps,
247
- children: [
248
- labelNode,
249
- /* @__PURE__ */ jsxDEV(RadioGroup, {
250
- id,
251
- name,
252
- disabled: !enabled,
253
- value: field.value,
254
- onValueChange: (v) => field.onChange(v),
255
- options: opts,
256
- ...f.uiProps
257
- }, undefined, false, undefined, this),
258
- descNode,
259
- fieldState.invalid ? /* @__PURE__ */ jsxDEV(DriverError, {
260
- errors: err
261
- }, undefined, false, undefined, this) : null
262
- ]
263
- }, undefined, true, undefined, this);
264
- }
265
- if (f.kind === "switch") {
266
- const Switch = driver.Switch;
267
- return /* @__PURE__ */ jsxDEV(DriverField, {
268
- ...commonWrapProps,
269
- children: [
270
- labelNode,
271
- /* @__PURE__ */ jsxDEV(Switch, {
272
- id,
273
- name,
274
- disabled: !enabled,
275
- checked: !!field.value,
276
- onCheckedChange: (v) => field.onChange(v),
277
- ...f.uiProps
278
- }, undefined, false, undefined, this),
279
- descNode,
280
- fieldState.invalid ? /* @__PURE__ */ jsxDEV(DriverError, {
281
- errors: err
282
- }, undefined, false, undefined, this) : null
283
- ]
284
- }, undefined, true, undefined, this);
285
- }
286
- return /* @__PURE__ */ jsxDEV(Fragment, {}, undefined, false, undefined, this);
287
- }
288
- }, name, false, undefined, this);
289
- };
290
- const renderArray = (f, parent) => {
291
- const name = fieldPath(parent, f.name);
292
- const { fields, append, remove } = useFieldArray({
293
- control: form.control,
294
- name
295
- });
296
- const canAdd = f.max == null || fields.length < f.max;
297
- const canRemove = (idx) => (f.min == null ? fields.length > 0 : fields.length > f.min) && idx >= 0;
298
- const Button2 = driver.Button;
299
- const Label = driver.FieldLabel;
300
- return /* @__PURE__ */ jsxDEV("div", {
301
- children: [
302
- f.labelI18n ? /* @__PURE__ */ jsxDEV(Label, {
303
- children: f.labelI18n
304
- }, undefined, false, undefined, this) : null,
305
- fields.map((row, idx) => /* @__PURE__ */ jsxDEV("div", {
306
- children: [
307
- renderOne(f.of, name, idx),
308
- canRemove(idx) ? /* @__PURE__ */ jsxDEV(Button2, {
309
- type: "button",
310
- variant: "ghost",
311
- size: "sm",
312
- onClick: () => remove(idx),
313
- children: "Remove"
314
- }, undefined, false, undefined, this) : null
315
- ]
316
- }, row.id ?? idx, true, undefined, this)),
317
- canAdd ? /* @__PURE__ */ jsxDEV(Button2, {
318
- type: "button",
319
- variant: "outline",
320
- size: "sm",
321
- onClick: () => append({}),
322
- children: "Add"
323
- }, undefined, false, undefined, this) : null
324
- ]
325
- }, name, true, undefined, this);
326
- };
327
- const onSubmit = async (data) => {
328
- const actionKey = spec.actions?.[0]?.key ?? "submit";
329
- if (merged.onSubmitOverride) {
330
- return merged.onSubmitOverride(data, actionKey);
331
- }
332
- };
333
- const Button = driver.Button;
334
- return /* @__PURE__ */ jsxDEV("form", {
335
- onSubmit: form.handleSubmit(onSubmit),
336
- children: [
337
- (spec.fields || []).map((f, i) => /* @__PURE__ */ jsxDEV(React.Fragment, {
338
- children: renderOne(f)
339
- }, i, false, undefined, this)),
340
- spec.actions && spec.actions.length ? /* @__PURE__ */ jsxDEV("div", {
341
- children: spec.actions.map((a) => /* @__PURE__ */ jsxDEV(Button, {
342
- type: "submit",
343
- children: a.labelI18n
344
- }, a.key, false, undefined, this))
345
- }, undefined, false, undefined, this) : null
346
- ]
347
- }, undefined, true, undefined, this);
348
- }
349
- return {
350
- render: (spec, options) => /* @__PURE__ */ jsxDEV(InternalForm, {
351
- spec,
352
- options,
353
- merged: {
354
- ...conf,
355
- ...options?.overrides ?? {}
356
- }
357
- }, undefined, false, undefined, this)
358
- };
359
- }
360
- export {
361
- createFormRenderer
362
- };
2
+ var TB=import.meta.require;import{buildZodWithRelations as d,evalPredicate as m,isFieldReadOnly as t,normalizeFormSpec as i}from"@contractspec/lib.contracts-spec/forms";import{zodResolver as l}from"@hookform/resolvers/zod";import V from"react";import{Controller as A,useFieldArray as s,useForm as o}from"react-hook-form";import{jsx as U,jsxs as q,Fragment as wB}from"react/jsx-runtime";function F(B){if(!B)return;if(Array.isArray(B))return{kind:"static",options:[...B]};return B}function y(B,G){if(!G)return;let Y=G.replace(/\[(\d+)\]/g,".$1").split(".").filter(Boolean),H=B;for(let J of Y){if(H==null)return;H=H[J]}return H}function r(B){if(!B)return[];return B.split(".").filter((G)=>/^\d+$/.test(G)).map((G)=>Number(G))}function u(B,G){if(!G)return B??"";return B?`${B}.${G}`:G}function f(B,G){if(!G||G.length===0)return"[]";try{return JSON.stringify(G.map((Y)=>y(B,Y)))}catch{return"[]"}}function e(B,G){let[Y,H]=V.useState(B);return V.useEffect(()=>{let J=globalThis.setTimeout(()=>H(B),G);return()=>globalThis.clearTimeout(J)},[G,B]),Y}function j(B,G,Y){let[H,J]=V.useState([]),_=V.useMemo(()=>{if(!G)return"nil";if(G.kind==="static")return JSON.stringify(G.options??[]);return`${G.resolverKey}:${f(B,G.deps)}`},[G,B]);return V.useEffect(()=>{let $=!0;return(async()=>{if(!G){J([]);return}if(G.kind==="static"){J([...G.options??[]]);return}let w=Y?.[G.resolverKey];if(!w){J([]);return}let b=await w(B,G.args);if($)J([...b??[]])})(),()=>{$=!1}},[_,Y,G,B]),H}function n(B){if(B instanceof Date&&!Number.isNaN(B.getTime()))return B;if(typeof B==="string"||typeof B==="number"){let G=new Date(B);if(!Number.isNaN(G.getTime()))return G}return null}function p(B){if(B instanceof Date&&!Number.isNaN(B.getTime()))return B;if(typeof B!=="string"||B.trim().length===0)return null;let[G,Y]=B.split(":").map(($)=>Number($)),H=G??Number.NaN,J=Y??Number.NaN;if(Number.isNaN(H)||Number.isNaN(J))return null;let _=new Date;return _.setHours(H,J,0,0),_}function BB(B){if(!B)return"";return`${String(B.getHours()).padStart(2,"0")}:${String(B.getMinutes()).padStart(2,"0")}`}function a(B){return{value:B.value,labelI18n:B.labelI18n,descriptionI18n:B.descriptionI18n,...B.data??{}}}function GB(B,G,Y){let H=G.trim().toLowerCase();if(!H)return[...B];let J=H.split(/\s+/).filter(Boolean);return B.filter((_)=>{let $=a(_),L=[_.labelI18n,_.descriptionI18n,String(_.value),...Y.map((w)=>String(y($,w)??""))].join(" ").toLowerCase();return J.every((w)=>L.includes(w))})}function x(B,G){let Y=a(B);switch(G.mode){case"scalar":return G.valueKey?y(Y,G.valueKey)??B.value:B.value;case"pick":return Object.fromEntries(G.pickKeys.map((H)=>[H,y(Y,H)]));case"object":default:return B.data??Y}}function v(B,G){try{return JSON.stringify(B)===JSON.stringify(G)}catch{return B===G}}function HB(B,G,Y,H){let J=H&&Array.isArray(G)?G:[G];return B.filter((_)=>J.some(($)=>v(x(_,Y),$)))}function c(B){if(!B)return{countryCode:"",nationalNumber:""};let G=B.countryCode.trim(),Y=B.nationalNumber.replace(/\s+/g,""),H=G.replace(/^\+?/,"+"),J={...B,countryCode:G,nationalNumber:B.nationalNumber};if(B.e164!=null||G||Y)J.e164=`${H}${Y}`.trim();return J}function JB(B){let G=j(B.values,F(B.spec.options),B.resolvers),Y=B.driver.Field,H=B.driver.FieldError;return U(A,{name:B.ctx.name,control:B.form.control,render:({field:J,fieldState:_})=>{let $=_.error?[_.error]:[];return q(Y,{...B.commonWrapProps,children:[B.labelNode,U(B.driver.Select,{id:B.ctx.id,name:B.ctx.name,"aria-invalid":_.invalid||void 0,disabled:!B.ctx.enabled||B.ctx.readOnly,value:J.value,onChange:(L)=>{if(B.ctx.readOnly)return;J.onChange(L)},options:G,...B.spec.uiProps}),B.descNode,_.invalid?U(H,{errors:$}):null]})}})}function UB(B){let G=j(B.values,F(B.spec.options),B.resolvers),Y=B.driver.Field,H=B.driver.FieldError;return U(A,{name:B.ctx.name,control:B.form.control,render:({field:J,fieldState:_})=>{let $=_.error?[_.error]:[];return q(Y,{...B.commonWrapProps,children:[B.labelNode,U(B.driver.RadioGroup,{id:B.ctx.id,name:B.ctx.name,disabled:!B.ctx.enabled||B.ctx.readOnly,value:J.value,onValueChange:(L)=>{if(B.ctx.readOnly)return;J.onChange(L)},options:G,...B.spec.uiProps}),B.descNode,_.invalid?U(H,{errors:$}):null]})}})}function XB(B){let[G,Y]=V.useState(""),H=B.spec.source.kind==="resolver"?B.spec.source.debounceMs??200:0,J=e(G,H),[_,$]=V.useState([]),L=V.useMemo(()=>{return B.spec.source.kind==="resolver"?`${B.spec.source.resolverKey}:${f(B.values,B.spec.source.deps)}:${J}`:"local"},[J,B.spec.source,B.values]);V.useEffect(()=>{if(B.spec.source.kind!=="resolver")return;let Z=B.resolvers?.[B.spec.source.resolverKey],k=B.spec.source.minQueryLength??0;if(!Z||J.trim().length<k){$([]);return}let g=!0,D={...B.spec.source.args??{},query:J};return Promise.resolve(Z(B.values,D)).then((C)=>{if(g)$([...C??[]])}),()=>{g=!1}},[L,B.resolvers,B.spec.source,B.values,J]);let w=B.spec.source.kind==="local"?GB(B.spec.source.options,G,B.spec.source.searchKeys):_,b=B.driver.Field,X=B.driver.FieldError;return U(A,{name:B.ctx.name,control:B.form.control,render:({field:Z,fieldState:k})=>{let g=k.error?[k.error]:[],D=HB(w,Z.value,B.spec.valueMapping,B.spec.multiple),C=(O)=>{if(B.ctx.readOnly)return;let W=x(O,B.spec.valueMapping);if(B.spec.multiple){let P=Array.isArray(Z.value)?Z.value:[],R=P.some((S)=>v(S,W));Z.onChange(R?P:[...P,W]);return}Z.onChange(W),Y(O.labelI18n)},T=(O)=>{if(B.ctx.readOnly||!B.spec.multiple)return;let W=x(O,B.spec.valueMapping),P=Array.isArray(Z.value)?Z.value:[];Z.onChange(P.filter((R)=>!v(R,W)))};return q(b,{...B.commonWrapProps,children:[B.labelNode,U(B.driver.Autocomplete,{id:B.ctx.id,name:B.ctx.name,disabled:!B.ctx.enabled,readOnly:B.ctx.readOnly,"aria-invalid":k.invalid||void 0,placeholder:B.spec.placeholderI18n,multiple:B.spec.multiple,query:G,options:w,selectedOptions:D,onQueryChange:Y,onSelectOption:C,onRemoveOption:T}),B.descNode,k.invalid?U(X,{errors:g}):null]})}})}function YB(B){let G=j(B.values,F(B.spec.countryOptions),B.resolvers),Y=B.driver.Field,H=B.driver.FieldError;return U(A,{name:B.ctx.name,control:B.form.control,render:({field:J,fieldState:_})=>{let $=_.error?[_.error]:[];return q(Y,{...B.commonWrapProps,children:[B.labelNode,U(B.driver.AddressField,{id:B.ctx.id,name:B.ctx.name,value:J.value??null,onChange:(L)=>{if(B.ctx.readOnly)return;J.onChange(L)},disabled:!B.ctx.enabled,readOnly:B.ctx.readOnly,"aria-invalid":_.invalid||void 0,parts:B.spec.parts,countryOptions:G}),B.descNode,_.invalid?U(H,{errors:$}):null]})}})}function _B(B){let G=j(B.values,F(B.spec.countryOptions),B.resolvers),Y=B.driver.Field,H=B.driver.FieldError;return U(A,{name:B.ctx.name,control:B.form.control,render:({field:J,fieldState:_})=>{let $=_.error?[_.error]:[];return q(Y,{...B.commonWrapProps,children:[B.labelNode,U(B.driver.PhoneField,{id:B.ctx.id,name:B.ctx.name,value:c(J.value??null),onChange:(L)=>{if(B.ctx.readOnly)return;J.onChange(c(L))},disabled:!B.ctx.enabled,readOnly:B.ctx.readOnly,"aria-invalid":_.invalid||void 0,parts:B.spec.parts,countryOptions:G}),B.descNode,_.invalid?U(H,{errors:$}):null]})}})}function $B(B){let G=B.driver.Field,Y=B.driver.FieldError;return U(A,{name:B.ctx.name,control:B.form.control,render:({field:H,fieldState:J})=>{let _=J.error?[J.error]:[];return q(G,{...B.commonWrapProps,children:[B.labelNode,U(B.driver.DateField,{id:B.ctx.id,name:B.ctx.name,value:n(H.value),onChange:($)=>{if(B.ctx.readOnly)return;H.onChange($)},disabled:!B.ctx.enabled,readOnly:B.ctx.readOnly,placeholder:B.spec.placeholderI18n,minDate:B.spec.minDate,maxDate:B.spec.maxDate}),B.descNode,J.invalid?U(Y,{errors:_}):null]})}})}function IB(B){let G=B.driver.Field,Y=B.driver.FieldError;return U(A,{name:B.ctx.name,control:B.form.control,render:({field:H,fieldState:J})=>{let _=J.error?[J.error]:[];return q(G,{...B.commonWrapProps,children:[B.labelNode,U(B.driver.TimeField,{id:B.ctx.id,name:B.ctx.name,value:p(H.value),onChange:($)=>{if(B.ctx.readOnly)return;H.onChange(BB($))},disabled:!B.ctx.enabled,readOnly:B.ctx.readOnly,placeholder:B.spec.placeholderI18n,is24Hour:B.spec.is24Hour}),B.descNode,J.invalid?U(Y,{errors:_}):null]})}})}function LB(B){let G=B.driver.Field,Y=B.driver.FieldError;return U(A,{name:B.ctx.name,control:B.form.control,render:({field:H,fieldState:J})=>{let _=J.error?[J.error]:[];return q(G,{...B.commonWrapProps,children:[B.labelNode,U(B.driver.DateTimeField,{id:B.ctx.id,name:B.ctx.name,value:n(H.value),onChange:($)=>{if(B.ctx.readOnly)return;H.onChange($)},disabled:!B.ctx.enabled,readOnly:B.ctx.readOnly,datePlaceholder:B.spec.placeholderI18n,timePlaceholder:B.spec.placeholderI18n,minDate:B.spec.minDate,maxDate:B.spec.maxDate,is24Hour:B.spec.is24Hour}),B.descNode,J.invalid?U(Y,{errors:_}):null]})}})}function ZB(B){let G=u(B.parent,B.spec.name),{fields:Y,append:H,remove:J}=s({control:B.form.control,name:G}),_=B.spec.max==null||Y.length<B.spec.max,$=(L)=>(B.spec.min==null?Y.length>0:Y.length>B.spec.min)&&L>=0;return q("div",{children:[B.spec.labelI18n?U(B.driver.FieldLabel,{children:B.spec.labelI18n}):null,Y.map((L,w)=>q("div",{children:[B.renderField(B.spec.of,`${G}.${w}`),$(w)?U(B.driver.Button,{type:"button",variant:"ghost",size:"sm",onClick:()=>J(w),children:"Remove"}):null]},L.id??w)),_?U(B.driver.Button,{type:"button",variant:"outline",size:"sm",onClick:()=>H({}),children:"Add"}):null]},G)}function kB(B){let G=B;function Y(H){let J=V.useMemo(()=>i(H.spec),[H.spec]),_=V.useMemo(()=>d(J),[J]),$=o({...H.merged.formOptions,resolver:l(_),defaultValues:H.options?.defaultValues}),L=$.watch(),w=(X,Z)=>{let k=H.merged.driver.Field,g=H.merged.driver.FieldLabel,D=H.merged.driver.FieldDescription,C=H.merged.driver.FieldError,T=u(Z,X.name),O=r(Z),W=m(L,X.visibleWhen,O),P=m(L,X.enabledWhen,O),R=t(X),S=Boolean($.getFieldState(T)?.invalid);if(!W)return null;let I={name:T,id:T.replace(/\./g,"-"),enabled:P,readOnly:R,visible:W},M={"data-invalid":S,hidden:!W,disabled:!P||R},K=X.labelI18n?U(g,{htmlFor:I.id,children:X.labelI18n}):null,Q=X.descriptionI18n?U(D,{children:X.descriptionI18n}):null;if(X.kind==="group")return q(k,{...M,children:[K,X.fields.map((N,z)=>U(V.Fragment,{children:w(N,T)},`${T}-${z}`)),Q]});if(X.kind==="array")return U(ZB,{driver:H.merged.driver,form:$,spec:X,parent:Z,renderField:w},T);if(X.kind==="select")return U(JB,{driver:H.merged.driver,form:$,values:L,spec:X,ctx:I,labelNode:K,descNode:Q,commonWrapProps:M,resolvers:H.merged.resolvers},T);if(X.kind==="radio")return U(UB,{driver:H.merged.driver,form:$,values:L,spec:X,ctx:I,labelNode:K,descNode:Q,commonWrapProps:M,resolvers:H.merged.resolvers},T);if(X.kind==="autocomplete")return U(XB,{driver:H.merged.driver,form:$,values:L,spec:X,ctx:I,labelNode:K,descNode:Q,commonWrapProps:M,resolvers:H.merged.resolvers},T);if(X.kind==="address")return U(YB,{driver:H.merged.driver,form:$,values:L,spec:X,ctx:I,labelNode:K,descNode:Q,commonWrapProps:M,resolvers:H.merged.resolvers},T);if(X.kind==="phone")return U(_B,{driver:H.merged.driver,form:$,values:L,spec:X,ctx:I,labelNode:K,descNode:Q,commonWrapProps:M,resolvers:H.merged.resolvers},T);if(X.kind==="date")return U($B,{driver:H.merged.driver,form:$,spec:X,ctx:I,labelNode:K,descNode:Q,commonWrapProps:M},T);if(X.kind==="time")return U(IB,{driver:H.merged.driver,form:$,spec:X,ctx:I,labelNode:K,descNode:Q,commonWrapProps:M},T);if(X.kind==="datetime")return U(LB,{driver:H.merged.driver,form:$,spec:X,ctx:I,labelNode:K,descNode:Q,commonWrapProps:M},T);return U(A,{name:T,control:$.control,render:({field:N,fieldState:z})=>{let h=z.error?[z.error]:[];if(X.kind==="text"){let E=X;return q(k,{...M,children:[K,U(H.merged.driver.Input,{id:I.id,"aria-invalid":z.invalid||void 0,placeholder:X.placeholderI18n,autoComplete:E.autoComplete,inputMode:E.inputMode,maxLength:E.maxLength,minLength:E.minLength,disabled:!I.enabled,readOnly:I.readOnly,...N,...X.uiProps}),Q,z.invalid?U(C,{errors:h}):null]})}if(X.kind==="textarea"){let E=X;return q(k,{...M,children:[K,U(H.merged.driver.Textarea,{id:I.id,"aria-invalid":z.invalid||void 0,placeholder:X.placeholderI18n,rows:E.rows,maxLength:E.maxLength,disabled:!I.enabled,readOnly:I.readOnly,...N,...X.uiProps}),Q,z.invalid?U(C,{errors:h}):null]})}if(X.kind==="checkbox")return q(k,{...M,children:[K,U(H.merged.driver.Checkbox,{id:I.id,name:I.name,disabled:!I.enabled||I.readOnly,checked:Boolean(N.value),onCheckedChange:(E)=>{if(I.readOnly)return;N.onChange(E)},...X.uiProps}),Q,z.invalid?U(C,{errors:h}):null]});if(X.kind==="switch")return q(k,{...M,children:[K,U(H.merged.driver.Switch,{id:I.id,name:I.name,disabled:!I.enabled||I.readOnly,checked:Boolean(N.value),onCheckedChange:(E)=>{if(I.readOnly)return;N.onChange(E)},...X.uiProps}),Q,z.invalid?U(C,{errors:h}):null]});return U(wB,{})}},T)},b=async(X)=>{let Z=J.actions?.[0]?.key??"submit";if(H.merged.onSubmitOverride)return H.merged.onSubmitOverride(X,Z)};return q("form",{onSubmit:$.handleSubmit(b),children:[J.fields.map((X,Z)=>U(V.Fragment,{children:w(X)},Z)),J.actions?.length?U("div",{children:J.actions.map((X)=>U(H.merged.driver.Button,{type:"submit",children:X.labelI18n},X.key))}):null]})}return{render:(H,J)=>U(Y,{spec:H,options:J,merged:{...G,...J?.overrides??{}}})}}export{x as mapAutocompleteValue,GB as filterAutocompleteOptions,kB as createFormRenderer};