@bsol-oss/react-datatable5 12.0.0-beta.70 → 12.0.0-beta.72

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.js CHANGED
@@ -3677,8 +3677,8 @@ const AccordionItem = react.Accordion.Item;
3677
3677
  //@ts-expect-error TODO: find appropriate type
3678
3678
  const SchemaFormContext = React.createContext({
3679
3679
  schema: {},
3680
- serverUrl: "",
3681
- requestUrl: "",
3680
+ serverUrl: '',
3681
+ requestUrl: '',
3682
3682
  order: [],
3683
3683
  ignore: [],
3684
3684
  include: [],
@@ -3734,11 +3734,11 @@ const idPickerSanityCheck = (column, foreign_key) => {
3734
3734
  throw new Error(`The key column does not exist in properties of column ${column} when using id-picker.`);
3735
3735
  }
3736
3736
  };
3737
- const FormRoot = ({ schema, idMap, setIdMap, form, serverUrl, translate, children, order = [], ignore = [], include = [], onSubmit = undefined, rowNumber = undefined, requestOptions = {}, getUpdatedData = () => { }, customErrorRenderer, displayConfig = {
3737
+ const FormRoot = ({ schema, idMap, setIdMap, form, serverUrl, translate, children, order = [], ignore = [], include = [], onSubmit = undefined, rowNumber = undefined, requestOptions = {}, getUpdatedData = () => { }, customErrorRenderer, customSuccessRenderer, displayConfig = {
3738
3738
  showSubmitButton: true,
3739
3739
  showResetButton: true,
3740
3740
  showTitle: true,
3741
- }, }) => {
3741
+ }, dateTimePickerLabels, idPickerLabels, }) => {
3742
3742
  const [isSuccess, setIsSuccess] = React.useState(false);
3743
3743
  const [isError, setIsError] = React.useState(false);
3744
3744
  const [isSubmiting, setIsSubmiting] = React.useState(false);
@@ -3772,7 +3772,10 @@ const FormRoot = ({ schema, idMap, setIdMap, form, serverUrl, translate, childre
3772
3772
  setError,
3773
3773
  getUpdatedData,
3774
3774
  customErrorRenderer,
3775
+ customSuccessRenderer,
3775
3776
  displayConfig,
3777
+ dateTimePickerLabels,
3778
+ idPickerLabels,
3776
3779
  }, children: jsxRuntime.jsx(reactHookForm.FormProvider, { ...form, children: children }) }));
3777
3780
  };
3778
3781
 
@@ -3824,7 +3827,7 @@ const Field = React__namespace.forwardRef(function Field(props, ref) {
3824
3827
  const BooleanPicker = ({ schema, column, prefix }) => {
3825
3828
  const { watch, formState: { errors }, setValue, } = reactHookForm.useFormContext();
3826
3829
  const { translate } = useSchemaContext();
3827
- const { required, gridColumn = "span 4", gridRow = "span 1" } = schema;
3830
+ const { required, gridColumn = "span 12", gridRow = "span 1" } = schema;
3828
3831
  const isRequired = required?.some((columnId) => columnId === column);
3829
3832
  const colLabel = `${prefix}${column}`;
3830
3833
  const value = watch(colLabel);
@@ -3963,18 +3966,79 @@ const PopoverRoot = react.Popover.Root;
3963
3966
  const PopoverBody = react.Popover.Body;
3964
3967
  const PopoverTrigger = react.Popover.Trigger;
3965
3968
 
3966
- function translateWrapper({ prefix, column, label, translate, }) {
3967
- return translate.t(removeIndex(`${prefix}${column}.${label}`));
3968
- }
3969
+ /**
3970
+ * Custom hook to simplify i18n translation for form fields.
3971
+ * Automatically handles colLabel construction and removeIndex logic.
3972
+ *
3973
+ * @param column - The column name
3974
+ * @param prefix - The prefix for the field (usually empty string or parent path)
3975
+ * @returns Object with translation helper functions
3976
+ *
3977
+ * @example
3978
+ * ```tsx
3979
+ * const formI18n = useFormI18n(column, prefix);
3980
+ *
3981
+ * // Get field label
3982
+ * <Field label={formI18n.label()} />
3983
+ *
3984
+ * // Get error message
3985
+ * <Text>{formI18n.required()}</Text>
3986
+ *
3987
+ * // Get custom translation key
3988
+ * <Text>{formI18n.t('add_more')}</Text>
3989
+ *
3990
+ * // Access the raw colLabel
3991
+ * const colLabel = formI18n.colLabel;
3992
+ * ```
3993
+ */
3994
+ const useFormI18n = (column, prefix = "") => {
3995
+ const { translate } = useSchemaContext();
3996
+ const colLabel = `${prefix}${column}`;
3997
+ return {
3998
+ /**
3999
+ * The constructed column label (prefix + column)
4000
+ */
4001
+ colLabel,
4002
+ /**
4003
+ * Get the field label translation
4004
+ * Equivalent to: translate.t(removeIndex(`${colLabel}.field_label`))
4005
+ */
4006
+ label: (options) => {
4007
+ return translate.t(removeIndex(`${colLabel}.field_label`), options);
4008
+ },
4009
+ /**
4010
+ * Get the required error message translation
4011
+ * Equivalent to: translate.t(removeIndex(`${colLabel}.field_required`))
4012
+ */
4013
+ required: (options) => {
4014
+ return translate.t(removeIndex(`${colLabel}.field_required`), options);
4015
+ },
4016
+ /**
4017
+ * Get a translation for any custom key relative to the field
4018
+ * Equivalent to: translate.t(removeIndex(`${colLabel}.${key}`))
4019
+ *
4020
+ * @param key - The translation key suffix (e.g., 'add_more', 'total', etc.)
4021
+ * @param options - Optional translation options (e.g., defaultValue, interpolation variables)
4022
+ */
4023
+ t: (key, options) => {
4024
+ return translate.t(removeIndex(`${colLabel}.${key}`), options);
4025
+ },
4026
+ /**
4027
+ * Access to the original translate object for edge cases
4028
+ */
4029
+ translate,
4030
+ };
4031
+ };
3969
4032
 
3970
4033
  dayjs.extend(utc);
3971
4034
  dayjs.extend(timezone);
3972
4035
  const DatePicker = ({ column, schema, prefix }) => {
3973
4036
  const { watch, formState: { errors }, setValue, } = reactHookForm.useFormContext();
3974
- const { translate, timezone } = useSchemaContext();
3975
- const { required, gridColumn = "span 4", gridRow = "span 1", displayDateFormat = "YYYY-MM-DD", dateFormat = "YYYY-MM-DD", } = schema;
4037
+ const { timezone } = useSchemaContext();
4038
+ const formI18n = useFormI18n(column, prefix);
4039
+ const { required, gridColumn = "span 12", gridRow = "span 1", displayDateFormat = "YYYY-MM-DD", dateFormat = "YYYY-MM-DD", } = schema;
3976
4040
  const isRequired = required?.some((columnId) => columnId === column);
3977
- const colLabel = `${prefix}${column}`;
4041
+ const colLabel = formI18n.colLabel;
3978
4042
  const [open, setOpen] = React.useState(false);
3979
4043
  const selectedDate = watch(colLabel);
3980
4044
  const displayDate = dayjs(selectedDate).tz(timezone).format(displayDateFormat);
@@ -4001,10 +4065,7 @@ const DatePicker = ({ column, schema, prefix }) => {
4001
4065
  console.error(e);
4002
4066
  }
4003
4067
  }, [selectedDate, dateFormat, colLabel, setValue]);
4004
- const customTranslate = (label) => {
4005
- return translateWrapper({ prefix, column, label, translate });
4006
- };
4007
- return (jsxRuntime.jsxs(Field, { label: `${customTranslate(`field_label`)}`, required: isRequired, alignItems: "stretch", gridColumn,
4068
+ return (jsxRuntime.jsxs(Field, { label: formI18n.label(), required: isRequired, alignItems: "stretch", gridColumn,
4008
4069
  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: () => {
4009
4070
  setOpen(true);
4010
4071
  }, 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 }) => {
@@ -4012,37 +4073,37 @@ const DatePicker = ({ column, schema, prefix }) => {
4012
4073
  setOpen(false);
4013
4074
  }, labels: {
4014
4075
  monthNamesShort: [
4015
- translate.t(`common.month_1`, { defaultValue: "January" }),
4016
- translate.t(`common.month_2`, { defaultValue: "February" }),
4017
- translate.t(`common.month_3`, { defaultValue: "March" }),
4018
- translate.t(`common.month_4`, { defaultValue: "April" }),
4019
- translate.t(`common.month_5`, { defaultValue: "May" }),
4020
- translate.t(`common.month_6`, { defaultValue: "June" }),
4021
- translate.t(`common.month_7`, { defaultValue: "July" }),
4022
- translate.t(`common.month_8`, { defaultValue: "August" }),
4023
- translate.t(`common.month_9`, { defaultValue: "September" }),
4024
- translate.t(`common.month_10`, { defaultValue: "October" }),
4025
- translate.t(`common.month_11`, { defaultValue: "November" }),
4026
- translate.t(`common.month_12`, { defaultValue: "December" }),
4076
+ formI18n.translate.t(`common.month_1`, { defaultValue: "January" }),
4077
+ formI18n.translate.t(`common.month_2`, { defaultValue: "February" }),
4078
+ formI18n.translate.t(`common.month_3`, { defaultValue: "March" }),
4079
+ formI18n.translate.t(`common.month_4`, { defaultValue: "April" }),
4080
+ formI18n.translate.t(`common.month_5`, { defaultValue: "May" }),
4081
+ formI18n.translate.t(`common.month_6`, { defaultValue: "June" }),
4082
+ formI18n.translate.t(`common.month_7`, { defaultValue: "July" }),
4083
+ formI18n.translate.t(`common.month_8`, { defaultValue: "August" }),
4084
+ formI18n.translate.t(`common.month_9`, { defaultValue: "September" }),
4085
+ formI18n.translate.t(`common.month_10`, { defaultValue: "October" }),
4086
+ formI18n.translate.t(`common.month_11`, { defaultValue: "November" }),
4087
+ formI18n.translate.t(`common.month_12`, { defaultValue: "December" }),
4027
4088
  ],
4028
4089
  weekdayNamesShort: [
4029
- translate.t(`common.weekday_1`, { defaultValue: "Sun" }),
4030
- translate.t(`common.weekday_2`, { defaultValue: "Mon" }),
4031
- translate.t(`common.weekday_3`, { defaultValue: "Tue" }),
4032
- translate.t(`common.weekday_4`, {
4090
+ formI18n.translate.t(`common.weekday_1`, { defaultValue: "Sun" }),
4091
+ formI18n.translate.t(`common.weekday_2`, { defaultValue: "Mon" }),
4092
+ formI18n.translate.t(`common.weekday_3`, { defaultValue: "Tue" }),
4093
+ formI18n.translate.t(`common.weekday_4`, {
4033
4094
  defaultValue: "Wed",
4034
4095
  }),
4035
- translate.t(`common.weekday_5`, { defaultValue: "Thu" }),
4036
- translate.t(`common.weekday_6`, { defaultValue: "Fri" }),
4037
- translate.t(`common.weekday_7`, { defaultValue: "Sat" }),
4096
+ formI18n.translate.t(`common.weekday_5`, { defaultValue: "Thu" }),
4097
+ formI18n.translate.t(`common.weekday_6`, { defaultValue: "Fri" }),
4098
+ formI18n.translate.t(`common.weekday_7`, { defaultValue: "Sat" }),
4038
4099
  ],
4039
- backButtonLabel: translate.t(`common.back_button`, {
4100
+ backButtonLabel: formI18n.translate.t(`common.back_button`, {
4040
4101
  defaultValue: "Back",
4041
4102
  }),
4042
- forwardButtonLabel: translate.t(`common.forward_button`, {
4103
+ forwardButtonLabel: formI18n.translate.t(`common.forward_button`, {
4043
4104
  defaultValue: "Forward",
4044
4105
  }),
4045
- } })] }) })] }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: customTranslate(`field_required`) }))] }));
4106
+ } })] }) })] }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: formI18n.required() }))] }));
4046
4107
  };
4047
4108
 
4048
4109
  function filterArray(array, searchTerm) {
@@ -4060,7 +4121,7 @@ const EnumPicker = ({ column, isMultiple = false, schema, prefix, showTotalAndLi
4060
4121
  const { translate } = useSchemaContext();
4061
4122
  const { required, variant } = schema;
4062
4123
  const isRequired = required?.some((columnId) => columnId === column);
4063
- const { gridColumn = "span 4", gridRow = "span 1", renderDisplay } = schema;
4124
+ const { gridColumn = "span 12", gridRow = "span 1", renderDisplay } = schema;
4064
4125
  const [searchText, setSearchText] = React.useState();
4065
4126
  const [limit, setLimit] = React.useState(10);
4066
4127
  const [openSearchResult, setOpenSearchResult] = React.useState();
@@ -4502,7 +4563,7 @@ const FileDropzone = ({ children = undefined, gridProps = {}, onDrop = () => { }
4502
4563
  const FilePicker = ({ column, schema, prefix }) => {
4503
4564
  const { setValue, formState: { errors }, watch, } = reactHookForm.useFormContext();
4504
4565
  const { translate } = useSchemaContext();
4505
- const { required, gridColumn = "span 4", gridRow = "span 1", } = schema;
4566
+ const { required, gridColumn = "span 12", gridRow = "span 1", } = schema;
4506
4567
  const isRequired = required?.some((columnId) => columnId === column);
4507
4568
  const currentFiles = (watch(column) ?? []);
4508
4569
  const colLabel = `${prefix}${column}`;
@@ -4557,16 +4618,17 @@ const getTableData = async ({ serverUrl, in_table, searching = "", where = [], l
4557
4618
 
4558
4619
  const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
4559
4620
  const { watch, formState: { errors }, setValue, } = reactHookForm.useFormContext();
4560
- const { serverUrl, idMap, setIdMap, translate, schema: parentSchema, } = useSchemaContext();
4561
- const { required, gridColumn = "span 4", gridRow = "span 1", renderDisplay, foreign_key, } = schema;
4621
+ const { serverUrl, idMap, setIdMap, schema: parentSchema, idPickerLabels, } = useSchemaContext();
4622
+ const formI18n = useFormI18n(column, prefix);
4623
+ const { required, gridColumn = 'span 12', gridRow = 'span 1', renderDisplay, foreign_key, } = schema;
4562
4624
  const isRequired = required?.some((columnId) => columnId === column);
4563
4625
  const { table, column: column_ref, display_column, customQueryFn, } = foreign_key;
4564
- const [searchText, setSearchText] = React.useState("");
4626
+ const [searchText, setSearchText] = React.useState('');
4565
4627
  const [limit, setLimit] = React.useState(10);
4566
4628
  const [openSearchResult, setOpenSearchResult] = React.useState();
4567
4629
  const [page, setPage] = React.useState(0);
4568
4630
  const ref = React.useRef(null);
4569
- const colLabel = `${prefix}${column}`;
4631
+ const colLabel = formI18n.colLabel;
4570
4632
  const watchId = watch(colLabel);
4571
4633
  const watchIds = isMultiple ? (watch(colLabel) ?? []) : [];
4572
4634
  // Query for search results
@@ -4575,7 +4637,7 @@ const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
4575
4637
  queryFn: async () => {
4576
4638
  if (customQueryFn) {
4577
4639
  const { data, idMap } = await customQueryFn({
4578
- searching: searchText ?? "",
4640
+ searching: searchText ?? '',
4579
4641
  limit: limit,
4580
4642
  offset: page * limit,
4581
4643
  });
@@ -4586,7 +4648,7 @@ const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
4586
4648
  }
4587
4649
  const data = await getTableData({
4588
4650
  serverUrl,
4589
- searching: searchText ?? "",
4651
+ searching: searchText ?? '',
4590
4652
  in_table: table,
4591
4653
  limit: limit,
4592
4654
  offset: page * limit,
@@ -4616,7 +4678,7 @@ const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
4616
4678
  queryFn: async () => {
4617
4679
  if (customQueryFn) {
4618
4680
  const { data, idMap } = await customQueryFn({
4619
- searching: watchIds.join(","),
4681
+ searching: watchIds.join(','),
4620
4682
  limit: isMultiple ? watchIds.length : 1,
4621
4683
  offset: 0,
4622
4684
  });
@@ -4628,7 +4690,7 @@ const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
4628
4690
  if (!watchId && (!watchIds || watchIds.length === 0)) {
4629
4691
  return { data: [] };
4630
4692
  }
4631
- const searchValue = isMultiple ? watchIds.join(",") : watchId;
4693
+ const searchValue = isMultiple ? watchIds.join(',') : watchId;
4632
4694
  const data = await getTableData({
4633
4695
  serverUrl,
4634
4696
  searching: searchValue,
@@ -4665,7 +4727,7 @@ const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
4665
4727
  React.useEffect(() => {
4666
4728
  if (openSearchResult) {
4667
4729
  // Reset search text when opening the popover
4668
- setSearchText("");
4730
+ setSearchText('');
4669
4731
  // Reset page to first page
4670
4732
  setPage(0);
4671
4733
  // Fetch initial data
@@ -4691,44 +4753,44 @@ const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
4691
4753
  const count = data?.count ?? 0;
4692
4754
  const getPickedValue = () => {
4693
4755
  if (Object.keys(idMap).length <= 0) {
4694
- return "";
4756
+ return '';
4695
4757
  }
4696
4758
  const record = idMap[watchId];
4697
4759
  if (record === undefined) {
4698
- return "";
4760
+ return '';
4699
4761
  }
4700
4762
  if (!!renderDisplay === true) {
4701
4763
  return renderDisplay(record);
4702
4764
  }
4703
4765
  return record[display_column];
4704
4766
  };
4705
- return (jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(removeIndex(`${column}.field_label`)))}`, required: isRequired, alignItems: "stretch", gridColumn,
4706
- gridRow, children: [isMultiple && (jsxRuntime.jsxs(react.Flex, { flexFlow: "wrap", gap: 1, children: [watchIds.map((id) => {
4767
+ return (jsxRuntime.jsxs(Field, { label: formI18n.label(), required: isRequired, alignItems: 'stretch', gridColumn,
4768
+ gridRow, children: [isMultiple && (jsxRuntime.jsxs(react.Flex, { flexFlow: 'wrap', gap: 1, children: [watchIds.map((id) => {
4707
4769
  const item = idMap[id];
4708
4770
  if (item === undefined) {
4709
- return (jsxRuntime.jsx(react.Text, { children: translate.t(removeIndex(`${colLabel}.undefined`)) }, id));
4771
+ return (jsxRuntime.jsx(react.Text, { children: idPickerLabels?.undefined ?? formI18n.t('undefined') }, id));
4710
4772
  }
4711
4773
  return (jsxRuntime.jsx(Tag, { closable: true, onClick: () => {
4712
4774
  setValue(colLabel, watchIds.filter((itemId) => itemId !== item[column_ref]));
4713
4775
  }, children: !!renderDisplay === true
4714
4776
  ? renderDisplay(item)
4715
4777
  : item[display_column] }, id));
4716
- }), jsxRuntime.jsx(Tag, { cursor: "pointer", onClick: () => {
4778
+ }), jsxRuntime.jsx(Tag, { cursor: 'pointer', onClick: () => {
4717
4779
  setOpenSearchResult(true);
4718
- }, children: translate.t(removeIndex(`${colLabel}.add_more`)) })] })), !isMultiple && (jsxRuntime.jsx(Button, { variant: "outline", onClick: () => {
4780
+ }, children: idPickerLabels?.addMore ?? formI18n.t('add_more') })] })), !isMultiple && (jsxRuntime.jsx(Button, { variant: 'outline', onClick: () => {
4719
4781
  setOpenSearchResult(true);
4720
- }, justifyContent: "start", children: queryDefault.isLoading ? jsxRuntime.jsx(react.Spinner, { size: "sm" }) : getPickedValue() })), jsxRuntime.jsxs(PopoverRoot, { open: openSearchResult, onOpenChange: (e) => setOpenSearchResult(e.open), closeOnInteractOutside: true, initialFocusEl: () => ref.current, positioning: { placement: "bottom-start", strategy: "fixed" }, children: [jsxRuntime.jsx(PopoverTrigger, {}), jsxRuntime.jsx(PopoverContent, { portalled: false, children: jsxRuntime.jsxs(PopoverBody, { display: "grid", gap: 1, children: [jsxRuntime.jsx(react.Input, { placeholder: translate.t(removeIndex(`${colLabel}.type_to_search`)), onChange: onSearchChange, autoComplete: "off", ref: ref, value: searchText }), jsxRuntime.jsx(PopoverTitle, {}), openSearchResult && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [(isFetching || isLoading || isPending) && jsxRuntime.jsx(react.Spinner, {}), isError && (jsxRuntime.jsx(react.Icon, { color: "red.400", children: jsxRuntime.jsx(bi.BiError, {}) })), jsxRuntime.jsxs(react.Flex, { justifyContent: "space-between", alignItems: "center", children: [jsxRuntime.jsxs(react.Flex, { alignItems: "center", gap: "2", children: [jsxRuntime.jsx(InfoTip, { children: `${translate.t(removeIndex(`${colLabel}.total`))} ${count}, ${translate.t(removeIndex(`${colLabel}.showing`))} ${limit} ${translate.t(removeIndex(`${colLabel}.per_page`), "per page")}` }), jsxRuntime.jsxs(react.Text, { fontSize: "sm", fontWeight: "bold", children: [count, jsxRuntime.jsxs(react.Text, { as: "span", fontSize: "xs", ml: "1", color: "gray.500", children: ["/", " ", count > 0
4782
+ }, justifyContent: 'start', children: queryDefault.isLoading ? jsxRuntime.jsx(react.Spinner, { size: "sm" }) : getPickedValue() })), jsxRuntime.jsxs(PopoverRoot, { open: openSearchResult, onOpenChange: (e) => setOpenSearchResult(e.open), closeOnInteractOutside: true, initialFocusEl: () => ref.current, positioning: { placement: 'bottom-start', strategy: 'fixed' }, children: [jsxRuntime.jsx(PopoverTrigger, {}), jsxRuntime.jsx(PopoverContent, { portalled: false, children: jsxRuntime.jsxs(PopoverBody, { display: 'grid', gap: 1, children: [jsxRuntime.jsx(react.Input, { placeholder: idPickerLabels?.typeToSearch ?? formI18n.t('type_to_search'), onChange: onSearchChange, autoComplete: "off", ref: ref, value: searchText }), jsxRuntime.jsx(PopoverTitle, {}), openSearchResult && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [(isFetching || isLoading || isPending) && jsxRuntime.jsx(react.Spinner, {}), isError && (jsxRuntime.jsx(react.Icon, { color: 'red.400', children: jsxRuntime.jsx(bi.BiError, {}) })), jsxRuntime.jsxs(react.Flex, { justifyContent: "space-between", alignItems: "center", children: [jsxRuntime.jsxs(react.Flex, { alignItems: "center", gap: "2", children: [jsxRuntime.jsx(InfoTip, { children: `${idPickerLabels?.total ?? formI18n.t('total')} ${count}, ${idPickerLabels?.showing ?? formI18n.t('showing')} ${limit} ${idPickerLabels?.perPage ?? formI18n.t('per_page', { defaultValue: 'per page' })}` }), jsxRuntime.jsxs(react.Text, { fontSize: "sm", fontWeight: "bold", children: [count, jsxRuntime.jsxs(react.Text, { as: "span", fontSize: "xs", ml: "1", color: "gray.500", children: ["/", ' ', count > 0
4721
4783
  ? `${page * limit + 1}-${Math.min((page + 1) * limit, count)}`
4722
- : "0"] })] })] }), jsxRuntime.jsx(react.Box, { children: jsxRuntime.jsxs("select", { value: limit, onChange: handleLimitChange, style: {
4723
- padding: "4px 8px",
4724
- borderRadius: "4px",
4725
- border: "1px solid #ccc",
4726
- fontSize: "14px",
4727
- }, children: [jsxRuntime.jsx("option", { value: "5", children: "5" }), jsxRuntime.jsx("option", { value: "10", children: "10" }), jsxRuntime.jsx("option", { value: "20", children: "20" }), jsxRuntime.jsx("option", { value: "30", children: "30" })] }) })] }), jsxRuntime.jsx(react.Grid, { overflowY: "auto", children: dataList.length > 0 ? (jsxRuntime.jsx(react.Flex, { flexFlow: "column wrap", gap: 1, children: dataList.map((item) => {
4784
+ : '0'] })] })] }), jsxRuntime.jsx(react.Box, { children: jsxRuntime.jsxs("select", { value: limit, onChange: handleLimitChange, style: {
4785
+ padding: '4px 8px',
4786
+ borderRadius: '4px',
4787
+ border: '1px solid #ccc',
4788
+ fontSize: '14px',
4789
+ }, children: [jsxRuntime.jsx("option", { value: "5", children: "5" }), jsxRuntime.jsx("option", { value: "10", children: "10" }), jsxRuntime.jsx("option", { value: "20", children: "20" }), jsxRuntime.jsx("option", { value: "30", children: "30" })] }) })] }), jsxRuntime.jsx(react.Grid, { overflowY: 'auto', children: dataList.length > 0 ? (jsxRuntime.jsx(react.Flex, { flexFlow: 'column wrap', gap: 1, children: dataList.map((item) => {
4728
4790
  const selected = isMultiple
4729
4791
  ? watchIds.some((id) => item[column_ref] === id)
4730
4792
  : watchId === item[column_ref];
4731
- return (jsxRuntime.jsx(react.Box, { cursor: "pointer", onClick: () => {
4793
+ return (jsxRuntime.jsx(react.Box, { cursor: 'pointer', onClick: () => {
4732
4794
  if (!isMultiple) {
4733
4795
  setOpenSearchResult(false);
4734
4796
  setValue(colLabel, item[column_ref]);
@@ -4744,15 +4806,17 @@ const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
4744
4806
  setValue(colLabel, [...newSet]);
4745
4807
  }, opacity: 0.7, _hover: { opacity: 1 }, ...(selected
4746
4808
  ? {
4747
- color: "colorPalette.400/50",
4748
- fontWeight: "bold",
4809
+ color: 'colorPalette.400/50',
4810
+ fontWeight: 'bold',
4749
4811
  }
4750
4812
  : {}), children: !!renderDisplay === true
4751
4813
  ? renderDisplay(item)
4752
4814
  : item[display_column] }, item[column_ref]));
4753
4815
  }) })) : (jsxRuntime.jsx(react.Text, { children: searchText
4754
- ? translate.t(removeIndex(`${colLabel}.empty_search_result`))
4755
- : translate.t(removeIndex(`${colLabel}.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: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
4816
+ ? idPickerLabels?.emptySearchResult ??
4817
+ formI18n.t('empty_search_result')
4818
+ : idPickerLabels?.initialResults ??
4819
+ 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() }))] }));
4756
4820
  };
4757
4821
 
4758
4822
  const NumberInputRoot = React__namespace.forwardRef(function NumberInput(props, ref) {
@@ -4766,7 +4830,7 @@ react.NumberInput.Label;
4766
4830
  const NumberInputField = ({ schema, column, prefix, }) => {
4767
4831
  const { setValue, formState: { errors }, watch, } = reactHookForm.useFormContext();
4768
4832
  const { translate } = useSchemaContext();
4769
- const { required, gridColumn = "span 4", gridRow = "span 1" } = schema;
4833
+ const { required, gridColumn = "span 12", gridRow = "span 1" } = schema;
4770
4834
  const isRequired = required?.some((columnId) => columnId === column);
4771
4835
  const colLabel = `${prefix}${column}`;
4772
4836
  const value = watch(`${colLabel}`);
@@ -4851,7 +4915,7 @@ const RecordInput$1 = ({ column, schema, prefix }) => {
4851
4915
  const StringInputField = ({ column, schema, prefix, }) => {
4852
4916
  const { register, formState: { errors }, } = reactHookForm.useFormContext();
4853
4917
  const { translate } = useSchemaContext();
4854
- const { required, gridColumn = "span 4", gridRow = "span 1" } = schema;
4918
+ const { required, gridColumn = "span 12", gridRow = "span 1" } = schema;
4855
4919
  const isRequired = required?.some((columnId) => columnId === column);
4856
4920
  const colLabel = `${prefix}${column}`;
4857
4921
  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`)) }))] }) }));
@@ -5040,7 +5104,7 @@ Textarea.displayName = "Textarea";
5040
5104
  const TextAreaInput = ({ column, schema, prefix, }) => {
5041
5105
  const { register, formState: { errors }, } = reactHookForm.useFormContext();
5042
5106
  const { translate } = useSchemaContext();
5043
- const { required, gridColumn = "span 4", gridRow = "span 1" } = schema;
5107
+ const { required, gridColumn = "span 12", gridRow = "span 1" } = schema;
5044
5108
  const isRequired = required?.some((columnId) => columnId === column);
5045
5109
  const colLabel = `${prefix}${column}`;
5046
5110
  const form = reactHookForm.useFormContext();
@@ -5177,7 +5241,7 @@ dayjs.extend(timezone);
5177
5241
  const TimePicker = ({ column, schema, prefix }) => {
5178
5242
  const { watch, formState: { errors }, setValue, } = reactHookForm.useFormContext();
5179
5243
  const { translate, timezone } = useSchemaContext();
5180
- const { required, gridColumn = "span 4", gridRow = "span 1", timeFormat = "HH:mm:ssZ", displayTimeFormat = "hh:mm A", } = schema;
5244
+ const { required, gridColumn = "span 12", gridRow = "span 1", timeFormat = "HH:mm:ssZ", displayTimeFormat = "hh:mm A", } = schema;
5181
5245
  const isRequired = required?.some((columnId) => columnId === column);
5182
5246
  const colLabel = `${prefix}${column}`;
5183
5247
  const [open, setOpen] = React.useState(false);
@@ -5439,12 +5503,13 @@ dayjs.extend(utc);
5439
5503
  dayjs.extend(timezone);
5440
5504
  const DateTimePicker = ({ column, schema, prefix, }) => {
5441
5505
  const { watch, formState: { errors }, setValue, } = reactHookForm.useFormContext();
5442
- const { translate, timezone } = useSchemaContext();
5443
- const { required, gridColumn = "span 4", gridRow = "span 1", displayDateFormat = "YYYY-MM-DD HH:mm:ss",
5506
+ const { timezone, dateTimePickerLabels } = useSchemaContext();
5507
+ const formI18n = useFormI18n(column, prefix);
5508
+ const { required, gridColumn = "span 12", gridRow = "span 1", displayDateFormat = "YYYY-MM-DD HH:mm:ss",
5444
5509
  // with timezone
5445
5510
  dateFormat = "YYYY-MM-DD[T]HH:mm:ssZ", } = schema;
5446
5511
  const isRequired = required?.some((columnId) => columnId === column);
5447
- const colLabel = `${prefix}${column}`;
5512
+ const colLabel = formI18n.colLabel;
5448
5513
  const [open, setOpen] = React.useState(false);
5449
5514
  const selectedDate = watch(colLabel);
5450
5515
  const displayDate = dayjs(selectedDate)
@@ -5473,47 +5538,44 @@ const DateTimePicker = ({ column, schema, prefix, }) => {
5473
5538
  console.error(e);
5474
5539
  }
5475
5540
  }, [selectedDate, dateFormat, colLabel, setValue]);
5476
- const customTranslate = (label) => {
5477
- return translateWrapper({ prefix, column, label, translate });
5478
- };
5479
- return (jsxRuntime.jsxs(Field, { label: `${customTranslate(`field_label`)}`, required: isRequired, alignItems: "stretch", gridColumn,
5541
+ return (jsxRuntime.jsxs(Field, { label: formI18n.label(), required: isRequired, alignItems: "stretch", gridColumn,
5480
5542
  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: () => {
5481
5543
  setOpen(true);
5482
5544
  }, 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) => {
5483
5545
  setValue(colLabel, dayjs(date).tz(timezone).format(dateFormat));
5484
5546
  }, timezone: timezone, labels: {
5485
- monthNamesShort: [
5486
- translate.t(`common.month_1`, { defaultValue: "January" }),
5487
- translate.t(`common.month_2`, { defaultValue: "February" }),
5488
- translate.t(`common.month_3`, { defaultValue: "March" }),
5489
- translate.t(`common.month_4`, { defaultValue: "April" }),
5490
- translate.t(`common.month_5`, { defaultValue: "May" }),
5491
- translate.t(`common.month_6`, { defaultValue: "June" }),
5492
- translate.t(`common.month_7`, { defaultValue: "July" }),
5493
- translate.t(`common.month_8`, { defaultValue: "August" }),
5494
- translate.t(`common.month_9`, { defaultValue: "September" }),
5495
- translate.t(`common.month_10`, { defaultValue: "October" }),
5496
- translate.t(`common.month_11`, { defaultValue: "November" }),
5497
- translate.t(`common.month_12`, { defaultValue: "December" }),
5547
+ monthNamesShort: dateTimePickerLabels?.monthNamesShort ?? [
5548
+ formI18n.translate.t(`common.month_1`, { defaultValue: "January" }),
5549
+ formI18n.translate.t(`common.month_2`, { defaultValue: "February" }),
5550
+ formI18n.translate.t(`common.month_3`, { defaultValue: "March" }),
5551
+ formI18n.translate.t(`common.month_4`, { defaultValue: "April" }),
5552
+ formI18n.translate.t(`common.month_5`, { defaultValue: "May" }),
5553
+ formI18n.translate.t(`common.month_6`, { defaultValue: "June" }),
5554
+ formI18n.translate.t(`common.month_7`, { defaultValue: "July" }),
5555
+ formI18n.translate.t(`common.month_8`, { defaultValue: "August" }),
5556
+ formI18n.translate.t(`common.month_9`, { defaultValue: "September" }),
5557
+ formI18n.translate.t(`common.month_10`, { defaultValue: "October" }),
5558
+ formI18n.translate.t(`common.month_11`, { defaultValue: "November" }),
5559
+ formI18n.translate.t(`common.month_12`, { defaultValue: "December" }),
5498
5560
  ],
5499
- weekdayNamesShort: [
5500
- translate.t(`common.weekday_1`, { defaultValue: "Sun" }),
5501
- translate.t(`common.weekday_2`, { defaultValue: "Mon" }),
5502
- translate.t(`common.weekday_3`, { defaultValue: "Tue" }),
5503
- translate.t(`common.weekday_4`, {
5561
+ weekdayNamesShort: dateTimePickerLabels?.weekdayNamesShort ?? [
5562
+ formI18n.translate.t(`common.weekday_1`, { defaultValue: "Sun" }),
5563
+ formI18n.translate.t(`common.weekday_2`, { defaultValue: "Mon" }),
5564
+ formI18n.translate.t(`common.weekday_3`, { defaultValue: "Tue" }),
5565
+ formI18n.translate.t(`common.weekday_4`, {
5504
5566
  defaultValue: "Wed",
5505
5567
  }),
5506
- translate.t(`common.weekday_5`, { defaultValue: "Thu" }),
5507
- translate.t(`common.weekday_6`, { defaultValue: "Fri" }),
5508
- translate.t(`common.weekday_7`, { defaultValue: "Sat" }),
5568
+ formI18n.translate.t(`common.weekday_5`, { defaultValue: "Thu" }),
5569
+ formI18n.translate.t(`common.weekday_6`, { defaultValue: "Fri" }),
5570
+ formI18n.translate.t(`common.weekday_7`, { defaultValue: "Sat" }),
5509
5571
  ],
5510
- backButtonLabel: translate.t(`common.back_button`, {
5572
+ backButtonLabel: dateTimePickerLabels?.backButtonLabel ?? formI18n.translate.t(`common.back_button`, {
5511
5573
  defaultValue: "Back",
5512
5574
  }),
5513
- forwardButtonLabel: translate.t(`common.forward_button`, {
5575
+ forwardButtonLabel: dateTimePickerLabels?.forwardButtonLabel ?? formI18n.translate.t(`common.forward_button`, {
5514
5576
  defaultValue: "Forward",
5515
5577
  }),
5516
- } })] }) })] }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: customTranslate(`field_required`) }))] }));
5578
+ } })] }) })] }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: formI18n.required() }))] }));
5517
5579
  };
5518
5580
 
5519
5581
  const SchemaRenderer = ({ schema, prefix, column, }) => {
@@ -5615,7 +5677,7 @@ const ArrayViewer = ({ schema, column, prefix }) => {
5615
5677
  const BooleanViewer = ({ schema, column, prefix, }) => {
5616
5678
  const { watch, formState: { errors }, } = reactHookForm.useFormContext();
5617
5679
  const { translate } = useSchemaContext();
5618
- const { required, gridColumn = "span 4", gridRow = "span 1" } = schema;
5680
+ const { required, gridColumn = "span 12", gridRow = "span 1" } = schema;
5619
5681
  const isRequired = required?.some((columnId) => columnId === column);
5620
5682
  const colLabel = `${prefix}${column}`;
5621
5683
  const value = watch(colLabel);
@@ -5651,17 +5713,14 @@ const DateViewer = ({ column, schema, prefix }) => {
5651
5713
 
5652
5714
  const EnumViewer = ({ column, isMultiple = false, schema, prefix, }) => {
5653
5715
  const { watch, formState: { errors }, } = reactHookForm.useFormContext();
5654
- const { translate } = useSchemaContext();
5716
+ const formI18n = useFormI18n(column, prefix);
5655
5717
  const { required } = schema;
5656
5718
  const isRequired = required?.some((columnId) => columnId === column);
5657
- const { gridColumn = "span 4", gridRow = "span 1", renderDisplay } = schema;
5658
- const colLabel = `${prefix}${column}`;
5719
+ const { gridColumn = "span 12", gridRow = "span 1", renderDisplay } = schema;
5720
+ const colLabel = formI18n.colLabel;
5659
5721
  const watchEnum = watch(colLabel);
5660
5722
  const watchEnums = (watch(colLabel) ?? []);
5661
- const customTranslate = (label) => {
5662
- return translateWrapper({ prefix, column, label, translate });
5663
- };
5664
- return (jsxRuntime.jsxs(Field, { label: `${customTranslate(`field_label`)}`, required: isRequired, alignItems: "stretch", gridColumn,
5723
+ return (jsxRuntime.jsxs(Field, { label: formI18n.label(), required: isRequired, alignItems: "stretch", gridColumn,
5665
5724
  gridRow, children: [isMultiple && (jsxRuntime.jsx(react.Flex, { flexFlow: "wrap", gap: 1, children: watchEnums.map((enumValue) => {
5666
5725
  const item = enumValue;
5667
5726
  if (item === undefined) {
@@ -5669,14 +5728,14 @@ const EnumViewer = ({ column, isMultiple = false, schema, prefix, }) => {
5669
5728
  }
5670
5729
  return (jsxRuntime.jsx(Tag, { size: "lg", children: !!renderDisplay === true
5671
5730
  ? renderDisplay(item)
5672
- : customTranslate(item) }, item));
5673
- }) })), !isMultiple && jsxRuntime.jsx(react.Text, { children: customTranslate(watchEnum) }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: customTranslate(`field_required`) }))] }));
5731
+ : formI18n.t(item) }, item));
5732
+ }) })), !isMultiple && jsxRuntime.jsx(react.Text, { children: formI18n.t(watchEnum) }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: formI18n.required() }))] }));
5674
5733
  };
5675
5734
 
5676
5735
  const FileViewer = ({ column, schema, prefix }) => {
5677
5736
  const { watch } = reactHookForm.useFormContext();
5678
5737
  const { translate } = useSchemaContext();
5679
- const { required, gridColumn = "span 4", gridRow = "span 1", } = schema;
5738
+ const { required, gridColumn = "span 12", gridRow = "span 1", } = schema;
5680
5739
  const isRequired = required?.some((columnId) => columnId === column);
5681
5740
  const currentFiles = (watch(column) ?? []);
5682
5741
  const colLabel = `${prefix}${column}`;
@@ -5688,7 +5747,7 @@ const FileViewer = ({ column, schema, prefix }) => {
5688
5747
  const IdViewer = ({ column, schema, prefix, isMultiple = false, }) => {
5689
5748
  const { watch, formState: { errors }, } = reactHookForm.useFormContext();
5690
5749
  const { idMap, translate } = useSchemaContext();
5691
- const { required, gridColumn = "span 4", gridRow = "span 1", renderDisplay, foreign_key, } = schema;
5750
+ const { required, gridColumn = "span 12", gridRow = "span 1", renderDisplay, foreign_key, } = schema;
5692
5751
  const isRequired = required?.some((columnId) => columnId === column);
5693
5752
  const { display_column } = foreign_key;
5694
5753
  const colLabel = `${prefix}${column}`;
@@ -5719,7 +5778,7 @@ const IdViewer = ({ column, schema, prefix, isMultiple = false, }) => {
5719
5778
  const NumberViewer = ({ schema, column, prefix, }) => {
5720
5779
  const { watch, formState: { errors }, } = reactHookForm.useFormContext();
5721
5780
  const { translate } = useSchemaContext();
5722
- const { required, gridColumn = "span 4", gridRow = "span 1" } = schema;
5781
+ const { required, gridColumn = "span 12", gridRow = "span 1" } = schema;
5723
5782
  const isRequired = required?.some((columnId) => columnId === column);
5724
5783
  const colLabel = `${prefix}${column}`;
5725
5784
  const value = watch(colLabel);
@@ -5750,7 +5809,7 @@ const ObjectViewer = ({ schema, column, prefix }) => {
5750
5809
  const RecordInput = ({ column, schema, prefix }) => {
5751
5810
  const { formState: { errors }, setValue, getValues, } = reactHookForm.useFormContext();
5752
5811
  const { translate } = useSchemaContext();
5753
- const { required, gridColumn = "span 4", gridRow = "span 1" } = schema;
5812
+ const { required, gridColumn = "span 12", gridRow = "span 1" } = schema;
5754
5813
  const isRequired = required?.some((columnId) => columnId === column);
5755
5814
  const entries = Object.entries(getValues(column) ?? {});
5756
5815
  const [showNewEntries, setShowNewEntries] = React.useState(false);
@@ -5802,7 +5861,7 @@ const RecordInput = ({ column, schema, prefix }) => {
5802
5861
  const StringViewer = ({ column, schema, prefix, }) => {
5803
5862
  const { watch, formState: { errors }, } = reactHookForm.useFormContext();
5804
5863
  const { translate } = useSchemaContext();
5805
- const { required, gridColumn = "span 4", gridRow = "span 1" } = schema;
5864
+ const { required, gridColumn = "span 12", gridRow = "span 1" } = schema;
5806
5865
  const isRequired = required?.some((columnId) => columnId === column);
5807
5866
  const colLabel = `${prefix}${column}`;
5808
5867
  const value = watch(colLabel);
@@ -5897,7 +5956,7 @@ const TagViewer = ({ column, schema, prefix }) => {
5897
5956
  const TextAreaViewer = ({ column, schema, prefix, }) => {
5898
5957
  const { watch, formState: { errors }, } = reactHookForm.useFormContext();
5899
5958
  const { translate } = useSchemaContext();
5900
- const { required, gridColumn = "span 4", gridRow = "span 1" } = schema;
5959
+ const { required, gridColumn = "span 12", gridRow = "span 1" } = schema;
5901
5960
  const isRequired = required?.some((columnId) => columnId === column);
5902
5961
  const colLabel = `${prefix}${column}`;
5903
5962
  const value = watch(colLabel);
@@ -5907,7 +5966,7 @@ const TextAreaViewer = ({ column, schema, prefix, }) => {
5907
5966
  const TimeViewer = ({ column, schema, prefix }) => {
5908
5967
  const { watch, formState: { errors }, } = reactHookForm.useFormContext();
5909
5968
  const { translate, timezone } = useSchemaContext();
5910
- const { required, gridColumn = "span 4", gridRow = "span 1", displayTimeFormat = "hh:mm A", } = schema;
5969
+ const { required, gridColumn = "span 12", gridRow = "span 1", displayTimeFormat = "hh:mm A", } = schema;
5911
5970
  const isRequired = required?.some((columnId) => columnId === column);
5912
5971
  const colLabel = `${prefix}${column}`;
5913
5972
  const selectedDate = watch(colLabel);
@@ -6039,7 +6098,7 @@ const SubmitButton = () => {
6039
6098
  };
6040
6099
 
6041
6100
  const FormBody = () => {
6042
- const { schema, requestUrl, order, ignore, include, onSubmit, translate, requestOptions, isSuccess, setIsSuccess, isError, setIsError, isSubmiting, setIsSubmiting, isConfirming, setIsConfirming, validatedData, setValidatedData, error, setError, getUpdatedData, customErrorRenderer, displayConfig, } = useSchemaContext();
6101
+ const { schema, requestUrl, order, ignore, include, onSubmit, translate, requestOptions, isSuccess, setIsSuccess, isError, setIsError, isSubmiting, setIsSubmiting, isConfirming, setIsConfirming, validatedData, setValidatedData, error, setError, getUpdatedData, customErrorRenderer, customSuccessRenderer, displayConfig, } = useSchemaContext();
6043
6102
  const { showSubmitButton, showResetButton } = displayConfig;
6044
6103
  const methods = reactHookForm.useFormContext();
6045
6104
  const { properties } = schema;
@@ -6136,15 +6195,19 @@ const FormBody = () => {
6136
6195
  include,
6137
6196
  });
6138
6197
  if (isSuccess) {
6139
- return (jsxRuntime.jsxs(react.Flex, { flexFlow: "column", gap: "2", children: [jsxRuntime.jsxs(react.Alert.Root, { status: "success", children: [jsxRuntime.jsx(react.Alert.Indicator, {}), jsxRuntime.jsx(react.Alert.Content, { children: jsxRuntime.jsx(react.Alert.Title, { children: translate.t("submit_success") }) })] }), jsxRuntime.jsx(react.Flex, { justifyContent: "end", children: jsxRuntime.jsx(react.Button, { onClick: async () => {
6140
- setIsError(false);
6141
- setIsSubmiting(false);
6142
- setIsSuccess(false);
6143
- setIsConfirming(false);
6144
- setValidatedData(undefined);
6145
- const data = await getUpdatedData();
6146
- methods.reset(data);
6147
- }, formNoValidate: true, children: translate.t("submit_again") }) })] }));
6198
+ const resetHandler = async () => {
6199
+ setIsError(false);
6200
+ setIsSubmiting(false);
6201
+ setIsSuccess(false);
6202
+ setIsConfirming(false);
6203
+ setValidatedData(undefined);
6204
+ const data = await getUpdatedData();
6205
+ methods.reset(data);
6206
+ };
6207
+ if (customSuccessRenderer) {
6208
+ return customSuccessRenderer(resetHandler);
6209
+ }
6210
+ return (jsxRuntime.jsxs(react.Flex, { flexFlow: "column", gap: "2", children: [jsxRuntime.jsxs(react.Alert.Root, { status: "success", children: [jsxRuntime.jsx(react.Alert.Indicator, {}), jsxRuntime.jsx(react.Alert.Content, { children: jsxRuntime.jsx(react.Alert.Title, { children: translate.t("submit_success") }) })] }), jsxRuntime.jsx(react.Flex, { justifyContent: "end", children: jsxRuntime.jsx(react.Button, { onClick: resetHandler, formNoValidate: true, children: translate.t("submit_again") }) })] }));
6148
6211
  }
6149
6212
  if (isConfirming) {
6150
6213
  return (jsxRuntime.jsxs(react.Flex, { flexFlow: "column", gap: "2", children: [jsxRuntime.jsx(react.Grid, { gap: 4, gridTemplateColumns: "repeat(12, 1fr)", gridTemplateRows: "repeat(12, max-content)", autoFlow: "row", children: ordered.map((column) => {
@@ -6182,12 +6245,12 @@ const DefaultForm = ({ formConfig, }) => {
6182
6245
  return (jsxRuntime.jsx(FormRoot, { ...formConfig, children: jsxRuntime.jsxs(react.Grid, { gap: "2", children: [showTitle && jsxRuntime.jsx(FormTitle, {}), jsxRuntime.jsx(FormBody, {})] }) }));
6183
6246
  };
6184
6247
 
6185
- const useForm = ({ preLoadedValues, keyPrefix }) => {
6248
+ const useForm = ({ preLoadedValues, keyPrefix, namespace }) => {
6186
6249
  const form = reactHookForm.useForm({
6187
6250
  values: preLoadedValues,
6188
6251
  });
6189
6252
  const [idMap, setIdMap] = React.useState({});
6190
- const translate = reactI18next.useTranslation("", { keyPrefix });
6253
+ const translate = reactI18next.useTranslation(namespace || "", { keyPrefix });
6191
6254
  return {
6192
6255
  form,
6193
6256
  idMap,
@@ -6196,6 +6259,207 @@ const useForm = ({ preLoadedValues, keyPrefix }) => {
6196
6259
  };
6197
6260
  };
6198
6261
 
6262
+ /**
6263
+ * Type definitions for error message configuration
6264
+ */
6265
+ /**
6266
+ * Schema-level error message builder
6267
+ *
6268
+ * Builds a complete errorMessage object compatible with ajv-errors plugin.
6269
+ * Supports both i18n translation keys and plain string messages.
6270
+ *
6271
+ * @param config - Error message configuration
6272
+ * @returns Complete errorMessage object for JSON Schema
6273
+ *
6274
+ * @example
6275
+ * ```typescript
6276
+ * // Simple required field errors
6277
+ * const errorMessage = buildErrorMessages({
6278
+ * required: {
6279
+ * username: "Username is required",
6280
+ * email: "user.email.field_required" // i18n key
6281
+ * }
6282
+ * });
6283
+ *
6284
+ * // With validation rules
6285
+ * const errorMessage = buildErrorMessages({
6286
+ * required: {
6287
+ * password: "Password is required"
6288
+ * },
6289
+ * properties: {
6290
+ * password: {
6291
+ * minLength: "Password must be at least 8 characters",
6292
+ * pattern: "Password must contain letters and numbers"
6293
+ * },
6294
+ * age: {
6295
+ * minimum: "Must be 18 or older",
6296
+ * maximum: "Must be under 120"
6297
+ * }
6298
+ * }
6299
+ * });
6300
+ *
6301
+ * // With global fallbacks
6302
+ * const errorMessage = buildErrorMessages({
6303
+ * required: {
6304
+ * email: "Email is required"
6305
+ * },
6306
+ * minLength: "This field is too short", // applies to all fields
6307
+ * minimum: "Value is too small"
6308
+ * });
6309
+ * ```
6310
+ */
6311
+ const buildErrorMessages = (config) => {
6312
+ const result = {};
6313
+ // Add required field errors
6314
+ if (config.required && Object.keys(config.required).length > 0) {
6315
+ result.required = config.required;
6316
+ }
6317
+ // Add field-specific validation errors
6318
+ if (config.properties && Object.keys(config.properties).length > 0) {
6319
+ result.properties = config.properties;
6320
+ }
6321
+ // Add global fallback error messages
6322
+ const globalKeys = [
6323
+ "minLength",
6324
+ "maxLength",
6325
+ "pattern",
6326
+ "minimum",
6327
+ "maximum",
6328
+ "multipleOf",
6329
+ "format",
6330
+ "type",
6331
+ "enum",
6332
+ ];
6333
+ globalKeys.forEach((key) => {
6334
+ if (config[key]) {
6335
+ result[key] = config[key];
6336
+ }
6337
+ });
6338
+ return result;
6339
+ };
6340
+ /**
6341
+ * Helper function to build required field errors
6342
+ *
6343
+ * Simplifies creating required field error messages, especially useful
6344
+ * for generating i18n translation keys following a pattern.
6345
+ *
6346
+ * @param fields - Array of required field names
6347
+ * @param messageOrGenerator - Either a string template or function to generate messages
6348
+ * @returns Required field error configuration
6349
+ *
6350
+ * @example
6351
+ * ```typescript
6352
+ * // Plain string messages
6353
+ * const required = buildRequiredErrors(
6354
+ * ["username", "email", "password"],
6355
+ * (field) => `${field} is required`
6356
+ * );
6357
+ * // Result: { username: "username is required", email: "email is required", ... }
6358
+ *
6359
+ * // i18n translation keys
6360
+ * const required = buildRequiredErrors(
6361
+ * ["username", "email"],
6362
+ * (field) => `user.${field}.field_required`
6363
+ * );
6364
+ * // Result: { username: "user.username.field_required", email: "user.email.field_required" }
6365
+ *
6366
+ * // Same message for all fields
6367
+ * const required = buildRequiredErrors(
6368
+ * ["username", "email"],
6369
+ * "This field is required"
6370
+ * );
6371
+ * // Result: { username: "This field is required", email: "This field is required" }
6372
+ *
6373
+ * // With keyPrefix for i18n
6374
+ * const required = buildRequiredErrors(
6375
+ * ["username", "email"],
6376
+ * (field) => `${field}.field_required`,
6377
+ * "user"
6378
+ * );
6379
+ * // Result: { username: "user.username.field_required", email: "user.email.field_required" }
6380
+ * ```
6381
+ */
6382
+ const buildRequiredErrors = (fields, messageOrGenerator, keyPrefix = "") => {
6383
+ const result = {};
6384
+ fields.forEach((field) => {
6385
+ if (typeof messageOrGenerator === "function") {
6386
+ const message = messageOrGenerator(field);
6387
+ result[field] = keyPrefix ? `${keyPrefix}.${message}` : message;
6388
+ }
6389
+ else {
6390
+ result[field] = messageOrGenerator;
6391
+ }
6392
+ });
6393
+ return result;
6394
+ };
6395
+ /**
6396
+ * Helper function to build field-specific validation errors
6397
+ *
6398
+ * Creates property-specific error messages for multiple fields at once.
6399
+ *
6400
+ * @param config - Maps field names to their validation error configurations
6401
+ * @returns Properties error configuration
6402
+ *
6403
+ * @example
6404
+ * ```typescript
6405
+ * const properties = buildFieldErrors({
6406
+ * username: {
6407
+ * minLength: "Username must be at least 3 characters",
6408
+ * pattern: "Username can only contain letters and numbers"
6409
+ * },
6410
+ * age: {
6411
+ * minimum: "Must be 18 or older",
6412
+ * maximum: "Must be under 120"
6413
+ * },
6414
+ * email: {
6415
+ * format: "Please enter a valid email address"
6416
+ * }
6417
+ * });
6418
+ * ```
6419
+ */
6420
+ const buildFieldErrors = (config) => {
6421
+ return config;
6422
+ };
6423
+ /**
6424
+ * Helper function to create a complete error message configuration in one call
6425
+ *
6426
+ * Convenient wrapper that combines required and validation errors.
6427
+ *
6428
+ * @param required - Required field error messages
6429
+ * @param properties - Field-specific validation error messages
6430
+ * @param globalFallbacks - Global fallback error messages
6431
+ * @returns Complete error message configuration
6432
+ *
6433
+ * @example
6434
+ * ```typescript
6435
+ * const errorMessage = createErrorMessage(
6436
+ * {
6437
+ * username: "Username is required",
6438
+ * email: "Email is required"
6439
+ * },
6440
+ * {
6441
+ * username: {
6442
+ * minLength: "Username must be at least 3 characters"
6443
+ * },
6444
+ * email: {
6445
+ * format: "Please enter a valid email"
6446
+ * }
6447
+ * },
6448
+ * {
6449
+ * minLength: "This field is too short",
6450
+ * format: "Invalid format"
6451
+ * }
6452
+ * );
6453
+ * ```
6454
+ */
6455
+ const createErrorMessage = (required, properties, globalFallbacks) => {
6456
+ return buildErrorMessages({
6457
+ required,
6458
+ properties,
6459
+ ...globalFallbacks,
6460
+ });
6461
+ };
6462
+
6199
6463
  const getMultiDates = ({ selected, selectedDate, selectedDates, selectable, }) => {
6200
6464
  if (!selectable) {
6201
6465
  return [...selectedDates];
@@ -6253,6 +6517,10 @@ exports.TableSorter = TableSorter;
6253
6517
  exports.TableViewer = TableViewer;
6254
6518
  exports.TextCell = TextCell;
6255
6519
  exports.ViewDialog = ViewDialog;
6520
+ exports.buildErrorMessages = buildErrorMessages;
6521
+ exports.buildFieldErrors = buildFieldErrors;
6522
+ exports.buildRequiredErrors = buildRequiredErrors;
6523
+ exports.createErrorMessage = createErrorMessage;
6256
6524
  exports.getColumns = getColumns;
6257
6525
  exports.getMultiDates = getMultiDates;
6258
6526
  exports.getRangeDates = getRangeDates;