@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.mjs CHANGED
@@ -3657,8 +3657,8 @@ const AccordionItem = Accordion.Item;
3657
3657
  //@ts-expect-error TODO: find appropriate type
3658
3658
  const SchemaFormContext = createContext({
3659
3659
  schema: {},
3660
- serverUrl: "",
3661
- requestUrl: "",
3660
+ serverUrl: '',
3661
+ requestUrl: '',
3662
3662
  order: [],
3663
3663
  ignore: [],
3664
3664
  include: [],
@@ -3714,11 +3714,11 @@ const idPickerSanityCheck = (column, foreign_key) => {
3714
3714
  throw new Error(`The key column does not exist in properties of column ${column} when using id-picker.`);
3715
3715
  }
3716
3716
  };
3717
- const FormRoot = ({ schema, idMap, setIdMap, form, serverUrl, translate, children, order = [], ignore = [], include = [], onSubmit = undefined, rowNumber = undefined, requestOptions = {}, getUpdatedData = () => { }, customErrorRenderer, displayConfig = {
3717
+ const FormRoot = ({ schema, idMap, setIdMap, form, serverUrl, translate, children, order = [], ignore = [], include = [], onSubmit = undefined, rowNumber = undefined, requestOptions = {}, getUpdatedData = () => { }, customErrorRenderer, customSuccessRenderer, displayConfig = {
3718
3718
  showSubmitButton: true,
3719
3719
  showResetButton: true,
3720
3720
  showTitle: true,
3721
- }, }) => {
3721
+ }, dateTimePickerLabels, idPickerLabels, }) => {
3722
3722
  const [isSuccess, setIsSuccess] = useState(false);
3723
3723
  const [isError, setIsError] = useState(false);
3724
3724
  const [isSubmiting, setIsSubmiting] = useState(false);
@@ -3752,7 +3752,10 @@ const FormRoot = ({ schema, idMap, setIdMap, form, serverUrl, translate, childre
3752
3752
  setError,
3753
3753
  getUpdatedData,
3754
3754
  customErrorRenderer,
3755
+ customSuccessRenderer,
3755
3756
  displayConfig,
3757
+ dateTimePickerLabels,
3758
+ idPickerLabels,
3756
3759
  }, children: jsx(FormProvider, { ...form, children: children }) }));
3757
3760
  };
3758
3761
 
@@ -3804,7 +3807,7 @@ const Field = React.forwardRef(function Field(props, ref) {
3804
3807
  const BooleanPicker = ({ schema, column, prefix }) => {
3805
3808
  const { watch, formState: { errors }, setValue, } = useFormContext();
3806
3809
  const { translate } = useSchemaContext();
3807
- const { required, gridColumn = "span 4", gridRow = "span 1" } = schema;
3810
+ const { required, gridColumn = "span 12", gridRow = "span 1" } = schema;
3808
3811
  const isRequired = required?.some((columnId) => columnId === column);
3809
3812
  const colLabel = `${prefix}${column}`;
3810
3813
  const value = watch(colLabel);
@@ -3943,18 +3946,79 @@ const PopoverRoot = Popover.Root;
3943
3946
  const PopoverBody = Popover.Body;
3944
3947
  const PopoverTrigger = Popover.Trigger;
3945
3948
 
3946
- function translateWrapper({ prefix, column, label, translate, }) {
3947
- return translate.t(removeIndex(`${prefix}${column}.${label}`));
3948
- }
3949
+ /**
3950
+ * Custom hook to simplify i18n translation for form fields.
3951
+ * Automatically handles colLabel construction and removeIndex logic.
3952
+ *
3953
+ * @param column - The column name
3954
+ * @param prefix - The prefix for the field (usually empty string or parent path)
3955
+ * @returns Object with translation helper functions
3956
+ *
3957
+ * @example
3958
+ * ```tsx
3959
+ * const formI18n = useFormI18n(column, prefix);
3960
+ *
3961
+ * // Get field label
3962
+ * <Field label={formI18n.label()} />
3963
+ *
3964
+ * // Get error message
3965
+ * <Text>{formI18n.required()}</Text>
3966
+ *
3967
+ * // Get custom translation key
3968
+ * <Text>{formI18n.t('add_more')}</Text>
3969
+ *
3970
+ * // Access the raw colLabel
3971
+ * const colLabel = formI18n.colLabel;
3972
+ * ```
3973
+ */
3974
+ const useFormI18n = (column, prefix = "") => {
3975
+ const { translate } = useSchemaContext();
3976
+ const colLabel = `${prefix}${column}`;
3977
+ return {
3978
+ /**
3979
+ * The constructed column label (prefix + column)
3980
+ */
3981
+ colLabel,
3982
+ /**
3983
+ * Get the field label translation
3984
+ * Equivalent to: translate.t(removeIndex(`${colLabel}.field_label`))
3985
+ */
3986
+ label: (options) => {
3987
+ return translate.t(removeIndex(`${colLabel}.field_label`), options);
3988
+ },
3989
+ /**
3990
+ * Get the required error message translation
3991
+ * Equivalent to: translate.t(removeIndex(`${colLabel}.field_required`))
3992
+ */
3993
+ required: (options) => {
3994
+ return translate.t(removeIndex(`${colLabel}.field_required`), options);
3995
+ },
3996
+ /**
3997
+ * Get a translation for any custom key relative to the field
3998
+ * Equivalent to: translate.t(removeIndex(`${colLabel}.${key}`))
3999
+ *
4000
+ * @param key - The translation key suffix (e.g., 'add_more', 'total', etc.)
4001
+ * @param options - Optional translation options (e.g., defaultValue, interpolation variables)
4002
+ */
4003
+ t: (key, options) => {
4004
+ return translate.t(removeIndex(`${colLabel}.${key}`), options);
4005
+ },
4006
+ /**
4007
+ * Access to the original translate object for edge cases
4008
+ */
4009
+ translate,
4010
+ };
4011
+ };
3949
4012
 
3950
4013
  dayjs.extend(utc);
3951
4014
  dayjs.extend(timezone);
3952
4015
  const DatePicker = ({ column, schema, prefix }) => {
3953
4016
  const { watch, formState: { errors }, setValue, } = useFormContext();
3954
- const { translate, timezone } = useSchemaContext();
3955
- const { required, gridColumn = "span 4", gridRow = "span 1", displayDateFormat = "YYYY-MM-DD", dateFormat = "YYYY-MM-DD", } = schema;
4017
+ const { timezone } = useSchemaContext();
4018
+ const formI18n = useFormI18n(column, prefix);
4019
+ const { required, gridColumn = "span 12", gridRow = "span 1", displayDateFormat = "YYYY-MM-DD", dateFormat = "YYYY-MM-DD", } = schema;
3956
4020
  const isRequired = required?.some((columnId) => columnId === column);
3957
- const colLabel = `${prefix}${column}`;
4021
+ const colLabel = formI18n.colLabel;
3958
4022
  const [open, setOpen] = useState(false);
3959
4023
  const selectedDate = watch(colLabel);
3960
4024
  const displayDate = dayjs(selectedDate).tz(timezone).format(displayDateFormat);
@@ -3981,10 +4045,7 @@ const DatePicker = ({ column, schema, prefix }) => {
3981
4045
  console.error(e);
3982
4046
  }
3983
4047
  }, [selectedDate, dateFormat, colLabel, setValue]);
3984
- const customTranslate = (label) => {
3985
- return translateWrapper({ prefix, column, label, translate });
3986
- };
3987
- return (jsxs(Field, { label: `${customTranslate(`field_label`)}`, required: isRequired, alignItems: "stretch", gridColumn,
4048
+ return (jsxs(Field, { label: formI18n.label(), required: isRequired, alignItems: "stretch", gridColumn,
3988
4049
  gridRow, children: [jsxs(PopoverRoot, { open: open, onOpenChange: (e) => setOpen(e.open), closeOnInteractOutside: true, children: [jsx(PopoverTrigger, { asChild: true, children: jsxs(Button, { size: "sm", variant: "outline", onClick: () => {
3989
4050
  setOpen(true);
3990
4051
  }, justifyContent: "start", children: [jsx(MdDateRange, {}), selectedDate !== undefined ? `${displayDate}` : ""] }) }), jsx(PopoverContent, { children: jsxs(PopoverBody, { children: [jsx(PopoverTitle, {}), jsx(DatePicker$1, { selected: new Date(selectedDate), onDateSelected: ({ date }) => {
@@ -3992,37 +4053,37 @@ const DatePicker = ({ column, schema, prefix }) => {
3992
4053
  setOpen(false);
3993
4054
  }, labels: {
3994
4055
  monthNamesShort: [
3995
- translate.t(`common.month_1`, { defaultValue: "January" }),
3996
- translate.t(`common.month_2`, { defaultValue: "February" }),
3997
- translate.t(`common.month_3`, { defaultValue: "March" }),
3998
- translate.t(`common.month_4`, { defaultValue: "April" }),
3999
- translate.t(`common.month_5`, { defaultValue: "May" }),
4000
- translate.t(`common.month_6`, { defaultValue: "June" }),
4001
- translate.t(`common.month_7`, { defaultValue: "July" }),
4002
- translate.t(`common.month_8`, { defaultValue: "August" }),
4003
- translate.t(`common.month_9`, { defaultValue: "September" }),
4004
- translate.t(`common.month_10`, { defaultValue: "October" }),
4005
- translate.t(`common.month_11`, { defaultValue: "November" }),
4006
- translate.t(`common.month_12`, { defaultValue: "December" }),
4056
+ formI18n.translate.t(`common.month_1`, { defaultValue: "January" }),
4057
+ formI18n.translate.t(`common.month_2`, { defaultValue: "February" }),
4058
+ formI18n.translate.t(`common.month_3`, { defaultValue: "March" }),
4059
+ formI18n.translate.t(`common.month_4`, { defaultValue: "April" }),
4060
+ formI18n.translate.t(`common.month_5`, { defaultValue: "May" }),
4061
+ formI18n.translate.t(`common.month_6`, { defaultValue: "June" }),
4062
+ formI18n.translate.t(`common.month_7`, { defaultValue: "July" }),
4063
+ formI18n.translate.t(`common.month_8`, { defaultValue: "August" }),
4064
+ formI18n.translate.t(`common.month_9`, { defaultValue: "September" }),
4065
+ formI18n.translate.t(`common.month_10`, { defaultValue: "October" }),
4066
+ formI18n.translate.t(`common.month_11`, { defaultValue: "November" }),
4067
+ formI18n.translate.t(`common.month_12`, { defaultValue: "December" }),
4007
4068
  ],
4008
4069
  weekdayNamesShort: [
4009
- translate.t(`common.weekday_1`, { defaultValue: "Sun" }),
4010
- translate.t(`common.weekday_2`, { defaultValue: "Mon" }),
4011
- translate.t(`common.weekday_3`, { defaultValue: "Tue" }),
4012
- translate.t(`common.weekday_4`, {
4070
+ formI18n.translate.t(`common.weekday_1`, { defaultValue: "Sun" }),
4071
+ formI18n.translate.t(`common.weekday_2`, { defaultValue: "Mon" }),
4072
+ formI18n.translate.t(`common.weekday_3`, { defaultValue: "Tue" }),
4073
+ formI18n.translate.t(`common.weekday_4`, {
4013
4074
  defaultValue: "Wed",
4014
4075
  }),
4015
- translate.t(`common.weekday_5`, { defaultValue: "Thu" }),
4016
- translate.t(`common.weekday_6`, { defaultValue: "Fri" }),
4017
- translate.t(`common.weekday_7`, { defaultValue: "Sat" }),
4076
+ formI18n.translate.t(`common.weekday_5`, { defaultValue: "Thu" }),
4077
+ formI18n.translate.t(`common.weekday_6`, { defaultValue: "Fri" }),
4078
+ formI18n.translate.t(`common.weekday_7`, { defaultValue: "Sat" }),
4018
4079
  ],
4019
- backButtonLabel: translate.t(`common.back_button`, {
4080
+ backButtonLabel: formI18n.translate.t(`common.back_button`, {
4020
4081
  defaultValue: "Back",
4021
4082
  }),
4022
- forwardButtonLabel: translate.t(`common.forward_button`, {
4083
+ forwardButtonLabel: formI18n.translate.t(`common.forward_button`, {
4023
4084
  defaultValue: "Forward",
4024
4085
  }),
4025
- } })] }) })] }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: customTranslate(`field_required`) }))] }));
4086
+ } })] }) })] }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: formI18n.required() }))] }));
4026
4087
  };
4027
4088
 
4028
4089
  function filterArray(array, searchTerm) {
@@ -4040,7 +4101,7 @@ const EnumPicker = ({ column, isMultiple = false, schema, prefix, showTotalAndLi
4040
4101
  const { translate } = useSchemaContext();
4041
4102
  const { required, variant } = schema;
4042
4103
  const isRequired = required?.some((columnId) => columnId === column);
4043
- const { gridColumn = "span 4", gridRow = "span 1", renderDisplay } = schema;
4104
+ const { gridColumn = "span 12", gridRow = "span 1", renderDisplay } = schema;
4044
4105
  const [searchText, setSearchText] = useState();
4045
4106
  const [limit, setLimit] = useState(10);
4046
4107
  const [openSearchResult, setOpenSearchResult] = useState();
@@ -4482,7 +4543,7 @@ const FileDropzone = ({ children = undefined, gridProps = {}, onDrop = () => { }
4482
4543
  const FilePicker = ({ column, schema, prefix }) => {
4483
4544
  const { setValue, formState: { errors }, watch, } = useFormContext();
4484
4545
  const { translate } = useSchemaContext();
4485
- const { required, gridColumn = "span 4", gridRow = "span 1", } = schema;
4546
+ const { required, gridColumn = "span 12", gridRow = "span 1", } = schema;
4486
4547
  const isRequired = required?.some((columnId) => columnId === column);
4487
4548
  const currentFiles = (watch(column) ?? []);
4488
4549
  const colLabel = `${prefix}${column}`;
@@ -4537,16 +4598,17 @@ const getTableData = async ({ serverUrl, in_table, searching = "", where = [], l
4537
4598
 
4538
4599
  const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
4539
4600
  const { watch, formState: { errors }, setValue, } = useFormContext();
4540
- const { serverUrl, idMap, setIdMap, translate, schema: parentSchema, } = useSchemaContext();
4541
- const { required, gridColumn = "span 4", gridRow = "span 1", renderDisplay, foreign_key, } = schema;
4601
+ const { serverUrl, idMap, setIdMap, schema: parentSchema, idPickerLabels, } = useSchemaContext();
4602
+ const formI18n = useFormI18n(column, prefix);
4603
+ const { required, gridColumn = 'span 12', gridRow = 'span 1', renderDisplay, foreign_key, } = schema;
4542
4604
  const isRequired = required?.some((columnId) => columnId === column);
4543
4605
  const { table, column: column_ref, display_column, customQueryFn, } = foreign_key;
4544
- const [searchText, setSearchText] = useState("");
4606
+ const [searchText, setSearchText] = useState('');
4545
4607
  const [limit, setLimit] = useState(10);
4546
4608
  const [openSearchResult, setOpenSearchResult] = useState();
4547
4609
  const [page, setPage] = useState(0);
4548
4610
  const ref = useRef(null);
4549
- const colLabel = `${prefix}${column}`;
4611
+ const colLabel = formI18n.colLabel;
4550
4612
  const watchId = watch(colLabel);
4551
4613
  const watchIds = isMultiple ? (watch(colLabel) ?? []) : [];
4552
4614
  // Query for search results
@@ -4555,7 +4617,7 @@ const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
4555
4617
  queryFn: async () => {
4556
4618
  if (customQueryFn) {
4557
4619
  const { data, idMap } = await customQueryFn({
4558
- searching: searchText ?? "",
4620
+ searching: searchText ?? '',
4559
4621
  limit: limit,
4560
4622
  offset: page * limit,
4561
4623
  });
@@ -4566,7 +4628,7 @@ const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
4566
4628
  }
4567
4629
  const data = await getTableData({
4568
4630
  serverUrl,
4569
- searching: searchText ?? "",
4631
+ searching: searchText ?? '',
4570
4632
  in_table: table,
4571
4633
  limit: limit,
4572
4634
  offset: page * limit,
@@ -4596,7 +4658,7 @@ const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
4596
4658
  queryFn: async () => {
4597
4659
  if (customQueryFn) {
4598
4660
  const { data, idMap } = await customQueryFn({
4599
- searching: watchIds.join(","),
4661
+ searching: watchIds.join(','),
4600
4662
  limit: isMultiple ? watchIds.length : 1,
4601
4663
  offset: 0,
4602
4664
  });
@@ -4608,7 +4670,7 @@ const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
4608
4670
  if (!watchId && (!watchIds || watchIds.length === 0)) {
4609
4671
  return { data: [] };
4610
4672
  }
4611
- const searchValue = isMultiple ? watchIds.join(",") : watchId;
4673
+ const searchValue = isMultiple ? watchIds.join(',') : watchId;
4612
4674
  const data = await getTableData({
4613
4675
  serverUrl,
4614
4676
  searching: searchValue,
@@ -4645,7 +4707,7 @@ const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
4645
4707
  useEffect(() => {
4646
4708
  if (openSearchResult) {
4647
4709
  // Reset search text when opening the popover
4648
- setSearchText("");
4710
+ setSearchText('');
4649
4711
  // Reset page to first page
4650
4712
  setPage(0);
4651
4713
  // Fetch initial data
@@ -4671,44 +4733,44 @@ const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
4671
4733
  const count = data?.count ?? 0;
4672
4734
  const getPickedValue = () => {
4673
4735
  if (Object.keys(idMap).length <= 0) {
4674
- return "";
4736
+ return '';
4675
4737
  }
4676
4738
  const record = idMap[watchId];
4677
4739
  if (record === undefined) {
4678
- return "";
4740
+ return '';
4679
4741
  }
4680
4742
  if (!!renderDisplay === true) {
4681
4743
  return renderDisplay(record);
4682
4744
  }
4683
4745
  return record[display_column];
4684
4746
  };
4685
- return (jsxs(Field, { label: `${translate.t(removeIndex(removeIndex(`${column}.field_label`)))}`, required: isRequired, alignItems: "stretch", gridColumn,
4686
- gridRow, children: [isMultiple && (jsxs(Flex, { flexFlow: "wrap", gap: 1, children: [watchIds.map((id) => {
4747
+ return (jsxs(Field, { label: formI18n.label(), required: isRequired, alignItems: 'stretch', gridColumn,
4748
+ gridRow, children: [isMultiple && (jsxs(Flex, { flexFlow: 'wrap', gap: 1, children: [watchIds.map((id) => {
4687
4749
  const item = idMap[id];
4688
4750
  if (item === undefined) {
4689
- return (jsx(Text, { children: translate.t(removeIndex(`${colLabel}.undefined`)) }, id));
4751
+ return (jsx(Text, { children: idPickerLabels?.undefined ?? formI18n.t('undefined') }, id));
4690
4752
  }
4691
4753
  return (jsx(Tag, { closable: true, onClick: () => {
4692
4754
  setValue(colLabel, watchIds.filter((itemId) => itemId !== item[column_ref]));
4693
4755
  }, children: !!renderDisplay === true
4694
4756
  ? renderDisplay(item)
4695
4757
  : item[display_column] }, id));
4696
- }), jsx(Tag, { cursor: "pointer", onClick: () => {
4758
+ }), jsx(Tag, { cursor: 'pointer', onClick: () => {
4697
4759
  setOpenSearchResult(true);
4698
- }, children: translate.t(removeIndex(`${colLabel}.add_more`)) })] })), !isMultiple && (jsx(Button, { variant: "outline", onClick: () => {
4760
+ }, children: idPickerLabels?.addMore ?? formI18n.t('add_more') })] })), !isMultiple && (jsx(Button, { variant: 'outline', onClick: () => {
4699
4761
  setOpenSearchResult(true);
4700
- }, justifyContent: "start", children: queryDefault.isLoading ? jsx(Spinner, { size: "sm" }) : getPickedValue() })), jsxs(PopoverRoot, { open: openSearchResult, onOpenChange: (e) => setOpenSearchResult(e.open), closeOnInteractOutside: true, initialFocusEl: () => ref.current, positioning: { placement: "bottom-start", strategy: "fixed" }, children: [jsx(PopoverTrigger, {}), jsx(PopoverContent, { portalled: false, children: jsxs(PopoverBody, { display: "grid", gap: 1, children: [jsx(Input, { placeholder: translate.t(removeIndex(`${colLabel}.type_to_search`)), onChange: onSearchChange, autoComplete: "off", ref: ref, value: searchText }), jsx(PopoverTitle, {}), openSearchResult && (jsxs(Fragment, { children: [(isFetching || isLoading || isPending) && jsx(Spinner, {}), isError && (jsx(Icon, { color: "red.400", children: jsx(BiError, {}) })), jsxs(Flex, { justifyContent: "space-between", alignItems: "center", children: [jsxs(Flex, { alignItems: "center", gap: "2", children: [jsx(InfoTip, { children: `${translate.t(removeIndex(`${colLabel}.total`))} ${count}, ${translate.t(removeIndex(`${colLabel}.showing`))} ${limit} ${translate.t(removeIndex(`${colLabel}.per_page`), "per page")}` }), jsxs(Text, { fontSize: "sm", fontWeight: "bold", children: [count, jsxs(Text, { as: "span", fontSize: "xs", ml: "1", color: "gray.500", children: ["/", " ", count > 0
4762
+ }, justifyContent: 'start', children: queryDefault.isLoading ? jsx(Spinner, { size: "sm" }) : getPickedValue() })), jsxs(PopoverRoot, { open: openSearchResult, onOpenChange: (e) => setOpenSearchResult(e.open), closeOnInteractOutside: true, initialFocusEl: () => ref.current, positioning: { placement: 'bottom-start', strategy: 'fixed' }, children: [jsx(PopoverTrigger, {}), jsx(PopoverContent, { portalled: false, children: jsxs(PopoverBody, { display: 'grid', gap: 1, children: [jsx(Input, { placeholder: idPickerLabels?.typeToSearch ?? formI18n.t('type_to_search'), onChange: onSearchChange, autoComplete: "off", ref: ref, value: searchText }), jsx(PopoverTitle, {}), openSearchResult && (jsxs(Fragment, { children: [(isFetching || isLoading || isPending) && jsx(Spinner, {}), isError && (jsx(Icon, { color: 'red.400', children: jsx(BiError, {}) })), jsxs(Flex, { justifyContent: "space-between", alignItems: "center", children: [jsxs(Flex, { alignItems: "center", gap: "2", children: [jsx(InfoTip, { children: `${idPickerLabels?.total ?? formI18n.t('total')} ${count}, ${idPickerLabels?.showing ?? formI18n.t('showing')} ${limit} ${idPickerLabels?.perPage ?? formI18n.t('per_page', { defaultValue: 'per page' })}` }), jsxs(Text, { fontSize: "sm", fontWeight: "bold", children: [count, jsxs(Text, { as: "span", fontSize: "xs", ml: "1", color: "gray.500", children: ["/", ' ', count > 0
4701
4763
  ? `${page * limit + 1}-${Math.min((page + 1) * limit, count)}`
4702
- : "0"] })] })] }), jsx(Box, { children: jsxs("select", { value: limit, onChange: handleLimitChange, style: {
4703
- padding: "4px 8px",
4704
- borderRadius: "4px",
4705
- border: "1px solid #ccc",
4706
- fontSize: "14px",
4707
- }, children: [jsx("option", { value: "5", children: "5" }), jsx("option", { value: "10", children: "10" }), jsx("option", { value: "20", children: "20" }), jsx("option", { value: "30", children: "30" })] }) })] }), jsx(Grid, { overflowY: "auto", children: dataList.length > 0 ? (jsx(Flex, { flexFlow: "column wrap", gap: 1, children: dataList.map((item) => {
4764
+ : '0'] })] })] }), jsx(Box, { children: jsxs("select", { value: limit, onChange: handleLimitChange, style: {
4765
+ padding: '4px 8px',
4766
+ borderRadius: '4px',
4767
+ border: '1px solid #ccc',
4768
+ fontSize: '14px',
4769
+ }, children: [jsx("option", { value: "5", children: "5" }), jsx("option", { value: "10", children: "10" }), jsx("option", { value: "20", children: "20" }), jsx("option", { value: "30", children: "30" })] }) })] }), jsx(Grid, { overflowY: 'auto', children: dataList.length > 0 ? (jsx(Flex, { flexFlow: 'column wrap', gap: 1, children: dataList.map((item) => {
4708
4770
  const selected = isMultiple
4709
4771
  ? watchIds.some((id) => item[column_ref] === id)
4710
4772
  : watchId === item[column_ref];
4711
- return (jsx(Box, { cursor: "pointer", onClick: () => {
4773
+ return (jsx(Box, { cursor: 'pointer', onClick: () => {
4712
4774
  if (!isMultiple) {
4713
4775
  setOpenSearchResult(false);
4714
4776
  setValue(colLabel, item[column_ref]);
@@ -4724,15 +4786,17 @@ const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
4724
4786
  setValue(colLabel, [...newSet]);
4725
4787
  }, opacity: 0.7, _hover: { opacity: 1 }, ...(selected
4726
4788
  ? {
4727
- color: "colorPalette.400/50",
4728
- fontWeight: "bold",
4789
+ color: 'colorPalette.400/50',
4790
+ fontWeight: 'bold',
4729
4791
  }
4730
4792
  : {}), children: !!renderDisplay === true
4731
4793
  ? renderDisplay(item)
4732
4794
  : item[display_column] }, item[column_ref]));
4733
4795
  }) })) : (jsx(Text, { children: searchText
4734
- ? translate.t(removeIndex(`${colLabel}.empty_search_result`))
4735
- : translate.t(removeIndex(`${colLabel}.initial_results`)) })) }), jsx(PaginationRoot, { justifySelf: "center", count: count, pageSize: limit, defaultPage: 1, page: page + 1, onPageChange: (e) => setPage(e.page - 1), children: jsxs(HStack, { gap: "4", children: [jsx(PaginationPrevTrigger, {}), count > 0 && jsx(PaginationPageText, {}), jsx(PaginationNextTrigger, {})] }) })] }))] }) })] }), errors[`${colLabel}`] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
4796
+ ? idPickerLabels?.emptySearchResult ??
4797
+ formI18n.t('empty_search_result')
4798
+ : idPickerLabels?.initialResults ??
4799
+ formI18n.t('initial_results') })) }), jsx(PaginationRoot, { justifySelf: 'center', count: count, pageSize: limit, defaultPage: 1, page: page + 1, onPageChange: (e) => setPage(e.page - 1), children: jsxs(HStack, { gap: "4", children: [jsx(PaginationPrevTrigger, {}), count > 0 && jsx(PaginationPageText, {}), jsx(PaginationNextTrigger, {})] }) })] }))] }) })] }), errors[`${colLabel}`] && (jsx(Text, { color: 'red.400', children: formI18n.required() }))] }));
4736
4800
  };
4737
4801
 
4738
4802
  const NumberInputRoot = React.forwardRef(function NumberInput$1(props, ref) {
@@ -4746,7 +4810,7 @@ NumberInput.Label;
4746
4810
  const NumberInputField = ({ schema, column, prefix, }) => {
4747
4811
  const { setValue, formState: { errors }, watch, } = useFormContext();
4748
4812
  const { translate } = useSchemaContext();
4749
- const { required, gridColumn = "span 4", gridRow = "span 1" } = schema;
4813
+ const { required, gridColumn = "span 12", gridRow = "span 1" } = schema;
4750
4814
  const isRequired = required?.some((columnId) => columnId === column);
4751
4815
  const colLabel = `${prefix}${column}`;
4752
4816
  const value = watch(`${colLabel}`);
@@ -4831,7 +4895,7 @@ const RecordInput$1 = ({ column, schema, prefix }) => {
4831
4895
  const StringInputField = ({ column, schema, prefix, }) => {
4832
4896
  const { register, formState: { errors }, } = useFormContext();
4833
4897
  const { translate } = useSchemaContext();
4834
- const { required, gridColumn = "span 4", gridRow = "span 1" } = schema;
4898
+ const { required, gridColumn = "span 12", gridRow = "span 1" } = schema;
4835
4899
  const isRequired = required?.some((columnId) => columnId === column);
4836
4900
  const colLabel = `${prefix}${column}`;
4837
4901
  return (jsx(Fragment, { children: jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, gridColumn: gridColumn, gridRow: gridRow, children: [jsx(Input, { ...register(`${colLabel}`, { required: isRequired }), autoComplete: "off" }), errors[colLabel] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }) }));
@@ -5020,7 +5084,7 @@ Textarea.displayName = "Textarea";
5020
5084
  const TextAreaInput = ({ column, schema, prefix, }) => {
5021
5085
  const { register, formState: { errors }, } = useFormContext();
5022
5086
  const { translate } = useSchemaContext();
5023
- const { required, gridColumn = "span 4", gridRow = "span 1" } = schema;
5087
+ const { required, gridColumn = "span 12", gridRow = "span 1" } = schema;
5024
5088
  const isRequired = required?.some((columnId) => columnId === column);
5025
5089
  const colLabel = `${prefix}${column}`;
5026
5090
  const form = useFormContext();
@@ -5157,7 +5221,7 @@ dayjs.extend(timezone);
5157
5221
  const TimePicker = ({ column, schema, prefix }) => {
5158
5222
  const { watch, formState: { errors }, setValue, } = useFormContext();
5159
5223
  const { translate, timezone } = useSchemaContext();
5160
- const { required, gridColumn = "span 4", gridRow = "span 1", timeFormat = "HH:mm:ssZ", displayTimeFormat = "hh:mm A", } = schema;
5224
+ const { required, gridColumn = "span 12", gridRow = "span 1", timeFormat = "HH:mm:ssZ", displayTimeFormat = "hh:mm A", } = schema;
5161
5225
  const isRequired = required?.some((columnId) => columnId === column);
5162
5226
  const colLabel = `${prefix}${column}`;
5163
5227
  const [open, setOpen] = useState(false);
@@ -5419,12 +5483,13 @@ dayjs.extend(utc);
5419
5483
  dayjs.extend(timezone);
5420
5484
  const DateTimePicker = ({ column, schema, prefix, }) => {
5421
5485
  const { watch, formState: { errors }, setValue, } = useFormContext();
5422
- const { translate, timezone } = useSchemaContext();
5423
- const { required, gridColumn = "span 4", gridRow = "span 1", displayDateFormat = "YYYY-MM-DD HH:mm:ss",
5486
+ const { timezone, dateTimePickerLabels } = useSchemaContext();
5487
+ const formI18n = useFormI18n(column, prefix);
5488
+ const { required, gridColumn = "span 12", gridRow = "span 1", displayDateFormat = "YYYY-MM-DD HH:mm:ss",
5424
5489
  // with timezone
5425
5490
  dateFormat = "YYYY-MM-DD[T]HH:mm:ssZ", } = schema;
5426
5491
  const isRequired = required?.some((columnId) => columnId === column);
5427
- const colLabel = `${prefix}${column}`;
5492
+ const colLabel = formI18n.colLabel;
5428
5493
  const [open, setOpen] = useState(false);
5429
5494
  const selectedDate = watch(colLabel);
5430
5495
  const displayDate = dayjs(selectedDate)
@@ -5453,47 +5518,44 @@ const DateTimePicker = ({ column, schema, prefix, }) => {
5453
5518
  console.error(e);
5454
5519
  }
5455
5520
  }, [selectedDate, dateFormat, colLabel, setValue]);
5456
- const customTranslate = (label) => {
5457
- return translateWrapper({ prefix, column, label, translate });
5458
- };
5459
- return (jsxs(Field, { label: `${customTranslate(`field_label`)}`, required: isRequired, alignItems: "stretch", gridColumn,
5521
+ return (jsxs(Field, { label: formI18n.label(), required: isRequired, alignItems: "stretch", gridColumn,
5460
5522
  gridRow, children: [jsxs(PopoverRoot, { open: open, onOpenChange: (e) => setOpen(e.open), closeOnInteractOutside: true, children: [jsx(PopoverTrigger, { asChild: true, children: jsxs(Button, { size: "sm", variant: "outline", onClick: () => {
5461
5523
  setOpen(true);
5462
5524
  }, justifyContent: "start", children: [jsx(MdDateRange, {}), selectedDate !== undefined ? `${displayDate}` : ""] }) }), jsx(PopoverContent, { minW: "450px", children: jsxs(PopoverBody, { children: [jsx(PopoverTitle, {}), jsx(DateTimePicker$1, { value: selectedDate, onChange: (date) => {
5463
5525
  setValue(colLabel, dayjs(date).tz(timezone).format(dateFormat));
5464
5526
  }, timezone: timezone, labels: {
5465
- monthNamesShort: [
5466
- translate.t(`common.month_1`, { defaultValue: "January" }),
5467
- translate.t(`common.month_2`, { defaultValue: "February" }),
5468
- translate.t(`common.month_3`, { defaultValue: "March" }),
5469
- translate.t(`common.month_4`, { defaultValue: "April" }),
5470
- translate.t(`common.month_5`, { defaultValue: "May" }),
5471
- translate.t(`common.month_6`, { defaultValue: "June" }),
5472
- translate.t(`common.month_7`, { defaultValue: "July" }),
5473
- translate.t(`common.month_8`, { defaultValue: "August" }),
5474
- translate.t(`common.month_9`, { defaultValue: "September" }),
5475
- translate.t(`common.month_10`, { defaultValue: "October" }),
5476
- translate.t(`common.month_11`, { defaultValue: "November" }),
5477
- translate.t(`common.month_12`, { defaultValue: "December" }),
5527
+ monthNamesShort: dateTimePickerLabels?.monthNamesShort ?? [
5528
+ formI18n.translate.t(`common.month_1`, { defaultValue: "January" }),
5529
+ formI18n.translate.t(`common.month_2`, { defaultValue: "February" }),
5530
+ formI18n.translate.t(`common.month_3`, { defaultValue: "March" }),
5531
+ formI18n.translate.t(`common.month_4`, { defaultValue: "April" }),
5532
+ formI18n.translate.t(`common.month_5`, { defaultValue: "May" }),
5533
+ formI18n.translate.t(`common.month_6`, { defaultValue: "June" }),
5534
+ formI18n.translate.t(`common.month_7`, { defaultValue: "July" }),
5535
+ formI18n.translate.t(`common.month_8`, { defaultValue: "August" }),
5536
+ formI18n.translate.t(`common.month_9`, { defaultValue: "September" }),
5537
+ formI18n.translate.t(`common.month_10`, { defaultValue: "October" }),
5538
+ formI18n.translate.t(`common.month_11`, { defaultValue: "November" }),
5539
+ formI18n.translate.t(`common.month_12`, { defaultValue: "December" }),
5478
5540
  ],
5479
- weekdayNamesShort: [
5480
- translate.t(`common.weekday_1`, { defaultValue: "Sun" }),
5481
- translate.t(`common.weekday_2`, { defaultValue: "Mon" }),
5482
- translate.t(`common.weekday_3`, { defaultValue: "Tue" }),
5483
- translate.t(`common.weekday_4`, {
5541
+ weekdayNamesShort: dateTimePickerLabels?.weekdayNamesShort ?? [
5542
+ formI18n.translate.t(`common.weekday_1`, { defaultValue: "Sun" }),
5543
+ formI18n.translate.t(`common.weekday_2`, { defaultValue: "Mon" }),
5544
+ formI18n.translate.t(`common.weekday_3`, { defaultValue: "Tue" }),
5545
+ formI18n.translate.t(`common.weekday_4`, {
5484
5546
  defaultValue: "Wed",
5485
5547
  }),
5486
- translate.t(`common.weekday_5`, { defaultValue: "Thu" }),
5487
- translate.t(`common.weekday_6`, { defaultValue: "Fri" }),
5488
- translate.t(`common.weekday_7`, { defaultValue: "Sat" }),
5548
+ formI18n.translate.t(`common.weekday_5`, { defaultValue: "Thu" }),
5549
+ formI18n.translate.t(`common.weekday_6`, { defaultValue: "Fri" }),
5550
+ formI18n.translate.t(`common.weekday_7`, { defaultValue: "Sat" }),
5489
5551
  ],
5490
- backButtonLabel: translate.t(`common.back_button`, {
5552
+ backButtonLabel: dateTimePickerLabels?.backButtonLabel ?? formI18n.translate.t(`common.back_button`, {
5491
5553
  defaultValue: "Back",
5492
5554
  }),
5493
- forwardButtonLabel: translate.t(`common.forward_button`, {
5555
+ forwardButtonLabel: dateTimePickerLabels?.forwardButtonLabel ?? formI18n.translate.t(`common.forward_button`, {
5494
5556
  defaultValue: "Forward",
5495
5557
  }),
5496
- } })] }) })] }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: customTranslate(`field_required`) }))] }));
5558
+ } })] }) })] }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: formI18n.required() }))] }));
5497
5559
  };
5498
5560
 
5499
5561
  const SchemaRenderer = ({ schema, prefix, column, }) => {
@@ -5595,7 +5657,7 @@ const ArrayViewer = ({ schema, column, prefix }) => {
5595
5657
  const BooleanViewer = ({ schema, column, prefix, }) => {
5596
5658
  const { watch, formState: { errors }, } = useFormContext();
5597
5659
  const { translate } = useSchemaContext();
5598
- const { required, gridColumn = "span 4", gridRow = "span 1" } = schema;
5660
+ const { required, gridColumn = "span 12", gridRow = "span 1" } = schema;
5599
5661
  const isRequired = required?.some((columnId) => columnId === column);
5600
5662
  const colLabel = `${prefix}${column}`;
5601
5663
  const value = watch(colLabel);
@@ -5631,17 +5693,14 @@ const DateViewer = ({ column, schema, prefix }) => {
5631
5693
 
5632
5694
  const EnumViewer = ({ column, isMultiple = false, schema, prefix, }) => {
5633
5695
  const { watch, formState: { errors }, } = useFormContext();
5634
- const { translate } = useSchemaContext();
5696
+ const formI18n = useFormI18n(column, prefix);
5635
5697
  const { required } = schema;
5636
5698
  const isRequired = required?.some((columnId) => columnId === column);
5637
- const { gridColumn = "span 4", gridRow = "span 1", renderDisplay } = schema;
5638
- const colLabel = `${prefix}${column}`;
5699
+ const { gridColumn = "span 12", gridRow = "span 1", renderDisplay } = schema;
5700
+ const colLabel = formI18n.colLabel;
5639
5701
  const watchEnum = watch(colLabel);
5640
5702
  const watchEnums = (watch(colLabel) ?? []);
5641
- const customTranslate = (label) => {
5642
- return translateWrapper({ prefix, column, label, translate });
5643
- };
5644
- return (jsxs(Field, { label: `${customTranslate(`field_label`)}`, required: isRequired, alignItems: "stretch", gridColumn,
5703
+ return (jsxs(Field, { label: formI18n.label(), required: isRequired, alignItems: "stretch", gridColumn,
5645
5704
  gridRow, children: [isMultiple && (jsx(Flex, { flexFlow: "wrap", gap: 1, children: watchEnums.map((enumValue) => {
5646
5705
  const item = enumValue;
5647
5706
  if (item === undefined) {
@@ -5649,14 +5708,14 @@ const EnumViewer = ({ column, isMultiple = false, schema, prefix, }) => {
5649
5708
  }
5650
5709
  return (jsx(Tag, { size: "lg", children: !!renderDisplay === true
5651
5710
  ? renderDisplay(item)
5652
- : customTranslate(item) }, item));
5653
- }) })), !isMultiple && jsx(Text, { children: customTranslate(watchEnum) }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: customTranslate(`field_required`) }))] }));
5711
+ : formI18n.t(item) }, item));
5712
+ }) })), !isMultiple && jsx(Text, { children: formI18n.t(watchEnum) }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: formI18n.required() }))] }));
5654
5713
  };
5655
5714
 
5656
5715
  const FileViewer = ({ column, schema, prefix }) => {
5657
5716
  const { watch } = useFormContext();
5658
5717
  const { translate } = useSchemaContext();
5659
- const { required, gridColumn = "span 4", gridRow = "span 1", } = schema;
5718
+ const { required, gridColumn = "span 12", gridRow = "span 1", } = schema;
5660
5719
  const isRequired = required?.some((columnId) => columnId === column);
5661
5720
  const currentFiles = (watch(column) ?? []);
5662
5721
  const colLabel = `${prefix}${column}`;
@@ -5668,7 +5727,7 @@ const FileViewer = ({ column, schema, prefix }) => {
5668
5727
  const IdViewer = ({ column, schema, prefix, isMultiple = false, }) => {
5669
5728
  const { watch, formState: { errors }, } = useFormContext();
5670
5729
  const { idMap, translate } = useSchemaContext();
5671
- const { required, gridColumn = "span 4", gridRow = "span 1", renderDisplay, foreign_key, } = schema;
5730
+ const { required, gridColumn = "span 12", gridRow = "span 1", renderDisplay, foreign_key, } = schema;
5672
5731
  const isRequired = required?.some((columnId) => columnId === column);
5673
5732
  const { display_column } = foreign_key;
5674
5733
  const colLabel = `${prefix}${column}`;
@@ -5699,7 +5758,7 @@ const IdViewer = ({ column, schema, prefix, isMultiple = false, }) => {
5699
5758
  const NumberViewer = ({ schema, column, prefix, }) => {
5700
5759
  const { watch, formState: { errors }, } = useFormContext();
5701
5760
  const { translate } = useSchemaContext();
5702
- const { required, gridColumn = "span 4", gridRow = "span 1" } = schema;
5761
+ const { required, gridColumn = "span 12", gridRow = "span 1" } = schema;
5703
5762
  const isRequired = required?.some((columnId) => columnId === column);
5704
5763
  const colLabel = `${prefix}${column}`;
5705
5764
  const value = watch(colLabel);
@@ -5730,7 +5789,7 @@ const ObjectViewer = ({ schema, column, prefix }) => {
5730
5789
  const RecordInput = ({ column, schema, prefix }) => {
5731
5790
  const { formState: { errors }, setValue, getValues, } = useFormContext();
5732
5791
  const { translate } = useSchemaContext();
5733
- const { required, gridColumn = "span 4", gridRow = "span 1" } = schema;
5792
+ const { required, gridColumn = "span 12", gridRow = "span 1" } = schema;
5734
5793
  const isRequired = required?.some((columnId) => columnId === column);
5735
5794
  const entries = Object.entries(getValues(column) ?? {});
5736
5795
  const [showNewEntries, setShowNewEntries] = useState(false);
@@ -5782,7 +5841,7 @@ const RecordInput = ({ column, schema, prefix }) => {
5782
5841
  const StringViewer = ({ column, schema, prefix, }) => {
5783
5842
  const { watch, formState: { errors }, } = useFormContext();
5784
5843
  const { translate } = useSchemaContext();
5785
- const { required, gridColumn = "span 4", gridRow = "span 1" } = schema;
5844
+ const { required, gridColumn = "span 12", gridRow = "span 1" } = schema;
5786
5845
  const isRequired = required?.some((columnId) => columnId === column);
5787
5846
  const colLabel = `${prefix}${column}`;
5788
5847
  const value = watch(colLabel);
@@ -5877,7 +5936,7 @@ const TagViewer = ({ column, schema, prefix }) => {
5877
5936
  const TextAreaViewer = ({ column, schema, prefix, }) => {
5878
5937
  const { watch, formState: { errors }, } = useFormContext();
5879
5938
  const { translate } = useSchemaContext();
5880
- const { required, gridColumn = "span 4", gridRow = "span 1" } = schema;
5939
+ const { required, gridColumn = "span 12", gridRow = "span 1" } = schema;
5881
5940
  const isRequired = required?.some((columnId) => columnId === column);
5882
5941
  const colLabel = `${prefix}${column}`;
5883
5942
  const value = watch(colLabel);
@@ -5887,7 +5946,7 @@ const TextAreaViewer = ({ column, schema, prefix, }) => {
5887
5946
  const TimeViewer = ({ column, schema, prefix }) => {
5888
5947
  const { watch, formState: { errors }, } = useFormContext();
5889
5948
  const { translate, timezone } = useSchemaContext();
5890
- const { required, gridColumn = "span 4", gridRow = "span 1", displayTimeFormat = "hh:mm A", } = schema;
5949
+ const { required, gridColumn = "span 12", gridRow = "span 1", displayTimeFormat = "hh:mm A", } = schema;
5891
5950
  const isRequired = required?.some((columnId) => columnId === column);
5892
5951
  const colLabel = `${prefix}${column}`;
5893
5952
  const selectedDate = watch(colLabel);
@@ -6019,7 +6078,7 @@ const SubmitButton = () => {
6019
6078
  };
6020
6079
 
6021
6080
  const FormBody = () => {
6022
- 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();
6081
+ 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();
6023
6082
  const { showSubmitButton, showResetButton } = displayConfig;
6024
6083
  const methods = useFormContext();
6025
6084
  const { properties } = schema;
@@ -6116,15 +6175,19 @@ const FormBody = () => {
6116
6175
  include,
6117
6176
  });
6118
6177
  if (isSuccess) {
6119
- return (jsxs(Flex, { flexFlow: "column", gap: "2", children: [jsxs(Alert.Root, { status: "success", children: [jsx(Alert.Indicator, {}), jsx(Alert.Content, { children: jsx(Alert.Title, { children: translate.t("submit_success") }) })] }), jsx(Flex, { justifyContent: "end", children: jsx(Button$1, { onClick: async () => {
6120
- setIsError(false);
6121
- setIsSubmiting(false);
6122
- setIsSuccess(false);
6123
- setIsConfirming(false);
6124
- setValidatedData(undefined);
6125
- const data = await getUpdatedData();
6126
- methods.reset(data);
6127
- }, formNoValidate: true, children: translate.t("submit_again") }) })] }));
6178
+ const resetHandler = async () => {
6179
+ setIsError(false);
6180
+ setIsSubmiting(false);
6181
+ setIsSuccess(false);
6182
+ setIsConfirming(false);
6183
+ setValidatedData(undefined);
6184
+ const data = await getUpdatedData();
6185
+ methods.reset(data);
6186
+ };
6187
+ if (customSuccessRenderer) {
6188
+ return customSuccessRenderer(resetHandler);
6189
+ }
6190
+ return (jsxs(Flex, { flexFlow: "column", gap: "2", children: [jsxs(Alert.Root, { status: "success", children: [jsx(Alert.Indicator, {}), jsx(Alert.Content, { children: jsx(Alert.Title, { children: translate.t("submit_success") }) })] }), jsx(Flex, { justifyContent: "end", children: jsx(Button$1, { onClick: resetHandler, formNoValidate: true, children: translate.t("submit_again") }) })] }));
6128
6191
  }
6129
6192
  if (isConfirming) {
6130
6193
  return (jsxs(Flex, { flexFlow: "column", gap: "2", children: [jsx(Grid, { gap: 4, gridTemplateColumns: "repeat(12, 1fr)", gridTemplateRows: "repeat(12, max-content)", autoFlow: "row", children: ordered.map((column) => {
@@ -6162,12 +6225,12 @@ const DefaultForm = ({ formConfig, }) => {
6162
6225
  return (jsx(FormRoot, { ...formConfig, children: jsxs(Grid, { gap: "2", children: [showTitle && jsx(FormTitle, {}), jsx(FormBody, {})] }) }));
6163
6226
  };
6164
6227
 
6165
- const useForm = ({ preLoadedValues, keyPrefix }) => {
6228
+ const useForm = ({ preLoadedValues, keyPrefix, namespace }) => {
6166
6229
  const form = useForm$1({
6167
6230
  values: preLoadedValues,
6168
6231
  });
6169
6232
  const [idMap, setIdMap] = useState({});
6170
- const translate = useTranslation("", { keyPrefix });
6233
+ const translate = useTranslation(namespace || "", { keyPrefix });
6171
6234
  return {
6172
6235
  form,
6173
6236
  idMap,
@@ -6176,6 +6239,207 @@ const useForm = ({ preLoadedValues, keyPrefix }) => {
6176
6239
  };
6177
6240
  };
6178
6241
 
6242
+ /**
6243
+ * Type definitions for error message configuration
6244
+ */
6245
+ /**
6246
+ * Schema-level error message builder
6247
+ *
6248
+ * Builds a complete errorMessage object compatible with ajv-errors plugin.
6249
+ * Supports both i18n translation keys and plain string messages.
6250
+ *
6251
+ * @param config - Error message configuration
6252
+ * @returns Complete errorMessage object for JSON Schema
6253
+ *
6254
+ * @example
6255
+ * ```typescript
6256
+ * // Simple required field errors
6257
+ * const errorMessage = buildErrorMessages({
6258
+ * required: {
6259
+ * username: "Username is required",
6260
+ * email: "user.email.field_required" // i18n key
6261
+ * }
6262
+ * });
6263
+ *
6264
+ * // With validation rules
6265
+ * const errorMessage = buildErrorMessages({
6266
+ * required: {
6267
+ * password: "Password is required"
6268
+ * },
6269
+ * properties: {
6270
+ * password: {
6271
+ * minLength: "Password must be at least 8 characters",
6272
+ * pattern: "Password must contain letters and numbers"
6273
+ * },
6274
+ * age: {
6275
+ * minimum: "Must be 18 or older",
6276
+ * maximum: "Must be under 120"
6277
+ * }
6278
+ * }
6279
+ * });
6280
+ *
6281
+ * // With global fallbacks
6282
+ * const errorMessage = buildErrorMessages({
6283
+ * required: {
6284
+ * email: "Email is required"
6285
+ * },
6286
+ * minLength: "This field is too short", // applies to all fields
6287
+ * minimum: "Value is too small"
6288
+ * });
6289
+ * ```
6290
+ */
6291
+ const buildErrorMessages = (config) => {
6292
+ const result = {};
6293
+ // Add required field errors
6294
+ if (config.required && Object.keys(config.required).length > 0) {
6295
+ result.required = config.required;
6296
+ }
6297
+ // Add field-specific validation errors
6298
+ if (config.properties && Object.keys(config.properties).length > 0) {
6299
+ result.properties = config.properties;
6300
+ }
6301
+ // Add global fallback error messages
6302
+ const globalKeys = [
6303
+ "minLength",
6304
+ "maxLength",
6305
+ "pattern",
6306
+ "minimum",
6307
+ "maximum",
6308
+ "multipleOf",
6309
+ "format",
6310
+ "type",
6311
+ "enum",
6312
+ ];
6313
+ globalKeys.forEach((key) => {
6314
+ if (config[key]) {
6315
+ result[key] = config[key];
6316
+ }
6317
+ });
6318
+ return result;
6319
+ };
6320
+ /**
6321
+ * Helper function to build required field errors
6322
+ *
6323
+ * Simplifies creating required field error messages, especially useful
6324
+ * for generating i18n translation keys following a pattern.
6325
+ *
6326
+ * @param fields - Array of required field names
6327
+ * @param messageOrGenerator - Either a string template or function to generate messages
6328
+ * @returns Required field error configuration
6329
+ *
6330
+ * @example
6331
+ * ```typescript
6332
+ * // Plain string messages
6333
+ * const required = buildRequiredErrors(
6334
+ * ["username", "email", "password"],
6335
+ * (field) => `${field} is required`
6336
+ * );
6337
+ * // Result: { username: "username is required", email: "email is required", ... }
6338
+ *
6339
+ * // i18n translation keys
6340
+ * const required = buildRequiredErrors(
6341
+ * ["username", "email"],
6342
+ * (field) => `user.${field}.field_required`
6343
+ * );
6344
+ * // Result: { username: "user.username.field_required", email: "user.email.field_required" }
6345
+ *
6346
+ * // Same message for all fields
6347
+ * const required = buildRequiredErrors(
6348
+ * ["username", "email"],
6349
+ * "This field is required"
6350
+ * );
6351
+ * // Result: { username: "This field is required", email: "This field is required" }
6352
+ *
6353
+ * // With keyPrefix for i18n
6354
+ * const required = buildRequiredErrors(
6355
+ * ["username", "email"],
6356
+ * (field) => `${field}.field_required`,
6357
+ * "user"
6358
+ * );
6359
+ * // Result: { username: "user.username.field_required", email: "user.email.field_required" }
6360
+ * ```
6361
+ */
6362
+ const buildRequiredErrors = (fields, messageOrGenerator, keyPrefix = "") => {
6363
+ const result = {};
6364
+ fields.forEach((field) => {
6365
+ if (typeof messageOrGenerator === "function") {
6366
+ const message = messageOrGenerator(field);
6367
+ result[field] = keyPrefix ? `${keyPrefix}.${message}` : message;
6368
+ }
6369
+ else {
6370
+ result[field] = messageOrGenerator;
6371
+ }
6372
+ });
6373
+ return result;
6374
+ };
6375
+ /**
6376
+ * Helper function to build field-specific validation errors
6377
+ *
6378
+ * Creates property-specific error messages for multiple fields at once.
6379
+ *
6380
+ * @param config - Maps field names to their validation error configurations
6381
+ * @returns Properties error configuration
6382
+ *
6383
+ * @example
6384
+ * ```typescript
6385
+ * const properties = buildFieldErrors({
6386
+ * username: {
6387
+ * minLength: "Username must be at least 3 characters",
6388
+ * pattern: "Username can only contain letters and numbers"
6389
+ * },
6390
+ * age: {
6391
+ * minimum: "Must be 18 or older",
6392
+ * maximum: "Must be under 120"
6393
+ * },
6394
+ * email: {
6395
+ * format: "Please enter a valid email address"
6396
+ * }
6397
+ * });
6398
+ * ```
6399
+ */
6400
+ const buildFieldErrors = (config) => {
6401
+ return config;
6402
+ };
6403
+ /**
6404
+ * Helper function to create a complete error message configuration in one call
6405
+ *
6406
+ * Convenient wrapper that combines required and validation errors.
6407
+ *
6408
+ * @param required - Required field error messages
6409
+ * @param properties - Field-specific validation error messages
6410
+ * @param globalFallbacks - Global fallback error messages
6411
+ * @returns Complete error message configuration
6412
+ *
6413
+ * @example
6414
+ * ```typescript
6415
+ * const errorMessage = createErrorMessage(
6416
+ * {
6417
+ * username: "Username is required",
6418
+ * email: "Email is required"
6419
+ * },
6420
+ * {
6421
+ * username: {
6422
+ * minLength: "Username must be at least 3 characters"
6423
+ * },
6424
+ * email: {
6425
+ * format: "Please enter a valid email"
6426
+ * }
6427
+ * },
6428
+ * {
6429
+ * minLength: "This field is too short",
6430
+ * format: "Invalid format"
6431
+ * }
6432
+ * );
6433
+ * ```
6434
+ */
6435
+ const createErrorMessage = (required, properties, globalFallbacks) => {
6436
+ return buildErrorMessages({
6437
+ required,
6438
+ properties,
6439
+ ...globalFallbacks,
6440
+ });
6441
+ };
6442
+
6179
6443
  const getMultiDates = ({ selected, selectedDate, selectedDates, selectable, }) => {
6180
6444
  if (!selectable) {
6181
6445
  return [...selectedDates];
@@ -6192,4 +6456,4 @@ const getMultiDates = ({ selected, selectedDate, selectedDates, selectable, }) =
6192
6456
  }
6193
6457
  };
6194
6458
 
6195
- export { CardHeader, DataDisplay, DataTable, DataTableServer, DefaultCardTitle, DefaultForm, DefaultTable, DensityToggleButton, EditSortingButton, EmptyState$1 as EmptyState, ErrorAlert, FilterDialog, FormBody, FormRoot, FormTitle, GlobalFilter, PageSizeControl, Pagination, RecordDisplay, ReloadButton, ResetFilteringButton, ResetSelectionButton, ResetSortingButton, RowCountText, Table, TableBody, TableCardContainer, TableCards, TableComponent, TableControls, TableDataDisplay, TableFilter, TableFilterTags, TableFooter, TableHeader, TableLoadingComponent, TableSelector, TableSorter, TableViewer, TextCell, ViewDialog, getColumns, getMultiDates, getRangeDates, idPickerSanityCheck, useDataTable, useDataTableContext, useDataTableServer, useForm, widthSanityCheck };
6459
+ export { CardHeader, DataDisplay, DataTable, DataTableServer, DefaultCardTitle, DefaultForm, DefaultTable, DensityToggleButton, EditSortingButton, EmptyState$1 as EmptyState, ErrorAlert, FilterDialog, FormBody, FormRoot, FormTitle, GlobalFilter, PageSizeControl, Pagination, RecordDisplay, ReloadButton, ResetFilteringButton, ResetSelectionButton, ResetSortingButton, RowCountText, Table, TableBody, TableCardContainer, TableCards, TableComponent, TableControls, TableDataDisplay, TableFilter, TableFilterTags, TableFooter, TableHeader, TableLoadingComponent, TableSelector, TableSorter, TableViewer, TextCell, ViewDialog, buildErrorMessages, buildFieldErrors, buildRequiredErrors, createErrorMessage, getColumns, getMultiDates, getRangeDates, idPickerSanityCheck, useDataTable, useDataTableContext, useDataTableServer, useForm, widthSanityCheck };