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

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.d.ts CHANGED
@@ -597,6 +597,11 @@ interface CustomJSONSchema7 extends JSONSchema7 {
597
597
  displayTimeFormat?: string;
598
598
  showLabel?: boolean;
599
599
  }
600
+ interface TagPickerProps {
601
+ column: string;
602
+ schema: CustomJSONSchema7;
603
+ prefix: string;
604
+ }
600
605
 
601
606
  interface FormRootProps<TData extends FieldValues> {
602
607
  schema: CustomJSONSchema7;
@@ -806,4 +811,4 @@ declare module "@tanstack/react-table" {
806
811
  }
807
812
  }
808
813
 
809
- export { type CalendarProps, CardHeader, type CardHeaderProps, type CustomJSONSchema7Definition, DataDisplay, type DataDisplayProps, type DataResponse, DataTable, type DataTableDefaultState, type DataTableProps, DataTableServer, type DataTableServerProps, type DatePickerLabels, type DatePickerProps, DefaultCardTitle, DefaultForm, type DefaultFormProps, DefaultTable, type DefaultTableProps, DensityToggleButton, type DensityToggleButtonProps, type EditFilterButtonProps, EditSortingButton, type EditSortingButtonProps, type EditViewButtonProps, EmptyState, type EmptyStateProps, ErrorAlert, type ErrorAlertProps, FilterDialog, FormBody, FormRoot, type FormRootProps, FormTitle, type GetColumnsConfigs, type GetDateColorProps, type GetMultiDatesProps, type GetRangeDatesProps, type GetStyleProps, type GetVariantProps, GlobalFilter, PageSizeControl, type PageSizeControlProps, Pagination, type QueryParams, type RangeCalendarProps, type RangeDatePickerProps, RecordDisplay, type RecordDisplayProps, ReloadButton, type ReloadButtonProps, ResetFilteringButton, ResetSelectionButton, ResetSortingButton, type Result, RowCountText, Table, TableBody, type TableBodyProps, TableCardContainer, type TableCardContainerProps, TableCards, type TableCardsProps, TableComponent, TableControls, type TableControlsProps, TableDataDisplay, type TableDataDisplayProps, TableFilter, TableFilterTags, TableFooter, type TableFooterProps, TableHeader, type TableHeaderProps, type TableHeaderTexts, TableLoadingComponent, type TableLoadingComponentProps, type TableProps, type TableRendererProps, type TableRowSelectorProps, TableSelector, TableSorter, TableViewer, TextCell, type TextCellProps, type UseDataTableProps, type UseDataTableReturn, type UseDataTableServerProps, type UseDataTableServerReturn, type UseFormProps, ViewDialog, getColumns, getMultiDates, getRangeDates, idPickerSanityCheck, useDataTable, useDataTableContext, useDataTableServer, useForm, widthSanityCheck };
814
+ export { type CalendarProps, CardHeader, type CardHeaderProps, type CustomJSONSchema7, type CustomJSONSchema7Definition, DataDisplay, type DataDisplayProps, type DataResponse, DataTable, type DataTableDefaultState, type DataTableProps, DataTableServer, type DataTableServerProps, type DatePickerLabels, type DatePickerProps, DefaultCardTitle, DefaultForm, type DefaultFormProps, DefaultTable, type DefaultTableProps, DensityToggleButton, type DensityToggleButtonProps, type EditFilterButtonProps, EditSortingButton, type EditSortingButtonProps, type EditViewButtonProps, EmptyState, type EmptyStateProps, ErrorAlert, type ErrorAlertProps, FilterDialog, FormBody, FormRoot, type FormRootProps, FormTitle, type GetColumnsConfigs, type GetDateColorProps, type GetMultiDatesProps, type GetRangeDatesProps, type GetStyleProps, type GetVariantProps, GlobalFilter, PageSizeControl, type PageSizeControlProps, Pagination, type QueryParams, type RangeCalendarProps, type RangeDatePickerProps, RecordDisplay, type RecordDisplayProps, ReloadButton, type ReloadButtonProps, ResetFilteringButton, ResetSelectionButton, ResetSortingButton, type Result, RowCountText, Table, TableBody, type TableBodyProps, TableCardContainer, type TableCardContainerProps, TableCards, type TableCardsProps, TableComponent, TableControls, type TableControlsProps, TableDataDisplay, type TableDataDisplayProps, TableFilter, TableFilterTags, TableFooter, type TableFooterProps, TableHeader, type TableHeaderProps, type TableHeaderTexts, TableLoadingComponent, type TableLoadingComponentProps, type TableProps, type TableRendererProps, type TableRowSelectorProps, TableSelector, TableSorter, TableViewer, type TagPickerProps, TextCell, type TextCellProps, type UseDataTableProps, type UseDataTableReturn, type UseDataTableServerProps, type UseDataTableServerReturn, type UseFormProps, ViewDialog, getColumns, getMultiDates, getRangeDates, idPickerSanityCheck, useDataTable, useDataTableContext, useDataTableServer, useForm, widthSanityCheck };
package/dist/index.js CHANGED
@@ -3824,7 +3824,7 @@ const Field = React__namespace.forwardRef(function Field(props, ref) {
3824
3824
  const BooleanPicker = ({ schema, column, prefix }) => {
3825
3825
  const { watch, formState: { errors }, setValue, } = reactHookForm.useFormContext();
3826
3826
  const { translate } = useSchemaContext();
3827
- const { required, gridColumn = "span 4", gridRow = "span 1" } = schema;
3827
+ const { required, gridColumn = "span 12", gridRow = "span 1" } = schema;
3828
3828
  const isRequired = required?.some((columnId) => columnId === column);
3829
3829
  const colLabel = `${prefix}${column}`;
3830
3830
  const value = watch(colLabel);
@@ -3963,18 +3963,79 @@ const PopoverRoot = react.Popover.Root;
3963
3963
  const PopoverBody = react.Popover.Body;
3964
3964
  const PopoverTrigger = react.Popover.Trigger;
3965
3965
 
3966
- function translateWrapper({ prefix, column, label, translate, }) {
3967
- return translate.t(removeIndex(`${prefix}${column}.${label}`));
3968
- }
3966
+ /**
3967
+ * Custom hook to simplify i18n translation for form fields.
3968
+ * Automatically handles colLabel construction and removeIndex logic.
3969
+ *
3970
+ * @param column - The column name
3971
+ * @param prefix - The prefix for the field (usually empty string or parent path)
3972
+ * @returns Object with translation helper functions
3973
+ *
3974
+ * @example
3975
+ * ```tsx
3976
+ * const formI18n = useFormI18n(column, prefix);
3977
+ *
3978
+ * // Get field label
3979
+ * <Field label={formI18n.label()} />
3980
+ *
3981
+ * // Get error message
3982
+ * <Text>{formI18n.required()}</Text>
3983
+ *
3984
+ * // Get custom translation key
3985
+ * <Text>{formI18n.t('add_more')}</Text>
3986
+ *
3987
+ * // Access the raw colLabel
3988
+ * const colLabel = formI18n.colLabel;
3989
+ * ```
3990
+ */
3991
+ const useFormI18n = (column, prefix = "") => {
3992
+ const { translate } = useSchemaContext();
3993
+ const colLabel = `${prefix}${column}`;
3994
+ return {
3995
+ /**
3996
+ * The constructed column label (prefix + column)
3997
+ */
3998
+ colLabel,
3999
+ /**
4000
+ * Get the field label translation
4001
+ * Equivalent to: translate.t(removeIndex(`${colLabel}.field_label`))
4002
+ */
4003
+ label: (options) => {
4004
+ return translate.t(removeIndex(`${colLabel}.field_label`), options);
4005
+ },
4006
+ /**
4007
+ * Get the required error message translation
4008
+ * Equivalent to: translate.t(removeIndex(`${colLabel}.field_required`))
4009
+ */
4010
+ required: (options) => {
4011
+ return translate.t(removeIndex(`${colLabel}.field_required`), options);
4012
+ },
4013
+ /**
4014
+ * Get a translation for any custom key relative to the field
4015
+ * Equivalent to: translate.t(removeIndex(`${colLabel}.${key}`))
4016
+ *
4017
+ * @param key - The translation key suffix (e.g., 'add_more', 'total', etc.)
4018
+ * @param options - Optional translation options (e.g., defaultValue, interpolation variables)
4019
+ */
4020
+ t: (key, options) => {
4021
+ return translate.t(removeIndex(`${colLabel}.${key}`), options);
4022
+ },
4023
+ /**
4024
+ * Access to the original translate object for edge cases
4025
+ */
4026
+ translate,
4027
+ };
4028
+ };
3969
4029
 
3970
4030
  dayjs.extend(utc);
3971
4031
  dayjs.extend(timezone);
3972
4032
  const DatePicker = ({ column, schema, prefix }) => {
3973
4033
  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;
4034
+ const { timezone } = useSchemaContext();
4035
+ const formI18n = useFormI18n(column, prefix);
4036
+ const { required, gridColumn = "span 12", gridRow = "span 1", displayDateFormat = "YYYY-MM-DD", dateFormat = "YYYY-MM-DD", } = schema;
3976
4037
  const isRequired = required?.some((columnId) => columnId === column);
3977
- const colLabel = `${prefix}${column}`;
4038
+ const colLabel = formI18n.colLabel;
3978
4039
  const [open, setOpen] = React.useState(false);
3979
4040
  const selectedDate = watch(colLabel);
3980
4041
  const displayDate = dayjs(selectedDate).tz(timezone).format(displayDateFormat);
@@ -4001,10 +4062,7 @@ const DatePicker = ({ column, schema, prefix }) => {
4001
4062
  console.error(e);
4002
4063
  }
4003
4064
  }, [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,
4065
+ return (jsxRuntime.jsxs(Field, { label: formI18n.label(), required: isRequired, alignItems: "stretch", gridColumn,
4008
4066
  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
4067
  setOpen(true);
4010
4068
  }, 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 +4070,37 @@ const DatePicker = ({ column, schema, prefix }) => {
4012
4070
  setOpen(false);
4013
4071
  }, labels: {
4014
4072
  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" }),
4073
+ formI18n.translate.t(`common.month_1`, { defaultValue: "January" }),
4074
+ formI18n.translate.t(`common.month_2`, { defaultValue: "February" }),
4075
+ formI18n.translate.t(`common.month_3`, { defaultValue: "March" }),
4076
+ formI18n.translate.t(`common.month_4`, { defaultValue: "April" }),
4077
+ formI18n.translate.t(`common.month_5`, { defaultValue: "May" }),
4078
+ formI18n.translate.t(`common.month_6`, { defaultValue: "June" }),
4079
+ formI18n.translate.t(`common.month_7`, { defaultValue: "July" }),
4080
+ formI18n.translate.t(`common.month_8`, { defaultValue: "August" }),
4081
+ formI18n.translate.t(`common.month_9`, { defaultValue: "September" }),
4082
+ formI18n.translate.t(`common.month_10`, { defaultValue: "October" }),
4083
+ formI18n.translate.t(`common.month_11`, { defaultValue: "November" }),
4084
+ formI18n.translate.t(`common.month_12`, { defaultValue: "December" }),
4027
4085
  ],
4028
4086
  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`, {
4087
+ formI18n.translate.t(`common.weekday_1`, { defaultValue: "Sun" }),
4088
+ formI18n.translate.t(`common.weekday_2`, { defaultValue: "Mon" }),
4089
+ formI18n.translate.t(`common.weekday_3`, { defaultValue: "Tue" }),
4090
+ formI18n.translate.t(`common.weekday_4`, {
4033
4091
  defaultValue: "Wed",
4034
4092
  }),
4035
- translate.t(`common.weekday_5`, { defaultValue: "Thu" }),
4036
- translate.t(`common.weekday_6`, { defaultValue: "Fri" }),
4037
- translate.t(`common.weekday_7`, { defaultValue: "Sat" }),
4093
+ formI18n.translate.t(`common.weekday_5`, { defaultValue: "Thu" }),
4094
+ formI18n.translate.t(`common.weekday_6`, { defaultValue: "Fri" }),
4095
+ formI18n.translate.t(`common.weekday_7`, { defaultValue: "Sat" }),
4038
4096
  ],
4039
- backButtonLabel: translate.t(`common.back_button`, {
4097
+ backButtonLabel: formI18n.translate.t(`common.back_button`, {
4040
4098
  defaultValue: "Back",
4041
4099
  }),
4042
- forwardButtonLabel: translate.t(`common.forward_button`, {
4100
+ forwardButtonLabel: formI18n.translate.t(`common.forward_button`, {
4043
4101
  defaultValue: "Forward",
4044
4102
  }),
4045
- } })] }) })] }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: customTranslate(`field_required`) }))] }));
4103
+ } })] }) })] }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: formI18n.required() }))] }));
4046
4104
  };
4047
4105
 
4048
4106
  function filterArray(array, searchTerm) {
@@ -4060,7 +4118,7 @@ const EnumPicker = ({ column, isMultiple = false, schema, prefix, showTotalAndLi
4060
4118
  const { translate } = useSchemaContext();
4061
4119
  const { required, variant } = schema;
4062
4120
  const isRequired = required?.some((columnId) => columnId === column);
4063
- const { gridColumn = "span 4", gridRow = "span 1", renderDisplay } = schema;
4121
+ const { gridColumn = "span 12", gridRow = "span 1", renderDisplay } = schema;
4064
4122
  const [searchText, setSearchText] = React.useState();
4065
4123
  const [limit, setLimit] = React.useState(10);
4066
4124
  const [openSearchResult, setOpenSearchResult] = React.useState();
@@ -4502,7 +4560,7 @@ const FileDropzone = ({ children = undefined, gridProps = {}, onDrop = () => { }
4502
4560
  const FilePicker = ({ column, schema, prefix }) => {
4503
4561
  const { setValue, formState: { errors }, watch, } = reactHookForm.useFormContext();
4504
4562
  const { translate } = useSchemaContext();
4505
- const { required, gridColumn = "span 4", gridRow = "span 1", } = schema;
4563
+ const { required, gridColumn = "span 12", gridRow = "span 1", } = schema;
4506
4564
  const isRequired = required?.some((columnId) => columnId === column);
4507
4565
  const currentFiles = (watch(column) ?? []);
4508
4566
  const colLabel = `${prefix}${column}`;
@@ -4557,8 +4615,9 @@ const getTableData = async ({ serverUrl, in_table, searching = "", where = [], l
4557
4615
 
4558
4616
  const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
4559
4617
  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;
4618
+ const { serverUrl, idMap, setIdMap, schema: parentSchema, } = useSchemaContext();
4619
+ const formI18n = useFormI18n(column, prefix);
4620
+ const { required, gridColumn = "span 12", gridRow = "span 1", renderDisplay, foreign_key, } = schema;
4562
4621
  const isRequired = required?.some((columnId) => columnId === column);
4563
4622
  const { table, column: column_ref, display_column, customQueryFn, } = foreign_key;
4564
4623
  const [searchText, setSearchText] = React.useState("");
@@ -4566,7 +4625,7 @@ const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
4566
4625
  const [openSearchResult, setOpenSearchResult] = React.useState();
4567
4626
  const [page, setPage] = React.useState(0);
4568
4627
  const ref = React.useRef(null);
4569
- const colLabel = `${prefix}${column}`;
4628
+ const colLabel = formI18n.colLabel;
4570
4629
  const watchId = watch(colLabel);
4571
4630
  const watchIds = isMultiple ? (watch(colLabel) ?? []) : [];
4572
4631
  // Query for search results
@@ -4702,11 +4761,11 @@ const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
4702
4761
  }
4703
4762
  return record[display_column];
4704
4763
  };
4705
- return (jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(removeIndex(`${column}.field_label`)))}`, required: isRequired, alignItems: "stretch", gridColumn,
4764
+ return (jsxRuntime.jsxs(Field, { label: formI18n.label(), required: isRequired, alignItems: "stretch", gridColumn,
4706
4765
  gridRow, children: [isMultiple && (jsxRuntime.jsxs(react.Flex, { flexFlow: "wrap", gap: 1, children: [watchIds.map((id) => {
4707
4766
  const item = idMap[id];
4708
4767
  if (item === undefined) {
4709
- return (jsxRuntime.jsx(react.Text, { children: translate.t(removeIndex(`${colLabel}.undefined`)) }, id));
4768
+ return (jsxRuntime.jsx(react.Text, { children: formI18n.t('undefined') }, id));
4710
4769
  }
4711
4770
  return (jsxRuntime.jsx(Tag, { closable: true, onClick: () => {
4712
4771
  setValue(colLabel, watchIds.filter((itemId) => itemId !== item[column_ref]));
@@ -4715,9 +4774,9 @@ const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
4715
4774
  : item[display_column] }, id));
4716
4775
  }), jsxRuntime.jsx(Tag, { cursor: "pointer", onClick: () => {
4717
4776
  setOpenSearchResult(true);
4718
- }, children: translate.t(removeIndex(`${colLabel}.add_more`)) })] })), !isMultiple && (jsxRuntime.jsx(Button, { variant: "outline", onClick: () => {
4777
+ }, children: formI18n.t('add_more') })] })), !isMultiple && (jsxRuntime.jsx(Button, { variant: "outline", onClick: () => {
4719
4778
  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
4779
+ }, 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: 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: `${formI18n.t('total')} ${count}, ${formI18n.t('showing')} ${limit} ${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
4780
  ? `${page * limit + 1}-${Math.min((page + 1) * limit, count)}`
4722
4781
  : "0"] })] })] }), jsxRuntime.jsx(react.Box, { children: jsxRuntime.jsxs("select", { value: limit, onChange: handleLimitChange, style: {
4723
4782
  padding: "4px 8px",
@@ -4751,8 +4810,8 @@ const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
4751
4810
  ? renderDisplay(item)
4752
4811
  : item[display_column] }, item[column_ref]));
4753
4812
  }) })) : (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`)) }))] }));
4813
+ ? formI18n.t('empty_search_result')
4814
+ : 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
4815
  };
4757
4816
 
4758
4817
  const NumberInputRoot = React__namespace.forwardRef(function NumberInput(props, ref) {
@@ -4766,7 +4825,7 @@ react.NumberInput.Label;
4766
4825
  const NumberInputField = ({ schema, column, prefix, }) => {
4767
4826
  const { setValue, formState: { errors }, watch, } = reactHookForm.useFormContext();
4768
4827
  const { translate } = useSchemaContext();
4769
- const { required, gridColumn = "span 4", gridRow = "span 1" } = schema;
4828
+ const { required, gridColumn = "span 12", gridRow = "span 1" } = schema;
4770
4829
  const isRequired = required?.some((columnId) => columnId === column);
4771
4830
  const colLabel = `${prefix}${column}`;
4772
4831
  const value = watch(`${colLabel}`);
@@ -4851,7 +4910,7 @@ const RecordInput$1 = ({ column, schema, prefix }) => {
4851
4910
  const StringInputField = ({ column, schema, prefix, }) => {
4852
4911
  const { register, formState: { errors }, } = reactHookForm.useFormContext();
4853
4912
  const { translate } = useSchemaContext();
4854
- const { required, gridColumn = "span 4", gridRow = "span 1" } = schema;
4913
+ const { required, gridColumn = "span 12", gridRow = "span 1" } = schema;
4855
4914
  const isRequired = required?.some((columnId) => columnId === column);
4856
4915
  const colLabel = `${prefix}${column}`;
4857
4916
  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 +5099,7 @@ Textarea.displayName = "Textarea";
5040
5099
  const TextAreaInput = ({ column, schema, prefix, }) => {
5041
5100
  const { register, formState: { errors }, } = reactHookForm.useFormContext();
5042
5101
  const { translate } = useSchemaContext();
5043
- const { required, gridColumn = "span 4", gridRow = "span 1" } = schema;
5102
+ const { required, gridColumn = "span 12", gridRow = "span 1" } = schema;
5044
5103
  const isRequired = required?.some((columnId) => columnId === column);
5045
5104
  const colLabel = `${prefix}${column}`;
5046
5105
  const form = reactHookForm.useFormContext();
@@ -5177,7 +5236,7 @@ dayjs.extend(timezone);
5177
5236
  const TimePicker = ({ column, schema, prefix }) => {
5178
5237
  const { watch, formState: { errors }, setValue, } = reactHookForm.useFormContext();
5179
5238
  const { translate, timezone } = useSchemaContext();
5180
- const { required, gridColumn = "span 4", gridRow = "span 1", timeFormat = "HH:mm:ssZ", displayTimeFormat = "hh:mm A", } = schema;
5239
+ const { required, gridColumn = "span 12", gridRow = "span 1", timeFormat = "HH:mm:ssZ", displayTimeFormat = "hh:mm A", } = schema;
5181
5240
  const isRequired = required?.some((columnId) => columnId === column);
5182
5241
  const colLabel = `${prefix}${column}`;
5183
5242
  const [open, setOpen] = React.useState(false);
@@ -5439,12 +5498,13 @@ dayjs.extend(utc);
5439
5498
  dayjs.extend(timezone);
5440
5499
  const DateTimePicker = ({ column, schema, prefix, }) => {
5441
5500
  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",
5501
+ const { timezone } = useSchemaContext();
5502
+ const formI18n = useFormI18n(column, prefix);
5503
+ const { required, gridColumn = "span 12", gridRow = "span 1", displayDateFormat = "YYYY-MM-DD HH:mm:ss",
5444
5504
  // with timezone
5445
5505
  dateFormat = "YYYY-MM-DD[T]HH:mm:ssZ", } = schema;
5446
5506
  const isRequired = required?.some((columnId) => columnId === column);
5447
- const colLabel = `${prefix}${column}`;
5507
+ const colLabel = formI18n.colLabel;
5448
5508
  const [open, setOpen] = React.useState(false);
5449
5509
  const selectedDate = watch(colLabel);
5450
5510
  const displayDate = dayjs(selectedDate)
@@ -5473,47 +5533,44 @@ const DateTimePicker = ({ column, schema, prefix, }) => {
5473
5533
  console.error(e);
5474
5534
  }
5475
5535
  }, [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,
5536
+ return (jsxRuntime.jsxs(Field, { label: formI18n.label(), required: isRequired, alignItems: "stretch", gridColumn,
5480
5537
  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
5538
  setOpen(true);
5482
5539
  }, 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
5540
  setValue(colLabel, dayjs(date).tz(timezone).format(dateFormat));
5484
5541
  }, timezone: timezone, labels: {
5485
5542
  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" }),
5543
+ formI18n.translate.t(`common.month_1`, { defaultValue: "January" }),
5544
+ formI18n.translate.t(`common.month_2`, { defaultValue: "February" }),
5545
+ formI18n.translate.t(`common.month_3`, { defaultValue: "March" }),
5546
+ formI18n.translate.t(`common.month_4`, { defaultValue: "April" }),
5547
+ formI18n.translate.t(`common.month_5`, { defaultValue: "May" }),
5548
+ formI18n.translate.t(`common.month_6`, { defaultValue: "June" }),
5549
+ formI18n.translate.t(`common.month_7`, { defaultValue: "July" }),
5550
+ formI18n.translate.t(`common.month_8`, { defaultValue: "August" }),
5551
+ formI18n.translate.t(`common.month_9`, { defaultValue: "September" }),
5552
+ formI18n.translate.t(`common.month_10`, { defaultValue: "October" }),
5553
+ formI18n.translate.t(`common.month_11`, { defaultValue: "November" }),
5554
+ formI18n.translate.t(`common.month_12`, { defaultValue: "December" }),
5498
5555
  ],
5499
5556
  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`, {
5557
+ formI18n.translate.t(`common.weekday_1`, { defaultValue: "Sun" }),
5558
+ formI18n.translate.t(`common.weekday_2`, { defaultValue: "Mon" }),
5559
+ formI18n.translate.t(`common.weekday_3`, { defaultValue: "Tue" }),
5560
+ formI18n.translate.t(`common.weekday_4`, {
5504
5561
  defaultValue: "Wed",
5505
5562
  }),
5506
- translate.t(`common.weekday_5`, { defaultValue: "Thu" }),
5507
- translate.t(`common.weekday_6`, { defaultValue: "Fri" }),
5508
- translate.t(`common.weekday_7`, { defaultValue: "Sat" }),
5563
+ formI18n.translate.t(`common.weekday_5`, { defaultValue: "Thu" }),
5564
+ formI18n.translate.t(`common.weekday_6`, { defaultValue: "Fri" }),
5565
+ formI18n.translate.t(`common.weekday_7`, { defaultValue: "Sat" }),
5509
5566
  ],
5510
- backButtonLabel: translate.t(`common.back_button`, {
5567
+ backButtonLabel: formI18n.translate.t(`common.back_button`, {
5511
5568
  defaultValue: "Back",
5512
5569
  }),
5513
- forwardButtonLabel: translate.t(`common.forward_button`, {
5570
+ forwardButtonLabel: formI18n.translate.t(`common.forward_button`, {
5514
5571
  defaultValue: "Forward",
5515
5572
  }),
5516
- } })] }) })] }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: customTranslate(`field_required`) }))] }));
5573
+ } })] }) })] }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: formI18n.required() }))] }));
5517
5574
  };
5518
5575
 
5519
5576
  const SchemaRenderer = ({ schema, prefix, column, }) => {
@@ -5615,7 +5672,7 @@ const ArrayViewer = ({ schema, column, prefix }) => {
5615
5672
  const BooleanViewer = ({ schema, column, prefix, }) => {
5616
5673
  const { watch, formState: { errors }, } = reactHookForm.useFormContext();
5617
5674
  const { translate } = useSchemaContext();
5618
- const { required, gridColumn = "span 4", gridRow = "span 1" } = schema;
5675
+ const { required, gridColumn = "span 12", gridRow = "span 1" } = schema;
5619
5676
  const isRequired = required?.some((columnId) => columnId === column);
5620
5677
  const colLabel = `${prefix}${column}`;
5621
5678
  const value = watch(colLabel);
@@ -5651,17 +5708,14 @@ const DateViewer = ({ column, schema, prefix }) => {
5651
5708
 
5652
5709
  const EnumViewer = ({ column, isMultiple = false, schema, prefix, }) => {
5653
5710
  const { watch, formState: { errors }, } = reactHookForm.useFormContext();
5654
- const { translate } = useSchemaContext();
5711
+ const formI18n = useFormI18n(column, prefix);
5655
5712
  const { required } = schema;
5656
5713
  const isRequired = required?.some((columnId) => columnId === column);
5657
- const { gridColumn = "span 4", gridRow = "span 1", renderDisplay } = schema;
5658
- const colLabel = `${prefix}${column}`;
5714
+ const { gridColumn = "span 12", gridRow = "span 1", renderDisplay } = schema;
5715
+ const colLabel = formI18n.colLabel;
5659
5716
  const watchEnum = watch(colLabel);
5660
5717
  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,
5718
+ return (jsxRuntime.jsxs(Field, { label: formI18n.label(), required: isRequired, alignItems: "stretch", gridColumn,
5665
5719
  gridRow, children: [isMultiple && (jsxRuntime.jsx(react.Flex, { flexFlow: "wrap", gap: 1, children: watchEnums.map((enumValue) => {
5666
5720
  const item = enumValue;
5667
5721
  if (item === undefined) {
@@ -5669,14 +5723,14 @@ const EnumViewer = ({ column, isMultiple = false, schema, prefix, }) => {
5669
5723
  }
5670
5724
  return (jsxRuntime.jsx(Tag, { size: "lg", children: !!renderDisplay === true
5671
5725
  ? 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`) }))] }));
5726
+ : formI18n.t(item) }, item));
5727
+ }) })), !isMultiple && jsxRuntime.jsx(react.Text, { children: formI18n.t(watchEnum) }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: formI18n.required() }))] }));
5674
5728
  };
5675
5729
 
5676
5730
  const FileViewer = ({ column, schema, prefix }) => {
5677
5731
  const { watch } = reactHookForm.useFormContext();
5678
5732
  const { translate } = useSchemaContext();
5679
- const { required, gridColumn = "span 4", gridRow = "span 1", } = schema;
5733
+ const { required, gridColumn = "span 12", gridRow = "span 1", } = schema;
5680
5734
  const isRequired = required?.some((columnId) => columnId === column);
5681
5735
  const currentFiles = (watch(column) ?? []);
5682
5736
  const colLabel = `${prefix}${column}`;
@@ -5688,7 +5742,7 @@ const FileViewer = ({ column, schema, prefix }) => {
5688
5742
  const IdViewer = ({ column, schema, prefix, isMultiple = false, }) => {
5689
5743
  const { watch, formState: { errors }, } = reactHookForm.useFormContext();
5690
5744
  const { idMap, translate } = useSchemaContext();
5691
- const { required, gridColumn = "span 4", gridRow = "span 1", renderDisplay, foreign_key, } = schema;
5745
+ const { required, gridColumn = "span 12", gridRow = "span 1", renderDisplay, foreign_key, } = schema;
5692
5746
  const isRequired = required?.some((columnId) => columnId === column);
5693
5747
  const { display_column } = foreign_key;
5694
5748
  const colLabel = `${prefix}${column}`;
@@ -5719,7 +5773,7 @@ const IdViewer = ({ column, schema, prefix, isMultiple = false, }) => {
5719
5773
  const NumberViewer = ({ schema, column, prefix, }) => {
5720
5774
  const { watch, formState: { errors }, } = reactHookForm.useFormContext();
5721
5775
  const { translate } = useSchemaContext();
5722
- const { required, gridColumn = "span 4", gridRow = "span 1" } = schema;
5776
+ const { required, gridColumn = "span 12", gridRow = "span 1" } = schema;
5723
5777
  const isRequired = required?.some((columnId) => columnId === column);
5724
5778
  const colLabel = `${prefix}${column}`;
5725
5779
  const value = watch(colLabel);
@@ -5750,7 +5804,7 @@ const ObjectViewer = ({ schema, column, prefix }) => {
5750
5804
  const RecordInput = ({ column, schema, prefix }) => {
5751
5805
  const { formState: { errors }, setValue, getValues, } = reactHookForm.useFormContext();
5752
5806
  const { translate } = useSchemaContext();
5753
- const { required, gridColumn = "span 4", gridRow = "span 1" } = schema;
5807
+ const { required, gridColumn = "span 12", gridRow = "span 1" } = schema;
5754
5808
  const isRequired = required?.some((columnId) => columnId === column);
5755
5809
  const entries = Object.entries(getValues(column) ?? {});
5756
5810
  const [showNewEntries, setShowNewEntries] = React.useState(false);
@@ -5802,7 +5856,7 @@ const RecordInput = ({ column, schema, prefix }) => {
5802
5856
  const StringViewer = ({ column, schema, prefix, }) => {
5803
5857
  const { watch, formState: { errors }, } = reactHookForm.useFormContext();
5804
5858
  const { translate } = useSchemaContext();
5805
- const { required, gridColumn = "span 4", gridRow = "span 1" } = schema;
5859
+ const { required, gridColumn = "span 12", gridRow = "span 1" } = schema;
5806
5860
  const isRequired = required?.some((columnId) => columnId === column);
5807
5861
  const colLabel = `${prefix}${column}`;
5808
5862
  const value = watch(colLabel);
@@ -5897,7 +5951,7 @@ const TagViewer = ({ column, schema, prefix }) => {
5897
5951
  const TextAreaViewer = ({ column, schema, prefix, }) => {
5898
5952
  const { watch, formState: { errors }, } = reactHookForm.useFormContext();
5899
5953
  const { translate } = useSchemaContext();
5900
- const { required, gridColumn = "span 4", gridRow = "span 1" } = schema;
5954
+ const { required, gridColumn = "span 12", gridRow = "span 1" } = schema;
5901
5955
  const isRequired = required?.some((columnId) => columnId === column);
5902
5956
  const colLabel = `${prefix}${column}`;
5903
5957
  const value = watch(colLabel);
@@ -5907,7 +5961,7 @@ const TextAreaViewer = ({ column, schema, prefix, }) => {
5907
5961
  const TimeViewer = ({ column, schema, prefix }) => {
5908
5962
  const { watch, formState: { errors }, } = reactHookForm.useFormContext();
5909
5963
  const { translate, timezone } = useSchemaContext();
5910
- const { required, gridColumn = "span 4", gridRow = "span 1", displayTimeFormat = "hh:mm A", } = schema;
5964
+ const { required, gridColumn = "span 12", gridRow = "span 1", displayTimeFormat = "hh:mm A", } = schema;
5911
5965
  const isRequired = required?.some((columnId) => columnId === column);
5912
5966
  const colLabel = `${prefix}${column}`;
5913
5967
  const selectedDate = watch(colLabel);
package/dist/index.mjs CHANGED
@@ -3804,7 +3804,7 @@ const Field = React.forwardRef(function Field(props, ref) {
3804
3804
  const BooleanPicker = ({ schema, column, prefix }) => {
3805
3805
  const { watch, formState: { errors }, setValue, } = useFormContext();
3806
3806
  const { translate } = useSchemaContext();
3807
- const { required, gridColumn = "span 4", gridRow = "span 1" } = schema;
3807
+ const { required, gridColumn = "span 12", gridRow = "span 1" } = schema;
3808
3808
  const isRequired = required?.some((columnId) => columnId === column);
3809
3809
  const colLabel = `${prefix}${column}`;
3810
3810
  const value = watch(colLabel);
@@ -3943,18 +3943,79 @@ const PopoverRoot = Popover.Root;
3943
3943
  const PopoverBody = Popover.Body;
3944
3944
  const PopoverTrigger = Popover.Trigger;
3945
3945
 
3946
- function translateWrapper({ prefix, column, label, translate, }) {
3947
- return translate.t(removeIndex(`${prefix}${column}.${label}`));
3948
- }
3946
+ /**
3947
+ * Custom hook to simplify i18n translation for form fields.
3948
+ * Automatically handles colLabel construction and removeIndex logic.
3949
+ *
3950
+ * @param column - The column name
3951
+ * @param prefix - The prefix for the field (usually empty string or parent path)
3952
+ * @returns Object with translation helper functions
3953
+ *
3954
+ * @example
3955
+ * ```tsx
3956
+ * const formI18n = useFormI18n(column, prefix);
3957
+ *
3958
+ * // Get field label
3959
+ * <Field label={formI18n.label()} />
3960
+ *
3961
+ * // Get error message
3962
+ * <Text>{formI18n.required()}</Text>
3963
+ *
3964
+ * // Get custom translation key
3965
+ * <Text>{formI18n.t('add_more')}</Text>
3966
+ *
3967
+ * // Access the raw colLabel
3968
+ * const colLabel = formI18n.colLabel;
3969
+ * ```
3970
+ */
3971
+ const useFormI18n = (column, prefix = "") => {
3972
+ const { translate } = useSchemaContext();
3973
+ const colLabel = `${prefix}${column}`;
3974
+ return {
3975
+ /**
3976
+ * The constructed column label (prefix + column)
3977
+ */
3978
+ colLabel,
3979
+ /**
3980
+ * Get the field label translation
3981
+ * Equivalent to: translate.t(removeIndex(`${colLabel}.field_label`))
3982
+ */
3983
+ label: (options) => {
3984
+ return translate.t(removeIndex(`${colLabel}.field_label`), options);
3985
+ },
3986
+ /**
3987
+ * Get the required error message translation
3988
+ * Equivalent to: translate.t(removeIndex(`${colLabel}.field_required`))
3989
+ */
3990
+ required: (options) => {
3991
+ return translate.t(removeIndex(`${colLabel}.field_required`), options);
3992
+ },
3993
+ /**
3994
+ * Get a translation for any custom key relative to the field
3995
+ * Equivalent to: translate.t(removeIndex(`${colLabel}.${key}`))
3996
+ *
3997
+ * @param key - The translation key suffix (e.g., 'add_more', 'total', etc.)
3998
+ * @param options - Optional translation options (e.g., defaultValue, interpolation variables)
3999
+ */
4000
+ t: (key, options) => {
4001
+ return translate.t(removeIndex(`${colLabel}.${key}`), options);
4002
+ },
4003
+ /**
4004
+ * Access to the original translate object for edge cases
4005
+ */
4006
+ translate,
4007
+ };
4008
+ };
3949
4009
 
3950
4010
  dayjs.extend(utc);
3951
4011
  dayjs.extend(timezone);
3952
4012
  const DatePicker = ({ column, schema, prefix }) => {
3953
4013
  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;
4014
+ const { timezone } = useSchemaContext();
4015
+ const formI18n = useFormI18n(column, prefix);
4016
+ const { required, gridColumn = "span 12", gridRow = "span 1", displayDateFormat = "YYYY-MM-DD", dateFormat = "YYYY-MM-DD", } = schema;
3956
4017
  const isRequired = required?.some((columnId) => columnId === column);
3957
- const colLabel = `${prefix}${column}`;
4018
+ const colLabel = formI18n.colLabel;
3958
4019
  const [open, setOpen] = useState(false);
3959
4020
  const selectedDate = watch(colLabel);
3960
4021
  const displayDate = dayjs(selectedDate).tz(timezone).format(displayDateFormat);
@@ -3981,10 +4042,7 @@ const DatePicker = ({ column, schema, prefix }) => {
3981
4042
  console.error(e);
3982
4043
  }
3983
4044
  }, [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,
4045
+ return (jsxs(Field, { label: formI18n.label(), required: isRequired, alignItems: "stretch", gridColumn,
3988
4046
  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
4047
  setOpen(true);
3990
4048
  }, 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 +4050,37 @@ const DatePicker = ({ column, schema, prefix }) => {
3992
4050
  setOpen(false);
3993
4051
  }, labels: {
3994
4052
  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" }),
4053
+ formI18n.translate.t(`common.month_1`, { defaultValue: "January" }),
4054
+ formI18n.translate.t(`common.month_2`, { defaultValue: "February" }),
4055
+ formI18n.translate.t(`common.month_3`, { defaultValue: "March" }),
4056
+ formI18n.translate.t(`common.month_4`, { defaultValue: "April" }),
4057
+ formI18n.translate.t(`common.month_5`, { defaultValue: "May" }),
4058
+ formI18n.translate.t(`common.month_6`, { defaultValue: "June" }),
4059
+ formI18n.translate.t(`common.month_7`, { defaultValue: "July" }),
4060
+ formI18n.translate.t(`common.month_8`, { defaultValue: "August" }),
4061
+ formI18n.translate.t(`common.month_9`, { defaultValue: "September" }),
4062
+ formI18n.translate.t(`common.month_10`, { defaultValue: "October" }),
4063
+ formI18n.translate.t(`common.month_11`, { defaultValue: "November" }),
4064
+ formI18n.translate.t(`common.month_12`, { defaultValue: "December" }),
4007
4065
  ],
4008
4066
  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`, {
4067
+ formI18n.translate.t(`common.weekday_1`, { defaultValue: "Sun" }),
4068
+ formI18n.translate.t(`common.weekday_2`, { defaultValue: "Mon" }),
4069
+ formI18n.translate.t(`common.weekday_3`, { defaultValue: "Tue" }),
4070
+ formI18n.translate.t(`common.weekday_4`, {
4013
4071
  defaultValue: "Wed",
4014
4072
  }),
4015
- translate.t(`common.weekday_5`, { defaultValue: "Thu" }),
4016
- translate.t(`common.weekday_6`, { defaultValue: "Fri" }),
4017
- translate.t(`common.weekday_7`, { defaultValue: "Sat" }),
4073
+ formI18n.translate.t(`common.weekday_5`, { defaultValue: "Thu" }),
4074
+ formI18n.translate.t(`common.weekday_6`, { defaultValue: "Fri" }),
4075
+ formI18n.translate.t(`common.weekday_7`, { defaultValue: "Sat" }),
4018
4076
  ],
4019
- backButtonLabel: translate.t(`common.back_button`, {
4077
+ backButtonLabel: formI18n.translate.t(`common.back_button`, {
4020
4078
  defaultValue: "Back",
4021
4079
  }),
4022
- forwardButtonLabel: translate.t(`common.forward_button`, {
4080
+ forwardButtonLabel: formI18n.translate.t(`common.forward_button`, {
4023
4081
  defaultValue: "Forward",
4024
4082
  }),
4025
- } })] }) })] }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: customTranslate(`field_required`) }))] }));
4083
+ } })] }) })] }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: formI18n.required() }))] }));
4026
4084
  };
4027
4085
 
4028
4086
  function filterArray(array, searchTerm) {
@@ -4040,7 +4098,7 @@ const EnumPicker = ({ column, isMultiple = false, schema, prefix, showTotalAndLi
4040
4098
  const { translate } = useSchemaContext();
4041
4099
  const { required, variant } = schema;
4042
4100
  const isRequired = required?.some((columnId) => columnId === column);
4043
- const { gridColumn = "span 4", gridRow = "span 1", renderDisplay } = schema;
4101
+ const { gridColumn = "span 12", gridRow = "span 1", renderDisplay } = schema;
4044
4102
  const [searchText, setSearchText] = useState();
4045
4103
  const [limit, setLimit] = useState(10);
4046
4104
  const [openSearchResult, setOpenSearchResult] = useState();
@@ -4482,7 +4540,7 @@ const FileDropzone = ({ children = undefined, gridProps = {}, onDrop = () => { }
4482
4540
  const FilePicker = ({ column, schema, prefix }) => {
4483
4541
  const { setValue, formState: { errors }, watch, } = useFormContext();
4484
4542
  const { translate } = useSchemaContext();
4485
- const { required, gridColumn = "span 4", gridRow = "span 1", } = schema;
4543
+ const { required, gridColumn = "span 12", gridRow = "span 1", } = schema;
4486
4544
  const isRequired = required?.some((columnId) => columnId === column);
4487
4545
  const currentFiles = (watch(column) ?? []);
4488
4546
  const colLabel = `${prefix}${column}`;
@@ -4537,8 +4595,9 @@ const getTableData = async ({ serverUrl, in_table, searching = "", where = [], l
4537
4595
 
4538
4596
  const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
4539
4597
  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;
4598
+ const { serverUrl, idMap, setIdMap, schema: parentSchema, } = useSchemaContext();
4599
+ const formI18n = useFormI18n(column, prefix);
4600
+ const { required, gridColumn = "span 12", gridRow = "span 1", renderDisplay, foreign_key, } = schema;
4542
4601
  const isRequired = required?.some((columnId) => columnId === column);
4543
4602
  const { table, column: column_ref, display_column, customQueryFn, } = foreign_key;
4544
4603
  const [searchText, setSearchText] = useState("");
@@ -4546,7 +4605,7 @@ const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
4546
4605
  const [openSearchResult, setOpenSearchResult] = useState();
4547
4606
  const [page, setPage] = useState(0);
4548
4607
  const ref = useRef(null);
4549
- const colLabel = `${prefix}${column}`;
4608
+ const colLabel = formI18n.colLabel;
4550
4609
  const watchId = watch(colLabel);
4551
4610
  const watchIds = isMultiple ? (watch(colLabel) ?? []) : [];
4552
4611
  // Query for search results
@@ -4682,11 +4741,11 @@ const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
4682
4741
  }
4683
4742
  return record[display_column];
4684
4743
  };
4685
- return (jsxs(Field, { label: `${translate.t(removeIndex(removeIndex(`${column}.field_label`)))}`, required: isRequired, alignItems: "stretch", gridColumn,
4744
+ return (jsxs(Field, { label: formI18n.label(), required: isRequired, alignItems: "stretch", gridColumn,
4686
4745
  gridRow, children: [isMultiple && (jsxs(Flex, { flexFlow: "wrap", gap: 1, children: [watchIds.map((id) => {
4687
4746
  const item = idMap[id];
4688
4747
  if (item === undefined) {
4689
- return (jsx(Text, { children: translate.t(removeIndex(`${colLabel}.undefined`)) }, id));
4748
+ return (jsx(Text, { children: formI18n.t('undefined') }, id));
4690
4749
  }
4691
4750
  return (jsx(Tag, { closable: true, onClick: () => {
4692
4751
  setValue(colLabel, watchIds.filter((itemId) => itemId !== item[column_ref]));
@@ -4695,9 +4754,9 @@ const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
4695
4754
  : item[display_column] }, id));
4696
4755
  }), jsx(Tag, { cursor: "pointer", onClick: () => {
4697
4756
  setOpenSearchResult(true);
4698
- }, children: translate.t(removeIndex(`${colLabel}.add_more`)) })] })), !isMultiple && (jsx(Button, { variant: "outline", onClick: () => {
4757
+ }, children: formI18n.t('add_more') })] })), !isMultiple && (jsx(Button, { variant: "outline", onClick: () => {
4699
4758
  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
4759
+ }, 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: 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: `${formI18n.t('total')} ${count}, ${formI18n.t('showing')} ${limit} ${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
4760
  ? `${page * limit + 1}-${Math.min((page + 1) * limit, count)}`
4702
4761
  : "0"] })] })] }), jsx(Box, { children: jsxs("select", { value: limit, onChange: handleLimitChange, style: {
4703
4762
  padding: "4px 8px",
@@ -4731,8 +4790,8 @@ const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
4731
4790
  ? renderDisplay(item)
4732
4791
  : item[display_column] }, item[column_ref]));
4733
4792
  }) })) : (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`)) }))] }));
4793
+ ? formI18n.t('empty_search_result')
4794
+ : 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
4795
  };
4737
4796
 
4738
4797
  const NumberInputRoot = React.forwardRef(function NumberInput$1(props, ref) {
@@ -4746,7 +4805,7 @@ NumberInput.Label;
4746
4805
  const NumberInputField = ({ schema, column, prefix, }) => {
4747
4806
  const { setValue, formState: { errors }, watch, } = useFormContext();
4748
4807
  const { translate } = useSchemaContext();
4749
- const { required, gridColumn = "span 4", gridRow = "span 1" } = schema;
4808
+ const { required, gridColumn = "span 12", gridRow = "span 1" } = schema;
4750
4809
  const isRequired = required?.some((columnId) => columnId === column);
4751
4810
  const colLabel = `${prefix}${column}`;
4752
4811
  const value = watch(`${colLabel}`);
@@ -4831,7 +4890,7 @@ const RecordInput$1 = ({ column, schema, prefix }) => {
4831
4890
  const StringInputField = ({ column, schema, prefix, }) => {
4832
4891
  const { register, formState: { errors }, } = useFormContext();
4833
4892
  const { translate } = useSchemaContext();
4834
- const { required, gridColumn = "span 4", gridRow = "span 1" } = schema;
4893
+ const { required, gridColumn = "span 12", gridRow = "span 1" } = schema;
4835
4894
  const isRequired = required?.some((columnId) => columnId === column);
4836
4895
  const colLabel = `${prefix}${column}`;
4837
4896
  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 +5079,7 @@ Textarea.displayName = "Textarea";
5020
5079
  const TextAreaInput = ({ column, schema, prefix, }) => {
5021
5080
  const { register, formState: { errors }, } = useFormContext();
5022
5081
  const { translate } = useSchemaContext();
5023
- const { required, gridColumn = "span 4", gridRow = "span 1" } = schema;
5082
+ const { required, gridColumn = "span 12", gridRow = "span 1" } = schema;
5024
5083
  const isRequired = required?.some((columnId) => columnId === column);
5025
5084
  const colLabel = `${prefix}${column}`;
5026
5085
  const form = useFormContext();
@@ -5157,7 +5216,7 @@ dayjs.extend(timezone);
5157
5216
  const TimePicker = ({ column, schema, prefix }) => {
5158
5217
  const { watch, formState: { errors }, setValue, } = useFormContext();
5159
5218
  const { translate, timezone } = useSchemaContext();
5160
- const { required, gridColumn = "span 4", gridRow = "span 1", timeFormat = "HH:mm:ssZ", displayTimeFormat = "hh:mm A", } = schema;
5219
+ const { required, gridColumn = "span 12", gridRow = "span 1", timeFormat = "HH:mm:ssZ", displayTimeFormat = "hh:mm A", } = schema;
5161
5220
  const isRequired = required?.some((columnId) => columnId === column);
5162
5221
  const colLabel = `${prefix}${column}`;
5163
5222
  const [open, setOpen] = useState(false);
@@ -5419,12 +5478,13 @@ dayjs.extend(utc);
5419
5478
  dayjs.extend(timezone);
5420
5479
  const DateTimePicker = ({ column, schema, prefix, }) => {
5421
5480
  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",
5481
+ const { timezone } = useSchemaContext();
5482
+ const formI18n = useFormI18n(column, prefix);
5483
+ const { required, gridColumn = "span 12", gridRow = "span 1", displayDateFormat = "YYYY-MM-DD HH:mm:ss",
5424
5484
  // with timezone
5425
5485
  dateFormat = "YYYY-MM-DD[T]HH:mm:ssZ", } = schema;
5426
5486
  const isRequired = required?.some((columnId) => columnId === column);
5427
- const colLabel = `${prefix}${column}`;
5487
+ const colLabel = formI18n.colLabel;
5428
5488
  const [open, setOpen] = useState(false);
5429
5489
  const selectedDate = watch(colLabel);
5430
5490
  const displayDate = dayjs(selectedDate)
@@ -5453,47 +5513,44 @@ const DateTimePicker = ({ column, schema, prefix, }) => {
5453
5513
  console.error(e);
5454
5514
  }
5455
5515
  }, [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,
5516
+ return (jsxs(Field, { label: formI18n.label(), required: isRequired, alignItems: "stretch", gridColumn,
5460
5517
  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
5518
  setOpen(true);
5462
5519
  }, 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
5520
  setValue(colLabel, dayjs(date).tz(timezone).format(dateFormat));
5464
5521
  }, timezone: timezone, labels: {
5465
5522
  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" }),
5523
+ formI18n.translate.t(`common.month_1`, { defaultValue: "January" }),
5524
+ formI18n.translate.t(`common.month_2`, { defaultValue: "February" }),
5525
+ formI18n.translate.t(`common.month_3`, { defaultValue: "March" }),
5526
+ formI18n.translate.t(`common.month_4`, { defaultValue: "April" }),
5527
+ formI18n.translate.t(`common.month_5`, { defaultValue: "May" }),
5528
+ formI18n.translate.t(`common.month_6`, { defaultValue: "June" }),
5529
+ formI18n.translate.t(`common.month_7`, { defaultValue: "July" }),
5530
+ formI18n.translate.t(`common.month_8`, { defaultValue: "August" }),
5531
+ formI18n.translate.t(`common.month_9`, { defaultValue: "September" }),
5532
+ formI18n.translate.t(`common.month_10`, { defaultValue: "October" }),
5533
+ formI18n.translate.t(`common.month_11`, { defaultValue: "November" }),
5534
+ formI18n.translate.t(`common.month_12`, { defaultValue: "December" }),
5478
5535
  ],
5479
5536
  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`, {
5537
+ formI18n.translate.t(`common.weekday_1`, { defaultValue: "Sun" }),
5538
+ formI18n.translate.t(`common.weekday_2`, { defaultValue: "Mon" }),
5539
+ formI18n.translate.t(`common.weekday_3`, { defaultValue: "Tue" }),
5540
+ formI18n.translate.t(`common.weekday_4`, {
5484
5541
  defaultValue: "Wed",
5485
5542
  }),
5486
- translate.t(`common.weekday_5`, { defaultValue: "Thu" }),
5487
- translate.t(`common.weekday_6`, { defaultValue: "Fri" }),
5488
- translate.t(`common.weekday_7`, { defaultValue: "Sat" }),
5543
+ formI18n.translate.t(`common.weekday_5`, { defaultValue: "Thu" }),
5544
+ formI18n.translate.t(`common.weekday_6`, { defaultValue: "Fri" }),
5545
+ formI18n.translate.t(`common.weekday_7`, { defaultValue: "Sat" }),
5489
5546
  ],
5490
- backButtonLabel: translate.t(`common.back_button`, {
5547
+ backButtonLabel: formI18n.translate.t(`common.back_button`, {
5491
5548
  defaultValue: "Back",
5492
5549
  }),
5493
- forwardButtonLabel: translate.t(`common.forward_button`, {
5550
+ forwardButtonLabel: formI18n.translate.t(`common.forward_button`, {
5494
5551
  defaultValue: "Forward",
5495
5552
  }),
5496
- } })] }) })] }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: customTranslate(`field_required`) }))] }));
5553
+ } })] }) })] }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: formI18n.required() }))] }));
5497
5554
  };
5498
5555
 
5499
5556
  const SchemaRenderer = ({ schema, prefix, column, }) => {
@@ -5595,7 +5652,7 @@ const ArrayViewer = ({ schema, column, prefix }) => {
5595
5652
  const BooleanViewer = ({ schema, column, prefix, }) => {
5596
5653
  const { watch, formState: { errors }, } = useFormContext();
5597
5654
  const { translate } = useSchemaContext();
5598
- const { required, gridColumn = "span 4", gridRow = "span 1" } = schema;
5655
+ const { required, gridColumn = "span 12", gridRow = "span 1" } = schema;
5599
5656
  const isRequired = required?.some((columnId) => columnId === column);
5600
5657
  const colLabel = `${prefix}${column}`;
5601
5658
  const value = watch(colLabel);
@@ -5631,17 +5688,14 @@ const DateViewer = ({ column, schema, prefix }) => {
5631
5688
 
5632
5689
  const EnumViewer = ({ column, isMultiple = false, schema, prefix, }) => {
5633
5690
  const { watch, formState: { errors }, } = useFormContext();
5634
- const { translate } = useSchemaContext();
5691
+ const formI18n = useFormI18n(column, prefix);
5635
5692
  const { required } = schema;
5636
5693
  const isRequired = required?.some((columnId) => columnId === column);
5637
- const { gridColumn = "span 4", gridRow = "span 1", renderDisplay } = schema;
5638
- const colLabel = `${prefix}${column}`;
5694
+ const { gridColumn = "span 12", gridRow = "span 1", renderDisplay } = schema;
5695
+ const colLabel = formI18n.colLabel;
5639
5696
  const watchEnum = watch(colLabel);
5640
5697
  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,
5698
+ return (jsxs(Field, { label: formI18n.label(), required: isRequired, alignItems: "stretch", gridColumn,
5645
5699
  gridRow, children: [isMultiple && (jsx(Flex, { flexFlow: "wrap", gap: 1, children: watchEnums.map((enumValue) => {
5646
5700
  const item = enumValue;
5647
5701
  if (item === undefined) {
@@ -5649,14 +5703,14 @@ const EnumViewer = ({ column, isMultiple = false, schema, prefix, }) => {
5649
5703
  }
5650
5704
  return (jsx(Tag, { size: "lg", children: !!renderDisplay === true
5651
5705
  ? renderDisplay(item)
5652
- : customTranslate(item) }, item));
5653
- }) })), !isMultiple && jsx(Text, { children: customTranslate(watchEnum) }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: customTranslate(`field_required`) }))] }));
5706
+ : formI18n.t(item) }, item));
5707
+ }) })), !isMultiple && jsx(Text, { children: formI18n.t(watchEnum) }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: formI18n.required() }))] }));
5654
5708
  };
5655
5709
 
5656
5710
  const FileViewer = ({ column, schema, prefix }) => {
5657
5711
  const { watch } = useFormContext();
5658
5712
  const { translate } = useSchemaContext();
5659
- const { required, gridColumn = "span 4", gridRow = "span 1", } = schema;
5713
+ const { required, gridColumn = "span 12", gridRow = "span 1", } = schema;
5660
5714
  const isRequired = required?.some((columnId) => columnId === column);
5661
5715
  const currentFiles = (watch(column) ?? []);
5662
5716
  const colLabel = `${prefix}${column}`;
@@ -5668,7 +5722,7 @@ const FileViewer = ({ column, schema, prefix }) => {
5668
5722
  const IdViewer = ({ column, schema, prefix, isMultiple = false, }) => {
5669
5723
  const { watch, formState: { errors }, } = useFormContext();
5670
5724
  const { idMap, translate } = useSchemaContext();
5671
- const { required, gridColumn = "span 4", gridRow = "span 1", renderDisplay, foreign_key, } = schema;
5725
+ const { required, gridColumn = "span 12", gridRow = "span 1", renderDisplay, foreign_key, } = schema;
5672
5726
  const isRequired = required?.some((columnId) => columnId === column);
5673
5727
  const { display_column } = foreign_key;
5674
5728
  const colLabel = `${prefix}${column}`;
@@ -5699,7 +5753,7 @@ const IdViewer = ({ column, schema, prefix, isMultiple = false, }) => {
5699
5753
  const NumberViewer = ({ schema, column, prefix, }) => {
5700
5754
  const { watch, formState: { errors }, } = useFormContext();
5701
5755
  const { translate } = useSchemaContext();
5702
- const { required, gridColumn = "span 4", gridRow = "span 1" } = schema;
5756
+ const { required, gridColumn = "span 12", gridRow = "span 1" } = schema;
5703
5757
  const isRequired = required?.some((columnId) => columnId === column);
5704
5758
  const colLabel = `${prefix}${column}`;
5705
5759
  const value = watch(colLabel);
@@ -5730,7 +5784,7 @@ const ObjectViewer = ({ schema, column, prefix }) => {
5730
5784
  const RecordInput = ({ column, schema, prefix }) => {
5731
5785
  const { formState: { errors }, setValue, getValues, } = useFormContext();
5732
5786
  const { translate } = useSchemaContext();
5733
- const { required, gridColumn = "span 4", gridRow = "span 1" } = schema;
5787
+ const { required, gridColumn = "span 12", gridRow = "span 1" } = schema;
5734
5788
  const isRequired = required?.some((columnId) => columnId === column);
5735
5789
  const entries = Object.entries(getValues(column) ?? {});
5736
5790
  const [showNewEntries, setShowNewEntries] = useState(false);
@@ -5782,7 +5836,7 @@ const RecordInput = ({ column, schema, prefix }) => {
5782
5836
  const StringViewer = ({ column, schema, prefix, }) => {
5783
5837
  const { watch, formState: { errors }, } = useFormContext();
5784
5838
  const { translate } = useSchemaContext();
5785
- const { required, gridColumn = "span 4", gridRow = "span 1" } = schema;
5839
+ const { required, gridColumn = "span 12", gridRow = "span 1" } = schema;
5786
5840
  const isRequired = required?.some((columnId) => columnId === column);
5787
5841
  const colLabel = `${prefix}${column}`;
5788
5842
  const value = watch(colLabel);
@@ -5877,7 +5931,7 @@ const TagViewer = ({ column, schema, prefix }) => {
5877
5931
  const TextAreaViewer = ({ column, schema, prefix, }) => {
5878
5932
  const { watch, formState: { errors }, } = useFormContext();
5879
5933
  const { translate } = useSchemaContext();
5880
- const { required, gridColumn = "span 4", gridRow = "span 1" } = schema;
5934
+ const { required, gridColumn = "span 12", gridRow = "span 1" } = schema;
5881
5935
  const isRequired = required?.some((columnId) => columnId === column);
5882
5936
  const colLabel = `${prefix}${column}`;
5883
5937
  const value = watch(colLabel);
@@ -5887,7 +5941,7 @@ const TextAreaViewer = ({ column, schema, prefix, }) => {
5887
5941
  const TimeViewer = ({ column, schema, prefix }) => {
5888
5942
  const { watch, formState: { errors }, } = useFormContext();
5889
5943
  const { translate, timezone } = useSchemaContext();
5890
- const { required, gridColumn = "span 4", gridRow = "span 1", displayTimeFormat = "hh:mm A", } = schema;
5944
+ const { required, gridColumn = "span 12", gridRow = "span 1", displayTimeFormat = "hh:mm A", } = schema;
5891
5945
  const isRequired = required?.some((columnId) => columnId === column);
5892
5946
  const colLabel = `${prefix}${column}`;
5893
5947
  const selectedDate = watch(colLabel);
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Custom hook to simplify i18n translation for form fields.
3
+ * Automatically handles colLabel construction and removeIndex logic.
4
+ *
5
+ * @param column - The column name
6
+ * @param prefix - The prefix for the field (usually empty string or parent path)
7
+ * @returns Object with translation helper functions
8
+ *
9
+ * @example
10
+ * ```tsx
11
+ * const formI18n = useFormI18n(column, prefix);
12
+ *
13
+ * // Get field label
14
+ * <Field label={formI18n.label()} />
15
+ *
16
+ * // Get error message
17
+ * <Text>{formI18n.required()}</Text>
18
+ *
19
+ * // Get custom translation key
20
+ * <Text>{formI18n.t('add_more')}</Text>
21
+ *
22
+ * // Access the raw colLabel
23
+ * const colLabel = formI18n.colLabel;
24
+ * ```
25
+ */
26
+ export declare const useFormI18n: (column: string, prefix?: string) => {
27
+ /**
28
+ * The constructed column label (prefix + column)
29
+ */
30
+ colLabel: string;
31
+ /**
32
+ * Get the field label translation
33
+ * Equivalent to: translate.t(removeIndex(`${colLabel}.field_label`))
34
+ */
35
+ label: (options?: any) => string;
36
+ /**
37
+ * Get the required error message translation
38
+ * Equivalent to: translate.t(removeIndex(`${colLabel}.field_required`))
39
+ */
40
+ required: (options?: any) => string;
41
+ /**
42
+ * Get a translation for any custom key relative to the field
43
+ * Equivalent to: translate.t(removeIndex(`${colLabel}.${key}`))
44
+ *
45
+ * @param key - The translation key suffix (e.g., 'add_more', 'total', etc.)
46
+ * @param options - Optional translation options (e.g., defaultValue, interpolation variables)
47
+ */
48
+ t: (key: string, options?: any) => string;
49
+ /**
50
+ * Access to the original translate object for edge cases
51
+ */
52
+ translate: import("react-i18next").UseTranslationResponse<any, any>;
53
+ };
@@ -115,6 +115,7 @@ export * from "./components/Form/components/core/DefaultForm";
115
115
  export * from "./components/Form/components/core/FormRoot";
116
116
  export * from "./components/Form/components/core/FormTitle";
117
117
  export * from "./components/Form/components/core/FormBody";
118
+ export * from "./components/Form/components/types/CustomJSONSchema7";
118
119
  export * from "./components/Form/useForm";
119
120
  export * from "./components/DatePicker/DatePicker";
120
121
  export * from "./components/DatePicker/getMultiDates";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bsol-oss/react-datatable5",
3
- "version": "12.0.0-beta.70",
3
+ "version": "12.0.0-beta.71",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",