@bsol-oss/react-datatable5 12.0.0-beta.91 → 12.0.0-beta.92

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (23) hide show
  1. package/dist/index.d.ts +11 -5
  2. package/dist/index.js +345 -273
  3. package/dist/index.mjs +345 -274
  4. package/dist/types/components/DataTable/display/RecordDisplay.d.ts +2 -2
  5. package/dist/types/components/Form/SchemaFormContext.d.ts +2 -1
  6. package/dist/types/components/Form/components/core/FormRoot.d.ts +3 -4
  7. package/dist/types/components/Form/components/fields/ArrayRenderer.d.ts +1 -1
  8. package/dist/types/components/Form/components/fields/StringInputField.d.ts +0 -1
  9. package/dist/types/components/Form/components/fields/TextAreaInput.d.ts +0 -5
  10. package/dist/types/components/Form/components/types/CustomJSONSchema7.d.ts +8 -0
  11. package/dist/types/components/Form/components/viewers/ArrayViewer.d.ts +1 -1
  12. package/dist/types/components/Form/components/viewers/BooleanViewer.d.ts +1 -1
  13. package/dist/types/components/Form/components/viewers/DateTimeViewer.d.ts +1 -1
  14. package/dist/types/components/Form/components/viewers/DateViewer.d.ts +1 -1
  15. package/dist/types/components/Form/components/viewers/IdViewer.d.ts +1 -1
  16. package/dist/types/components/Form/components/viewers/ObjectViewer.d.ts +1 -1
  17. package/dist/types/components/Form/components/viewers/RecordViewer.d.ts +2 -2
  18. package/dist/types/components/Form/components/viewers/StringViewer.d.ts +1 -6
  19. package/dist/types/components/Form/components/viewers/TextAreaViewer.d.ts +1 -6
  20. package/dist/types/components/Form/components/viewers/TimeViewer.d.ts +1 -1
  21. package/dist/types/components/Form/utils/useFormI18n.d.ts +5 -3
  22. package/dist/types/components/ui/pagination.d.ts +10 -7
  23. package/package.json +4 -4
package/dist/index.mjs CHANGED
@@ -542,16 +542,111 @@ const { withContext } = createRecipeContext({ key: "button" });
542
542
  const LinkButton = withContext("a");
543
543
 
544
544
  const [RootPropsProvider, useRootProps] = createContext$1({
545
- name: "RootPropsProvider",
545
+ name: 'RootPropsProvider',
546
546
  });
547
547
  const variantMap = {
548
- outline: { default: "ghost", ellipsis: "plain", current: "outline" },
549
- solid: { default: "outline", ellipsis: "outline", current: "solid" },
550
- subtle: { default: "ghost", ellipsis: "plain", current: "subtle" },
548
+ outline: { default: 'ghost', ellipsis: 'plain', current: 'outline' },
549
+ solid: { default: 'outline', ellipsis: 'outline', current: 'solid' },
550
+ subtle: { default: 'ghost', ellipsis: 'plain', current: 'subtle' },
551
551
  };
552
552
  const PaginationRoot = React.forwardRef(function PaginationRoot(props, ref) {
553
- const { size = "sm", variant = "outline", getHref, ...rest } = props;
554
- return (jsx(RootPropsProvider, { value: { size, variantMap: variantMap[variant], getHref }, children: jsx(Pagination$1.Root, { ref: ref, type: getHref ? "link" : "button", ...rest }) }));
553
+ const { size = 'sm', variant = 'outline', getHref, siblingCount, minSiblingCount = 1, maxSiblingCount, ...rest } = props;
554
+ const containerRef = React.useRef(null);
555
+ const [calculatedSiblingCount, setCalculatedSiblingCount] = React.useState(siblingCount);
556
+ React.useEffect(() => {
557
+ if (siblingCount !== undefined || !containerRef.current) {
558
+ setCalculatedSiblingCount(siblingCount);
559
+ return;
560
+ }
561
+ const container = containerRef.current;
562
+ let rafId = null;
563
+ const calculateSiblingCount = () => {
564
+ if (!container)
565
+ return;
566
+ const width = container.offsetWidth;
567
+ if (width === 0)
568
+ return;
569
+ // Estimate button width based on size
570
+ // These are approximate widths including padding for different button sizes
571
+ const buttonWidthMap = {
572
+ xs: 28,
573
+ sm: 36,
574
+ md: 40,
575
+ lg: 44,
576
+ };
577
+ let buttonWidth = buttonWidthMap[size] || 36;
578
+ // Try to measure actual button if available (for more accuracy)
579
+ const buttons = container.querySelectorAll('button');
580
+ if (buttons.length > 0) {
581
+ const firstButton = buttons[0];
582
+ if (firstButton.offsetWidth > 0) {
583
+ // Use measured width, but account for text content variation
584
+ const measuredWidth = firstButton.offsetWidth;
585
+ // Page number buttons might be slightly wider due to text, use measured width
586
+ buttonWidth = Math.max(buttonWidth, measuredWidth);
587
+ }
588
+ }
589
+ // Account for prev/next buttons and gaps
590
+ // HStack gap is typically 8px in Chakra UI
591
+ const gap = 8;
592
+ const prevNextWidth = buttonWidth * 2 + gap;
593
+ const availableWidth = Math.max(0, width - prevNextWidth);
594
+ // Each page button takes buttonWidth + gap
595
+ const buttonWithGap = buttonWidth + gap;
596
+ const maxButtons = Math.floor(availableWidth / buttonWithGap);
597
+ // Calculate sibling count
598
+ // Minimum structure: [prev] [1] [current] [last] [next] = 5 buttons
599
+ // With siblings: [prev] [1] [...] [current-N] ... [current] ... [current+N] [...] [last] [next]
600
+ // We need: prev(1) + first(1) + ellipsis(1) + siblings*2 + current(1) + ellipsis(1) + last(1) + next(1)
601
+ // Minimum: 5 buttons (prev, first, current, last, next)
602
+ // With siblings: 5 + siblings*2 + ellipsis*2 (if needed)
603
+ const minRequired = 5;
604
+ const extraButtons = Math.max(0, maxButtons - minRequired);
605
+ // Calculate sibling count
606
+ // If we have enough space for ellipsis (2 buttons), account for that
607
+ let calculated = minSiblingCount;
608
+ if (extraButtons >= 4) {
609
+ // Space for ellipsis (2) + siblings
610
+ calculated = Math.floor((extraButtons - 2) / 2);
611
+ }
612
+ else if (extraButtons >= 2) {
613
+ // Space for some siblings but not ellipsis
614
+ calculated = Math.floor(extraButtons / 2);
615
+ }
616
+ // Apply max limit if provided
617
+ if (maxSiblingCount !== undefined) {
618
+ calculated = Math.min(calculated, maxSiblingCount);
619
+ }
620
+ setCalculatedSiblingCount(Math.max(minSiblingCount, calculated));
621
+ };
622
+ const resizeObserver = new ResizeObserver(() => {
623
+ // Use requestAnimationFrame to debounce and ensure DOM is updated
624
+ if (rafId !== null) {
625
+ cancelAnimationFrame(rafId);
626
+ }
627
+ rafId = requestAnimationFrame(calculateSiblingCount);
628
+ });
629
+ resizeObserver.observe(container);
630
+ // Initial calculation after a short delay to ensure buttons are rendered
631
+ const timeoutId = setTimeout(calculateSiblingCount, 100);
632
+ return () => {
633
+ resizeObserver.disconnect();
634
+ if (rafId !== null) {
635
+ cancelAnimationFrame(rafId);
636
+ }
637
+ clearTimeout(timeoutId);
638
+ };
639
+ }, [size, siblingCount, minSiblingCount, maxSiblingCount]);
640
+ const mergedRef = React.useCallback((node) => {
641
+ if (typeof ref === 'function') {
642
+ ref(node);
643
+ }
644
+ else if (ref) {
645
+ ref.current = node;
646
+ }
647
+ containerRef.current = node;
648
+ }, [ref]);
649
+ return (jsx(RootPropsProvider, { value: { size, variantMap: variantMap[variant], getHref }, children: jsx(Pagination$1.Root, { ref: mergedRef, type: getHref ? 'link' : 'button', siblingCount: calculatedSiblingCount, ...rest }) }));
555
650
  });
556
651
  const PaginationEllipsis = React.forwardRef(function PaginationEllipsis(props, ref) {
557
652
  const { size, variantMap } = useRootProps();
@@ -585,16 +680,16 @@ const PaginationNextTrigger = React.forwardRef(function PaginationNextTrigger(pr
585
680
  });
586
681
  const PaginationItems = (props) => {
587
682
  return (jsx(Pagination$1.Context, { children: ({ pages }) => pages.map((page, index) => {
588
- return page.type === "ellipsis" ? (jsx(PaginationEllipsis, { index: index, ...props }, index)) : (jsx(PaginationItem, { type: "page", value: page.value, ...props }, index));
683
+ return page.type === 'ellipsis' ? (jsx(PaginationEllipsis, { index: index, ...props }, index)) : (jsx(PaginationItem, { type: "page", value: page.value, ...props }, index));
589
684
  }) }));
590
685
  };
591
686
  React.forwardRef(function PaginationPageText(props, ref) {
592
- const { format = "compact", ...rest } = props;
687
+ const { format = 'compact', ...rest } = props;
593
688
  const { page, totalPages, pageRange, count } = usePaginationContext();
594
689
  const content = React.useMemo(() => {
595
- if (format === "short")
690
+ if (format === 'short')
596
691
  return `${page} / ${totalPages}`;
597
- if (format === "compact")
692
+ if (format === 'compact')
598
693
  return `${page} / ${totalPages}`;
599
694
  return `${pageRange.start + 1} - ${Math.min(pageRange.end, count)} / ${count}`;
600
695
  }, [format, page, totalPages, pageRange, count]);
@@ -3082,14 +3177,14 @@ const DefaultCardTitle = () => {
3082
3177
  const TableCards = ({ isSelectable = false, showDisplayNameOnly = false, renderTitle = DefaultCardTitle, cardBodyProps = {}, }) => {
3083
3178
  const { table, rowSelection, setRowSelection } = useDataTableContext();
3084
3179
  return (jsx(Fragment, { children: table.getRowModel().rows.map((row) => {
3085
- return (jsx(Card.Root, { flex: '1 0 20rem', children: jsxs(Card.Body, { display: 'flex', flexFlow: 'column', gap: '0.5rem', ...cardBodyProps, children: [isSelectable && (jsx(Checkbox, { isChecked: isRowSelected(row.id, rowSelection),
3180
+ return (jsx(Card.Root, { flex: '1 0 20rem', children: jsxs(Card.Body, { display: 'flex', flexFlow: 'column', gap: '0.5rem', ...cardBodyProps, children: [isSelectable && (jsx(Checkbox, { checked: isRowSelected(row.id, rowSelection),
3086
3181
  disabled: !canRowSelect(row),
3087
3182
  // indeterminate: row.getIsSomeSelected(),
3088
3183
  onChange: createRowToggleHandler(row, rowSelection, setRowSelection) })), renderTitle(row), jsx(Grid, { templateColumns: 'auto 1fr', gap: '1rem', children: row.getVisibleCells().map((cell) => {
3089
- return (jsxs(Fragment, { children: [jsxs(Box, { children: [showDisplayNameOnly && (jsx(Text, { fontWeight: 'bold', children: cell.column.columnDef.meta?.displayName ??
3184
+ return (jsxs(Box, { display: "contents", children: [jsxs(Box, { children: [showDisplayNameOnly && (jsx(Text, { fontWeight: 'bold', children: cell.column.columnDef.meta?.displayName ??
3090
3185
  cell.column.id })), !showDisplayNameOnly && (jsx(Fragment, { children: flexRender(cell.column.columnDef.header,
3091
3186
  // @ts-expect-error Assuming the CellContext interface is the same as HeaderContext
3092
- cell.getContext()) }))] }, `chakra-table-cardcolumnid-${row.id}`), jsx(Box, { justifySelf: 'end', children: flexRender(cell.column.columnDef.cell, cell.getContext()) }, `chakra-table-cardcolumn-${row.id}`)] }));
3187
+ cell.getContext()) }))] }), jsx(Box, { justifySelf: 'end', children: flexRender(cell.column.columnDef.cell, cell.getContext()) })] }, `chakra-table-cardcell-${cell.id}`));
3093
3188
  }) })] }) }, `chakra-table-card-${row.id}`));
3094
3189
  }) }));
3095
3190
  };
@@ -3120,9 +3215,13 @@ const TableFooter = ({ showSelector = false, alwaysShowSelector = true, }) => {
3120
3215
  }
3121
3216
  return false;
3122
3217
  };
3123
- return (jsx(Table$1.Footer, { children: table.getFooterGroups().map((footerGroup) => (jsxs(Table$1.Row, { display: 'flex', children: [showSelector && (jsxs(Table$1.Header, { padding: `${table.getDensityValue()}px`, onMouseEnter: () => handleRowHover(true), onMouseLeave: () => handleRowHover(false), display: 'grid', children: [isCheckBoxVisible() && (jsx(Box, { margin: '0rem', display: 'grid', justifyItems: 'center', alignItems: 'center', children: jsx(Checkbox, { width: `${SELECTION_BOX_WIDTH}px`, height: `${SELECTION_BOX_WIDTH}px`, isChecked: areAllRowsSelected(table, rowSelection),
3124
- // indeterminate: areSomeRowsSelected(table, rowSelection),
3125
- onChange: createToggleAllRowsHandler(table, rowSelection, setRowSelection) }) })), !isCheckBoxVisible() && (jsx(Box, { as: "span", margin: '0rem', display: 'grid', justifyItems: 'center', alignItems: 'center', width: `${SELECTION_BOX_WIDTH}px`, height: `${SELECTION_BOX_WIDTH}px` }))] })), footerGroup.headers.map((header) => (jsx(Table$1.Cell, { padding: '0', columnSpan: `${header.colSpan}`,
3218
+ return (jsx(Table$1.Footer, { children: table.getFooterGroups().map((footerGroup) => (jsxs(Table$1.Row, { display: 'flex', children: [showSelector && (jsx(Table$1.Cell, { padding: `${table.getDensityValue()}px`, onMouseEnter: () => handleRowHover(true), onMouseLeave: () => handleRowHover(false), display: 'grid', justifyItems: 'center', alignItems: 'center', color: {
3219
+ base: 'colorPalette.900',
3220
+ _dark: 'colorPalette.100',
3221
+ },
3222
+ bg: { base: 'colorPalette.50', _dark: 'colorPalette.950' }, children: isCheckBoxVisible() ? (jsx(Checkbox, { width: `${SELECTION_BOX_WIDTH}px`, height: `${SELECTION_BOX_WIDTH}px`, checked: areAllRowsSelected(table, rowSelection),
3223
+ // indeterminate: areSomeRowsSelected(table, rowSelection),
3224
+ onChange: createToggleAllRowsHandler(table, rowSelection, setRowSelection) })) : (jsx(Box, { as: "span", width: `${SELECTION_BOX_WIDTH}px`, height: `${SELECTION_BOX_WIDTH}px` })) })), footerGroup.headers.map((header) => (jsx(Table$1.Cell, { padding: '0', columnSpan: `${header.colSpan}`,
3126
3225
  // styling resize and pinning start
3127
3226
  maxWidth: `${header.getSize()}px`, width: `${header.getSize()}px`, display: 'grid', children: jsx(MenuRoot$1, { children: jsx(MenuTrigger$1, { asChild: true, children: jsx(Box, { padding: `${table.getDensityValue()}px`, display: 'flex', alignItems: 'center', justifyContent: 'start', borderRadius: '0rem', children: jsxs(Flex, { gap: "0.5rem", alignItems: 'center', children: [header.isPlaceholder
3128
3227
  ? null
@@ -3354,7 +3453,7 @@ const TextWithCopy = ({ text, globalFilter, highlightedText, }) => {
3354
3453
  const displayText = highlightedText !== undefined
3355
3454
  ? highlightedText
3356
3455
  : highlightText$1(textValue, globalFilter);
3357
- return (jsxs(HStack, { gap: 2, alignItems: "center", children: [jsx(Text, { as: "span", children: displayText }), jsx(Clipboard.Root, { value: textValue, children: jsx(Clipboard.Trigger, { asChild: true, children: jsx(IconButton, { size: "xs", variant: "ghost", "aria-label": "Copy", children: jsx(Clipboard.Indicator, { copied: jsx(LuCheck, {}), children: jsx(LuCopy, {}) }) }) }) })] }));
3456
+ return (jsxs(HStack, { gap: 2, alignItems: "center", children: [jsx(Text, { as: "span", children: displayText }), jsx(Clipboard.Root, { value: textValue, children: jsx(Clipboard.Trigger, { asChild: true, children: jsx(IconButton, { size: "xs", variant: "ghost", "aria-label": "Copy", fontSize: "1em", children: jsx(Clipboard.Indicator, { copied: jsx(LuCheck, {}), children: jsx(LuCopy, {}) }) }) }) })] }));
3358
3457
  };
3359
3458
 
3360
3459
  // Helper function to highlight matching text
@@ -3608,7 +3707,7 @@ const snakeToLabel = (str) => {
3608
3707
  .join(" "); // Join with space
3609
3708
  };
3610
3709
 
3611
- const RecordDisplay = ({ object, boxProps, translate, prefix = "", }) => {
3710
+ const RecordDisplay = ({ object, boxProps, translate, prefix = '', }) => {
3612
3711
  const getColumn = ({ field }) => {
3613
3712
  if (translate !== undefined) {
3614
3713
  return translate.t(`${prefix}${field}`);
@@ -3618,8 +3717,9 @@ const RecordDisplay = ({ object, boxProps, translate, prefix = "", }) => {
3618
3717
  if (object === null) {
3619
3718
  return jsx(Fragment, { children: "null" });
3620
3719
  }
3621
- return (jsx(Grid, { rowGap: 1, padding: 1, overflow: "auto", ...boxProps, children: Object.entries(object).map(([field, value]) => {
3622
- return (jsxs(Grid, { columnGap: 2, gridTemplateColumns: "auto 1fr", children: [jsx(Text, { color: "colorPalette.400", children: getColumn({ field }) }), typeof value === "object" ? (jsx(RecordDisplay, { object: value, prefix: `${prefix}${field}.`, translate: translate })) : (jsx(Text, { children: JSON.stringify(value) }))] }, field));
3720
+ return (jsx(Grid, { rowGap: 1, padding: 1, overflow: 'auto', ...boxProps, children: Object.entries(object).map(([field, value], index) => {
3721
+ const uniqueKey = `${prefix}${field}-${index}`;
3722
+ return (jsxs(Grid, { columnGap: 2, gridTemplateColumns: 'auto 1fr', children: [jsx(Text, { color: 'colorPalette.400', children: getColumn({ field }) }), typeof value === 'object' && value !== null ? (jsx(RecordDisplay, { object: value, prefix: `${prefix}${field}.`, translate: translate })) : (jsx(Text, { children: JSON.stringify(value) }))] }, uniqueKey));
3623
3723
  }) }));
3624
3724
  };
3625
3725
 
@@ -3910,13 +4010,10 @@ const idPickerSanityCheck = (column, foreign_key) => {
3910
4010
  if (!!foreign_key == false) {
3911
4011
  throw new Error(`The key foreign_key does not exist in properties of column ${column} when using id-picker.`);
3912
4012
  }
3913
- const { table, column: foreignKeyColumn, display_column } = foreign_key;
4013
+ const { table, column: foreignKeyColumn } = foreign_key;
3914
4014
  if (!!table == false) {
3915
4015
  throw new Error(`The key table does not exist in properties of column ${table} when using id-picker.`);
3916
4016
  }
3917
- if (!!display_column == false) {
3918
- throw new Error(`The key display_column does not exist in properties of column ${column} when using id-picker.`);
3919
- }
3920
4017
  if (!!foreignKeyColumn == false) {
3921
4018
  throw new Error(`The key column does not exist in properties of column ${column} when using id-picker.`);
3922
4019
  }
@@ -3925,7 +4022,7 @@ const FormRoot = ({ schema, idMap, setIdMap, form, serverUrl, translate, childre
3925
4022
  showSubmitButton: true,
3926
4023
  showResetButton: true,
3927
4024
  showTitle: true,
3928
- }, requireConfirmation = false, dateTimePickerLabels, idPickerLabels, enumPickerLabels, filePickerLabels, insideDialog = false, }) => {
4025
+ }, requireConfirmation = false, dateTimePickerLabels, idPickerLabels, enumPickerLabels, filePickerLabels, formButtonLabels, insideDialog = false, }) => {
3929
4026
  const [isSuccess, setIsSuccess] = useState(false);
3930
4027
  const [isError, setIsError] = useState(false);
3931
4028
  const [isSubmiting, setIsSubmiting] = useState(false);
@@ -4015,6 +4112,7 @@ const FormRoot = ({ schema, idMap, setIdMap, form, serverUrl, translate, childre
4015
4112
  idPickerLabels,
4016
4113
  enumPickerLabels,
4017
4114
  filePickerLabels,
4115
+ formButtonLabels,
4018
4116
  ajvResolver: ajvResolver(schema),
4019
4117
  insideDialog,
4020
4118
  }, children: jsx(FormProvider, { ...form, children: children }) }));
@@ -4024,40 +4122,107 @@ function removeIndex(str) {
4024
4122
  return str.replace(/\.\d+\./g, ".");
4025
4123
  }
4026
4124
 
4125
+ /**
4126
+ * Custom hook to simplify i18n translation for form fields.
4127
+ * Automatically handles colLabel construction and removeIndex logic.
4128
+ *
4129
+ * @param column - The column name
4130
+ * @param prefix - The prefix for the field (usually empty string or parent path)
4131
+ * @returns Object with translation helper functions
4132
+ *
4133
+ * @example
4134
+ * ```tsx
4135
+ * const formI18n = useFormI18n(column, prefix);
4136
+ *
4137
+ * // Get field label
4138
+ * <Field label={formI18n.label()} />
4139
+ *
4140
+ * // Get error message
4141
+ * <Text>{formI18n.required()}</Text>
4142
+ *
4143
+ * // Get custom translation key
4144
+ * <Text>{formI18n.t('add_more')}</Text>
4145
+ *
4146
+ * // Access the raw colLabel
4147
+ * const colLabel = formI18n.colLabel;
4148
+ * ```
4149
+ */
4150
+ const useFormI18n$1 = (column, prefix = '', schema) => {
4151
+ const { translate } = useSchemaContext();
4152
+ const colLabel = `${prefix}${column}`;
4153
+ return {
4154
+ /**
4155
+ * The constructed column label (prefix + column)
4156
+ */
4157
+ colLabel,
4158
+ /**
4159
+ * Get the field label from schema title prop, or fall back to translation
4160
+ * Uses schema.title if available, otherwise: translate.t(removeIndex(`${colLabel}.field_label`))
4161
+ */
4162
+ label: (options) => {
4163
+ if (schema?.title) {
4164
+ return schema.title;
4165
+ }
4166
+ return translate.t(removeIndex(`${colLabel}.field_label`), options);
4167
+ },
4168
+ /**
4169
+ * Get the required error message translation
4170
+ * Equivalent to: translate.t(removeIndex(`${colLabel}.field_required`))
4171
+ */
4172
+ required: (options) => {
4173
+ return translate.t(removeIndex(`${colLabel}.field_required`), options);
4174
+ },
4175
+ /**
4176
+ * Get a translation for any custom key relative to the field
4177
+ * Equivalent to: translate.t(removeIndex(`${colLabel}.${key}`))
4178
+ *
4179
+ * @param key - The translation key suffix (e.g., 'add_more', 'total', etc.)
4180
+ * @param options - Optional translation options (e.g., defaultValue, interpolation variables)
4181
+ */
4182
+ t: (key, options) => {
4183
+ return translate.t(removeIndex(`${colLabel}.${key}`), options);
4184
+ },
4185
+ /**
4186
+ * Access to the original translate object for edge cases
4187
+ */
4188
+ translate,
4189
+ };
4190
+ };
4191
+
4027
4192
  const ArrayRenderer = ({ schema, column, prefix, }) => {
4028
- const { gridRow, gridColumn = "1/span 12", required, items } = schema;
4193
+ const { gridRow, gridColumn = '1/span 12', required, items } = schema;
4029
4194
  // @ts-expect-error TODO: find suitable types
4030
4195
  const { type } = items;
4031
- const { translate } = useSchemaContext();
4032
4196
  const colLabel = `${prefix}${column}`;
4033
4197
  const isRequired = required?.some((columnId) => columnId === column);
4198
+ const formI18n = useFormI18n$1(column, prefix, schema);
4034
4199
  const { formState: { errors }, setValue, watch, } = useFormContext();
4035
4200
  const fields = (watch(colLabel) ?? []);
4036
- return (jsxs(Flex, { gridRow, gridColumn, flexFlow: "column", gap: 2, children: [jsxs(Box, { as: "label", children: [`${translate.t(removeIndex(`${colLabel}.field_label`))}`, isRequired && jsx("span", { children: "*" })] }), jsx(Flex, { flexFlow: "column", gap: 2, children: fields.map((field, index) => (jsxs(Grid, { gridTemplateColumns: '1fr auto', gap: 2, bgColor: { base: "colorPalette.100", _dark: "colorPalette.900" }, p: 2, borderRadius: 4, borderWidth: 1, borderColor: {
4037
- base: "colorPalette.200",
4038
- _dark: "colorPalette.800",
4039
- }, children: [jsx(Grid, { gridTemplateColumns: "repeat(12, 1fr)", autoFlow: "row", children: jsx(SchemaRenderer, { column: `${index}`,
4201
+ return (jsxs(Flex, { gridRow, gridColumn, flexFlow: 'column', gap: 2, children: [jsxs(Box, { as: "label", children: [formI18n.label(), isRequired && jsx("span", { children: "*" })] }), jsx(Flex, { flexFlow: 'column', gap: 2, children: fields.map((field, index) => (jsxs(Grid, { gridTemplateColumns: '1fr auto', gap: 2, bgColor: { base: 'colorPalette.100', _dark: 'colorPalette.900' }, p: 2, borderRadius: 4, borderWidth: 1, borderColor: {
4202
+ base: 'colorPalette.200',
4203
+ _dark: 'colorPalette.800',
4204
+ }, children: [jsx(Grid, { gridTemplateColumns: 'repeat(12, 1fr)', autoFlow: 'row', children: jsx(SchemaRenderer, { column: `${index}`,
4040
4205
  prefix: `${colLabel}.`,
4041
4206
  // @ts-expect-error find suitable types
4042
- schema: { showLabel: false, ...(items ?? {}) } }) }), jsx(Flex, { justifyContent: "end", children: jsx(Button$1, { variant: "ghost", onClick: () => {
4207
+ schema: { showLabel: false, ...(items ?? {}) } }) }), jsx(Flex, { justifyContent: 'end', children: jsx(Button$1, { variant: 'ghost', onClick: () => {
4043
4208
  setValue(colLabel, fields.filter((_, curIndex) => {
4044
4209
  return curIndex !== index;
4045
4210
  }));
4046
4211
  }, children: jsx(Icon, { children: jsx(CgTrash, {}) }) }) })] }, `${colLabel}.${index}`))) }), jsx(Flex, { children: jsx(Button$1, { onClick: () => {
4047
- if (type === "number") {
4212
+ if (type === 'number') {
4048
4213
  setValue(colLabel, [...fields, 0]);
4049
4214
  return;
4050
4215
  }
4051
- if (type === "string") {
4052
- setValue(colLabel, [...fields, ""]);
4216
+ if (type === 'string') {
4217
+ setValue(colLabel, [...fields, '']);
4053
4218
  return;
4054
4219
  }
4055
- if (type === "boolean") {
4220
+ if (type === 'boolean') {
4056
4221
  setValue(colLabel, [...fields, false]);
4057
4222
  return;
4058
4223
  }
4059
4224
  setValue(colLabel, [...fields, {}]);
4060
- }, children: translate.t(removeIndex(`${colLabel}.add`)) }) }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
4225
+ }, children: translate.t(removeIndex(`${colLabel}.add`)) }) }), errors[`${column}`] && (jsx(Text, { color: 'red.400', children: formI18n.required() }))] }));
4061
4226
  };
4062
4227
 
4063
4228
  const Field = React.forwardRef(function Field(props, ref) {
@@ -4067,15 +4232,13 @@ const Field = React.forwardRef(function Field(props, ref) {
4067
4232
 
4068
4233
  const BooleanPicker = ({ schema, column, prefix }) => {
4069
4234
  const { watch, formState: { errors }, setValue, } = useFormContext();
4070
- const { translate } = useSchemaContext();
4071
4235
  const { required, gridColumn = 'span 12', gridRow = 'span 1' } = schema;
4072
4236
  const isRequired = required?.some((columnId) => columnId === column);
4073
4237
  const colLabel = `${prefix}${column}`;
4074
4238
  const value = watch(colLabel);
4075
- return (jsx(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, alignItems: 'stretch', gridColumn,
4076
- gridRow, errorText: errors[`${colLabel}`]
4077
- ? translate.t(removeIndex(`${colLabel}.field_required`))
4078
- : undefined, invalid: !!errors[colLabel], children: jsx(CheckboxCard, { checked: value, variant: 'surface', onChange: () => {
4239
+ const formI18n = useFormI18n$1(column, prefix, schema);
4240
+ return (jsx(Field, { label: formI18n.label(), required: isRequired, alignItems: 'stretch', gridColumn,
4241
+ gridRow, errorText: errors[`${colLabel}`] ? formI18n.required() : undefined, invalid: !!errors[colLabel], children: jsx(CheckboxCard, { checked: value, variant: 'surface', onChange: () => {
4079
4242
  setValue(colLabel, !value);
4080
4243
  } }) }));
4081
4244
  };
@@ -4191,76 +4354,12 @@ let DatePicker$1 = class DatePicker extends React__default.Component {
4191
4354
  }
4192
4355
  };
4193
4356
 
4194
- /**
4195
- * Custom hook to simplify i18n translation for form fields.
4196
- * Automatically handles colLabel construction and removeIndex logic.
4197
- *
4198
- * @param column - The column name
4199
- * @param prefix - The prefix for the field (usually empty string or parent path)
4200
- * @returns Object with translation helper functions
4201
- *
4202
- * @example
4203
- * ```tsx
4204
- * const formI18n = useFormI18n(column, prefix);
4205
- *
4206
- * // Get field label
4207
- * <Field label={formI18n.label()} />
4208
- *
4209
- * // Get error message
4210
- * <Text>{formI18n.required()}</Text>
4211
- *
4212
- * // Get custom translation key
4213
- * <Text>{formI18n.t('add_more')}</Text>
4214
- *
4215
- * // Access the raw colLabel
4216
- * const colLabel = formI18n.colLabel;
4217
- * ```
4218
- */
4219
- const useFormI18n = (column, prefix = "") => {
4220
- const { translate } = useSchemaContext();
4221
- const colLabel = `${prefix}${column}`;
4222
- return {
4223
- /**
4224
- * The constructed column label (prefix + column)
4225
- */
4226
- colLabel,
4227
- /**
4228
- * Get the field label translation
4229
- * Equivalent to: translate.t(removeIndex(`${colLabel}.field_label`))
4230
- */
4231
- label: (options) => {
4232
- return translate.t(removeIndex(`${colLabel}.field_label`), options);
4233
- },
4234
- /**
4235
- * Get the required error message translation
4236
- * Equivalent to: translate.t(removeIndex(`${colLabel}.field_required`))
4237
- */
4238
- required: (options) => {
4239
- return translate.t(removeIndex(`${colLabel}.field_required`), options);
4240
- },
4241
- /**
4242
- * Get a translation for any custom key relative to the field
4243
- * Equivalent to: translate.t(removeIndex(`${colLabel}.${key}`))
4244
- *
4245
- * @param key - The translation key suffix (e.g., 'add_more', 'total', etc.)
4246
- * @param options - Optional translation options (e.g., defaultValue, interpolation variables)
4247
- */
4248
- t: (key, options) => {
4249
- return translate.t(removeIndex(`${colLabel}.${key}`), options);
4250
- },
4251
- /**
4252
- * Access to the original translate object for edge cases
4253
- */
4254
- translate,
4255
- };
4256
- };
4257
-
4258
4357
  dayjs.extend(utc);
4259
4358
  dayjs.extend(timezone);
4260
4359
  const DatePicker = ({ column, schema, prefix }) => {
4261
4360
  const { watch, formState: { errors }, setValue, } = useFormContext();
4262
4361
  const { timezone, dateTimePickerLabels, insideDialog } = useSchemaContext();
4263
- const formI18n = useFormI18n(column, prefix);
4362
+ const formI18n = useFormI18n$1(column, prefix, schema);
4264
4363
  const { required, gridColumn = 'span 12', gridRow = 'span 1', displayDateFormat = 'YYYY-MM-DD', dateFormat = 'YYYY-MM-DD', } = schema;
4265
4364
  const isRequired = required?.some((columnId) => columnId === column);
4266
4365
  const colLabel = formI18n.colLabel;
@@ -4378,7 +4477,7 @@ dayjs.extend(timezone);
4378
4477
  const DateRangePicker = ({ column, schema, prefix, }) => {
4379
4478
  const { watch, formState: { errors }, setValue, } = useFormContext();
4380
4479
  const { timezone, insideDialog } = useSchemaContext();
4381
- const formI18n = useFormI18n(column, prefix);
4480
+ const formI18n = useFormI18n$1(column, prefix);
4382
4481
  const { required, gridColumn = 'span 12', gridRow = 'span 1', displayDateFormat = 'YYYY-MM-DD', dateFormat = 'YYYY-MM-DD', } = schema;
4383
4482
  const isRequired = required?.some((columnId) => columnId === column);
4384
4483
  const colLabel = formI18n.colLabel;
@@ -4476,7 +4575,7 @@ const DateRangePicker = ({ column, schema, prefix, }) => {
4476
4575
  const EnumPicker = ({ column, isMultiple = false, schema, prefix, showTotalAndLimit = false, }) => {
4477
4576
  const { watch, formState: { errors }, setValue, } = useFormContext();
4478
4577
  const { enumPickerLabels, insideDialog } = useSchemaContext();
4479
- const formI18n = useFormI18n(column, prefix);
4578
+ const formI18n = useFormI18n$1(column, prefix, schema);
4480
4579
  const { required, variant } = schema;
4481
4580
  const isRequired = required?.some((columnId) => columnId === column);
4482
4581
  const { gridColumn = 'span 12', gridRow = 'span 1', renderDisplay } = schema;
@@ -5120,7 +5219,7 @@ function MediaBrowserDialog({ open, onClose, onSelect, title, filterImageOnly =
5120
5219
  const FilePicker = ({ column, schema, prefix }) => {
5121
5220
  const { setValue, formState: { errors }, watch, } = useFormContext();
5122
5221
  const { filePickerLabels } = useSchemaContext();
5123
- const formI18n = useFormI18n(column, prefix);
5222
+ const formI18n = useFormI18n$1(column, prefix);
5124
5223
  const { required, gridColumn = 'span 12', gridRow = 'span 1', type, } = schema;
5125
5224
  const isRequired = required?.some((columnId) => columnId === column);
5126
5225
  const isSingleSelect = type === 'string';
@@ -5196,7 +5295,7 @@ const FilePicker = ({ column, schema, prefix }) => {
5196
5295
  const FormMediaLibraryBrowser = ({ column, schema, prefix, }) => {
5197
5296
  const { setValue, formState: { errors }, watch, } = useFormContext();
5198
5297
  const { filePickerLabels } = useSchemaContext();
5199
- const formI18n = useFormI18n(column, prefix);
5298
+ const formI18n = useFormI18n$1(column, prefix);
5200
5299
  const { required, gridColumn = 'span 12', gridRow = 'span 1', filePicker, type, } = schema;
5201
5300
  const isRequired = required?.some((columnId) => columnId === column);
5202
5301
  const isSingleSelect = type === 'string';
@@ -5337,13 +5436,18 @@ const getTableData = async ({ serverUrl, in_table, searching = "", where = [], l
5337
5436
  }
5338
5437
  };
5339
5438
 
5439
+ // Default renderDisplay function that stringifies JSON
5440
+ const defaultRenderDisplay = (item) => {
5441
+ return JSON.stringify(item);
5442
+ };
5443
+
5340
5444
  const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
5341
5445
  const { watch, getValues, formState: { errors }, setValue, } = useFormContext();
5342
5446
  const { serverUrl, idMap, setIdMap, idPickerLabels, insideDialog } = useSchemaContext();
5343
- const formI18n = useFormI18n(column, prefix);
5447
+ const formI18n = useFormI18n$1(column, prefix, schema);
5344
5448
  const { required, gridColumn = 'span 12', gridRow = 'span 1', renderDisplay, foreign_key, } = schema;
5345
5449
  const isRequired = required?.some((columnId) => columnId === column);
5346
- const { table, column: column_ref, display_column, customQueryFn, } = foreign_key;
5450
+ const { table, column: column_ref, customQueryFn, } = foreign_key;
5347
5451
  const [searchText, setSearchText] = useState('');
5348
5452
  const [debouncedSearchText, setDebouncedSearchText] = useState('');
5349
5453
  const [limit] = useState(50); // Increased limit for combobox
@@ -5424,12 +5528,16 @@ const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
5424
5528
  // label is used for filtering/searching (must be a string)
5425
5529
  // raw item is stored for custom rendering
5426
5530
  const comboboxItems = useMemo(() => {
5427
- return dataList.map((item) => ({
5428
- label: String(item[display_column] ?? ''), // Always use display_column for filtering
5429
- value: String(item[column_ref]),
5430
- raw: item,
5431
- }));
5432
- }, [dataList, display_column, column_ref]);
5531
+ const renderFn = renderDisplay || defaultRenderDisplay;
5532
+ return dataList.map((item) => {
5533
+ const rendered = renderFn(item);
5534
+ return {
5535
+ label: typeof rendered === 'string' ? rendered : JSON.stringify(item), // Use string for filtering
5536
+ value: String(item[column_ref]),
5537
+ raw: item,
5538
+ };
5539
+ });
5540
+ }, [dataList, column_ref, renderDisplay]);
5433
5541
  // Use filter hook for combobox
5434
5542
  const { contains } = useFilter({ sensitivity: 'base' });
5435
5543
  // Create collection for combobox
@@ -5475,9 +5583,9 @@ const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
5475
5583
  return (jsx(Tag, { closable: true, onClick: () => {
5476
5584
  const newValue = currentValue.filter((itemId) => itemId !== id);
5477
5585
  setValue(colLabel, newValue);
5478
- }, children: !!renderDisplay === true
5586
+ }, children: renderDisplay
5479
5587
  ? renderDisplay(item)
5480
- : item[display_column] }, id));
5588
+ : defaultRenderDisplay(item) }, id));
5481
5589
  }) })), jsxs(Combobox.Root, { collection: collection, value: currentValue, onValueChange: handleValueChange, onInputValueChange: handleInputValueChange, multiple: isMultiple, closeOnSelect: !isMultiple, openOnClick: true, invalid: !!errors[colLabel], width: "100%", positioning: insideDialog
5482
5590
  ? { strategy: 'fixed', hideWhenDetached: true }
5483
5591
  : undefined, children: [jsxs(Combobox.Control, { children: [jsx(Combobox.Input, { placeholder: idPickerLabels?.typeToSearch ?? formI18n.t('type_to_search') }), jsxs(Combobox.IndicatorGroup, { children: [(isFetching || isLoading || isPending) && jsx(Spinner, { size: "xs" }), isError && (jsx(Icon, { color: "fg.error", children: jsx(BiError, {}) })), !isMultiple && currentValue.length > 0 && (jsx(Combobox.ClearTrigger, { onClick: () => {
@@ -5566,15 +5674,15 @@ const extractErrorMessage = (error) => {
5566
5674
 
5567
5675
  const NumberInputField = ({ schema, column, prefix, }) => {
5568
5676
  const { setValue, formState: { errors }, watch, } = useFormContext();
5569
- const { translate } = useSchemaContext();
5570
5677
  const { required, gridColumn = 'span 12', gridRow = 'span 1', numberStorageType = 'number', } = schema;
5571
5678
  const isRequired = required?.some((columnId) => columnId === column);
5572
5679
  const colLabel = `${prefix}${column}`;
5573
5680
  const value = watch(`${colLabel}`);
5574
5681
  const fieldError = getFieldError(errors, colLabel);
5575
- return (jsx(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, gridColumn, gridRow, errorText: fieldError
5682
+ const formI18n = useFormI18n$1(column, prefix, schema);
5683
+ return (jsx(Field, { label: formI18n.label(), required: isRequired, gridColumn, gridRow, errorText: fieldError
5576
5684
  ? fieldError.includes('required')
5577
- ? translate.t(removeIndex(`${colLabel}.field_required`))
5685
+ ? formI18n.required()
5578
5686
  : fieldError
5579
5687
  : undefined, invalid: !!fieldError, children: jsx(NumberInputRoot, { value: value, onValueChange: (details) => {
5580
5688
  // Store as string or number based on configuration, default to number
@@ -5587,14 +5695,14 @@ const NumberInputField = ({ schema, column, prefix, }) => {
5587
5695
 
5588
5696
  const ObjectInput = ({ schema, column, prefix }) => {
5589
5697
  const { properties, gridColumn = 'span 12', gridRow = 'span 1', required, showLabel = true, } = schema;
5590
- const { translate } = useSchemaContext();
5591
5698
  const colLabel = `${prefix}${column}`;
5592
5699
  const isRequired = required?.some((columnId) => columnId === column);
5700
+ const formI18n = useFormI18n$1(column, prefix, schema);
5593
5701
  const { formState: { errors }, } = useFormContext();
5594
5702
  if (properties === undefined) {
5595
5703
  throw new Error(`properties is undefined when using ObjectInput`);
5596
5704
  }
5597
- return (jsxs(Box, { gridRow, gridColumn, children: [showLabel && (jsxs(Box, { as: "label", children: [`${translate.t(removeIndex(`${colLabel}.field_label`))}`, isRequired && jsx("span", { children: "*" })] })), jsx(Grid, { bgColor: { base: 'colorPalette.100', _dark: 'colorPalette.900' }, p: 2, borderRadius: 4, borderWidth: 1, borderColor: {
5705
+ return (jsxs(Box, { gridRow, gridColumn, children: [showLabel && (jsxs(Box, { as: "label", children: [formI18n.label(), isRequired && jsx("span", { children: "*" })] })), jsx(Grid, { bgColor: { base: 'colorPalette.100', _dark: 'colorPalette.900' }, p: 2, borderRadius: 4, borderWidth: 1, borderColor: {
5598
5706
  base: 'colorPalette.200',
5599
5707
  _dark: 'colorPalette.800',
5600
5708
  }, gap: "4", padding: '4', gridTemplateColumns: 'repeat(12, 1fr)', autoFlow: 'row', children: Object.keys(properties ?? {}).map((key) => {
@@ -5604,10 +5712,10 @@ const ObjectInput = ({ schema, column, prefix }) => {
5604
5712
  prefix: `${prefix}${column}.`,
5605
5713
  properties,
5606
5714
  parentRequired: required }, `form-${colLabel}-${key}`));
5607
- }) }), errors[`${column}`] && (jsx(Text, { color: 'red.400', children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
5715
+ }) }), errors[`${column}`] && (jsx(Text, { color: 'red.400', children: formI18n.required() }))] }));
5608
5716
  };
5609
5717
 
5610
- const RecordInput$1 = ({ column, schema, prefix }) => {
5718
+ const RecordInput = ({ column, schema, prefix }) => {
5611
5719
  const { formState: { errors }, setValue, getValues, } = useFormContext();
5612
5720
  const { translate } = useSchemaContext();
5613
5721
  const { required, gridColumn = 'span 12', gridRow = 'span 1' } = schema;
@@ -5616,9 +5724,8 @@ const RecordInput$1 = ({ column, schema, prefix }) => {
5616
5724
  const [showNewEntries, setShowNewEntries] = useState(false);
5617
5725
  const [newKey, setNewKey] = useState();
5618
5726
  const [newValue, setNewValue] = useState();
5619
- return (jsxs(Field, { label: `${translate.t(`${column}.field_label`)}`, required: isRequired, alignItems: 'stretch', gridColumn, gridRow, errorText: errors[`${column}`]
5620
- ? translate.t(`${column}.field_required`)
5621
- : undefined, invalid: !!errors[column], children: [entries.map(([key, value]) => {
5727
+ const formI18n = useFormI18n$1(column, prefix, schema);
5728
+ return (jsxs(Field, { label: formI18n.label(), required: isRequired, alignItems: 'stretch', gridColumn, gridRow, errorText: errors[`${column}`] ? formI18n.required() : undefined, invalid: !!errors[column], children: [entries.map(([key, value]) => {
5622
5729
  return (jsxs(Grid, { templateColumns: '1fr 1fr auto', gap: 1, children: [jsx(Input, { value: key, onChange: (e) => {
5623
5730
  const filtered = entries.filter(([target]) => {
5624
5731
  return target !== key;
@@ -5663,12 +5770,12 @@ const RecordInput$1 = ({ column, schema, prefix }) => {
5663
5770
 
5664
5771
  const StringInputField = ({ column, schema, prefix, }) => {
5665
5772
  const { register, formState: { errors }, } = useFormContext();
5666
- const { translate } = useSchemaContext();
5667
5773
  const { required, gridColumn = 'span 12', gridRow = 'span 1' } = schema;
5668
5774
  const isRequired = required?.some((columnId) => columnId === column);
5669
5775
  const colLabel = `${prefix}${column}`;
5670
5776
  const fieldError = getFieldError(errors, colLabel);
5671
- return (jsx(Fragment, { children: jsx(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, gridColumn: gridColumn, gridRow: gridRow, errorText: fieldError, invalid: !!fieldError, children: jsx(Input, { ...register(`${colLabel}`, { required: isRequired }), autoComplete: "off" }) }) }));
5777
+ const formI18n = useFormI18n$1(column, prefix, schema);
5778
+ return (jsx(Fragment, { children: jsx(Field, { label: formI18n.label(), required: isRequired, gridColumn: gridColumn, gridRow: gridRow, errorText: fieldError, invalid: !!fieldError, children: jsx(Input, { ...register(`${colLabel}`, { required: isRequired }), autoComplete: "off" }) }) }));
5672
5779
  };
5673
5780
 
5674
5781
  const RadioCardItem = React.forwardRef(function RadioCardItem(props, ref) {
@@ -5853,17 +5960,17 @@ Textarea.displayName = "Textarea";
5853
5960
 
5854
5961
  const TextAreaInput = ({ column, schema, prefix, }) => {
5855
5962
  const { register, formState: { errors }, } = useFormContext();
5856
- const { translate } = useSchemaContext();
5857
5963
  const { required, gridColumn = 'span 12', gridRow = 'span 1' } = schema;
5858
5964
  const isRequired = required?.some((columnId) => columnId === column);
5859
5965
  const colLabel = `${prefix}${column}`;
5860
5966
  const form = useFormContext();
5861
5967
  const { setValue, watch } = form;
5862
5968
  const fieldError = getFieldError(errors, colLabel);
5969
+ const formI18n = useFormI18n$1(column, prefix, schema);
5863
5970
  const watchValue = watch(colLabel);
5864
- return (jsx(Fragment, { children: jsx(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, gridColumn: gridColumn ?? 'span 4', gridRow: gridRow ?? 'span 1', display: "grid", errorText: fieldError
5971
+ return (jsx(Fragment, { children: jsx(Field, { label: formI18n.label(), required: isRequired, gridColumn: gridColumn ?? 'span 4', gridRow: gridRow ?? 'span 1', display: "grid", errorText: fieldError
5865
5972
  ? fieldError.includes('required')
5866
- ? translate.t(removeIndex(`${colLabel}.field_required`))
5973
+ ? formI18n.required()
5867
5974
  : fieldError
5868
5975
  : undefined, invalid: !!fieldError, children: jsx(Textarea, { value: watchValue, onChange: (value) => setValue(colLabel, value) }) }) }));
5869
5976
  };
@@ -6185,10 +6292,11 @@ onChange = (_newValue) => { }, timezone = 'Asia/Hong_Kong', startTime, selectedD
6185
6292
  dayjs.extend(timezone);
6186
6293
  const TimePicker = ({ column, schema, prefix }) => {
6187
6294
  const { watch, formState: { errors }, setValue, } = useFormContext();
6188
- const { translate, timezone, insideDialog } = useSchemaContext();
6295
+ const { timezone, insideDialog } = useSchemaContext();
6189
6296
  const { required, gridColumn = 'span 12', gridRow = 'span 1', timeFormat = 'HH:mm:ssZ', displayTimeFormat = 'hh:mm A', } = schema;
6190
6297
  const isRequired = required?.some((columnId) => columnId === column);
6191
6298
  const colLabel = `${prefix}${column}`;
6299
+ const formI18n = useFormI18n$1(column, prefix, schema);
6192
6300
  const [open, setOpen] = useState(false);
6193
6301
  const value = watch(colLabel);
6194
6302
  const displayedTime = dayjs(`1970-01-01T${value}`).tz(timezone).isValid()
@@ -6243,10 +6351,8 @@ const TimePicker = ({ column, schema, prefix }) => {
6243
6351
  const timeString = getTimeString(newHour, newMinute, newMeridiem);
6244
6352
  setValue(colLabel, timeString, { shouldValidate: true, shouldDirty: true });
6245
6353
  };
6246
- return (jsx(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, alignItems: 'stretch', gridColumn,
6247
- gridRow, errorText: errors[`${colLabel}`]
6248
- ? translate.t(removeIndex(`${colLabel}.field_required`))
6249
- : undefined, invalid: !!errors[colLabel], children: jsxs(Popover.Root, { open: open, onOpenChange: (e) => setOpen(e.open), closeOnInteractOutside: true, children: [jsx(Popover.Trigger, { asChild: true, children: jsxs(Button, { size: "sm", variant: "outline", onClick: () => {
6354
+ return (jsx(Field, { label: formI18n.label(), required: isRequired, alignItems: 'stretch', gridColumn,
6355
+ gridRow, errorText: errors[`${colLabel}`] ? formI18n.required() : undefined, invalid: !!errors[colLabel], children: jsxs(Popover.Root, { open: open, onOpenChange: (e) => setOpen(e.open), closeOnInteractOutside: true, children: [jsx(Popover.Trigger, { asChild: true, children: jsxs(Button, { size: "sm", variant: "outline", onClick: () => {
6250
6356
  setOpen(true);
6251
6357
  }, justifyContent: 'start', children: [jsx(IoMdClock, {}), !!value ? `${displayedTime}` : ''] }) }), insideDialog ? (jsx(Popover.Positioner, { children: jsx(Popover.Content, { maxH: "70vh", overflowY: "auto", children: jsx(Popover.Body, { overflow: "visible", children: jsx(TimePicker$1, { hour: hour, setHour: setHour, minute: minute, setMinute: setMinute, meridiem: meridiem, setMeridiem: setMeridiem, onChange: handleTimeChange, meridiemLabel: {
6252
6358
  am: translate.t(`common.am`, { defaultValue: 'AM' }),
@@ -7136,7 +7242,7 @@ dayjs.extend(timezone);
7136
7242
  const DateTimePicker = ({ column, schema, prefix, }) => {
7137
7243
  const { watch, formState: { errors }, setValue, } = useFormContext();
7138
7244
  const { timezone, dateTimePickerLabels, insideDialog } = useSchemaContext();
7139
- const formI18n = useFormI18n(column, prefix);
7245
+ const formI18n = useFormI18n$1(column, prefix, schema);
7140
7246
  const { required, gridColumn = 'span 12', gridRow = 'span 1', displayDateFormat = 'YYYY-MM-DD HH:mm:ss',
7141
7247
  // with timezone
7142
7248
  dateFormat = 'YYYY-MM-DD[T]HH:mm:ssZ', } = schema;
@@ -7278,7 +7384,7 @@ const SchemaRenderer = ({ schema, prefix, column, }) => {
7278
7384
  if (innerProperties) {
7279
7385
  return jsx(ObjectInput, { schema: colSchema, prefix, column });
7280
7386
  }
7281
- return jsx(RecordInput$1, { schema: colSchema, prefix, column });
7387
+ return jsx(RecordInput, { schema: colSchema, prefix, column });
7282
7388
  }
7283
7389
  if (type === 'array') {
7284
7390
  if (variant === 'id-picker') {
@@ -7332,32 +7438,30 @@ const ColumnRenderer = ({ column, properties, prefix, parentRequired, }) => {
7332
7438
  };
7333
7439
 
7334
7440
  const ArrayViewer = ({ schema, column, prefix }) => {
7335
- const { gridColumn = "span 12", gridRow = "span 1", required, items, } = schema;
7336
- const { translate } = useSchemaContext();
7441
+ const { gridColumn = 'span 12', gridRow = 'span 1', required, items, } = schema;
7337
7442
  const colLabel = `${prefix}${column}`;
7338
7443
  const isRequired = required?.some((columnId) => columnId === column);
7444
+ const formI18n = useFormI18n$1(column, prefix, schema);
7339
7445
  const { watch, formState: { errors }, } = useFormContext();
7340
7446
  const values = watch(colLabel) ?? [];
7341
- return (jsxs(Box, { gridRow, gridColumn, children: [jsxs(Box, { as: "label", gridColumn: "1/span12", children: [`${translate.t(removeIndex(`${colLabel}.field_label`))}`, isRequired && jsx("span", { children: "*" })] }), jsx(Flex, { flexFlow: "column", gap: 1, children: values.map((field, index) => (jsx(Flex, { flexFlow: "column", bgColor: { base: "colorPalette.100", _dark: "colorPalette.900" }, p: "2", borderRadius: "md", borderWidth: "thin", borderColor: {
7342
- base: "colorPalette.200",
7343
- _dark: "colorPalette.800",
7344
- }, children: jsx(Grid, { gap: "4", gridTemplateColumns: "repeat(12, 1fr)", autoFlow: "row", children: jsx(SchemaViewer, { column: `${index}`,
7447
+ return (jsxs(Box, { gridRow, gridColumn, children: [jsxs(Box, { as: "label", gridColumn: '1/span12', children: [formI18n.label(), isRequired && jsx("span", { children: "*" })] }), jsx(Flex, { flexFlow: 'column', gap: 1, children: values.map((field, index) => (jsx(Flex, { flexFlow: 'column', bgColor: { base: 'colorPalette.100', _dark: 'colorPalette.900' }, p: '2', borderRadius: 'md', borderWidth: 'thin', borderColor: {
7448
+ base: 'colorPalette.200',
7449
+ _dark: 'colorPalette.800',
7450
+ }, children: jsx(Grid, { gap: "4", gridTemplateColumns: 'repeat(12, 1fr)', autoFlow: 'row', children: jsx(SchemaViewer, { column: `${index}`,
7345
7451
  prefix: `${colLabel}.`,
7346
7452
  // @ts-expect-error find suitable types
7347
- schema: { showLabel: false, ...(items ?? {}) } }) }) }, `form-${prefix}${column}.${index}`))) }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
7453
+ schema: { showLabel: false, ...(items ?? {}) } }) }) }, `form-${prefix}${column}.${index}`))) }), errors[`${column}`] && (jsx(Text, { color: 'red.400', children: formI18n.required() }))] }));
7348
7454
  };
7349
7455
 
7350
7456
  const BooleanViewer = ({ schema, column, prefix, }) => {
7351
7457
  const { watch, formState: { errors }, } = useFormContext();
7352
- const { translate } = useSchemaContext();
7353
- const { required, gridColumn = "span 12", gridRow = "span 1" } = schema;
7458
+ const { required, gridColumn = 'span 12', gridRow = 'span 1' } = schema;
7354
7459
  const isRequired = required?.some((columnId) => columnId === column);
7355
7460
  const colLabel = `${prefix}${column}`;
7356
7461
  const value = watch(colLabel);
7357
- return (jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, alignItems: "stretch", gridColumn,
7358
- gridRow, children: [jsx(Text, { children: value
7359
- ? translate.t(removeIndex(`${colLabel}.true`))
7360
- : translate.t(removeIndex(`${colLabel}.false`)) }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
7462
+ const formI18n = useFormI18n$1(column, prefix, schema);
7463
+ return (jsxs(Field, { label: formI18n.label(), required: isRequired, alignItems: 'stretch', gridColumn,
7464
+ gridRow, children: [jsx(Text, { children: value ? formI18n.t('true') : formI18n.t('false') }), errors[`${column}`] && (jsx(Text, { color: 'red.400', children: formI18n.required() }))] }));
7361
7465
  };
7362
7466
 
7363
7467
  const CustomViewer = ({ column, schema, prefix }) => {
@@ -7374,19 +7478,22 @@ const CustomViewer = ({ column, schema, prefix }) => {
7374
7478
 
7375
7479
  const DateViewer = ({ column, schema, prefix }) => {
7376
7480
  const { watch, formState: { errors }, } = useFormContext();
7377
- const { translate, timezone } = useSchemaContext();
7378
- const { required, gridColumn = "span 4", gridRow = "span 1", displayDateFormat = "YYYY-MM-DD", } = schema;
7481
+ const { timezone } = useSchemaContext();
7482
+ const { required, gridColumn = 'span 4', gridRow = 'span 1', displayDateFormat = 'YYYY-MM-DD', } = schema;
7379
7483
  const isRequired = required?.some((columnId) => columnId === column);
7380
7484
  const colLabel = `${prefix}${column}`;
7381
7485
  const selectedDate = watch(colLabel);
7382
- const displayDate = dayjs(selectedDate).tz(timezone).format(displayDateFormat);
7383
- return (jsxs(Field, { label: `${translate.t(removeIndex(`${column}.field_label`))}`, required: isRequired, alignItems: "stretch", gridColumn,
7384
- gridRow, children: [jsxs(Text, { children: [" ", selectedDate !== undefined ? displayDate : ""] }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: translate.t(`${column}.field_required`) }))] }));
7486
+ const formI18n = useFormI18n$1(column, prefix, schema);
7487
+ const displayDate = dayjs(selectedDate)
7488
+ .tz(timezone)
7489
+ .format(displayDateFormat);
7490
+ return (jsxs(Field, { label: formI18n.label(), required: isRequired, alignItems: 'stretch', gridColumn,
7491
+ gridRow, children: [jsxs(Text, { children: [" ", selectedDate !== undefined ? displayDate : ''] }), errors[`${column}`] && (jsx(Text, { color: 'red.400', children: formI18n.required() }))] }));
7385
7492
  };
7386
7493
 
7387
7494
  const EnumViewer = ({ column, isMultiple = false, schema, prefix, }) => {
7388
7495
  const { watch, formState: { errors }, } = useFormContext();
7389
- const formI18n = useFormI18n(column, prefix);
7496
+ const formI18n = useFormI18n$1(column, prefix);
7390
7497
  const { required } = schema;
7391
7498
  const isRequired = required?.some((columnId) => columnId === column);
7392
7499
  const { gridColumn = "span 12", gridRow = "span 1", renderDisplay } = schema;
@@ -7407,54 +7514,56 @@ const EnumViewer = ({ column, isMultiple = false, schema, prefix, }) => {
7407
7514
 
7408
7515
  const FileViewer = ({ column, schema, prefix }) => {
7409
7516
  const { watch } = useFormContext();
7410
- const { translate } = useSchemaContext();
7411
- const { required, gridColumn = "span 12", gridRow = "span 1", } = schema;
7517
+ const { required, gridColumn = 'span 12', gridRow = 'span 1', } = schema;
7412
7518
  const isRequired = required?.some((columnId) => columnId === column);
7413
7519
  const currentFiles = (watch(column) ?? []);
7414
- const colLabel = `${prefix}${column}`;
7415
- return (jsx(Field, { label: `${translate.t(`${colLabel}.field_label`)}`, required: isRequired, gridColumn: gridColumn, gridRow: gridRow, display: "grid", gridTemplateRows: "auto 1fr auto", alignItems: "stretch", children: jsx(Flex, { flexFlow: "column", gap: 1, children: currentFiles.map((file) => {
7416
- return (jsx(Card.Root, { variant: "subtle", children: jsxs(Card.Body, { gap: "2", display: "flex", flexFlow: "row", alignItems: "center", padding: "2", children: [file.type.startsWith("image/") && (jsx(Image, { src: URL.createObjectURL(file), alt: file.name, boxSize: "50px", objectFit: "cover", borderRadius: "md", marginRight: "2" })), jsx(Box, { children: file.name })] }) }, file.name));
7520
+ const formI18n = useFormI18n$1(column, prefix, schema);
7521
+ return (jsx(Field, { label: formI18n.label(), required: isRequired, gridColumn: gridColumn, gridRow: gridRow, display: 'grid', gridTemplateRows: 'auto 1fr auto', alignItems: 'stretch', children: jsx(Flex, { flexFlow: 'column', gap: 1, children: currentFiles.map((file) => {
7522
+ return (jsx(Card.Root, { variant: 'subtle', children: jsxs(Card.Body, { gap: "2", display: 'flex', flexFlow: 'row', alignItems: 'center', padding: '2', children: [file.type.startsWith('image/') && (jsx(Image, { src: URL.createObjectURL(file), alt: file.name, boxSize: "50px", objectFit: "cover", borderRadius: "md", marginRight: "2" })), jsx(Box, { children: file.name })] }) }, file.name));
7417
7523
  }) }) }));
7418
7524
  };
7419
7525
 
7420
7526
  const IdViewer = ({ column, schema, prefix, isMultiple = false, }) => {
7421
7527
  const { watch, formState: { errors }, } = useFormContext();
7422
7528
  const { idMap, translate } = useSchemaContext();
7423
- const { required, gridColumn = "span 12", gridRow = "span 1", renderDisplay, foreign_key, } = schema;
7529
+ const { required, gridColumn = 'span 12', gridRow = 'span 1', renderDisplay, foreign_key, } = schema;
7424
7530
  const isRequired = required?.some((columnId) => columnId === column);
7425
- const { display_column } = foreign_key;
7531
+ const formI18n = useFormI18n(column, prefix, schema);
7426
7532
  const colLabel = `${prefix}${column}`;
7427
7533
  const watchId = watch(colLabel);
7428
7534
  const watchIds = (watch(colLabel) ?? []);
7429
7535
  const getPickedValue = () => {
7430
7536
  if (Object.keys(idMap).length <= 0) {
7431
- return "";
7537
+ return '';
7432
7538
  }
7433
7539
  const record = idMap[watchId];
7434
7540
  if (record === undefined) {
7435
- return "";
7541
+ return '';
7436
7542
  }
7437
- return record[display_column];
7543
+ const rendered = renderDisplay
7544
+ ? renderDisplay(record)
7545
+ : defaultRenderDisplay(record);
7546
+ return typeof rendered === 'string' ? rendered : JSON.stringify(record);
7438
7547
  };
7439
- return (jsxs(Field, { label: `${translate.t(removeIndex(`${column}.field_label`))}`, required: isRequired, alignItems: "stretch", gridColumn,
7440
- gridRow, children: [isMultiple && (jsx(Flex, { flexFlow: "wrap", gap: 1, children: watchIds.map((id) => {
7548
+ return (jsxs(Field, { label: formI18n.label(), required: isRequired, alignItems: 'stretch', gridColumn,
7549
+ gridRow, children: [isMultiple && (jsx(Flex, { flexFlow: 'wrap', gap: 1, children: watchIds.map((id) => {
7441
7550
  const item = idMap[id];
7442
7551
  if (item === undefined) {
7443
7552
  return (jsx(Text, { children: translate.t(removeIndex(`${colLabel}.undefined`)) }, id));
7444
7553
  }
7445
- return (jsx(Tag, { closable: true, children: !!renderDisplay === true
7554
+ return (jsx(Tag, { closable: true, children: renderDisplay
7446
7555
  ? renderDisplay(item)
7447
- : item[display_column] }, id));
7448
- }) })), !isMultiple && jsx(Text, { children: getPickedValue() }), errors[`${colLabel}`] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
7556
+ : defaultRenderDisplay(item) }, id));
7557
+ }) })), !isMultiple && jsx(Text, { children: getPickedValue() }), errors[`${colLabel}`] && (jsx(Text, { color: 'red.400', children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
7449
7558
  };
7450
7559
 
7451
7560
  const NumberViewer = ({ schema, column, prefix, }) => {
7452
7561
  const { watch, formState: { errors }, } = useFormContext();
7453
- const { translate } = useSchemaContext();
7454
7562
  const { required, gridColumn = 'span 12', gridRow = 'span 1' } = schema;
7455
7563
  const isRequired = required?.some((columnId) => columnId === column);
7456
7564
  const colLabel = `${prefix}${column}`;
7457
7565
  const value = watch(colLabel);
7566
+ const formI18n = useFormI18n$1(column, prefix, schema);
7458
7567
  // Format the value for display if formatOptions are provided
7459
7568
  const formatValue = (val) => {
7460
7569
  if (val === undefined || val === null || val === '')
@@ -7473,90 +7582,49 @@ const NumberViewer = ({ schema, column, prefix, }) => {
7473
7582
  }
7474
7583
  return String(val);
7475
7584
  };
7476
- return (jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, gridColumn, gridRow, children: [jsx(Text, { children: formatValue(value) }), errors[`${column}`] && (jsx(Text, { color: 'red.400', children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
7585
+ return (jsxs(Field, { label: formI18n.label(), required: isRequired, gridColumn, gridRow, children: [jsx(Text, { children: formatValue(value) }), errors[`${column}`] && (jsx(Text, { color: 'red.400', children: formI18n.required() }))] }));
7477
7586
  };
7478
7587
 
7479
7588
  const ObjectViewer = ({ schema, column, prefix }) => {
7480
- const { properties, gridColumn = "span 12", gridRow = "span 1", required, showLabel = true, } = schema;
7481
- const { translate } = useSchemaContext();
7589
+ const { properties, gridColumn = 'span 12', gridRow = 'span 1', required, showLabel = true, } = schema;
7482
7590
  const colLabel = `${prefix}${column}`;
7483
7591
  const isRequired = required?.some((columnId) => columnId === column);
7592
+ const formI18n = useFormI18n$1(column, prefix, schema);
7484
7593
  const { formState: { errors }, } = useFormContext();
7485
7594
  if (properties === undefined) {
7486
7595
  throw new Error(`properties is undefined when using ObjectInput`);
7487
7596
  }
7488
- return (jsxs(Box, { gridRow, gridColumn, children: [showLabel && (jsxs(Box, { as: "label", children: [`${translate.t(removeIndex(`${colLabel}.field_label`))}`, isRequired && jsx("span", { children: "*" })] })), jsx(Grid, { gap: "4", padding: "4", gridTemplateColumns: "repeat(12, 1fr)", autoFlow: "row", bgColor: { base: "colorPalette.100", _dark: "colorPalette.900" }, p: "1", borderRadius: "md", borderWidth: "thin", borderColor: {
7489
- base: "colorPalette.200",
7490
- _dark: "colorPalette.800",
7597
+ return (jsxs(Box, { gridRow, gridColumn, children: [showLabel && (jsxs(Box, { as: "label", children: [formI18n.label(), isRequired && jsx("span", { children: "*" })] })), jsx(Grid, { gap: "4", padding: '4', gridTemplateColumns: 'repeat(12, 1fr)', autoFlow: 'row', bgColor: { base: 'colorPalette.100', _dark: 'colorPalette.900' }, p: '1', borderRadius: 'md', borderWidth: 'thin', borderColor: {
7598
+ base: 'colorPalette.200',
7599
+ _dark: 'colorPalette.800',
7491
7600
  }, children: Object.keys(properties ?? {}).map((key) => {
7492
7601
  return (
7493
7602
  // @ts-expect-error find suitable types
7494
7603
  jsx(ColumnViewer, { column: `${key}`,
7495
7604
  prefix: `${prefix}${column}.`,
7496
7605
  properties }, `form-objectviewer-${colLabel}-${key}`));
7497
- }) }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
7606
+ }) }), errors[`${column}`] && (jsx(Text, { color: 'red.400', children: formI18n.required() }))] }));
7498
7607
  };
7499
7608
 
7500
- const RecordInput = ({ column, schema, prefix }) => {
7501
- const { formState: { errors }, setValue, getValues, } = useFormContext();
7502
- const { translate } = useSchemaContext();
7503
- const { required, gridColumn = "span 12", gridRow = "span 1" } = schema;
7609
+ const RecordViewer = ({ column, schema, prefix }) => {
7610
+ const { formState: { errors }, getValues, } = useFormContext();
7611
+ const { required, gridColumn = 'span 12', gridRow = 'span 1' } = schema;
7504
7612
  const isRequired = required?.some((columnId) => columnId === column);
7505
7613
  const entries = Object.entries(getValues(column) ?? {});
7506
- const [showNewEntries, setShowNewEntries] = useState(false);
7507
- const [newKey, setNewKey] = useState();
7508
- const [newValue, setNewValue] = useState();
7509
- return (jsxs(Field, { label: `${translate.t(`${column}.field_label`)}`, required: isRequired, alignItems: "stretch", gridColumn, gridRow, children: [entries.map(([key, value]) => {
7510
- return (jsxs(Grid, { templateColumns: "1fr 1fr auto", gap: 1, children: [jsx(Input, { value: key, onChange: (e) => {
7511
- const filtered = entries.filter(([target]) => {
7512
- return target !== key;
7513
- });
7514
- setValue(column, Object.fromEntries([...filtered, [e.target.value, value]]));
7515
- }, autoComplete: "off" }), jsx(Input, { value: value, onChange: (e) => {
7516
- setValue(column, {
7517
- ...getValues(column),
7518
- [key]: e.target.value,
7519
- });
7520
- }, autoComplete: "off" }), jsx(IconButton, { variant: "ghost", onClick: () => {
7521
- const filtered = entries.filter(([target]) => {
7522
- return target !== key;
7523
- });
7524
- setValue(column, Object.fromEntries([...filtered]));
7525
- }, children: jsx(CgClose, {}) })] }));
7526
- }), jsx(Show, { when: showNewEntries, children: jsxs(Card.Root, { children: [jsx(Card.Body, { gap: "2", children: jsxs(Grid, { templateColumns: "1fr 1fr auto", gap: 1, children: [jsx(Input, { value: newKey, onChange: (e) => {
7527
- setNewKey(e.target.value);
7528
- }, autoComplete: "off" }), jsx(Input, { value: newValue, onChange: (e) => {
7529
- setNewValue(e.target.value);
7530
- }, autoComplete: "off" })] }) }), jsxs(Card.Footer, { justifyContent: "flex-end", children: [jsx(IconButton, { variant: "subtle", onClick: () => {
7531
- setShowNewEntries(false);
7532
- setNewKey(undefined);
7533
- setNewValue(undefined);
7534
- }, children: jsx(CgClose, {}) }), jsx(Button, { onClick: () => {
7535
- if (!!newKey === false) {
7536
- setShowNewEntries(false);
7537
- setNewKey(undefined);
7538
- setNewValue(undefined);
7539
- return;
7540
- }
7541
- setValue(column, Object.fromEntries([...entries, [newKey, newValue]]));
7542
- setShowNewEntries(false);
7543
- setNewKey(undefined);
7544
- setNewValue(undefined);
7545
- }, children: translate.t(`${column}.save`) })] })] }) }), jsx(Button, { onClick: () => {
7546
- setShowNewEntries(true);
7547
- setNewKey(undefined);
7548
- setNewValue(undefined);
7549
- }, children: translate.t(`${column}.addNew`) }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: translate.t(`${column}.field_required`) }))] }));
7614
+ const formI18n = useFormI18n$1(column, prefix, schema);
7615
+ return (jsxs(Field, { label: formI18n.label(), required: isRequired, alignItems: 'stretch', gridColumn, gridRow, children: [entries.length === 0 ? (jsx(Text, { color: "gray.500", children: "No entries" })) : (jsx(Grid, { templateColumns: '1fr 1fr', gap: 2, children: entries.map(([key, value]) => {
7616
+ return (jsxs(Grid, { templateColumns: '1fr 1fr', gap: 2, children: [jsxs(Text, { fontWeight: "medium", children: [key, ":"] }), jsx(Text, { children: String(value ?? '') })] }, key));
7617
+ }) })), errors[`${column}`] && (jsx(Text, { color: 'red.400', children: formI18n.required() }))] }));
7550
7618
  };
7551
7619
 
7552
7620
  const StringViewer = ({ column, schema, prefix, }) => {
7553
7621
  const { watch, formState: { errors }, } = useFormContext();
7554
- const { translate } = useSchemaContext();
7555
- const { required, gridColumn = "span 12", gridRow = "span 1" } = schema;
7622
+ const { required, gridColumn = 'span 12', gridRow = 'span 1' } = schema;
7556
7623
  const isRequired = required?.some((columnId) => columnId === column);
7557
7624
  const colLabel = `${prefix}${column}`;
7558
7625
  const value = watch(colLabel);
7559
- return (jsx(Fragment, { children: jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, gridColumn: gridColumn ?? "span 4", gridRow: gridRow ?? "span 1", children: [jsx(Text, { children: value }), errors[colLabel] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }) }));
7626
+ const formI18n = useFormI18n$1(column, prefix, schema);
7627
+ return (jsx(Fragment, { children: jsxs(Field, { label: formI18n.label(), required: isRequired, gridColumn: gridColumn ?? 'span 4', gridRow: gridRow ?? 'span 1', children: [jsx(Text, { children: value }), errors[colLabel] && (jsx(Text, { color: 'red.400', children: formI18n.required() }))] }) }));
7560
7628
  };
7561
7629
 
7562
7630
  const TagViewer = ({ column, schema, prefix }) => {
@@ -7646,40 +7714,44 @@ const TagViewer = ({ column, schema, prefix }) => {
7646
7714
 
7647
7715
  const TextAreaViewer = ({ column, schema, prefix, }) => {
7648
7716
  const { watch, formState: { errors }, } = useFormContext();
7649
- const { translate } = useSchemaContext();
7650
- const { required, gridColumn = "span 12", gridRow = "span 1" } = schema;
7717
+ const { required, gridColumn = 'span 12', gridRow = 'span 1' } = schema;
7651
7718
  const isRequired = required?.some((columnId) => columnId === column);
7652
7719
  const colLabel = `${prefix}${column}`;
7653
7720
  const value = watch(colLabel);
7654
- return (jsx(Fragment, { children: jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, gridColumn: gridColumn, gridRow: gridRow, children: [jsx(Text, { whiteSpace: "pre-wrap", children: value }), " ", errors[colLabel] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }) }));
7721
+ const formI18n = useFormI18n$1(column, prefix, schema);
7722
+ return (jsx(Fragment, { children: jsxs(Field, { label: formI18n.label(), required: isRequired, gridColumn: gridColumn, gridRow: gridRow, children: [jsx(Text, { whiteSpace: "pre-wrap", children: value }), ' ', errors[colLabel] && (jsx(Text, { color: 'red.400', children: formI18n.required() }))] }) }));
7655
7723
  };
7656
7724
 
7657
7725
  const TimeViewer = ({ column, schema, prefix }) => {
7658
7726
  const { watch, formState: { errors }, } = useFormContext();
7659
- const { translate, timezone } = useSchemaContext();
7660
- const { required, gridColumn = "span 12", gridRow = "span 1", displayTimeFormat = "hh:mm A", } = schema;
7727
+ const { timezone } = useSchemaContext();
7728
+ const { required, gridColumn = 'span 12', gridRow = 'span 1', displayTimeFormat = 'hh:mm A', } = schema;
7661
7729
  const isRequired = required?.some((columnId) => columnId === column);
7662
7730
  const colLabel = `${prefix}${column}`;
7663
7731
  const selectedDate = watch(colLabel);
7732
+ const formI18n = useFormI18n$1(column, prefix, schema);
7664
7733
  const displayedTime = dayjs(`1970-01-01T${selectedDate}`)
7665
7734
  .tz(timezone)
7666
7735
  .isValid()
7667
7736
  ? dayjs(`1970-01-01T${selectedDate}`).tz(timezone).format(displayTimeFormat)
7668
- : "";
7669
- return (jsxs(Field, { label: `${translate.t(removeIndex(`${column}.field_label`))}`, required: isRequired, alignItems: "stretch", gridColumn,
7670
- gridRow, children: [jsx(Text, { children: displayedTime }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: translate.t(`${column}.field_required`) }))] }));
7737
+ : '';
7738
+ return (jsxs(Field, { label: formI18n.label(), required: isRequired, alignItems: 'stretch', gridColumn,
7739
+ gridRow, children: [jsx(Text, { children: displayedTime }), errors[`${column}`] && (jsx(Text, { color: 'red.400', children: formI18n.required() }))] }));
7671
7740
  };
7672
7741
 
7673
7742
  const DateTimeViewer = ({ column, schema, prefix }) => {
7674
7743
  const { watch, formState: { errors }, } = useFormContext();
7675
- const { translate, timezone } = useSchemaContext();
7676
- const { required, gridColumn = "span 4", gridRow = "span 1", displayDateFormat = "YYYY-MM-DD HH:mm:ss", } = schema;
7744
+ const { timezone } = useSchemaContext();
7745
+ const { required, gridColumn = 'span 4', gridRow = 'span 1', displayDateFormat = 'YYYY-MM-DD HH:mm:ss', } = schema;
7677
7746
  const isRequired = required?.some((columnId) => columnId === column);
7678
7747
  const colLabel = `${prefix}${column}`;
7679
7748
  const selectedDate = watch(colLabel);
7680
- const displayDate = dayjs(selectedDate).tz(timezone).format(displayDateFormat);
7681
- return (jsxs(Field, { label: `${translate.t(removeIndex(`${column}.field_label`))}`, required: isRequired, alignItems: "stretch", gridColumn,
7682
- gridRow, children: [jsxs(Text, { children: [" ", selectedDate !== undefined ? displayDate : ""] }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: translate.t(`${column}.field_required`) }))] }));
7749
+ const formI18n = useFormI18n$1(column, prefix, schema);
7750
+ const displayDate = dayjs(selectedDate)
7751
+ .tz(timezone)
7752
+ .format(displayDateFormat);
7753
+ return (jsxs(Field, { label: formI18n.label(), required: isRequired, alignItems: 'stretch', gridColumn,
7754
+ gridRow, children: [jsxs(Text, { children: [" ", selectedDate !== undefined ? displayDate : ''] }), errors[`${column}`] && (jsx(Text, { color: 'red.400', children: formI18n.required() }))] }));
7683
7755
  };
7684
7756
 
7685
7757
  const SchemaViewer = ({ schema, prefix, column, }) => {
@@ -7720,7 +7792,7 @@ const SchemaViewer = ({ schema, prefix, column, }) => {
7720
7792
  if (innerProperties) {
7721
7793
  return jsx(ObjectViewer, { schema: colSchema, prefix, column });
7722
7794
  }
7723
- return jsx(RecordInput, { schema: colSchema, prefix, column });
7795
+ return jsx(RecordViewer, { schema: colSchema, prefix, column });
7724
7796
  }
7725
7797
  if (type === 'array') {
7726
7798
  if (variant === 'id-picker') {
@@ -7768,7 +7840,7 @@ const ColumnViewer = ({ column, properties, prefix, }) => {
7768
7840
  };
7769
7841
 
7770
7842
  const SubmitButton = () => {
7771
- const { translate, setValidatedData, setIsError, setIsConfirming, setError, schema, requireConfirmation, onFormSubmit, } = useSchemaContext();
7843
+ const { translate, setValidatedData, setIsError, setIsConfirming, requireConfirmation, onFormSubmit, formButtonLabels, } = useSchemaContext();
7772
7844
  const methods = useFormContext();
7773
7845
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
7774
7846
  const onValid = (data) => {
@@ -7797,11 +7869,11 @@ const SubmitButton = () => {
7797
7869
  };
7798
7870
  return (jsx(Button$1, { onClick: () => {
7799
7871
  methods.handleSubmit(onValid)();
7800
- }, formNoValidate: true, children: translate.t('submit') }));
7872
+ }, formNoValidate: true, children: formButtonLabels?.submit ?? translate.t('submit') }));
7801
7873
  };
7802
7874
 
7803
7875
  const FormBody = () => {
7804
- const { schema, order, ignore, include, translate, isSuccess, setIsSuccess, isError, setIsError, isSubmiting, setIsSubmiting, isConfirming, setIsConfirming, validatedData, setValidatedData, error, getUpdatedData, customErrorRenderer, customSuccessRenderer, displayConfig, onFormSubmit, } = useSchemaContext();
7876
+ const { schema, order, ignore, include, translate, isSuccess, setIsSuccess, isError, setIsError, isSubmiting, setIsSubmiting, isConfirming, setIsConfirming, validatedData, setValidatedData, error, getUpdatedData, customErrorRenderer, customSuccessRenderer, displayConfig, onFormSubmit, formButtonLabels, } = useSchemaContext();
7805
7877
  const { showSubmitButton, showResetButton } = displayConfig;
7806
7878
  const methods = useFormContext();
7807
7879
  const { properties } = schema;
@@ -7831,7 +7903,7 @@ const FormBody = () => {
7831
7903
  if (customSuccessRenderer) {
7832
7904
  return customSuccessRenderer(resetHandler);
7833
7905
  }
7834
- 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') }) })] }));
7906
+ 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: formButtonLabels?.submitAgain ?? translate.t('submit_again') }) })] }));
7835
7907
  }
7836
7908
  if (isConfirming) {
7837
7909
  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) => {
@@ -7842,9 +7914,9 @@ const FormBody = () => {
7842
7914
  properties: properties, prefix: ``, column }, `form-viewer-${column}`));
7843
7915
  }) }), jsxs(Flex, { justifyContent: 'end', gap: '2', children: [jsx(Button$1, { onClick: () => {
7844
7916
  setIsConfirming(false);
7845
- }, variant: 'subtle', children: translate.t('cancel') }), jsx(Button$1, { onClick: () => {
7917
+ }, variant: 'subtle', children: formButtonLabels?.cancel ?? translate.t('cancel') }), jsx(Button$1, { onClick: () => {
7846
7918
  onFormSubmit(validatedData);
7847
- }, children: translate.t('confirm') })] }), isSubmiting && (jsx(Box, { pos: "absolute", inset: "0", bg: "bg/80", children: jsx(Center, { h: "full", children: jsx(Spinner, { color: "teal.500" }) }) })), isError && customErrorRenderer && customErrorRenderer(error)] }));
7919
+ }, children: formButtonLabels?.confirm ?? translate.t('confirm') })] }), isSubmiting && (jsx(Box, { pos: "absolute", inset: "0", bg: "bg/80", children: jsx(Center, { h: "full", children: jsx(Spinner, { color: "teal.500" }) }) })), isError && customErrorRenderer && customErrorRenderer(error)] }));
7848
7920
  }
7849
7921
  return (jsxs(Flex, { flexFlow: 'column', gap: "2", children: [jsx(Grid, { gap: "4", gridTemplateColumns: 'repeat(12, 1fr)', autoFlow: 'row', children: ordered.map((column) => {
7850
7922
  return (jsx(ColumnRenderer
@@ -7854,7 +7926,7 @@ const FormBody = () => {
7854
7926
  properties: properties, prefix: ``, parentRequired: schema.required, column }, `form-input-${column}`));
7855
7927
  }) }), jsxs(Flex, { justifyContent: 'end', gap: "2", children: [showResetButton && (jsx(Button$1, { onClick: () => {
7856
7928
  methods.reset();
7857
- }, variant: 'subtle', children: translate.t('reset') })), showSubmitButton && jsx(SubmitButton, {})] }), isError && customErrorRenderer && customErrorRenderer(error)] }));
7929
+ }, variant: 'subtle', children: formButtonLabels?.reset ?? translate.t('reset') })), showSubmitButton && jsx(SubmitButton, {})] }), isError && customErrorRenderer && customErrorRenderer(error)] }));
7858
7930
  };
7859
7931
 
7860
7932
  const FormTitle = () => {
@@ -8173,7 +8245,6 @@ const TableDataDisplay = ({ colorPalette, emptyComponent, }) => {
8173
8245
  return `minmax(${size}px, ${(size / totalWidths) * 100}%)`;
8174
8246
  })
8175
8247
  .join(' ');
8176
- console.log({ columnWidths }, 'hadfg');
8177
8248
  const cellProps = {
8178
8249
  flex: '1 0 0%',
8179
8250
  overflow: 'auto',
@@ -8190,22 +8261,22 @@ const TableDataDisplay = ({ colorPalette, emptyComponent, }) => {
8190
8261
  }
8191
8262
  return (jsxs(Grid, { templateColumns: `${columnWidths}`, overflow: 'auto', borderWidth: '1px', color: { base: 'colorPalette.900', _dark: 'colorPalette.100' }, borderColor: { base: 'colorPalette.200', _dark: 'colorPalette.800' }, colorPalette, children: [jsx(Grid, { templateColumns: `${columnWidths}`, column: `1/span ${columns.length}`, bg: { base: 'colorPalette.200', _dark: 'colorPalette.800' }, colorPalette, children: columnHeaders.map((header) => {
8192
8263
  const columnDef = columnsMap[header];
8193
- return (jsx(Box, { flex: '1 0 0%', paddingX: '2', py: '1', overflow: 'auto', textOverflow: 'ellipsis', children: columnDef?.meta?.displayName ?? header }));
8194
- }) }), data.map((record) => {
8195
- return (jsx(Fragment, { children: columnHeaders.map((header) => {
8264
+ return (jsx(Box, { flex: '1 0 0%', paddingX: '2', py: '1', overflow: 'auto', textOverflow: 'ellipsis', children: columnDef?.meta?.displayName ?? header }, `chakra-table-header-${header}`));
8265
+ }) }), data.map((record, recordIndex) => {
8266
+ return (jsx(Box, { display: "contents", children: columnHeaders.map((header) => {
8196
8267
  const { cell } = columnsMap[header];
8197
8268
  const value = record[header];
8198
8269
  if (!!record === false) {
8199
- return (jsx(Box, { ...cellProps }));
8270
+ return (jsx(Box, { ...cellProps }, `chakra-table-cell-${recordIndex}-${header}`));
8200
8271
  }
8201
8272
  if (cell) {
8202
- return (jsx(Box, { ...cellProps, children: cell({ row: { original: record } }) }));
8273
+ return (jsx(Box, { ...cellProps, children: cell({ row: { original: record } }) }, `chakra-table-cell-${recordIndex}-${header}`));
8203
8274
  }
8204
8275
  if (typeof value === 'object') {
8205
- return (jsx(Box, { ...cellProps, children: jsx(RecordDisplay, { object: value }) }));
8276
+ return (jsx(Box, { ...cellProps, children: jsx(RecordDisplay, { object: value }) }, `chakra-table-cell-${recordIndex}-${header}`));
8206
8277
  }
8207
- return jsx(Box, { ...cellProps, children: value });
8208
- }) }));
8278
+ return (jsx(Box, { ...cellProps, children: value }, `chakra-table-cell-${recordIndex}-${header}`));
8279
+ }) }, `chakra-table-record-${recordIndex}`));
8209
8280
  })] }));
8210
8281
  };
8211
8282
 
@@ -8358,19 +8429,19 @@ const DataDisplay = ({ variant = '' }) => {
8358
8429
  return cell.id === `${rowId}_${column.id}`;
8359
8430
  });
8360
8431
  if (column.columns.length > 0) {
8361
- return (jsxs(Card.Root, { margin: '1', gridColumn: 'span 12', children: [jsx(Card.Header, { color: 'gray.400', children: column.columnDef.meta?.displayName ?? column.id }), jsx(Card.Body, { display: 'grid', gap: '4', gridTemplateColumns: 'repeat(12, 1fr)', children: column.columns.map((column) => {
8362
- if (!column.getIsVisible()) {
8363
- return jsx(Fragment, {});
8432
+ return (jsxs(Card.Root, { margin: '1', gridColumn: 'span 12', children: [jsx(Card.Header, { color: 'gray.400', children: column.columnDef.meta?.displayName ?? column.id }), jsx(Card.Body, { display: 'grid', gap: '4', gridTemplateColumns: 'repeat(12, 1fr)', children: column.columns.map((subColumn) => {
8433
+ if (!subColumn.getIsVisible()) {
8434
+ return null;
8364
8435
  }
8365
8436
  const foundCell = row
8366
8437
  .getVisibleCells()
8367
8438
  .find((cell) => {
8368
- return cell.id === `${rowId}_${column.id}`;
8439
+ return cell.id === `${rowId}_${subColumn.id}`;
8369
8440
  });
8370
- return jsx(CellRenderer, { cell: foundCell });
8371
- }) })] }, `chakra-table-card-${childCell?.id}`));
8441
+ return (jsx(CellRenderer, { cell: foundCell }, `chakra-table-cell-${rowId}-${subColumn.id}`));
8442
+ }) })] }, `chakra-table-card-${rowId}-${column.id}`));
8372
8443
  }
8373
- return jsx(CellRenderer, { cell: childCell });
8444
+ return (jsx(CellRenderer, { cell: childCell }, `chakra-table-cell-${rowId}-${column.id}`));
8374
8445
  }) }) }, `chakra-table-card-${rowId}`));
8375
8446
  }) }));
8376
8447
  };
@@ -8665,4 +8736,4 @@ function DataTableServer({ columns, enableRowSelection = true, enableMultiRowSel
8665
8736
  }, children: jsx(DataTableServerContext.Provider, { value: { url, query }, children: children }) }));
8666
8737
  }
8667
8738
 
8668
- export { CardHeader, DataDisplay, DataTable, DataTableServer, DatePickerInput, DefaultCardTitle, DefaultForm, DefaultTable, DefaultTableServer, DensityToggleButton, EditSortingButton, EmptyState, ErrorAlert, FilterDialog, FormBody, FormRoot, FormTitle, GlobalFilter, MediaLibraryBrowser, PageSizeControl, Pagination, RecordDisplay, ReloadButton, ResetFilteringButton, ResetSelectionButton, ResetSortingButton, RowCountText, SelectAllRowsToggle, Table, TableBody, TableCardContainer, TableCards, TableComponent, TableControls, TableDataDisplay, TableFilter, TableFilterTags, TableFooter, TableHeader, TableLoadingComponent, TableSelector, TableSorter, TableViewer, TextCell, ViewDialog, buildErrorMessages, buildFieldErrors, buildRequiredErrors, convertToAjvErrorsFormat, createErrorMessage, getColumns, getMultiDates, getRangeDates, idPickerSanityCheck, useDataTable, useDataTableContext, useDataTableServer, useForm, widthSanityCheck };
8739
+ export { CardHeader, DataDisplay, DataTable, DataTableServer, DatePickerInput, DefaultCardTitle, DefaultForm, DefaultTable, DefaultTableServer, DensityToggleButton, EditSortingButton, EmptyState, ErrorAlert, FilterDialog, FormBody, FormRoot, FormTitle, GlobalFilter, MediaLibraryBrowser, PageSizeControl, Pagination, RecordDisplay, ReloadButton, ResetFilteringButton, ResetSelectionButton, ResetSortingButton, RowCountText, SelectAllRowsToggle, Table, TableBody, TableCardContainer, TableCards, TableComponent, TableControls, TableDataDisplay, TableFilter, TableFilterTags, TableFooter, TableHeader, TableLoadingComponent, TableSelector, TableSorter, TableViewer, TextCell, ViewDialog, buildErrorMessages, buildFieldErrors, buildRequiredErrors, convertToAjvErrorsFormat, createErrorMessage, defaultRenderDisplay, getColumns, getMultiDates, getRangeDates, idPickerSanityCheck, useDataTable, useDataTableContext, useDataTableServer, useForm, widthSanityCheck };