@connect-soft/form-generator 1.1.0-alpha3 → 1.1.0-alpha5

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/dist/index.mjs CHANGED
@@ -1,9 +1,9 @@
1
1
  import { jsx, jsxs } from 'react/jsx-runtime';
2
- import React, { createElement, memo, useRef, useMemo, useImperativeHandle } from 'react';
2
+ import React, { createElement, memo, useRef, useMemo, useCallback, useImperativeHandle } from 'react';
3
3
  import * as n$1 from 'zod/v4/core';
4
+ import { c } from 'react/compiler-runtime';
4
5
  import { z } from 'zod';
5
6
  export { z } from 'zod';
6
- import { c } from 'react/compiler-runtime';
7
7
 
8
8
  var isCheckBoxInput = (element) => element.type === 'checkbox';
9
9
 
@@ -3110,6 +3110,105 @@ function clearAllRegistries() {
3110
3110
  clearLayoutRegistry();
3111
3111
  }
3112
3112
 
3113
+ const RESERVED_PROPS = new Set(['all', 'remaining', 'names', 'has', 'render']);
3114
+ function createTemplateFields(fieldEntries) {
3115
+ const accessedFields = new Set();
3116
+ const handler = {
3117
+ get(_, prop) {
3118
+ if (typeof prop === 'symbol') {
3119
+ return undefined;
3120
+ }
3121
+ if (prop === 'all') {
3122
+ return Array.from(fieldEntries.values()).map(entry => entry.element);
3123
+ }
3124
+ if (prop === 'remaining') {
3125
+ return Array.from(fieldEntries.entries()).filter(([name]) => !accessedFields.has(name)).map(([, entry]) => entry.element);
3126
+ }
3127
+ if (prop === 'names') {
3128
+ return Array.from(fieldEntries.keys());
3129
+ }
3130
+ if (prop === 'has') {
3131
+ return name => fieldEntries.has(name);
3132
+ }
3133
+ if (prop === 'render') {
3134
+ return (...names) => {
3135
+ return names.filter(name => fieldEntries.has(name)).map(name => {
3136
+ accessedFields.add(name);
3137
+ return fieldEntries.get(name).element;
3138
+ });
3139
+ };
3140
+ }
3141
+ if (fieldEntries.has(prop)) {
3142
+ accessedFields.add(prop);
3143
+ return fieldEntries.get(prop).element;
3144
+ }
3145
+ return undefined;
3146
+ },
3147
+ has(_, prop) {
3148
+ if (typeof prop === 'symbol') {
3149
+ return false;
3150
+ }
3151
+ return RESERVED_PROPS.has(prop) || fieldEntries.has(prop);
3152
+ },
3153
+ ownKeys() {
3154
+ return [...RESERVED_PROPS, ...fieldEntries.keys()];
3155
+ },
3156
+ getOwnPropertyDescriptor(_, prop) {
3157
+ if (typeof prop === 'symbol') {
3158
+ return undefined;
3159
+ }
3160
+ if (RESERVED_PROPS.has(prop) || fieldEntries.has(prop)) {
3161
+ return {
3162
+ configurable: true,
3163
+ enumerable: true,
3164
+ value: this.get(_, prop, {})
3165
+ };
3166
+ }
3167
+ return undefined;
3168
+ }
3169
+ };
3170
+ return new Proxy({}, handler);
3171
+ }
3172
+ function createTemplateLayouts(layoutEntries) {
3173
+ const handler = {
3174
+ get(_, prop) {
3175
+ if (typeof prop === 'symbol') {
3176
+ return undefined;
3177
+ }
3178
+ if (prop === 'all') {
3179
+ return Array.from(layoutEntries.values()).map(entry => entry.element);
3180
+ }
3181
+ if (layoutEntries.has(prop)) {
3182
+ return layoutEntries.get(prop).element;
3183
+ }
3184
+ return undefined;
3185
+ },
3186
+ has(_, prop) {
3187
+ if (typeof prop === 'symbol') {
3188
+ return false;
3189
+ }
3190
+ return prop === 'all' || layoutEntries.has(prop);
3191
+ },
3192
+ ownKeys() {
3193
+ return ['all', ...layoutEntries.keys()];
3194
+ },
3195
+ getOwnPropertyDescriptor(_, prop) {
3196
+ if (typeof prop === 'symbol') {
3197
+ return undefined;
3198
+ }
3199
+ if (prop === 'all' || layoutEntries.has(prop)) {
3200
+ return {
3201
+ configurable: true,
3202
+ enumerable: true,
3203
+ value: this.get(_, prop, {})
3204
+ };
3205
+ }
3206
+ return undefined;
3207
+ }
3208
+ };
3209
+ return new Proxy({}, handler);
3210
+ }
3211
+
3113
3212
  const FieldRenderer = /*#__PURE__*/memo(t0 => {
3114
3213
  const $ = c(5);
3115
3214
  const {
@@ -3120,6 +3219,10 @@ const FieldRenderer = /*#__PURE__*/memo(t0 => {
3120
3219
  if (field.hidden) {
3121
3220
  return null;
3122
3221
  }
3222
+ if (!field.name) {
3223
+ console.error(`Field is missing required "name" property. Field type: "${field.type}". ` + "Every field must have a unique name for form state management.");
3224
+ return null;
3225
+ }
3123
3226
  let t1;
3124
3227
  let t2;
3125
3228
  if ($[0] !== field || $[1] !== form || $[2] !== namePrefix) {
@@ -3355,8 +3458,9 @@ const defaultValidators = {
3355
3458
  tel: stringValidator,
3356
3459
  number: field => {
3357
3460
  let schema = z.coerce.number();
3358
- if (field.min !== undefined) schema = schema.min(field.min);
3359
- if (field.max !== undefined) schema = schema.max(field.max);
3461
+ const numberField = field;
3462
+ if (numberField.min !== undefined) schema = schema.min(numberField.min);
3463
+ if (numberField.max !== undefined) schema = schema.max(numberField.max);
3360
3464
  return schema;
3361
3465
  },
3362
3466
  checkbox: () => z.coerce.boolean(),
@@ -3442,6 +3546,38 @@ function getItemKey(item, index) {
3442
3546
  }
3443
3547
  return item.name;
3444
3548
  }
3549
+ function extractFields(items) {
3550
+ const fields = [];
3551
+ for (const item of items) {
3552
+ if (isLayoutBlock(item)) {
3553
+ let childItems = [];
3554
+ if (item.type === 'columns') {
3555
+ for (const column of item.columns) {
3556
+ childItems.push(...column.children);
3557
+ }
3558
+ } else if (item.type === 'section') {
3559
+ childItems = item.children;
3560
+ }
3561
+ fields.push(...extractFields(childItems));
3562
+ } else {
3563
+ fields.push(item);
3564
+ }
3565
+ }
3566
+ return fields;
3567
+ }
3568
+ function extractLayouts(items) {
3569
+ const layouts = [];
3570
+ items.forEach((item, index) => {
3571
+ if (isLayoutBlock(item)) {
3572
+ layouts.push({
3573
+ layout: item,
3574
+ index
3575
+ });
3576
+ }
3577
+ });
3578
+ return layouts;
3579
+ }
3580
+
3445
3581
  function hasSchema(props) {
3446
3582
  return props.schema !== undefined;
3447
3583
  }
@@ -3453,6 +3589,11 @@ function FormGeneratorImpl(props) {
3453
3589
  submitText = 'Submit',
3454
3590
  disabled,
3455
3591
  mode = 'onChange',
3592
+ title,
3593
+ description,
3594
+ showReset = false,
3595
+ resetText = 'Reset',
3596
+ children,
3456
3597
  ref
3457
3598
  } = props;
3458
3599
  const userSchema = hasSchema(props) ? props.schema : undefined;
@@ -3476,6 +3617,9 @@ function FormGeneratorImpl(props) {
3476
3617
  const handleSubmit = form.handleSubmit(async data => {
3477
3618
  await onSubmit(data);
3478
3619
  });
3620
+ const handleReset = useCallback(() => {
3621
+ form.reset(mergedDefaultValues);
3622
+ }, [form, mergedDefaultValues]);
3479
3623
  useImperativeHandle(ref, () => ({
3480
3624
  setValues: values => {
3481
3625
  Object.entries(values).forEach(([key, value]) => {
@@ -3500,26 +3644,124 @@ function FormGeneratorImpl(props) {
3500
3644
  setError: (name, error) => form.setError(name, error),
3501
3645
  isValid: () => form.formState.isValid,
3502
3646
  isDirty: () => form.formState.isDirty,
3503
- form
3647
+ form: form
3504
3648
  }), [form, handleSubmit, mergedDefaultValues]);
3505
3649
  const SubmitButton = getFormComponent('SubmitButton');
3650
+ const fieldEntries = useMemo(() => {
3651
+ const entries = new Map();
3652
+ const allFields = extractFields(fields);
3653
+ allFields.forEach((field, index) => {
3654
+ if (!field.hidden) {
3655
+ const element = jsx(FieldRenderer, {
3656
+ field: field
3657
+ }, field.name || `field-${index}`);
3658
+ entries.set(field.name, {
3659
+ field,
3660
+ element,
3661
+ accessed: false
3662
+ });
3663
+ }
3664
+ });
3665
+ return entries;
3666
+ }, [fields]);
3667
+ const layoutEntries = useMemo(() => {
3668
+ const entries_0 = new Map();
3669
+ const allLayouts = extractLayouts(fields);
3670
+ allLayouts.forEach(({
3671
+ layout,
3672
+ index: index_0
3673
+ }) => {
3674
+ if (!layout.hidden) {
3675
+ const key_0 = layout.name || `layout-${layout.type}-${index_0}`;
3676
+ const element_0 = jsx(FormItemRenderer, {
3677
+ item: layout
3678
+ }, key_0);
3679
+ if (layout.name) {
3680
+ entries_0.set(layout.name, {
3681
+ layout,
3682
+ element: element_0
3683
+ });
3684
+ }
3685
+ }
3686
+ });
3687
+ return entries_0;
3688
+ }, [fields]);
3689
+ const templateFields = useMemo(() => createTemplateFields(fieldEntries), [fieldEntries]);
3690
+ const templateLayouts = useMemo(() => createTemplateLayouts(layoutEntries), [layoutEntries]);
3691
+ const buttons = useMemo(() => {
3692
+ const result = {
3693
+ submit: jsx(SubmitButton, {
3694
+ disabled: disabled || form.formState.isSubmitting,
3695
+ isSubmitting: form.formState.isSubmitting,
3696
+ children: submitText
3697
+ }, "submit")
3698
+ };
3699
+ if (showReset) {
3700
+ result.reset = jsx("button", {
3701
+ type: "button",
3702
+ onClick: handleReset,
3703
+ disabled: disabled,
3704
+ children: resetText
3705
+ }, "reset");
3706
+ }
3707
+ return result;
3708
+ }, [SubmitButton, disabled, form.formState.isSubmitting, submitText, showReset, resetText, handleReset]);
3709
+ const renderField = useCallback((field_0, options) => {
3710
+ return jsx(FieldRenderer, {
3711
+ field: field_0,
3712
+ namePrefix: options === null || options === void 0 ? void 0 : options.namePrefix
3713
+ });
3714
+ }, []);
3715
+ const renderLayout = useCallback((layout_0, options_0) => {
3716
+ return jsx(FormItemRenderer, {
3717
+ item: layout_0,
3718
+ namePrefix: options_0 === null || options_0 === void 0 ? void 0 : options_0.namePrefix
3719
+ });
3720
+ }, []);
3721
+ if (!children) {
3722
+ return jsx(FormProvider, {
3723
+ ...form,
3724
+ children: jsxs("form", {
3725
+ ref: formRef,
3726
+ onSubmit: handleSubmit,
3727
+ className: className,
3728
+ children: [fields.map((item, index_1) => jsx(FormItemRenderer, {
3729
+ item: item
3730
+ }, getItemKey(item, index_1))), jsx(SubmitButton, {
3731
+ disabled: disabled || form.formState.isSubmitting,
3732
+ isSubmitting: form.formState.isSubmitting,
3733
+ children: submitText
3734
+ })]
3735
+ })
3736
+ });
3737
+ }
3738
+ const renderProps = {
3739
+ fields: templateFields,
3740
+ layouts: templateLayouts,
3741
+ buttons,
3742
+ title,
3743
+ description,
3744
+ form: form,
3745
+ isSubmitting: form.formState.isSubmitting,
3746
+ isValid: form.formState.isValid,
3747
+ isDirty: form.formState.isDirty,
3748
+ renderField,
3749
+ renderLayout
3750
+ };
3751
+ const renderFn = children;
3506
3752
  return jsx(FormProvider, {
3507
3753
  ...form,
3508
- children: jsxs("form", {
3754
+ children: jsx("form", {
3509
3755
  ref: formRef,
3510
3756
  onSubmit: handleSubmit,
3511
3757
  className: className,
3512
- children: [fields.map((item, index) => jsx(FormItemRenderer, {
3513
- item: item
3514
- }, getItemKey(item, index))), jsx(SubmitButton, {
3515
- disabled: disabled || form.formState.isSubmitting,
3516
- isSubmitting: form.formState.isSubmitting,
3517
- children: submitText
3518
- })]
3758
+ children: renderFn(renderProps)
3519
3759
  })
3520
3760
  });
3521
3761
  }
3522
- const FormGenerator = FormGeneratorImpl;
3762
+ function FormGenerator(props) {
3763
+ return FormGeneratorImpl(props);
3764
+ }
3523
3765
 
3524
3766
  export { Controller, FieldRenderer, FormGenerator, FormProvider, clearAllRegistries, clearFieldRegistry, clearFormComponentRegistry, clearLayoutRegistry, getFieldComponent, getFormComponent, getFormComponents, getLayoutComponent, getRegisteredFieldTypes, hasFieldType, hasFormComponent, hasLayoutComponent, isLayoutBlock, registerField, registerFields, registerFormComponent, registerFormComponents, registerLayoutComponent, registerLayoutComponents, resetFormComponentRegistry, unregisterField, useFieldArray, useForm, useFormContext, useWatch };
3525
3767
  //# sourceMappingURL=index.mjs.map