@bsol-oss/react-datatable5 12.0.0-beta.74 → 12.0.0-beta.75

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.
Files changed (81) hide show
  1. package/dist/index.d.ts +133 -126
  2. package/dist/index.js +567 -253
  3. package/dist/index.mjs +569 -256
  4. package/dist/types/components/Form/SchemaFormContext.d.ts +3 -2
  5. package/dist/types/components/Form/components/fields/BooleanPicker.d.ts +1 -1
  6. package/dist/types/components/Form/components/fields/ColumnRenderer.d.ts +3 -2
  7. package/dist/types/components/Form/components/fields/DateTimePicker.d.ts +1 -1
  8. package/dist/types/components/Form/components/fields/FilePicker.d.ts +1 -1
  9. package/dist/types/components/Form/components/fields/ObjectInput.d.ts +1 -1
  10. package/dist/types/components/Form/components/fields/RecordInput.d.ts +1 -1
  11. package/dist/types/components/Form/components/fields/StringInputField.d.ts +1 -1
  12. package/dist/types/components/Form/components/fields/TextAreaInput.d.ts +1 -1
  13. package/dist/types/components/Form/components/fields/TimePicker.d.ts +1 -1
  14. package/dist/types/components/Form/components/types/CustomJSONSchema7.d.ts +3 -0
  15. package/dist/types/components/Form/useForm.d.ts +4 -2
  16. package/dist/types/components/Form/utils/ajvResolver.d.ts +13 -0
  17. package/dist/types/components/Form/utils/buildErrorMessages.d.ts +5 -1
  18. package/dist/types/components/Form/utils/getFieldError.d.ts +6 -0
  19. package/dist/types/components/Form/utils/useFormI18n.d.ts +1 -1
  20. package/dist/types/components/Form/utils/validateData.d.ts +2 -2
  21. package/dist/types/components/ui/field.d.ts +3 -3
  22. package/package.json +1 -1
  23. package/dist/types/components/Controls/DensityFeature.d.ts +0 -23
  24. package/dist/types/components/Controls/DensityToggleButton.d.ts +0 -6
  25. package/dist/types/components/Controls/EditFilterButton.d.ts +0 -9
  26. package/dist/types/components/Controls/EditOrderButton.d.ts +0 -7
  27. package/dist/types/components/Controls/EditSortingButton.d.ts +0 -7
  28. package/dist/types/components/Controls/EditViewButton.d.ts +0 -7
  29. package/dist/types/components/Controls/FilterDialog.d.ts +0 -5
  30. package/dist/types/components/Controls/PageSizeControl.d.ts +0 -4
  31. package/dist/types/components/Controls/Pagination.d.ts +0 -1
  32. package/dist/types/components/Controls/ResetFilteringButton.d.ts +0 -4
  33. package/dist/types/components/Controls/ResetSelectionButton.d.ts +0 -4
  34. package/dist/types/components/Controls/ResetSortingButton.d.ts +0 -4
  35. package/dist/types/components/Controls/RowCountText.d.ts +0 -1
  36. package/dist/types/components/Controls/SelectAllRowsToggle.d.ts +0 -8
  37. package/dist/types/components/Controls/TablePagination.d.ts +0 -1
  38. package/dist/types/components/Controls/ViewDialog.d.ts +0 -5
  39. package/dist/types/components/DataTable/CardHeader.d.ts +0 -13
  40. package/dist/types/components/DataTable/DataDisplay.d.ts +0 -6
  41. package/dist/types/components/DataTable/ReloadButton.d.ts +0 -5
  42. package/dist/types/components/DataTable/Table.d.ts +0 -10
  43. package/dist/types/components/DataTable/TableBody.d.ts +0 -21
  44. package/dist/types/components/DataTable/TableCardContainer.d.ts +0 -7
  45. package/dist/types/components/DataTable/TableCards.d.ts +0 -11
  46. package/dist/types/components/DataTable/TableComponent.d.ts +0 -6
  47. package/dist/types/components/DataTable/TableControls.d.ts +0 -21
  48. package/dist/types/components/DataTable/TableFilter.d.ts +0 -1
  49. package/dist/types/components/DataTable/TableFilterTags.d.ts +0 -1
  50. package/dist/types/components/DataTable/TableFilters.d.ts +0 -1
  51. package/dist/types/components/DataTable/TableFooter.d.ts +0 -9
  52. package/dist/types/components/DataTable/TableHeader.d.ts +0 -13
  53. package/dist/types/components/DataTable/TableLoadingComponent.d.ts +0 -5
  54. package/dist/types/components/DataTable/TableOrderer.d.ts +0 -1
  55. package/dist/types/components/DataTable/TableSelector.d.ts +0 -1
  56. package/dist/types/components/DataTable/TableSorter.d.ts +0 -1
  57. package/dist/types/components/DataTable/TableViewer.d.ts +0 -1
  58. package/dist/types/components/DataTable/TextCell.d.ts +0 -10
  59. package/dist/types/components/DataTable/components/EmptyState.d.ts +0 -5
  60. package/dist/types/components/DataTable/components/ErrorAlert.d.ts +0 -4
  61. package/dist/types/components/DataTable/components/RecordDisplay.d.ts +0 -9
  62. package/dist/types/components/DataTable/components/TextCell.d.ts +0 -10
  63. package/dist/types/components/Filter/DateRangeFilter.d.ts +0 -9
  64. package/dist/types/components/Filter/FilterOptions.d.ts +0 -4
  65. package/dist/types/components/Form/Form.d.ts +0 -36
  66. package/dist/types/components/Form/components/ArrayRenderer.d.ts +0 -7
  67. package/dist/types/components/Form/components/BooleanPicker.d.ts +0 -7
  68. package/dist/types/components/Form/components/ColumnRenderer.d.ts +0 -7
  69. package/dist/types/components/Form/components/DatePicker.d.ts +0 -7
  70. package/dist/types/components/Form/components/EnumPicker.d.ts +0 -8
  71. package/dist/types/components/Form/components/FilePicker.d.ts +0 -5
  72. package/dist/types/components/Form/components/IdPicker.d.ts +0 -8
  73. package/dist/types/components/Form/components/IdViewer.d.ts +0 -5
  74. package/dist/types/components/Form/components/NumberInputField.d.ts +0 -7
  75. package/dist/types/components/Form/components/ObjectInput.d.ts +0 -7
  76. package/dist/types/components/Form/components/RecordInput.d.ts +0 -7
  77. package/dist/types/components/Form/components/SchemaRenderer.d.ts +0 -7
  78. package/dist/types/components/Form/components/StringInputField.d.ts +0 -20
  79. package/dist/types/components/Form/components/TagPicker.d.ts +0 -30
  80. package/dist/types/components/Form/utils/translateWrapper.d.ts +0 -6
  81. package/dist/types/components/Form/utils/validation.d.ts +0 -104
package/dist/index.js CHANGED
@@ -31,7 +31,6 @@ var axios = require('axios');
31
31
  var reactHookForm = require('react-hook-form');
32
32
  var Ajv = require('ajv');
33
33
  var addFormats = require('ajv-formats');
34
- var addErrors = require('ajv-errors');
35
34
  var dayjs = require('dayjs');
36
35
  var utc = require('dayjs/plugin/utc');
37
36
  var timezone = require('dayjs/plugin/timezone');
@@ -3664,16 +3663,6 @@ const TableDataDisplay = ({ colorPalette, emptyComponent, }) => {
3664
3663
  })] }));
3665
3664
  };
3666
3665
 
3667
- const AccordionItemTrigger = React__namespace.forwardRef(function AccordionItemTrigger(props, ref) {
3668
- const { children, indicatorPlacement = "end", ...rest } = props;
3669
- return (jsxRuntime.jsxs(react.Accordion.ItemTrigger, { ...rest, ref: ref, children: [indicatorPlacement === "start" && (jsxRuntime.jsx(react.Accordion.ItemIndicator, { rotate: { base: "-90deg", _open: "0deg" }, children: jsxRuntime.jsx(lu.LuChevronDown, {}) })), jsxRuntime.jsx(react.HStack, { gap: "4", flex: "1", textAlign: "start", width: "full", children: children }), indicatorPlacement === "end" && (jsxRuntime.jsx(react.Accordion.ItemIndicator, { children: jsxRuntime.jsx(lu.LuChevronDown, {}) }))] }));
3670
- });
3671
- const AccordionItemContent = React__namespace.forwardRef(function AccordionItemContent(props, ref) {
3672
- return (jsxRuntime.jsx(react.Accordion.ItemContent, { children: jsxRuntime.jsx(react.Accordion.ItemBody, { ...props, ref: ref }) }));
3673
- });
3674
- const AccordionRoot = react.Accordion.Root;
3675
- const AccordionItem = react.Accordion.Item;
3676
-
3677
3666
  //@ts-expect-error TODO: find appropriate type
3678
3667
  const SchemaFormContext = React.createContext({
3679
3668
  schema: {},
@@ -3693,19 +3682,23 @@ const SchemaFormContext = React.createContext({
3693
3682
  },
3694
3683
  requireConfirmation: false,
3695
3684
  onFormSubmit: async () => { },
3685
+ ajvResolver: async () => ({ values: {}, errors: {} }),
3696
3686
  });
3697
3687
 
3698
3688
  const useSchemaContext = () => {
3699
3689
  return React.useContext(SchemaFormContext);
3700
3690
  };
3701
3691
 
3692
+ const clearEmptyString = (object) => {
3693
+ return Object.fromEntries(Object.entries(object).filter(([, value]) => value !== ""));
3694
+ };
3695
+
3702
3696
  const validateData = (data, schema) => {
3703
3697
  const ajv = new Ajv({
3704
3698
  strict: false,
3705
3699
  allErrors: true,
3706
3700
  });
3707
3701
  addFormats(ajv);
3708
- addErrors(ajv);
3709
3702
  const validate = ajv.compile(schema);
3710
3703
  const validationResult = validate(data);
3711
3704
  const errors = validate.errors;
@@ -3717,8 +3710,183 @@ const validateData = (data, schema) => {
3717
3710
  };
3718
3711
  };
3719
3712
 
3720
- const clearEmptyString = (object) => {
3721
- return Object.fromEntries(Object.entries(object).filter(([, value]) => value !== ""));
3713
+ /**
3714
+ * Gets the schema node for a field by following the path from root schema
3715
+ */
3716
+ const getSchemaNodeForField = (schema, fieldPath) => {
3717
+ if (!fieldPath || fieldPath === '') {
3718
+ return schema;
3719
+ }
3720
+ const pathParts = fieldPath.split('.');
3721
+ let currentSchema = schema;
3722
+ for (const part of pathParts) {
3723
+ if (currentSchema &&
3724
+ currentSchema.properties &&
3725
+ currentSchema.properties[part] &&
3726
+ typeof currentSchema.properties[part] === 'object' &&
3727
+ currentSchema.properties[part] !== null) {
3728
+ currentSchema = currentSchema.properties[part];
3729
+ }
3730
+ else {
3731
+ return undefined;
3732
+ }
3733
+ }
3734
+ return currentSchema;
3735
+ };
3736
+ /**
3737
+ * Converts AJV error objects to react-hook-form field errors format
3738
+ */
3739
+ const convertAjvErrorsToFieldErrors = (errors, schema) => {
3740
+ if (!errors || errors.length === 0) {
3741
+ return {};
3742
+ }
3743
+ const fieldErrors = {};
3744
+ errors.forEach((error) => {
3745
+ let fieldName = '';
3746
+ // Special handling for required keyword: map to the specific missing property
3747
+ if (error.keyword === 'required') {
3748
+ const basePath = (error.instancePath || '')
3749
+ .replace(/^\//, '')
3750
+ .replace(/\//g, '.');
3751
+ const missingProperty = (error.params &&
3752
+ error.params.missingProperty);
3753
+ if (missingProperty) {
3754
+ fieldName = basePath
3755
+ ? `${basePath}.${missingProperty}`
3756
+ : missingProperty;
3757
+ }
3758
+ else {
3759
+ // Fallback to schemaPath conversion if missingProperty is unavailable
3760
+ fieldName = (error.schemaPath || '')
3761
+ .replace(/^#\//, '#.')
3762
+ .replace(/\//g, '.');
3763
+ }
3764
+ }
3765
+ else {
3766
+ const fieldPath = error.instancePath || error.schemaPath;
3767
+ if (fieldPath) {
3768
+ fieldName = fieldPath.replace(/^\//, '').replace(/\//g, '.');
3769
+ }
3770
+ }
3771
+ if (fieldName) {
3772
+ // Get the schema node for this field to check for custom error messages
3773
+ const fieldSchema = getSchemaNodeForField(schema, fieldName);
3774
+ const customMessage = fieldSchema?.errorMessages?.[error.keyword];
3775
+ // Provide helpful fallback message if no custom message is provided
3776
+ const fallbackMessage = customMessage ||
3777
+ `Missing error message for ${error.keyword}. Add errorMessages.${error.keyword} to schema for field '${fieldName}'`;
3778
+ if (error.keyword === 'required') {
3779
+ // Required errors override any existing non-required errors for this field
3780
+ fieldErrors[fieldName] = {
3781
+ type: 'required',
3782
+ keyword: error.keyword,
3783
+ params: error.params,
3784
+ message: fallbackMessage,
3785
+ };
3786
+ }
3787
+ else {
3788
+ const existing = fieldErrors[fieldName];
3789
+ if (existing) {
3790
+ // Do not override required errors
3791
+ if (existing.type === 'required') {
3792
+ return;
3793
+ }
3794
+ // Combine messages if multiple errors for same field
3795
+ existing.message = existing.message
3796
+ ? `${existing.message}; ${fallbackMessage}`
3797
+ : fallbackMessage;
3798
+ }
3799
+ else {
3800
+ fieldErrors[fieldName] = {
3801
+ type: error.keyword,
3802
+ keyword: error.keyword,
3803
+ params: error.params,
3804
+ message: fallbackMessage,
3805
+ };
3806
+ }
3807
+ }
3808
+ }
3809
+ });
3810
+ return fieldErrors;
3811
+ };
3812
+ /**
3813
+ * AJV resolver for react-hook-form
3814
+ * Integrates AJV validation with react-hook-form's validation system
3815
+ */
3816
+ /**
3817
+ * Strips null, undefined, and empty string values from an object
3818
+ */
3819
+ const stripEmptyValues = (obj) => {
3820
+ if (obj === null || obj === undefined) {
3821
+ return undefined;
3822
+ }
3823
+ if (typeof obj === 'string' && obj.trim() === '') {
3824
+ return undefined;
3825
+ }
3826
+ if (Array.isArray(obj)) {
3827
+ const filtered = obj
3828
+ .map(stripEmptyValues)
3829
+ .filter((item) => item !== undefined);
3830
+ return filtered.length > 0 ? filtered : undefined;
3831
+ }
3832
+ if (typeof obj === 'object' && obj !== null) {
3833
+ const result = {};
3834
+ let hasValues = false;
3835
+ for (const [key, value] of Object.entries(obj)) {
3836
+ const cleanedValue = stripEmptyValues(value);
3837
+ if (cleanedValue !== undefined) {
3838
+ result[key] = cleanedValue;
3839
+ hasValues = true;
3840
+ }
3841
+ }
3842
+ return hasValues ? result : undefined;
3843
+ }
3844
+ return obj;
3845
+ };
3846
+ const ajvResolver = (schema) => {
3847
+ return async (values) => {
3848
+ try {
3849
+ // Strip empty values before validation
3850
+ const cleanedValues = stripEmptyValues(values);
3851
+ // Use empty object for validation if all values were stripped
3852
+ const valuesToValidate = cleanedValues === undefined ? {} : cleanedValues;
3853
+ const { isValid, errors } = validateData(valuesToValidate, schema);
3854
+ console.debug('AJV Validation Result:', {
3855
+ isValid,
3856
+ errors,
3857
+ cleanedValues,
3858
+ valuesToValidate,
3859
+ });
3860
+ if (isValid) {
3861
+ return {
3862
+ values: (cleanedValues || {}),
3863
+ errors: {},
3864
+ };
3865
+ }
3866
+ const fieldErrors = convertAjvErrorsToFieldErrors(errors, schema);
3867
+ console.debug('AJV Validation Failed:', {
3868
+ errors,
3869
+ fieldErrors,
3870
+ cleanedValues,
3871
+ valuesToValidate,
3872
+ });
3873
+ return {
3874
+ values: {},
3875
+ errors: fieldErrors,
3876
+ };
3877
+ }
3878
+ catch (error) {
3879
+ return {
3880
+ values: {},
3881
+ errors: {
3882
+ root: {
3883
+ type: 'validation',
3884
+ message: error instanceof Error ? error.message : 'Validation failed',
3885
+ },
3886
+ },
3887
+ };
3888
+ }
3889
+ };
3722
3890
  };
3723
3891
 
3724
3892
  const idPickerSanityCheck = (column, foreign_key) => {
@@ -3760,33 +3928,16 @@ const FormRoot = ({ schema, idMap, setIdMap, form, serverUrl, translate, childre
3760
3928
  const onSubmitSuccess = () => {
3761
3929
  setIsSuccess(true);
3762
3930
  };
3763
- const validateFormData = (data) => {
3764
- try {
3765
- const { isValid, errors } = validateData(data, schema);
3766
- return {
3767
- isValid,
3768
- errors,
3769
- };
3770
- }
3771
- catch (error) {
3772
- return {
3773
- isValid: false,
3774
- errors: [
3775
- {
3776
- field: 'validation',
3777
- message: error instanceof Error ? error.message : 'Unknown error',
3778
- },
3779
- ],
3780
- };
3781
- }
3782
- };
3783
3931
  const defaultOnSubmit = async (promise) => {
3784
3932
  try {
3933
+ console.log('onBeforeSubmit');
3785
3934
  onBeforeSubmit();
3786
3935
  await promise;
3936
+ console.log('onSubmitSuccess');
3787
3937
  onSubmitSuccess();
3788
3938
  }
3789
3939
  catch (error) {
3940
+ console.log('onSubmitError', error);
3790
3941
  onSubmitError(error);
3791
3942
  }
3792
3943
  finally {
@@ -3796,7 +3947,7 @@ const FormRoot = ({ schema, idMap, setIdMap, form, serverUrl, translate, childre
3796
3947
  const defaultSubmitPromise = (data) => {
3797
3948
  const options = {
3798
3949
  method: 'POST',
3799
- url: `${requestUrl}`,
3950
+ url: `${serverUrl}`,
3800
3951
  data: clearEmptyString(data),
3801
3952
  ...requestOptions,
3802
3953
  };
@@ -3804,23 +3955,13 @@ const FormRoot = ({ schema, idMap, setIdMap, form, serverUrl, translate, childre
3804
3955
  };
3805
3956
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
3806
3957
  const onFormSubmit = async (data) => {
3807
- // Validate data using AJV before submission
3808
- const validationResult = validateFormData(data);
3809
- if (!validationResult.isValid) {
3810
- // Set validation errors
3811
- const validationErrorMessage = {
3812
- type: 'validation',
3813
- errors: validationResult.errors,
3814
- message: translate.t('validation_error'),
3815
- };
3816
- onSubmitError(validationErrorMessage);
3817
- return;
3818
- }
3958
+ // AJV validation is now handled by react-hook-form resolver
3959
+ // This function will only be called if validation passes
3819
3960
  if (onSubmit === undefined) {
3820
- await defaultOnSubmit(defaultSubmitPromise(data));
3961
+ await defaultOnSubmit(Promise.resolve(defaultSubmitPromise(data)));
3821
3962
  return;
3822
3963
  }
3823
- await defaultOnSubmit(onSubmit(data));
3964
+ await defaultOnSubmit(Promise.resolve(onSubmit(data)));
3824
3965
  };
3825
3966
  return (jsxRuntime.jsx(SchemaFormContext.Provider, { value: {
3826
3967
  schema,
@@ -3856,6 +3997,7 @@ const FormRoot = ({ schema, idMap, setIdMap, form, serverUrl, translate, childre
3856
3997
  dateTimePickerLabels,
3857
3998
  idPickerLabels,
3858
3999
  enumPickerLabels,
4000
+ ajvResolver: ajvResolver(schema),
3859
4001
  }, children: jsxRuntime.jsx(reactHookForm.FormProvider, { ...form, children: children }) }));
3860
4002
  };
3861
4003
 
@@ -3901,20 +4043,22 @@ const ArrayRenderer = ({ schema, column, prefix, }) => {
3901
4043
 
3902
4044
  const Field = React__namespace.forwardRef(function Field(props, ref) {
3903
4045
  const { label, children, helperText, errorText, optionalText, ...rest } = props;
3904
- return (jsxRuntime.jsxs(react.Field.Root, { ref: ref, ...rest, children: [label && (jsxRuntime.jsxs(react.Field.Label, { children: [label, jsxRuntime.jsx(react.Field.RequiredIndicator, { fallback: optionalText })] })), children, helperText && (jsxRuntime.jsx(react.Field.HelperText, { children: helperText })), errorText && (jsxRuntime.jsx(react.Field.ErrorText, { children: errorText }))] }));
4046
+ return (jsxRuntime.jsxs(react.Field.Root, { ref: ref, ...rest, children: [label && (jsxRuntime.jsxs(react.Field.Label, { children: [label, jsxRuntime.jsx(react.Field.RequiredIndicator, { color: rest.invalid && rest.required ? 'red.500' : undefined, fallback: optionalText })] })), children, helperText && (jsxRuntime.jsx(react.Field.HelperText, { children: helperText })), !!errorText && (jsxRuntime.jsxs(react.Field.ErrorText, { children: [rest.required && rest.invalid && (jsxRuntime.jsx("span", { style: { color: 'var(--chakra-colors-red-500)' }, children: "* " })), errorText] }))] }));
3905
4047
  });
3906
4048
 
3907
4049
  const BooleanPicker = ({ schema, column, prefix }) => {
3908
4050
  const { watch, formState: { errors }, setValue, } = reactHookForm.useFormContext();
3909
4051
  const { translate } = useSchemaContext();
3910
- const { required, gridColumn = "span 12", gridRow = "span 1" } = schema;
4052
+ const { required, gridColumn = 'span 12', gridRow = 'span 1' } = schema;
3911
4053
  const isRequired = required?.some((columnId) => columnId === column);
3912
4054
  const colLabel = `${prefix}${column}`;
3913
4055
  const value = watch(colLabel);
3914
- return (jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, alignItems: "stretch", gridColumn,
3915
- gridRow, children: [jsxRuntime.jsx(CheckboxCard, { checked: value, variant: "surface", onChange: () => {
3916
- setValue(colLabel, !value);
3917
- } }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
4056
+ return (jsxRuntime.jsx(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, alignItems: 'stretch', gridColumn,
4057
+ gridRow, errorText: errors[`${colLabel}`]
4058
+ ? translate.t(removeIndex(`${colLabel}.field_required`))
4059
+ : undefined, invalid: !!errors[colLabel], children: jsxRuntime.jsx(CheckboxCard, { checked: value, variant: 'surface', onChange: () => {
4060
+ setValue(colLabel, !value);
4061
+ } }) }));
3918
4062
  };
3919
4063
 
3920
4064
  const CustomInput = ({ column, schema, prefix }) => {
@@ -4147,83 +4291,83 @@ const DatePicker = ({ column, schema, prefix }) => {
4147
4291
  console.error(e);
4148
4292
  }
4149
4293
  }, [selectedDate, dateFormat, colLabel, setValue]);
4150
- return (jsxRuntime.jsxs(Field, { label: formI18n.label(), required: isRequired, alignItems: 'stretch', gridColumn,
4151
- gridRow, children: [jsxRuntime.jsxs(PopoverRoot, { open: open, onOpenChange: (e) => setOpen(e.open), closeOnInteractOutside: true, children: [jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: jsxRuntime.jsxs(Button, { size: "sm", variant: "outline", onClick: () => {
4152
- setOpen(true);
4153
- }, justifyContent: 'start', children: [jsxRuntime.jsx(md.MdDateRange, {}), selectedDate !== undefined ? `${displayDate}` : ''] }) }), jsxRuntime.jsx(PopoverContent, { children: jsxRuntime.jsxs(PopoverBody, { children: [jsxRuntime.jsx(PopoverTitle, {}), jsxRuntime.jsx(DatePicker$1, { selected: new Date(selectedDate), onDateSelected: ({ date }) => {
4154
- setValue(colLabel, dayjs(date).format(dateFormat));
4155
- setOpen(false);
4156
- }, labels: {
4157
- monthNamesShort: dateTimePickerLabels?.monthNamesShort ?? [
4158
- formI18n.translate.t(`common.month_1`, {
4159
- defaultValue: 'January',
4160
- }),
4161
- formI18n.translate.t(`common.month_2`, {
4162
- defaultValue: 'February',
4163
- }),
4164
- formI18n.translate.t(`common.month_3`, {
4165
- defaultValue: 'March',
4166
- }),
4167
- formI18n.translate.t(`common.month_4`, {
4168
- defaultValue: 'April',
4169
- }),
4170
- formI18n.translate.t(`common.month_5`, {
4171
- defaultValue: 'May',
4172
- }),
4173
- formI18n.translate.t(`common.month_6`, {
4174
- defaultValue: 'June',
4175
- }),
4176
- formI18n.translate.t(`common.month_7`, {
4177
- defaultValue: 'July',
4178
- }),
4179
- formI18n.translate.t(`common.month_8`, {
4180
- defaultValue: 'August',
4181
- }),
4182
- formI18n.translate.t(`common.month_9`, {
4183
- defaultValue: 'September',
4184
- }),
4185
- formI18n.translate.t(`common.month_10`, {
4186
- defaultValue: 'October',
4187
- }),
4188
- formI18n.translate.t(`common.month_11`, {
4189
- defaultValue: 'November',
4190
- }),
4191
- formI18n.translate.t(`common.month_12`, {
4192
- defaultValue: 'December',
4193
- }),
4194
- ],
4195
- weekdayNamesShort: dateTimePickerLabels?.weekdayNamesShort ?? [
4196
- formI18n.translate.t(`common.weekday_1`, {
4197
- defaultValue: 'Sun',
4198
- }),
4199
- formI18n.translate.t(`common.weekday_2`, {
4200
- defaultValue: 'Mon',
4201
- }),
4202
- formI18n.translate.t(`common.weekday_3`, {
4203
- defaultValue: 'Tue',
4204
- }),
4205
- formI18n.translate.t(`common.weekday_4`, {
4206
- defaultValue: 'Wed',
4207
- }),
4208
- formI18n.translate.t(`common.weekday_5`, {
4209
- defaultValue: 'Thu',
4210
- }),
4211
- formI18n.translate.t(`common.weekday_6`, {
4212
- defaultValue: 'Fri',
4213
- }),
4214
- formI18n.translate.t(`common.weekday_7`, {
4215
- defaultValue: 'Sat',
4216
- }),
4217
- ],
4218
- backButtonLabel: dateTimePickerLabels?.backButtonLabel ??
4219
- formI18n.translate.t(`common.back_button`, {
4220
- defaultValue: 'Back',
4221
- }),
4222
- forwardButtonLabel: dateTimePickerLabels?.forwardButtonLabel ??
4223
- formI18n.translate.t(`common.forward_button`, {
4224
- defaultValue: 'Forward',
4225
- }),
4226
- } })] }) })] }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: 'red.400', children: formI18n.required() }))] }));
4294
+ return (jsxRuntime.jsx(Field, { label: formI18n.label(), required: isRequired, alignItems: 'stretch', gridColumn,
4295
+ gridRow, errorText: errors[`${colLabel}`] ? formI18n.required() : undefined, invalid: !!errors[colLabel], children: jsxRuntime.jsxs(PopoverRoot, { open: open, onOpenChange: (e) => setOpen(e.open), closeOnInteractOutside: true, children: [jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: jsxRuntime.jsxs(Button, { size: "sm", variant: "outline", onClick: () => {
4296
+ setOpen(true);
4297
+ }, justifyContent: 'start', children: [jsxRuntime.jsx(md.MdDateRange, {}), selectedDate !== undefined ? `${displayDate}` : ''] }) }), jsxRuntime.jsx(PopoverContent, { children: jsxRuntime.jsxs(PopoverBody, { children: [jsxRuntime.jsx(PopoverTitle, {}), jsxRuntime.jsx(DatePicker$1, { selected: new Date(selectedDate), onDateSelected: ({ date }) => {
4298
+ setValue(colLabel, dayjs(date).format(dateFormat));
4299
+ setOpen(false);
4300
+ }, labels: {
4301
+ monthNamesShort: dateTimePickerLabels?.monthNamesShort ?? [
4302
+ formI18n.translate.t(`common.month_1`, {
4303
+ defaultValue: 'January',
4304
+ }),
4305
+ formI18n.translate.t(`common.month_2`, {
4306
+ defaultValue: 'February',
4307
+ }),
4308
+ formI18n.translate.t(`common.month_3`, {
4309
+ defaultValue: 'March',
4310
+ }),
4311
+ formI18n.translate.t(`common.month_4`, {
4312
+ defaultValue: 'April',
4313
+ }),
4314
+ formI18n.translate.t(`common.month_5`, {
4315
+ defaultValue: 'May',
4316
+ }),
4317
+ formI18n.translate.t(`common.month_6`, {
4318
+ defaultValue: 'June',
4319
+ }),
4320
+ formI18n.translate.t(`common.month_7`, {
4321
+ defaultValue: 'July',
4322
+ }),
4323
+ formI18n.translate.t(`common.month_8`, {
4324
+ defaultValue: 'August',
4325
+ }),
4326
+ formI18n.translate.t(`common.month_9`, {
4327
+ defaultValue: 'September',
4328
+ }),
4329
+ formI18n.translate.t(`common.month_10`, {
4330
+ defaultValue: 'October',
4331
+ }),
4332
+ formI18n.translate.t(`common.month_11`, {
4333
+ defaultValue: 'November',
4334
+ }),
4335
+ formI18n.translate.t(`common.month_12`, {
4336
+ defaultValue: 'December',
4337
+ }),
4338
+ ],
4339
+ weekdayNamesShort: dateTimePickerLabels?.weekdayNamesShort ?? [
4340
+ formI18n.translate.t(`common.weekday_1`, {
4341
+ defaultValue: 'Sun',
4342
+ }),
4343
+ formI18n.translate.t(`common.weekday_2`, {
4344
+ defaultValue: 'Mon',
4345
+ }),
4346
+ formI18n.translate.t(`common.weekday_3`, {
4347
+ defaultValue: 'Tue',
4348
+ }),
4349
+ formI18n.translate.t(`common.weekday_4`, {
4350
+ defaultValue: 'Wed',
4351
+ }),
4352
+ formI18n.translate.t(`common.weekday_5`, {
4353
+ defaultValue: 'Thu',
4354
+ }),
4355
+ formI18n.translate.t(`common.weekday_6`, {
4356
+ defaultValue: 'Fri',
4357
+ }),
4358
+ formI18n.translate.t(`common.weekday_7`, {
4359
+ defaultValue: 'Sat',
4360
+ }),
4361
+ ],
4362
+ backButtonLabel: dateTimePickerLabels?.backButtonLabel ??
4363
+ formI18n.translate.t(`common.back_button`, {
4364
+ defaultValue: 'Back',
4365
+ }),
4366
+ forwardButtonLabel: dateTimePickerLabels?.forwardButtonLabel ??
4367
+ formI18n.translate.t(`common.forward_button`, {
4368
+ defaultValue: 'Forward',
4369
+ }),
4370
+ } })] }) })] }) }));
4227
4371
  };
4228
4372
 
4229
4373
  function filterArray(array, searchTerm) {
@@ -4258,7 +4402,9 @@ const EnumPicker = ({ column, isMultiple = false, schema, prefix, showTotalAndLi
4258
4402
  };
4259
4403
  if (variant === 'radio') {
4260
4404
  return (jsxRuntime.jsx(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, alignItems: 'stretch', gridColumn,
4261
- gridRow, children: jsxRuntime.jsx(react.RadioGroup.Root, { defaultValue: "1", children: jsxRuntime.jsx(react.HStack, { gap: "6", children: filterArray(dataList, searchText ?? '').map((item) => {
4405
+ gridRow, errorText: errors[`${colLabel}`]
4406
+ ? translate.t(removeIndex(`${colLabel}.field_required`))
4407
+ : undefined, invalid: !!errors[colLabel], children: jsxRuntime.jsx(react.RadioGroup.Root, { defaultValue: "1", children: jsxRuntime.jsx(react.HStack, { gap: "6", children: filterArray(dataList, searchText ?? '').map((item) => {
4262
4408
  return (jsxRuntime.jsxs(react.RadioGroup.Item, { onClick: () => {
4263
4409
  if (!isMultiple) {
4264
4410
  setOpenSearchResult(false);
@@ -4273,7 +4419,9 @@ const EnumPicker = ({ column, isMultiple = false, schema, prefix, showTotalAndLi
4273
4419
  }) }) }) }));
4274
4420
  }
4275
4421
  return (jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, alignItems: 'stretch', gridColumn,
4276
- gridRow, children: [isMultiple && (jsxRuntime.jsxs(react.Flex, { flexFlow: 'wrap', gap: 1, children: [watchEnums.map((enumValue) => {
4422
+ gridRow, errorText: errors[`${colLabel}`]
4423
+ ? translate.t(removeIndex(`${colLabel}.field_required`))
4424
+ : undefined, invalid: !!errors[colLabel], children: [isMultiple && (jsxRuntime.jsxs(react.Flex, { flexFlow: 'wrap', gap: 1, children: [watchEnums.map((enumValue) => {
4277
4425
  const item = enumValue;
4278
4426
  if (!!item === false) {
4279
4427
  return jsxRuntime.jsx(jsxRuntime.Fragment, {});
@@ -4328,7 +4476,7 @@ const EnumPicker = ({ column, isMultiple = false, schema, prefix, showTotalAndLi
4328
4476
  ? renderDisplay(item)
4329
4477
  : translate.t(removeIndex(`${colLabel}.${item}`)) }, `${colLabel}-${item}`));
4330
4478
  }) }), isDirty && (jsxRuntime.jsx(jsxRuntime.Fragment, { children: dataList.length <= 0 && (jsxRuntime.jsx(jsxRuntime.Fragment, { children: enumPickerLabels?.emptySearchResult ??
4331
- translate.t(removeIndex(`${colLabel}.empty_search_result`)) })) }))] })] }) })] }), errors[`${colLabel}`] && (jsxRuntime.jsx(react.Text, { color: 'red.400', children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
4479
+ translate.t(removeIndex(`${colLabel}.empty_search_result`)) })) }))] })] }) })] })] }));
4332
4480
  };
4333
4481
 
4334
4482
  function isEnteringWindow(_ref) {
@@ -4686,20 +4834,22 @@ const FileDropzone = ({ children = undefined, gridProps = {}, onDrop = () => { }
4686
4834
  const FilePicker = ({ column, schema, prefix }) => {
4687
4835
  const { setValue, formState: { errors }, watch, } = reactHookForm.useFormContext();
4688
4836
  const { translate } = useSchemaContext();
4689
- const { required, gridColumn = "span 12", gridRow = "span 1", } = schema;
4837
+ const { required, gridColumn = 'span 12', gridRow = 'span 1', } = schema;
4690
4838
  const isRequired = required?.some((columnId) => columnId === column);
4691
4839
  const currentFiles = (watch(column) ?? []);
4692
4840
  const colLabel = `${prefix}${column}`;
4693
- return (jsxRuntime.jsxs(Field, { label: `${translate.t(`${colLabel}.field_label`)}`, required: isRequired, gridColumn: gridColumn ?? "span 4", gridRow: gridRow ?? "span 1", display: "grid", gridTemplateRows: "auto 1fr auto", alignItems: "stretch", children: [jsxRuntime.jsx(FileDropzone, { onDrop: ({ files }) => {
4841
+ return (jsxRuntime.jsxs(Field, { label: `${translate.t(`${colLabel}.field_label`)}`, required: isRequired, gridColumn: gridColumn ?? 'span 4', gridRow: gridRow ?? 'span 1', display: 'grid', gridTemplateRows: 'auto 1fr auto', alignItems: 'stretch', errorText: errors[`${colLabel}`]
4842
+ ? translate.t(removeIndex(`${colLabel}.field_required`))
4843
+ : undefined, invalid: !!errors[colLabel], children: [jsxRuntime.jsx(FileDropzone, { onDrop: ({ files }) => {
4694
4844
  const newFiles = files.filter(({ name }) => !currentFiles.some((cur) => cur.name === name));
4695
4845
  setValue(colLabel, [...currentFiles, ...newFiles]);
4696
- }, placeholder: translate.t(removeIndex(`${colLabel}.fileDropzone`)) }), jsxRuntime.jsx(react.Flex, { flexFlow: "column", gap: 1, children: currentFiles.map((file) => {
4697
- return (jsxRuntime.jsx(react.Card.Root, { variant: "subtle", children: jsxRuntime.jsxs(react.Card.Body, { gap: "2", cursor: "pointer", onClick: () => {
4846
+ }, placeholder: translate.t(removeIndex(`${colLabel}.fileDropzone`)) }), jsxRuntime.jsx(react.Flex, { flexFlow: 'column', gap: 1, children: currentFiles.map((file) => {
4847
+ return (jsxRuntime.jsx(react.Card.Root, { variant: 'subtle', children: jsxRuntime.jsxs(react.Card.Body, { gap: "2", cursor: 'pointer', onClick: () => {
4698
4848
  setValue(column, currentFiles.filter(({ name }) => {
4699
4849
  return name !== file.name;
4700
4850
  }));
4701
- }, display: "flex", flexFlow: "row", alignItems: "center", padding: "2", children: [file.type.startsWith("image/") && (jsxRuntime.jsx(react.Image, { src: URL.createObjectURL(file), alt: file.name, boxSize: "50px", objectFit: "cover", borderRadius: "md", marginRight: "2" })), jsxRuntime.jsx(react.Box, { children: file.name }), jsxRuntime.jsx(ti.TiDeleteOutline, {})] }) }, file.name));
4702
- }) }), errors[`${colLabel}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
4851
+ }, display: 'flex', flexFlow: 'row', alignItems: 'center', padding: '2', children: [file.type.startsWith('image/') && (jsxRuntime.jsx(react.Image, { src: URL.createObjectURL(file), alt: file.name, boxSize: "50px", objectFit: "cover", borderRadius: "md", marginRight: "2" })), jsxRuntime.jsx(react.Box, { children: file.name }), jsxRuntime.jsx(ti.TiDeleteOutline, {})] }) }, file.name));
4852
+ }) })] }));
4703
4853
  };
4704
4854
 
4705
4855
  const ToggleTip = React__namespace.forwardRef(function ToggleTip(props, ref) {
@@ -4888,7 +5038,7 @@ const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
4888
5038
  return record[display_column];
4889
5039
  };
4890
5040
  return (jsxRuntime.jsxs(Field, { label: formI18n.label(), required: isRequired, alignItems: 'stretch', gridColumn,
4891
- gridRow, children: [isMultiple && (jsxRuntime.jsxs(react.Flex, { flexFlow: 'wrap', gap: 1, children: [watchIds.map((id) => {
5041
+ gridRow, errorText: errors[`${colLabel}`] ? formI18n.required() : undefined, invalid: !!errors[colLabel], children: [isMultiple && (jsxRuntime.jsxs(react.Flex, { flexFlow: 'wrap', gap: 1, children: [watchIds.map((id) => {
4892
5042
  const item = idMap[id];
4893
5043
  if (item === undefined) {
4894
5044
  return (jsxRuntime.jsx(react.Text, { children: idPickerLabels?.undefined ?? formI18n.t('undefined') }, id));
@@ -4939,7 +5089,7 @@ const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
4939
5089
  ? idPickerLabels?.emptySearchResult ??
4940
5090
  formI18n.t('empty_search_result')
4941
5091
  : idPickerLabels?.initialResults ??
4942
- formI18n.t('initial_results') })) }), jsxRuntime.jsx(PaginationRoot, { justifySelf: 'center', count: count, pageSize: limit, defaultPage: 1, page: page + 1, onPageChange: (e) => setPage(e.page - 1), children: jsxRuntime.jsxs(react.HStack, { gap: "4", children: [jsxRuntime.jsx(PaginationPrevTrigger, {}), count > 0 && jsxRuntime.jsx(PaginationPageText, {}), jsxRuntime.jsx(PaginationNextTrigger, {})] }) })] }))] }) })] }), errors[`${colLabel}`] && (jsxRuntime.jsx(react.Text, { color: 'red.400', children: formI18n.required() }))] }));
5092
+ formI18n.t('initial_results') })) }), jsxRuntime.jsx(PaginationRoot, { justifySelf: 'center', count: count, pageSize: limit, defaultPage: 1, page: page + 1, onPageChange: (e) => setPage(e.page - 1), children: jsxRuntime.jsxs(react.HStack, { gap: "4", children: [jsxRuntime.jsx(PaginationPrevTrigger, {}), count > 0 && jsxRuntime.jsx(PaginationPageText, {}), jsxRuntime.jsx(PaginationNextTrigger, {})] }) })] }))] }) })] })] }));
4943
5093
  };
4944
5094
 
4945
5095
  const NumberInputRoot = React__namespace.forwardRef(function NumberInput(props, ref) {
@@ -4950,20 +5100,84 @@ const NumberInputField$1 = react.NumberInput.Input;
4950
5100
  react.NumberInput.Scrubber;
4951
5101
  react.NumberInput.Label;
4952
5102
 
5103
+ /**
5104
+ * Gets the error message for a specific field from react-hook-form errors
5105
+ * Prioritizes required errors (#.required) over field-specific validation errors
5106
+ */
5107
+ const getFieldError = (errors, fieldName) => {
5108
+ // Check for form-level required errors first (highest priority)
5109
+ const requiredError = errors['#.required'];
5110
+ if (requiredError) {
5111
+ const requiredErrorMessage = extractErrorMessage(requiredError);
5112
+ if (requiredErrorMessage) {
5113
+ return requiredErrorMessage;
5114
+ }
5115
+ }
5116
+ // If no required errors, return field-specific error
5117
+ const fieldError = errors[fieldName];
5118
+ if (fieldError) {
5119
+ const fieldErrorMessage = extractErrorMessage(fieldError);
5120
+ if (fieldErrorMessage) {
5121
+ return fieldErrorMessage;
5122
+ }
5123
+ }
5124
+ return undefined;
5125
+ };
5126
+ /**
5127
+ * Helper function to extract error message from various error formats
5128
+ * Only returns message if explicitly provided, no fallback text
5129
+ */
5130
+ const extractErrorMessage = (error) => {
5131
+ if (!error) {
5132
+ return undefined;
5133
+ }
5134
+ // If it's a simple string error
5135
+ if (typeof error === 'string') {
5136
+ return error;
5137
+ }
5138
+ // If it's an error object with a message property
5139
+ if (error && typeof error === 'object' && 'message' in error) {
5140
+ return error.message;
5141
+ }
5142
+ // If it's an array of errors, get the first one
5143
+ if (Array.isArray(error) && error.length > 0) {
5144
+ const firstError = error[0];
5145
+ if (typeof firstError === 'string') {
5146
+ return firstError;
5147
+ }
5148
+ if (firstError &&
5149
+ typeof firstError === 'object' &&
5150
+ 'message' in firstError) {
5151
+ return firstError.message;
5152
+ }
5153
+ }
5154
+ // No fallback - return undefined if no message provided
5155
+ return undefined;
5156
+ };
5157
+
4953
5158
  const NumberInputField = ({ schema, column, prefix, }) => {
4954
5159
  const { setValue, formState: { errors }, watch, } = reactHookForm.useFormContext();
4955
5160
  const { translate } = useSchemaContext();
4956
- const { required, gridColumn = 'span 12', gridRow = 'span 1' } = schema;
5161
+ const { required, gridColumn = 'span 12', gridRow = 'span 1', numberStorageType = 'number', } = schema;
4957
5162
  const isRequired = required?.some((columnId) => columnId === column);
4958
5163
  const colLabel = `${prefix}${column}`;
4959
5164
  const value = watch(`${colLabel}`);
4960
- return (jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, gridColumn, gridRow, children: [jsxRuntime.jsx(NumberInputRoot, { value: value, onValueChange: (details) => {
4961
- setValue(`${colLabel}`, details.value); // Store as string to avoid floating-point precision issues
4962
- }, min: schema.minimum, max: schema.maximum, step: schema.multipleOf || 0.01, allowOverflow: false, clampValueOnBlur: false, inputMode: "decimal", formatOptions: schema.formatOptions, children: jsxRuntime.jsx(NumberInputField$1, { required: isRequired }) }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: 'red.400', children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
5165
+ const fieldError = getFieldError(errors, colLabel);
5166
+ return (jsxRuntime.jsx(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, gridColumn, gridRow, errorText: fieldError
5167
+ ? fieldError.includes('required')
5168
+ ? translate.t(removeIndex(`${colLabel}.field_required`))
5169
+ : fieldError
5170
+ : undefined, invalid: !!fieldError, children: jsxRuntime.jsx(NumberInputRoot, { value: value, onValueChange: (details) => {
5171
+ // Store as string or number based on configuration, default to number
5172
+ const value = numberStorageType === 'string'
5173
+ ? details.value
5174
+ : details.valueAsNumber;
5175
+ setValue(`${colLabel}`, value);
5176
+ }, min: schema.minimum, max: schema.maximum, step: schema.multipleOf || 0.01, allowOverflow: false, clampValueOnBlur: false, inputMode: "decimal", formatOptions: schema.formatOptions, children: jsxRuntime.jsx(NumberInputField$1, { required: isRequired }) }) }));
4963
5177
  };
4964
5178
 
4965
5179
  const ObjectInput = ({ schema, column, prefix }) => {
4966
- const { properties, gridColumn = "span 12", gridRow = "span 1", required, showLabel = true, } = schema;
5180
+ const { properties, gridColumn = 'span 12', gridRow = 'span 1', required, showLabel = true, } = schema;
4967
5181
  const { translate } = useSchemaContext();
4968
5182
  const colLabel = `${prefix}${column}`;
4969
5183
  const isRequired = required?.some((columnId) => columnId === column);
@@ -4971,29 +5185,32 @@ const ObjectInput = ({ schema, column, prefix }) => {
4971
5185
  if (properties === undefined) {
4972
5186
  throw new Error(`properties is undefined when using ObjectInput`);
4973
5187
  }
4974
- return (jsxRuntime.jsxs(react.Box, { gridRow, gridColumn, children: [showLabel && (jsxRuntime.jsxs(react.Box, { as: "label", children: [`${translate.t(removeIndex(`${colLabel}.field_label`))}`, isRequired && jsxRuntime.jsx("span", { children: "*" })] })), jsxRuntime.jsx(react.Grid, { bgColor: { base: "colorPalette.100", _dark: "colorPalette.900" }, p: 2, borderRadius: 4, borderWidth: 1, borderColor: {
4975
- base: "colorPalette.200",
4976
- _dark: "colorPalette.800",
4977
- }, gap: "4", padding: "4", gridTemplateColumns: "repeat(12, 1fr)", autoFlow: "row", children: Object.keys(properties ?? {}).map((key) => {
5188
+ return (jsxRuntime.jsxs(react.Box, { gridRow, gridColumn, children: [showLabel && (jsxRuntime.jsxs(react.Box, { as: "label", children: [`${translate.t(removeIndex(`${colLabel}.field_label`))}`, isRequired && jsxRuntime.jsx("span", { children: "*" })] })), jsxRuntime.jsx(react.Grid, { bgColor: { base: 'colorPalette.100', _dark: 'colorPalette.900' }, p: 2, borderRadius: 4, borderWidth: 1, borderColor: {
5189
+ base: 'colorPalette.200',
5190
+ _dark: 'colorPalette.800',
5191
+ }, gap: "4", padding: '4', gridTemplateColumns: 'repeat(12, 1fr)', autoFlow: 'row', children: Object.keys(properties ?? {}).map((key) => {
4978
5192
  return (
4979
5193
  // @ts-expect-error find suitable types
4980
5194
  jsxRuntime.jsx(ColumnRenderer, { column: `${key}`,
4981
5195
  prefix: `${prefix}${column}.`,
4982
- properties }, `form-${colLabel}-${key}`));
4983
- }) }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
5196
+ properties,
5197
+ parentRequired: required }, `form-${colLabel}-${key}`));
5198
+ }) }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: 'red.400', children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
4984
5199
  };
4985
5200
 
4986
5201
  const RecordInput$1 = ({ column, schema, prefix }) => {
4987
5202
  const { formState: { errors }, setValue, getValues, } = reactHookForm.useFormContext();
4988
5203
  const { translate } = useSchemaContext();
4989
- const { required, gridColumn = "span 12", gridRow = "span 1" } = schema;
5204
+ const { required, gridColumn = 'span 12', gridRow = 'span 1' } = schema;
4990
5205
  const isRequired = required?.some((columnId) => columnId === column);
4991
5206
  const entries = Object.entries(getValues(column) ?? {});
4992
5207
  const [showNewEntries, setShowNewEntries] = React.useState(false);
4993
5208
  const [newKey, setNewKey] = React.useState();
4994
5209
  const [newValue, setNewValue] = React.useState();
4995
- return (jsxRuntime.jsxs(Field, { label: `${translate.t(`${column}.field_label`)}`, required: isRequired, alignItems: "stretch", gridColumn, gridRow, children: [entries.map(([key, value]) => {
4996
- return (jsxRuntime.jsxs(react.Grid, { templateColumns: "1fr 1fr auto", gap: 1, children: [jsxRuntime.jsx(react.Input, { value: key, onChange: (e) => {
5210
+ return (jsxRuntime.jsxs(Field, { label: `${translate.t(`${column}.field_label`)}`, required: isRequired, alignItems: 'stretch', gridColumn, gridRow, errorText: errors[`${column}`]
5211
+ ? translate.t(`${column}.field_required`)
5212
+ : undefined, invalid: !!errors[column], children: [entries.map(([key, value]) => {
5213
+ return (jsxRuntime.jsxs(react.Grid, { templateColumns: '1fr 1fr auto', gap: 1, children: [jsxRuntime.jsx(react.Input, { value: key, onChange: (e) => {
4997
5214
  const filtered = entries.filter(([target]) => {
4998
5215
  return target !== key;
4999
5216
  });
@@ -5003,17 +5220,17 @@ const RecordInput$1 = ({ column, schema, prefix }) => {
5003
5220
  ...getValues(column),
5004
5221
  [key]: e.target.value,
5005
5222
  });
5006
- }, autoComplete: "off" }), jsxRuntime.jsx(react.IconButton, { variant: "ghost", onClick: () => {
5223
+ }, autoComplete: "off" }), jsxRuntime.jsx(react.IconButton, { variant: 'ghost', onClick: () => {
5007
5224
  const filtered = entries.filter(([target]) => {
5008
5225
  return target !== key;
5009
5226
  });
5010
5227
  setValue(column, Object.fromEntries([...filtered]));
5011
5228
  }, children: jsxRuntime.jsx(cg.CgClose, {}) })] }));
5012
- }), jsxRuntime.jsx(react.Show, { when: showNewEntries, children: jsxRuntime.jsxs(react.Card.Root, { children: [jsxRuntime.jsx(react.Card.Body, { gap: "2", children: jsxRuntime.jsxs(react.Grid, { templateColumns: "1fr 1fr auto", gap: 1, children: [jsxRuntime.jsx(react.Input, { value: newKey, onChange: (e) => {
5229
+ }), jsxRuntime.jsx(react.Show, { when: showNewEntries, children: jsxRuntime.jsxs(react.Card.Root, { children: [jsxRuntime.jsx(react.Card.Body, { gap: "2", children: jsxRuntime.jsxs(react.Grid, { templateColumns: '1fr 1fr auto', gap: 1, children: [jsxRuntime.jsx(react.Input, { value: newKey, onChange: (e) => {
5013
5230
  setNewKey(e.target.value);
5014
5231
  }, autoComplete: "off" }), jsxRuntime.jsx(react.Input, { value: newValue, onChange: (e) => {
5015
5232
  setNewValue(e.target.value);
5016
- }, autoComplete: "off" })] }) }), jsxRuntime.jsxs(react.Card.Footer, { justifyContent: "flex-end", children: [jsxRuntime.jsx(react.IconButton, { variant: "subtle", onClick: () => {
5233
+ }, autoComplete: "off" })] }) }), jsxRuntime.jsxs(react.Card.Footer, { justifyContent: "flex-end", children: [jsxRuntime.jsx(react.IconButton, { variant: 'subtle', onClick: () => {
5017
5234
  setShowNewEntries(false);
5018
5235
  setNewKey(undefined);
5019
5236
  setNewValue(undefined);
@@ -5032,16 +5249,17 @@ const RecordInput$1 = ({ column, schema, prefix }) => {
5032
5249
  setShowNewEntries(true);
5033
5250
  setNewKey(undefined);
5034
5251
  setNewValue(undefined);
5035
- }, children: translate.t(`${column}.addNew`) }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(`${column}.field_required`) }))] }));
5252
+ }, children: translate.t(`${column}.addNew`) })] }));
5036
5253
  };
5037
5254
 
5038
5255
  const StringInputField = ({ column, schema, prefix, }) => {
5039
5256
  const { register, formState: { errors }, } = reactHookForm.useFormContext();
5040
5257
  const { translate } = useSchemaContext();
5041
- const { required, gridColumn = "span 12", gridRow = "span 1" } = schema;
5258
+ const { required, gridColumn = 'span 12', gridRow = 'span 1' } = schema;
5042
5259
  const isRequired = required?.some((columnId) => columnId === column);
5043
5260
  const colLabel = `${prefix}${column}`;
5044
- return (jsxRuntime.jsx(jsxRuntime.Fragment, { children: jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, gridColumn: gridColumn, gridRow: gridRow, children: [jsxRuntime.jsx(react.Input, { ...register(`${colLabel}`, { required: isRequired }), autoComplete: "off" }), errors[colLabel] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }) }));
5261
+ const fieldError = getFieldError(errors, colLabel);
5262
+ return (jsxRuntime.jsx(jsxRuntime.Fragment, { children: jsxRuntime.jsx(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, gridColumn: gridColumn, gridRow: gridRow, errorText: fieldError, invalid: !!fieldError, children: jsxRuntime.jsx(react.Input, { ...register(`${colLabel}`, { required: isRequired }), autoComplete: "off" }) }) }));
5045
5263
  };
5046
5264
 
5047
5265
  const RadioCardItem = React__namespace.forwardRef(function RadioCardItem(props, ref) {
@@ -5227,13 +5445,18 @@ Textarea.displayName = "Textarea";
5227
5445
  const TextAreaInput = ({ column, schema, prefix, }) => {
5228
5446
  const { register, formState: { errors }, } = reactHookForm.useFormContext();
5229
5447
  const { translate } = useSchemaContext();
5230
- const { required, gridColumn = "span 12", gridRow = "span 1" } = schema;
5448
+ const { required, gridColumn = 'span 12', gridRow = 'span 1' } = schema;
5231
5449
  const isRequired = required?.some((columnId) => columnId === column);
5232
5450
  const colLabel = `${prefix}${column}`;
5233
5451
  const form = reactHookForm.useFormContext();
5234
5452
  const { setValue, watch } = form;
5453
+ const fieldError = getFieldError(errors, colLabel);
5235
5454
  const watchValue = watch(colLabel);
5236
- return (jsxRuntime.jsx(jsxRuntime.Fragment, { children: jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, gridColumn: gridColumn ?? "span 4", gridRow: gridRow ?? "span 1", display: "grid", children: [jsxRuntime.jsx(Textarea, { value: watchValue, onChange: (value) => setValue(colLabel, value) }), errors[colLabel] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }) }));
5455
+ return (jsxRuntime.jsx(jsxRuntime.Fragment, { children: jsxRuntime.jsx(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, gridColumn: gridColumn ?? 'span 4', gridRow: gridRow ?? 'span 1', display: "grid", errorText: fieldError
5456
+ ? fieldError.includes('required')
5457
+ ? translate.t(removeIndex(`${colLabel}.field_required`))
5458
+ : fieldError
5459
+ : undefined, invalid: !!fieldError, children: jsxRuntime.jsx(Textarea, { value: watchValue, onChange: (value) => setValue(colLabel, value) }) }) }));
5237
5460
  };
5238
5461
 
5239
5462
  function TimePicker$1({ hour, setHour, minute, setMinute, meridiem, setMeridiem, meridiemLabel = {
@@ -5364,25 +5587,25 @@ dayjs.extend(timezone);
5364
5587
  const TimePicker = ({ column, schema, prefix }) => {
5365
5588
  const { watch, formState: { errors }, setValue, } = reactHookForm.useFormContext();
5366
5589
  const { translate, timezone } = useSchemaContext();
5367
- const { required, gridColumn = "span 12", gridRow = "span 1", timeFormat = "HH:mm:ssZ", displayTimeFormat = "hh:mm A", } = schema;
5590
+ const { required, gridColumn = 'span 12', gridRow = 'span 1', timeFormat = 'HH:mm:ssZ', displayTimeFormat = 'hh:mm A', } = schema;
5368
5591
  const isRequired = required?.some((columnId) => columnId === column);
5369
5592
  const colLabel = `${prefix}${column}`;
5370
5593
  const [open, setOpen] = React.useState(false);
5371
5594
  const value = watch(colLabel);
5372
5595
  const displayedTime = dayjs(`1970-01-01T${value}`).tz(timezone).isValid()
5373
5596
  ? dayjs(`1970-01-01T${value}`).tz(timezone).format(displayTimeFormat)
5374
- : "";
5597
+ : '';
5375
5598
  // Parse the initial time parts from the time string (HH:mm:ssZ)
5376
5599
  const parseTime = (time) => {
5377
5600
  if (!time)
5378
- return { hour: 12, minute: 0, meridiem: "am" };
5601
+ return { hour: 12, minute: 0, meridiem: 'am' };
5379
5602
  const parsed = dayjs(`1970-01-01T${time}`).tz(timezone);
5380
5603
  if (!parsed.isValid()) {
5381
- return { hour: 12, minute: 0, meridiem: "am" };
5604
+ return { hour: 12, minute: 0, meridiem: 'am' };
5382
5605
  }
5383
5606
  let hour = parsed.hour();
5384
5607
  const minute = parsed.minute();
5385
- const meridiem = hour >= 12 ? "pm" : "am";
5608
+ const meridiem = hour >= 12 ? 'pm' : 'am';
5386
5609
  if (hour === 0)
5387
5610
  hour = 12;
5388
5611
  else if (hour > 12)
@@ -5403,10 +5626,15 @@ const TimePicker = ({ column, schema, prefix }) => {
5403
5626
  if (hour === null || minute === null || meridiem === null)
5404
5627
  return null;
5405
5628
  let newHour = hour;
5406
- if (meridiem === "pm" && hour !== 12) {
5629
+ if (meridiem === 'pm' && hour !== 12) {
5407
5630
  newHour = hour + 12;
5408
5631
  }
5409
- return dayjs().tz(timezone).hour(newHour).minute(minute).second(0).format(timeFormat);
5632
+ return dayjs()
5633
+ .tz(timezone)
5634
+ .hour(newHour)
5635
+ .minute(minute)
5636
+ .second(0)
5637
+ .format(timeFormat);
5410
5638
  };
5411
5639
  // Handle changes to time parts
5412
5640
  const handleTimeChange = ({ hour: newHour, minute: newMinute, meridiem: newMeridiem, }) => {
@@ -5416,13 +5644,15 @@ const TimePicker = ({ column, schema, prefix }) => {
5416
5644
  const timeString = getTimeString(newHour, newMinute, newMeridiem);
5417
5645
  setValue(colLabel, timeString, { shouldValidate: true, shouldDirty: true });
5418
5646
  };
5419
- return (jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, alignItems: "stretch", gridColumn,
5420
- gridRow, children: [jsxRuntime.jsxs(react.Popover.Root, { open: open, onOpenChange: (e) => setOpen(e.open), closeOnInteractOutside: true, children: [jsxRuntime.jsx(react.Popover.Trigger, { asChild: true, children: jsxRuntime.jsxs(Button, { size: "sm", variant: "outline", onClick: () => {
5421
- setOpen(true);
5422
- }, justifyContent: "start", children: [jsxRuntime.jsx(io.IoMdClock, {}), !!value ? `${displayedTime}` : ""] }) }), jsxRuntime.jsx(react.Popover.Positioner, { children: jsxRuntime.jsx(react.Popover.Content, { children: jsxRuntime.jsx(react.Popover.Body, { children: jsxRuntime.jsx(TimePicker$1, { hour: hour, setHour: setHour, minute: minute, setMinute: setMinute, meridiem: meridiem, setMeridiem: setMeridiem, onChange: handleTimeChange, meridiemLabel: {
5423
- am: translate.t(`common.am`, { defaultValue: "AM" }),
5424
- pm: translate.t(`common.pm`, { defaultValue: "PM" }),
5425
- } }) }) }) })] }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
5647
+ return (jsxRuntime.jsx(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, alignItems: 'stretch', gridColumn,
5648
+ gridRow, errorText: errors[`${colLabel}`]
5649
+ ? translate.t(removeIndex(`${colLabel}.field_required`))
5650
+ : undefined, invalid: !!errors[colLabel], children: jsxRuntime.jsxs(react.Popover.Root, { open: open, onOpenChange: (e) => setOpen(e.open), closeOnInteractOutside: true, children: [jsxRuntime.jsx(react.Popover.Trigger, { asChild: true, children: jsxRuntime.jsxs(Button, { size: "sm", variant: "outline", onClick: () => {
5651
+ setOpen(true);
5652
+ }, justifyContent: 'start', children: [jsxRuntime.jsx(io.IoMdClock, {}), !!value ? `${displayedTime}` : ''] }) }), jsxRuntime.jsx(react.Popover.Positioner, { children: jsxRuntime.jsx(react.Popover.Content, { children: jsxRuntime.jsx(react.Popover.Body, { children: jsxRuntime.jsx(TimePicker$1, { hour: hour, setHour: setHour, minute: minute, setMinute: setMinute, meridiem: meridiem, setMeridiem: setMeridiem, onChange: handleTimeChange, meridiemLabel: {
5653
+ am: translate.t(`common.am`, { defaultValue: 'AM' }),
5654
+ pm: translate.t(`common.pm`, { defaultValue: 'PM' }),
5655
+ } }) }) }) })] }) }));
5426
5656
  };
5427
5657
 
5428
5658
  function IsoTimePicker({ hour, setHour, minute, setMinute, second, setSecond, onChange = (_newValue) => { }, }) {
@@ -5628,9 +5858,9 @@ const DateTimePicker = ({ column, schema, prefix, }) => {
5628
5858
  const { watch, formState: { errors }, setValue, } = reactHookForm.useFormContext();
5629
5859
  const { timezone, dateTimePickerLabels } = useSchemaContext();
5630
5860
  const formI18n = useFormI18n(column, prefix);
5631
- const { required, gridColumn = "span 12", gridRow = "span 1", displayDateFormat = "YYYY-MM-DD HH:mm:ss",
5861
+ const { required, gridColumn = 'span 12', gridRow = 'span 1', displayDateFormat = 'YYYY-MM-DD HH:mm:ss',
5632
5862
  // with timezone
5633
- dateFormat = "YYYY-MM-DD[T]HH:mm:ssZ", } = schema;
5863
+ dateFormat = 'YYYY-MM-DD[T]HH:mm:ssZ', } = schema;
5634
5864
  const isRequired = required?.some((columnId) => columnId === column);
5635
5865
  const colLabel = formI18n.colLabel;
5636
5866
  const [open, setOpen] = React.useState(false);
@@ -5661,44 +5891,82 @@ const DateTimePicker = ({ column, schema, prefix, }) => {
5661
5891
  console.error(e);
5662
5892
  }
5663
5893
  }, [selectedDate, dateFormat, colLabel, setValue]);
5664
- return (jsxRuntime.jsxs(Field, { label: formI18n.label(), required: isRequired, alignItems: "stretch", gridColumn,
5665
- gridRow, children: [jsxRuntime.jsxs(PopoverRoot, { open: open, onOpenChange: (e) => setOpen(e.open), closeOnInteractOutside: true, children: [jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: jsxRuntime.jsxs(Button, { size: "sm", variant: "outline", onClick: () => {
5666
- setOpen(true);
5667
- }, justifyContent: "start", children: [jsxRuntime.jsx(md.MdDateRange, {}), selectedDate !== undefined ? `${displayDate}` : ""] }) }), jsxRuntime.jsx(PopoverContent, { minW: "450px", children: jsxRuntime.jsxs(PopoverBody, { children: [jsxRuntime.jsx(PopoverTitle, {}), jsxRuntime.jsx(DateTimePicker$1, { value: selectedDate, onChange: (date) => {
5668
- setValue(colLabel, dayjs(date).tz(timezone).format(dateFormat));
5669
- }, timezone: timezone, labels: {
5670
- monthNamesShort: dateTimePickerLabels?.monthNamesShort ?? [
5671
- formI18n.translate.t(`common.month_1`, { defaultValue: "January" }),
5672
- formI18n.translate.t(`common.month_2`, { defaultValue: "February" }),
5673
- formI18n.translate.t(`common.month_3`, { defaultValue: "March" }),
5674
- formI18n.translate.t(`common.month_4`, { defaultValue: "April" }),
5675
- formI18n.translate.t(`common.month_5`, { defaultValue: "May" }),
5676
- formI18n.translate.t(`common.month_6`, { defaultValue: "June" }),
5677
- formI18n.translate.t(`common.month_7`, { defaultValue: "July" }),
5678
- formI18n.translate.t(`common.month_8`, { defaultValue: "August" }),
5679
- formI18n.translate.t(`common.month_9`, { defaultValue: "September" }),
5680
- formI18n.translate.t(`common.month_10`, { defaultValue: "October" }),
5681
- formI18n.translate.t(`common.month_11`, { defaultValue: "November" }),
5682
- formI18n.translate.t(`common.month_12`, { defaultValue: "December" }),
5683
- ],
5684
- weekdayNamesShort: dateTimePickerLabels?.weekdayNamesShort ?? [
5685
- formI18n.translate.t(`common.weekday_1`, { defaultValue: "Sun" }),
5686
- formI18n.translate.t(`common.weekday_2`, { defaultValue: "Mon" }),
5687
- formI18n.translate.t(`common.weekday_3`, { defaultValue: "Tue" }),
5688
- formI18n.translate.t(`common.weekday_4`, {
5689
- defaultValue: "Wed",
5690
- }),
5691
- formI18n.translate.t(`common.weekday_5`, { defaultValue: "Thu" }),
5692
- formI18n.translate.t(`common.weekday_6`, { defaultValue: "Fri" }),
5693
- formI18n.translate.t(`common.weekday_7`, { defaultValue: "Sat" }),
5694
- ],
5695
- backButtonLabel: dateTimePickerLabels?.backButtonLabel ?? formI18n.translate.t(`common.back_button`, {
5696
- defaultValue: "Back",
5894
+ return (jsxRuntime.jsx(Field, { label: formI18n.label(), required: isRequired, alignItems: 'stretch', gridColumn,
5895
+ gridRow, errorText: errors[`${colLabel}`] ? formI18n.required() : undefined, invalid: !!errors[colLabel], children: jsxRuntime.jsxs(PopoverRoot, { open: open, onOpenChange: (e) => setOpen(e.open), closeOnInteractOutside: true, children: [jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: jsxRuntime.jsxs(Button, { size: "sm", variant: "outline", onClick: () => {
5896
+ setOpen(true);
5897
+ }, justifyContent: 'start', children: [jsxRuntime.jsx(md.MdDateRange, {}), selectedDate !== undefined ? `${displayDate}` : ''] }) }), jsxRuntime.jsx(PopoverContent, { minW: '450px', children: jsxRuntime.jsxs(PopoverBody, { children: [jsxRuntime.jsx(PopoverTitle, {}), jsxRuntime.jsx(DateTimePicker$1, { value: selectedDate, onChange: (date) => {
5898
+ setValue(colLabel, dayjs(date).tz(timezone).format(dateFormat));
5899
+ }, timezone: timezone, labels: {
5900
+ monthNamesShort: dateTimePickerLabels?.monthNamesShort ?? [
5901
+ formI18n.translate.t(`common.month_1`, {
5902
+ defaultValue: 'January',
5903
+ }),
5904
+ formI18n.translate.t(`common.month_2`, {
5905
+ defaultValue: 'February',
5906
+ }),
5907
+ formI18n.translate.t(`common.month_3`, {
5908
+ defaultValue: 'March',
5909
+ }),
5910
+ formI18n.translate.t(`common.month_4`, {
5911
+ defaultValue: 'April',
5912
+ }),
5913
+ formI18n.translate.t(`common.month_5`, {
5914
+ defaultValue: 'May',
5915
+ }),
5916
+ formI18n.translate.t(`common.month_6`, {
5917
+ defaultValue: 'June',
5918
+ }),
5919
+ formI18n.translate.t(`common.month_7`, {
5920
+ defaultValue: 'July',
5921
+ }),
5922
+ formI18n.translate.t(`common.month_8`, {
5923
+ defaultValue: 'August',
5924
+ }),
5925
+ formI18n.translate.t(`common.month_9`, {
5926
+ defaultValue: 'September',
5927
+ }),
5928
+ formI18n.translate.t(`common.month_10`, {
5929
+ defaultValue: 'October',
5930
+ }),
5931
+ formI18n.translate.t(`common.month_11`, {
5932
+ defaultValue: 'November',
5933
+ }),
5934
+ formI18n.translate.t(`common.month_12`, {
5935
+ defaultValue: 'December',
5936
+ }),
5937
+ ],
5938
+ weekdayNamesShort: dateTimePickerLabels?.weekdayNamesShort ?? [
5939
+ formI18n.translate.t(`common.weekday_1`, {
5940
+ defaultValue: 'Sun',
5941
+ }),
5942
+ formI18n.translate.t(`common.weekday_2`, {
5943
+ defaultValue: 'Mon',
5944
+ }),
5945
+ formI18n.translate.t(`common.weekday_3`, {
5946
+ defaultValue: 'Tue',
5947
+ }),
5948
+ formI18n.translate.t(`common.weekday_4`, {
5949
+ defaultValue: 'Wed',
5950
+ }),
5951
+ formI18n.translate.t(`common.weekday_5`, {
5952
+ defaultValue: 'Thu',
5953
+ }),
5954
+ formI18n.translate.t(`common.weekday_6`, {
5955
+ defaultValue: 'Fri',
5956
+ }),
5957
+ formI18n.translate.t(`common.weekday_7`, {
5958
+ defaultValue: 'Sat',
5959
+ }),
5960
+ ],
5961
+ backButtonLabel: dateTimePickerLabels?.backButtonLabel ??
5962
+ formI18n.translate.t(`common.back_button`, {
5963
+ defaultValue: 'Back',
5697
5964
  }),
5698
- forwardButtonLabel: dateTimePickerLabels?.forwardButtonLabel ?? formI18n.translate.t(`common.forward_button`, {
5699
- defaultValue: "Forward",
5965
+ forwardButtonLabel: dateTimePickerLabels?.forwardButtonLabel ??
5966
+ formI18n.translate.t(`common.forward_button`, {
5967
+ defaultValue: 'Forward',
5700
5968
  }),
5701
- } })] }) })] }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: formI18n.required() }))] }));
5969
+ } })] }) })] }) }));
5702
5970
  };
5703
5971
 
5704
5972
  const SchemaRenderer = ({ schema, prefix, column, }) => {
@@ -5772,13 +6040,18 @@ const SchemaRenderer = ({ schema, prefix, column, }) => {
5772
6040
  return jsxRuntime.jsx(react.Text, { children: "missing type" });
5773
6041
  };
5774
6042
 
5775
- const ColumnRenderer = ({ column, properties, prefix, }) => {
6043
+ const ColumnRenderer = ({ column, properties, prefix, parentRequired, }) => {
5776
6044
  const colSchema = properties[column];
5777
6045
  const colLabel = `${prefix}${column}`;
5778
6046
  if (colSchema === undefined) {
5779
6047
  throw new Error(`${colLabel} does not exist when using ColumnRenderer`);
5780
6048
  }
5781
- return jsxRuntime.jsx(SchemaRenderer, { schema: colSchema, prefix, column });
6049
+ // Merge parent's required array with the schema's required array
6050
+ const schemaWithRequired = {
6051
+ ...colSchema,
6052
+ required: parentRequired || colSchema.required,
6053
+ };
6054
+ return jsxRuntime.jsx(SchemaRenderer, { schema: schemaWithRequired, prefix, column });
5782
6055
  };
5783
6056
 
5784
6057
  const ArrayViewer = ({ schema, column, prefix }) => {
@@ -6219,15 +6492,15 @@ const SubmitButton = () => {
6219
6492
  const methods = reactHookForm.useFormContext();
6220
6493
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
6221
6494
  const onValid = (data) => {
6222
- const { isValid, errors } = validateData(data, schema);
6223
- if (!isValid) {
6224
- setError({
6225
- type: 'validation',
6226
- errors,
6227
- });
6228
- setIsError(true);
6229
- return;
6230
- }
6495
+ // const { isValid, errors } = validateData(data, schema);
6496
+ // if (!isValid) {
6497
+ // setError({
6498
+ // type: 'validation',
6499
+ // errors,
6500
+ // });
6501
+ // setIsError(true);
6502
+ // return;
6503
+ // }
6231
6504
  // If validation passes, check if confirmation is required
6232
6505
  if (requireConfirmation) {
6233
6506
  // Show confirmation (existing behavior)
@@ -6252,10 +6525,6 @@ const FormBody = () => {
6252
6525
  const { showSubmitButton, showResetButton } = displayConfig;
6253
6526
  const methods = reactHookForm.useFormContext();
6254
6527
  const { properties } = schema;
6255
- // Custom error renderer for validation errors with i18n support
6256
- const renderValidationErrors = (validationErrors) => {
6257
- return (jsxRuntime.jsx(react.Flex, { flexFlow: 'column', gap: "2", children: validationErrors.map((err, index) => (jsxRuntime.jsxs(react.Alert.Root, { status: "error", display: "flex", alignItems: "center", children: [jsxRuntime.jsx(react.Alert.Indicator, {}), jsxRuntime.jsx(react.Alert.Content, { children: jsxRuntime.jsx(react.Alert.Description, { children: err.message }) })] }, index))) }));
6258
- };
6259
6528
  const renderColumns = ({ order, keys, ignore, include, }) => {
6260
6529
  const included = include.length > 0 ? include : keys;
6261
6530
  const not_exist = included.filter((columnA) => !order.some((columnB) => columnA === columnB));
@@ -6295,19 +6564,17 @@ const FormBody = () => {
6295
6564
  setIsConfirming(false);
6296
6565
  }, variant: 'subtle', children: translate.t('cancel') }), jsxRuntime.jsx(react.Button, { onClick: () => {
6297
6566
  onFormSubmit(validatedData);
6298
- }, children: translate.t('confirm') })] }), isSubmiting && (jsxRuntime.jsx(react.Box, { pos: "absolute", inset: "0", bg: "bg/80", children: jsxRuntime.jsx(react.Center, { h: "full", children: jsxRuntime.jsx(react.Spinner, { color: "teal.500" }) }) })), isError && (jsxRuntime.jsx(jsxRuntime.Fragment, { children: customErrorRenderer ? (customErrorRenderer(error)) : (jsxRuntime.jsx(jsxRuntime.Fragment, { children: error?.type === 'validation' &&
6299
- error?.errors ? (renderValidationErrors(error.errors)) : (jsxRuntime.jsxs(react.Alert.Root, { status: "error", children: [jsxRuntime.jsx(react.Alert.Indicator, {}), jsxRuntime.jsxs(react.Alert.Content, { children: [jsxRuntime.jsx(react.Alert.Title, { children: "Error" }), jsxRuntime.jsx(react.Alert.Description, { children: jsxRuntime.jsx(AccordionRoot, { collapsible: true, defaultValue: [], children: jsxRuntime.jsxs(AccordionItem, { value: 'b', children: [jsxRuntime.jsx(AccordionItemTrigger, { children: `${error}` }), jsxRuntime.jsx(AccordionItemContent, { children: `${JSON.stringify(error)}` })] }) }) })] })] })) })) }))] }));
6567
+ }, children: translate.t('confirm') })] }), isSubmiting && (jsxRuntime.jsx(react.Box, { pos: "absolute", inset: "0", bg: "bg/80", children: jsxRuntime.jsx(react.Center, { h: "full", children: jsxRuntime.jsx(react.Spinner, { color: "teal.500" }) }) })), isError && customErrorRenderer && customErrorRenderer(error)] }));
6300
6568
  }
6301
6569
  return (jsxRuntime.jsxs(react.Flex, { flexFlow: 'column', gap: "2", children: [jsxRuntime.jsx(react.Grid, { gap: "4", gridTemplateColumns: 'repeat(12, 1fr)', autoFlow: 'row', children: ordered.map((column) => {
6302
6570
  return (jsxRuntime.jsx(ColumnRenderer
6303
6571
  // @ts-expect-error find suitable types
6304
6572
  , {
6305
6573
  // @ts-expect-error find suitable types
6306
- properties: properties, prefix: ``, column }, `form-input-${column}`));
6574
+ properties: properties, prefix: ``, parentRequired: schema.required, column }, `form-input-${column}`));
6307
6575
  }) }), jsxRuntime.jsxs(react.Flex, { justifyContent: 'end', gap: "2", children: [showResetButton && (jsxRuntime.jsx(react.Button, { onClick: () => {
6308
6576
  methods.reset();
6309
- }, variant: 'subtle', children: translate.t('reset') })), showSubmitButton && jsxRuntime.jsx(SubmitButton, {})] }), isError && (jsxRuntime.jsx(jsxRuntime.Fragment, { children: customErrorRenderer ? (customErrorRenderer(error)) : (jsxRuntime.jsx(jsxRuntime.Fragment, { children: error?.type === 'validation' &&
6310
- error?.errors ? (renderValidationErrors(error.errors)) : (jsxRuntime.jsxs(react.Alert.Root, { status: "error", children: [jsxRuntime.jsx(react.Alert.Indicator, {}), jsxRuntime.jsxs(react.Alert.Content, { children: [jsxRuntime.jsx(react.Alert.Title, { children: "Error" }), jsxRuntime.jsx(react.Alert.Description, { children: jsxRuntime.jsx(AccordionRoot, { collapsible: true, defaultValue: [], children: jsxRuntime.jsxs(AccordionItem, { value: 'b', children: [jsxRuntime.jsx(AccordionItemTrigger, { children: `${error}` }), jsxRuntime.jsx(AccordionItemContent, { children: `${JSON.stringify(error)}` })] }) }) })] })] })) })) }))] }));
6577
+ }, variant: 'subtle', children: translate.t('reset') })), showSubmitButton && jsxRuntime.jsx(SubmitButton, {})] }), isError && customErrorRenderer && customErrorRenderer(error)] }));
6311
6578
  };
6312
6579
 
6313
6580
  const FormTitle = () => {
@@ -6320,12 +6587,15 @@ const DefaultForm = ({ formConfig, }) => {
6320
6587
  return (jsxRuntime.jsx(FormRoot, { ...formConfig, children: jsxRuntime.jsxs(react.Grid, { gap: "2", children: [showTitle && jsxRuntime.jsx(FormTitle, {}), jsxRuntime.jsx(FormBody, {})] }) }));
6321
6588
  };
6322
6589
 
6323
- const useForm = ({ preLoadedValues, keyPrefix, namespace }) => {
6590
+ const useForm = ({ preLoadedValues, keyPrefix, namespace, schema, }) => {
6324
6591
  const form = reactHookForm.useForm({
6325
6592
  values: preLoadedValues,
6593
+ resolver: schema ? ajvResolver(schema) : undefined,
6594
+ mode: 'onBlur',
6595
+ reValidateMode: 'onBlur',
6326
6596
  });
6327
6597
  const [idMap, setIdMap] = React.useState({});
6328
- const translate = reactI18next.useTranslation(namespace || "", { keyPrefix });
6598
+ const translate = reactI18next.useTranslation(namespace || '', { keyPrefix });
6329
6599
  return {
6330
6600
  form,
6331
6601
  idMap,
@@ -6395,15 +6665,15 @@ const buildErrorMessages = (config) => {
6395
6665
  }
6396
6666
  // Add global fallback error messages
6397
6667
  const globalKeys = [
6398
- "minLength",
6399
- "maxLength",
6400
- "pattern",
6401
- "minimum",
6402
- "maximum",
6403
- "multipleOf",
6404
- "format",
6405
- "type",
6406
- "enum",
6668
+ 'minLength',
6669
+ 'maxLength',
6670
+ 'pattern',
6671
+ 'minimum',
6672
+ 'maximum',
6673
+ 'multipleOf',
6674
+ 'format',
6675
+ 'type',
6676
+ 'enum',
6407
6677
  ];
6408
6678
  globalKeys.forEach((key) => {
6409
6679
  if (config[key]) {
@@ -6412,6 +6682,46 @@ const buildErrorMessages = (config) => {
6412
6682
  });
6413
6683
  return result;
6414
6684
  };
6685
+ /**
6686
+ * Converts buildErrorMessages result to ajv-errors compatible format
6687
+ */
6688
+ const convertToAjvErrorsFormat = (errorMessages) => {
6689
+ const result = {};
6690
+ // Convert required field errors
6691
+ if (errorMessages.required) {
6692
+ result.required = errorMessages.required;
6693
+ }
6694
+ // Convert properties errors to ajv-errors format
6695
+ if (errorMessages.properties) {
6696
+ result.properties = {};
6697
+ Object.keys(errorMessages.properties).forEach((fieldName) => {
6698
+ const fieldErrors = errorMessages.properties[fieldName];
6699
+ result.properties[fieldName] = {};
6700
+ Object.keys(fieldErrors).forEach((keyword) => {
6701
+ result.properties[fieldName][keyword] =
6702
+ fieldErrors[keyword];
6703
+ });
6704
+ });
6705
+ }
6706
+ // Add global fallback errors
6707
+ const globalKeys = [
6708
+ 'minLength',
6709
+ 'maxLength',
6710
+ 'pattern',
6711
+ 'minimum',
6712
+ 'maximum',
6713
+ 'multipleOf',
6714
+ 'format',
6715
+ 'type',
6716
+ 'enum',
6717
+ ];
6718
+ globalKeys.forEach((key) => {
6719
+ if (errorMessages[key]) {
6720
+ result[key] = errorMessages[key];
6721
+ }
6722
+ });
6723
+ return result;
6724
+ };
6415
6725
  /**
6416
6726
  * Helper function to build required field errors
6417
6727
  *
@@ -6454,10 +6764,10 @@ const buildErrorMessages = (config) => {
6454
6764
  * // Result: { username: "user.username.field_required", email: "user.email.field_required" }
6455
6765
  * ```
6456
6766
  */
6457
- const buildRequiredErrors = (fields, messageOrGenerator, keyPrefix = "") => {
6767
+ const buildRequiredErrors = (fields, messageOrGenerator, keyPrefix = '') => {
6458
6768
  const result = {};
6459
6769
  fields.forEach((field) => {
6460
- if (typeof messageOrGenerator === "function") {
6770
+ if (typeof messageOrGenerator === 'function') {
6461
6771
  const message = messageOrGenerator(field);
6462
6772
  result[field] = keyPrefix ? `${keyPrefix}.${message}` : message;
6463
6773
  }
@@ -6528,11 +6838,14 @@ const buildFieldErrors = (config) => {
6528
6838
  * ```
6529
6839
  */
6530
6840
  const createErrorMessage = (required, properties, globalFallbacks) => {
6531
- return buildErrorMessages({
6841
+ const config = {
6532
6842
  required,
6533
6843
  properties,
6534
- ...globalFallbacks,
6535
- });
6844
+ };
6845
+ if (globalFallbacks) {
6846
+ Object.assign(config, globalFallbacks);
6847
+ }
6848
+ return buildErrorMessages(config);
6536
6849
  };
6537
6850
 
6538
6851
  const getMultiDates = ({ selected, selectedDate, selectedDates, selectable, }) => {
@@ -6595,6 +6908,7 @@ exports.ViewDialog = ViewDialog;
6595
6908
  exports.buildErrorMessages = buildErrorMessages;
6596
6909
  exports.buildFieldErrors = buildFieldErrors;
6597
6910
  exports.buildRequiredErrors = buildRequiredErrors;
6911
+ exports.convertToAjvErrorsFormat = convertToAjvErrorsFormat;
6598
6912
  exports.createErrorMessage = createErrorMessage;
6599
6913
  exports.getColumns = getColumns;
6600
6914
  exports.getMultiDates = getMultiDates;