@bsol-oss/react-datatable5 13.0.1-beta.14 → 13.0.1-beta.16

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
@@ -130,8 +130,6 @@ interface TableControlsProps {
130
130
  children?: ReactNode;
131
131
  showGlobalFilter?: boolean;
132
132
  showFilter?: boolean;
133
- showFilterName?: boolean;
134
- showFilterTags?: boolean;
135
133
  showReload?: boolean;
136
134
  showPagination?: boolean;
137
135
  showPageSizeControl?: boolean;
@@ -149,7 +147,7 @@ interface TableControlsProps {
149
147
  hasError?: boolean;
150
148
  gridProps?: GridProps;
151
149
  }
152
- declare const TableControls: ({ fitTableWidth, fitTableHeight, children, showGlobalFilter, showFilter, showFilterName, showFilterTags, showReload, showPagination, showPageSizeControl, showPageCountText, showView, filterTagsOptions, extraItems, loading, hasError, gridProps, }: TableControlsProps) => react_jsx_runtime.JSX.Element;
150
+ declare const TableControls: ({ fitTableWidth, fitTableHeight, children, showGlobalFilter, showFilter, showReload, showPagination, showPageSizeControl, showPageCountText, showView, filterTagsOptions, extraItems, loading, hasError, gridProps, }: TableControlsProps) => react_jsx_runtime.JSX.Element;
153
151
 
154
152
  declare const TableFilter: () => react_jsx_runtime.JSX.Element;
155
153
 
@@ -322,7 +320,7 @@ interface UseDataTableReturn {
322
320
  }
323
321
  declare const useDataTable: ({ default: { sorting: defaultSorting, pagination: defaultPagination, rowSelection: defaultRowSelection, columnFilters: defaultColumnFilters, columnOrder: defaultColumnOrder, columnVisibility: defaultColumnVisibility, globalFilter: defaultGlobalFilter, density: defaultDensity, }, }?: UseDataTableProps) => UseDataTableReturn;
324
322
 
325
- interface UseDataTableServerProps<TData> extends Omit<UseDataTableProps, 'keyPrefix'> {
323
+ interface UseDataTableServerProps<TData> extends UseDataTableProps {
326
324
  /**
327
325
  * Delay to send the request if the `refreshData` called multiple times
328
326
  *
@@ -511,11 +509,10 @@ interface Translate {
511
509
  }
512
510
  interface UseFormProps {
513
511
  preLoadedValues?: FieldValues | undefined;
514
- keyPrefix?: string;
515
512
  namespace?: string;
516
513
  schema?: JSONSchema7;
517
514
  }
518
- declare const useForm: ({ preLoadedValues, keyPrefix: _keyPrefix, namespace: _namespace, schema, }: UseFormProps) => {
515
+ declare const useForm: ({ preLoadedValues, namespace: _namespace, schema, }: UseFormProps) => {
519
516
  form: react_hook_form.UseFormReturn<FieldValues, any, undefined>;
520
517
  idMap: Record<string, object>;
521
518
  setIdMap: React$1.Dispatch<React$1.SetStateAction<Record<string, object>>>;
@@ -702,16 +699,15 @@ declare const convertToAjvErrorsFormat: (errorMessages: ErrorMessageResult) => R
702
699
  * );
703
700
  * // Result: { username: "This field is required", email: "This field is required" }
704
701
  *
705
- * // With keyPrefix for i18n
702
+ * // With prefix in generator function
706
703
  * const required = buildRequiredErrors(
707
704
  * ["username", "email"],
708
- * (field) => `${field}.field_required`,
709
- * "user"
705
+ * (field) => `user.${field}.field_required`
710
706
  * );
711
707
  * // Result: { username: "user.username.field_required", email: "user.email.field_required" }
712
708
  * ```
713
709
  */
714
- declare const buildRequiredErrors: (fields: string[], messageOrGenerator: string | ((field: string) => string), keyPrefix?: string) => Record<string, string>;
710
+ declare const buildRequiredErrors: (fields: string[], messageOrGenerator: string | ((field: string) => string)) => Record<string, string>;
715
711
  /**
716
712
  * Helper function to build field-specific validation errors
717
713
  *
package/dist/index.js CHANGED
@@ -3198,19 +3198,31 @@ const TableSelector = () => {
3198
3198
  }, "aria-label": 'reset selection', children: jsxRuntime.jsx(md.MdClear, {}) }))] }));
3199
3199
  };
3200
3200
 
3201
+ const Tag = React__namespace.forwardRef(function Tag(props, ref) {
3202
+ const { startElement, endElement, onClose, closable = !!onClose, children, ...rest } = props;
3203
+ return (jsxRuntime.jsxs(react.Tag.Root, { ref: ref, ...rest, children: [startElement && (jsxRuntime.jsx(react.Tag.StartElement, { children: startElement })), jsxRuntime.jsx(react.Tag.Label, { children: children }), endElement && (jsxRuntime.jsx(react.Tag.EndElement, { children: endElement })), closable && (jsxRuntime.jsx(react.Tag.EndElement, { children: jsxRuntime.jsx(react.Tag.CloseTrigger, { onClick: onClose }) }))] }));
3204
+ });
3205
+
3201
3206
  const Checkbox = React__namespace.forwardRef(function Checkbox(props, ref) {
3202
3207
  const { icon, children, inputProps, rootRef, ...rest } = props;
3203
3208
  return (jsxRuntime.jsxs(react.Checkbox.Root, { ref: rootRef, ...rest, children: [jsxRuntime.jsx(react.Checkbox.HiddenInput, { ref: ref, ...inputProps }), jsxRuntime.jsx(react.Checkbox.Control, { children: icon || jsxRuntime.jsx(react.Checkbox.Indicator, {}) }), children != null && (jsxRuntime.jsx(react.Checkbox.Label, { children: children }))] }));
3204
3209
  });
3205
3210
 
3206
- const ColumnFilterMenu = ({ displayName, filterOptions, filterVariant, colorPalette, value: controlledValue, onChange, labels, }) => {
3211
+ const ColumnFilterMenu = ({ displayName, filterOptions, filterVariant, colorPalette, value: controlledValue, onChange, labels, open: controlledOpen, onOpenChange, }) => {
3207
3212
  const [searchTerm, setSearchTerm] = React.useState('');
3208
3213
  const debouncedSearchTerm = usehooks.useDebounce(searchTerm, 300);
3209
- const [isOpen, setIsOpen] = React.useState(false);
3214
+ const [internalOpen, setInternalOpen] = React.useState(false);
3215
+ // Use controlled open state if provided, otherwise use internal state
3216
+ const isOpen = controlledOpen !== undefined ? controlledOpen : internalOpen;
3217
+ const handleOpenChange = (details) => {
3218
+ if (onOpenChange) {
3219
+ onOpenChange(details.open);
3220
+ }
3221
+ else {
3222
+ setInternalOpen(details.open);
3223
+ }
3224
+ };
3210
3225
  const [internalValue, setInternalValue] = React.useState(undefined);
3211
- const [pendingFilterValue, setPendingFilterValue] = React.useState(undefined);
3212
- const debouncedFilterValue = usehooks.useDebounce(pendingFilterValue, 300);
3213
- const lastAppliedValueRef = React.useRef('__INITIAL__');
3214
3226
  // Use controlled value if provided, otherwise use internal state
3215
3227
  const currentFilterValue = controlledValue !== undefined ? controlledValue : internalValue;
3216
3228
  const isArrayFilter = filterVariant === 'tag';
@@ -3221,31 +3233,20 @@ const ColumnFilterMenu = ({ displayName, filterOptions, filterVariant, colorPale
3221
3233
  noFiltersMatchText: 'No filters match your search',
3222
3234
  };
3223
3235
  const finalLabels = { ...defaultLabels, ...labels };
3224
- // Apply debounced filter value via onChange callback
3236
+ // Reset search term when menu closes
3225
3237
  React.useEffect(() => {
3226
- const currentKey = JSON.stringify(debouncedFilterValue);
3227
- // Only apply if the value has changed from what we last applied
3228
- if (currentKey !== lastAppliedValueRef.current) {
3229
- if (onChange) {
3230
- onChange(debouncedFilterValue);
3231
- }
3232
- else {
3233
- setInternalValue(debouncedFilterValue);
3234
- }
3235
- lastAppliedValueRef.current = currentKey;
3238
+ if (!isOpen) {
3239
+ setSearchTerm('');
3240
+ }
3241
+ }, [isOpen]);
3242
+ // Filter update function
3243
+ const setFilterValue = (value) => {
3244
+ if (onChange) {
3245
+ onChange(value);
3246
+ }
3247
+ else {
3248
+ setInternalValue(value);
3236
3249
  }
3237
- }, [debouncedFilterValue, onChange]);
3238
- // Sync internal value when controlled value changes
3239
- React.useEffect(() => {
3240
- if (controlledValue !== undefined) {
3241
- setInternalValue(controlledValue);
3242
- setPendingFilterValue(controlledValue);
3243
- lastAppliedValueRef.current = JSON.stringify(controlledValue);
3244
- }
3245
- }, [controlledValue]);
3246
- // Debounced filter update function
3247
- const debouncedSetFilterValue = (value) => {
3248
- setPendingFilterValue(value);
3249
3250
  };
3250
3251
  // Get active count for this column
3251
3252
  const activeCount = React.useMemo(() => {
@@ -3264,7 +3265,7 @@ const ColumnFilterMenu = ({ displayName, filterOptions, filterVariant, colorPale
3264
3265
  const searchLower = debouncedSearchTerm.toLowerCase();
3265
3266
  return filterOptions.filter((option) => option.label.toLowerCase().includes(searchLower));
3266
3267
  }, [filterOptions, debouncedSearchTerm]);
3267
- return (jsxRuntime.jsxs(MenuRoot, { open: isOpen, onOpenChange: (details) => setIsOpen(details.open), children: [jsxRuntime.jsx(MenuTrigger, { asChild: true, children: jsxRuntime.jsxs(react.Button, { variant: "outline", size: "sm", gap: 2, children: [jsxRuntime.jsx(react.Icon, { as: md.MdFilterList }), jsxRuntime.jsxs(react.Text, { children: [displayName, " ", activeCount > 0 && `(${activeCount})`] })] }) }), jsxRuntime.jsx(MenuContent, { maxW: "20rem", minW: "18rem", children: jsxRuntime.jsxs(react.VStack, { align: "stretch", gap: 2, p: 2, children: [jsxRuntime.jsxs(react.Heading, { size: "sm", px: 2, children: [finalLabels.filterByLabel, " ", displayName] }), jsxRuntime.jsx(InputGroup, { startElement: jsxRuntime.jsx(react.Icon, { as: md.MdSearch }), children: jsxRuntime.jsx(react.Input, { placeholder: finalLabels.filterLabelsPlaceholder, value: searchTerm, onChange: (e) => setSearchTerm(e.target.value) }) }), jsxRuntime.jsx(react.Box, { maxH: "20rem", overflowY: "auto", css: {
3268
+ return (jsxRuntime.jsxs(MenuRoot, { open: isOpen, onOpenChange: handleOpenChange, children: [jsxRuntime.jsx(MenuTrigger, { asChild: true, children: jsxRuntime.jsxs(react.Button, { variant: "outline", size: "sm", gap: 2, children: [jsxRuntime.jsx(react.Icon, { as: md.MdFilterList }), jsxRuntime.jsxs(react.Text, { children: [displayName, " ", activeCount > 0 && `(${activeCount})`] })] }) }), jsxRuntime.jsx(MenuContent, { maxW: "20rem", minW: "18rem", children: jsxRuntime.jsxs(react.VStack, { align: "stretch", gap: 2, p: 2, children: [jsxRuntime.jsxs(react.Heading, { size: "sm", px: 2, children: [finalLabels.filterByLabel, " ", displayName] }), jsxRuntime.jsx(InputGroup, { startElement: jsxRuntime.jsx(react.Icon, { as: md.MdSearch }), children: jsxRuntime.jsx(react.Input, { placeholder: finalLabels.filterLabelsPlaceholder, value: searchTerm, onChange: (e) => setSearchTerm(e.target.value) }) }), jsxRuntime.jsx(react.Box, { maxH: "20rem", overflowY: "auto", css: {
3268
3269
  '&::-webkit-scrollbar': {
3269
3270
  width: '8px',
3270
3271
  },
@@ -3290,29 +3291,26 @@ const ColumnFilterMenu = ({ displayName, filterOptions, filterVariant, colorPale
3290
3291
  // Remove from filter
3291
3292
  const newArray = currentArray.filter((v) => v !== option.value);
3292
3293
  if (newArray.length === 0) {
3293
- debouncedSetFilterValue(undefined);
3294
+ setFilterValue(undefined);
3294
3295
  }
3295
3296
  else {
3296
- debouncedSetFilterValue(newArray);
3297
+ setFilterValue(newArray);
3297
3298
  }
3298
3299
  }
3299
3300
  else {
3300
3301
  // Add to filter
3301
3302
  if (!currentArray.includes(option.value)) {
3302
- debouncedSetFilterValue([
3303
- ...currentArray,
3304
- option.value,
3305
- ]);
3303
+ setFilterValue([...currentArray, option.value]);
3306
3304
  }
3307
3305
  }
3308
3306
  }
3309
3307
  else {
3310
3308
  // Handle single value filters (select variant)
3311
3309
  if (isActive) {
3312
- debouncedSetFilterValue(undefined);
3310
+ setFilterValue(undefined);
3313
3311
  }
3314
3312
  else {
3315
- debouncedSetFilterValue(option.value);
3313
+ setFilterValue(option.value);
3316
3314
  }
3317
3315
  }
3318
3316
  };
@@ -3327,7 +3325,7 @@ const ColumnFilterMenu = ({ displayName, filterOptions, filterVariant, colorPale
3327
3325
  if (details.checked) {
3328
3326
  // Add to filter
3329
3327
  if (!currentArray.includes(option.value)) {
3330
- debouncedSetFilterValue([
3328
+ setFilterValue([
3331
3329
  ...currentArray,
3332
3330
  option.value,
3333
3331
  ]);
@@ -3337,20 +3335,20 @@ const ColumnFilterMenu = ({ displayName, filterOptions, filterVariant, colorPale
3337
3335
  // Remove from filter
3338
3336
  const newArray = currentArray.filter((v) => v !== option.value);
3339
3337
  if (newArray.length === 0) {
3340
- debouncedSetFilterValue(undefined);
3338
+ setFilterValue(undefined);
3341
3339
  }
3342
3340
  else {
3343
- debouncedSetFilterValue(newArray);
3341
+ setFilterValue(newArray);
3344
3342
  }
3345
3343
  }
3346
3344
  }
3347
3345
  else {
3348
3346
  // Handle single value filters (select variant)
3349
3347
  if (details.checked) {
3350
- debouncedSetFilterValue(option.value);
3348
+ setFilterValue(option.value);
3351
3349
  }
3352
3350
  else {
3353
- debouncedSetFilterValue(undefined);
3351
+ setFilterValue(undefined);
3354
3352
  }
3355
3353
  }
3356
3354
  } }) }), jsxRuntime.jsx(react.Box, { flex: 1, minW: 0, children: jsxRuntime.jsxs(react.HStack, { gap: 2, align: "center", children: [jsxRuntime.jsx(react.Box, { w: 3, h: 3, borderRadius: "full", bg: `${colorPalette}.500`, flexShrink: 0 }), jsxRuntime.jsx(react.Text, { fontSize: "sm", fontWeight: "medium", truncate: true, children: option.label })] }) })] }) }, option.value));
@@ -3418,10 +3416,64 @@ const TableFilterTags = ({ filterTagsOptions = [], } = {}) => {
3418
3416
  }) }));
3419
3417
  };
3420
3418
 
3421
- const TableControls = ({ fitTableWidth = false, fitTableHeight = false, children = jsxRuntime.jsx(jsxRuntime.Fragment, {}), showGlobalFilter = false, showFilter = false, showFilterName = false, showFilterTags = false, showReload = false, showPagination = true, showPageSizeControl = true, showPageCountText = true, showView = true, filterTagsOptions = [], extraItems = jsxRuntime.jsx(jsxRuntime.Fragment, {}), loading = false, hasError = false, gridProps = {}, }) => {
3422
- const { tableLabel, table } = useDataTableContext();
3419
+ const TableControls = ({ fitTableWidth = false, fitTableHeight = false, children = jsxRuntime.jsx(jsxRuntime.Fragment, {}), showGlobalFilter = false, showFilter = false, showReload = false, showPagination = true, showPageSizeControl = true, showPageCountText = true, showView = true, filterTagsOptions = [], extraItems = jsxRuntime.jsx(jsxRuntime.Fragment, {}), loading = false, hasError = false, gridProps = {}, }) => {
3420
+ const { tableLabel, table, columnFilters, setColumnFilters } = useDataTableContext();
3423
3421
  const { hasErrorText } = tableLabel;
3424
- return (jsxRuntime.jsxs(react.Grid, { templateRows: 'auto 1fr', width: fitTableWidth ? 'fit-content' : '100%', height: fitTableHeight ? 'fit-content' : '100%', gap: '0.5rem', p: 1, ...gridProps, children: [jsxRuntime.jsxs(react.Flex, { flexFlow: 'column', gap: 2, children: [jsxRuntime.jsxs(react.Flex, { justifyContent: 'space-between', children: [jsxRuntime.jsx(react.Box, { children: showView && jsxRuntime.jsx(ViewDialog, { icon: jsxRuntime.jsx(md.MdOutlineViewColumn, {}) }) }), jsxRuntime.jsxs(react.Flex, { gap: '0.5rem', alignItems: 'center', justifySelf: 'end', children: [loading && jsxRuntime.jsx(react.Spinner, { size: 'sm' }), hasError && (jsxRuntime.jsx(Tooltip, { content: hasErrorText, children: jsxRuntime.jsx(react.Icon, { as: bs.BsExclamationCircleFill, color: 'red.400' }) })), showGlobalFilter && jsxRuntime.jsx(GlobalFilter, {}), showFilter && jsxRuntime.jsx(FilterDialog, {}), showReload && jsxRuntime.jsx(ReloadButton, {}), extraItems] })] }), showFilterTags && (jsxRuntime.jsx(TableFilterTags, { filterTagsOptions: filterTagsOptions }))] }), jsxRuntime.jsx(react.Grid, { children: children }), (showPageSizeControl || showPageCountText || showPagination) && (jsxRuntime.jsxs(react.Flex, { justifyContent: 'space-between', children: [jsxRuntime.jsxs(react.Flex, { gap: '1rem', alignItems: 'center', children: [showPageSizeControl && jsxRuntime.jsx(PageSizeControl, {}), showPageCountText && jsxRuntime.jsx(RowCountText, {})] }), jsxRuntime.jsx(react.Box, { justifySelf: 'end', children: showPagination && jsxRuntime.jsx(Pagination, {}) })] }))] }));
3422
+ // Get applied filters with display information
3423
+ const appliedFilters = React.useMemo(() => {
3424
+ return columnFilters
3425
+ .map((filter) => {
3426
+ const column = table.getColumn(filter.id);
3427
+ if (!column)
3428
+ return null;
3429
+ const meta = column.columnDef.meta;
3430
+ const displayName = meta?.displayName ?? filter.id;
3431
+ const filterValue = filter.value;
3432
+ // Handle array values (tag filters)
3433
+ if (Array.isArray(filterValue)) {
3434
+ return {
3435
+ columnId: filter.id,
3436
+ displayName,
3437
+ values: filterValue,
3438
+ isArray: true,
3439
+ };
3440
+ }
3441
+ // Handle single values (select filters)
3442
+ if (filterValue !== undefined &&
3443
+ filterValue !== null &&
3444
+ filterValue !== '') {
3445
+ return {
3446
+ columnId: filter.id,
3447
+ displayName,
3448
+ value: String(filterValue),
3449
+ isArray: false,
3450
+ };
3451
+ }
3452
+ return null;
3453
+ })
3454
+ .filter((filter) => filter !== null);
3455
+ }, [columnFilters, table]);
3456
+ const handleRemoveFilter = (columnId) => {
3457
+ setColumnFilters(columnFilters.filter((f) => f.id !== columnId));
3458
+ };
3459
+ return (jsxRuntime.jsxs(react.Grid, { templateRows: 'auto 1fr', width: fitTableWidth ? 'fit-content' : '100%', height: fitTableHeight ? 'fit-content' : '100%', gap: '0.5rem', p: 1, ...gridProps, children: [jsxRuntime.jsx(react.Flex, { flexFlow: 'column', gap: 2, children: jsxRuntime.jsxs(react.Flex, { justifyContent: 'space-between', children: [jsxRuntime.jsxs(react.Flex, { gap: 2, alignItems: 'center', flexWrap: 'wrap', children: [showView && jsxRuntime.jsx(ViewDialog, { icon: jsxRuntime.jsx(md.MdOutlineViewColumn, {}) }), appliedFilters.length > 0 && (jsxRuntime.jsx(react.Flex, { gap: 1.5, alignItems: 'center', flexWrap: 'wrap', children: appliedFilters.map((filter) => {
3460
+ if (filter.isArray) {
3461
+ return filter.values.map((value, index) => (jsxRuntime.jsxs(Tag, { size: "sm", colorPalette: "blue", onClose: () => {
3462
+ const column = table.getColumn(filter.columnId);
3463
+ if (column) {
3464
+ const currentValue = column.getFilterValue() ?? [];
3465
+ const newValue = currentValue.filter((v) => v !== value);
3466
+ if (newValue.length === 0) {
3467
+ handleRemoveFilter(filter.columnId);
3468
+ }
3469
+ else {
3470
+ column.setFilterValue(newValue);
3471
+ }
3472
+ }
3473
+ }, children: [filter.displayName, ": ", value] }, `${filter.columnId}-${value}-${index}`)));
3474
+ }
3475
+ return (jsxRuntime.jsxs(Tag, { size: "sm", colorPalette: "blue", onClose: () => handleRemoveFilter(filter.columnId), children: [filter.displayName, ": ", filter.value] }, filter.columnId));
3476
+ }) }))] }), jsxRuntime.jsxs(react.Flex, { gap: '0.5rem', alignItems: 'center', justifySelf: 'end', children: [loading && jsxRuntime.jsx(react.Spinner, { size: 'sm' }), hasError && (jsxRuntime.jsx(Tooltip, { content: hasErrorText, children: jsxRuntime.jsx(react.Icon, { as: bs.BsExclamationCircleFill, color: 'red.400' }) })), showGlobalFilter && jsxRuntime.jsx(GlobalFilter, {}), filterTagsOptions.length > 0 && (jsxRuntime.jsx(TableFilterTags, { filterTagsOptions: filterTagsOptions })), showFilter && jsxRuntime.jsx(FilterDialog, {}), showReload && jsxRuntime.jsx(ReloadButton, {}), extraItems] })] }) }), jsxRuntime.jsx(react.Grid, { children: children }), (showPageSizeControl || showPageCountText || showPagination) && (jsxRuntime.jsxs(react.Flex, { justifyContent: 'space-between', children: [jsxRuntime.jsxs(react.Flex, { gap: '1rem', alignItems: 'center', children: [showPageSizeControl && jsxRuntime.jsx(PageSizeControl, {}), showPageCountText && jsxRuntime.jsx(RowCountText, {})] }), jsxRuntime.jsx(react.Box, { justifySelf: 'end', children: showPagination && jsxRuntime.jsx(Pagination, {}) })] }))] }));
3425
3477
  };
3426
3478
 
3427
3479
  const EmptyState$1 = React__namespace.forwardRef(function EmptyState(props, ref) {
@@ -3989,11 +4041,6 @@ label, containerProps = {}, textProps = {}, children, }) => {
3989
4041
  return (jsxRuntime.jsx(react.Box, { textOverflow: "ellipsis", whiteSpace: "nowrap", wordBreak: "break-all", overflow: "auto", display: "flex", alignItems: "center", justifyContent: alignEnd ? 'flex-end' : undefined, height: "100%", textAlign: alignEnd ? 'right' : undefined, children: jsxRuntime.jsx(RenderValue, { text: displayValue, href: href, onClick: onClick, isCopyable: isCopyable, isBadge: isBadge, badgeColor: badgeColor, colorPalette: colorPalette, globalFilter: globalFilter, alignEnd: alignEnd }) }));
3990
4042
  };
3991
4043
 
3992
- const Tag = React__namespace.forwardRef(function Tag(props, ref) {
3993
- const { startElement, endElement, onClose, closable = !!onClose, children, ...rest } = props;
3994
- return (jsxRuntime.jsxs(react.Tag.Root, { ref: ref, ...rest, children: [startElement && (jsxRuntime.jsx(react.Tag.StartElement, { children: startElement })), jsxRuntime.jsx(react.Tag.Label, { children: children }), endElement && (jsxRuntime.jsx(react.Tag.EndElement, { children: endElement })), closable && (jsxRuntime.jsx(react.Tag.EndElement, { children: jsxRuntime.jsx(react.Tag.CloseTrigger, { onClick: onClose }) }))] }));
3995
- });
3996
-
3997
4044
  const CardHeader = ({ row, imageColumnId = undefined, titleColumnId = undefined, tagColumnId = undefined, tagIcon = undefined, showTag = true, imageProps = {}, }) => {
3998
4045
  if (!!row.original === false) {
3999
4046
  return jsxRuntime.jsx(jsxRuntime.Fragment, {});
@@ -8985,8 +9032,7 @@ const DefaultForm = ({ formConfig, }) => {
8985
9032
  return (jsxRuntime.jsx(FormRoot, { ...formConfig, children: jsxRuntime.jsxs(react.Grid, { gap: "2", children: [showTitle && jsxRuntime.jsx(FormTitle, {}), jsxRuntime.jsx(FormBody, {})] }) }));
8986
9033
  };
8987
9034
 
8988
- const useForm = ({ preLoadedValues, keyPrefix: _keyPrefix, // Deprecated: kept for backward compatibility
8989
- namespace: _namespace, // Deprecated: kept for backward compatibility
9035
+ const useForm = ({ preLoadedValues, namespace: _namespace, // Deprecated: kept for backward compatibility
8990
9036
  schema, }) => {
8991
9037
  const form = reactHookForm.useForm({
8992
9038
  values: preLoadedValues,
@@ -9159,21 +9205,19 @@ const convertToAjvErrorsFormat = (errorMessages) => {
9159
9205
  * );
9160
9206
  * // Result: { username: "This field is required", email: "This field is required" }
9161
9207
  *
9162
- * // With keyPrefix for i18n
9208
+ * // With prefix in generator function
9163
9209
  * const required = buildRequiredErrors(
9164
9210
  * ["username", "email"],
9165
- * (field) => `${field}.field_required`,
9166
- * "user"
9211
+ * (field) => `user.${field}.field_required`
9167
9212
  * );
9168
9213
  * // Result: { username: "user.username.field_required", email: "user.email.field_required" }
9169
9214
  * ```
9170
9215
  */
9171
- const buildRequiredErrors = (fields, messageOrGenerator, keyPrefix = '') => {
9216
+ const buildRequiredErrors = (fields, messageOrGenerator) => {
9172
9217
  const result = {};
9173
9218
  fields.forEach((field) => {
9174
9219
  if (typeof messageOrGenerator === 'function') {
9175
- const message = messageOrGenerator(field);
9176
- result[field] = keyPrefix ? `${keyPrefix}.${message}` : message;
9220
+ result[field] = messageOrGenerator(field);
9177
9221
  }
9178
9222
  else {
9179
9223
  result[field] = messageOrGenerator;
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
- import { Button as Button$1, AbsoluteCenter, Spinner, Span, IconButton, Portal, Dialog, Flex, Text, useDisclosure, DialogBackdrop, RadioGroup as RadioGroup$1, Grid, Box, Slider as Slider$1, HStack, For, CheckboxCard as CheckboxCard$1, Input, Menu, createRecipeContext, createContext as createContext$1, Pagination as Pagination$1, usePaginationContext, Tooltip as Tooltip$1, Group, InputElement, Checkbox as Checkbox$1, Icon, VStack, Heading, EmptyState as EmptyState$2, List, Table as Table$1, Card, MenuRoot as MenuRoot$1, MenuTrigger as MenuTrigger$1, Clipboard, Badge, Link, Tag as Tag$1, Image, Alert, Field as Field$1, Popover, useFilter, useListCollection, Combobox, Tabs, useCombobox, Show, Skeleton, NumberInput, RadioCard, CheckboxGroup, Textarea as Textarea$1, InputGroup as InputGroup$1, Select, Center, Stack } from '@chakra-ui/react';
2
+ import { Button as Button$1, AbsoluteCenter, Spinner, Span, IconButton, Portal, Dialog, Flex, Text, useDisclosure, DialogBackdrop, RadioGroup as RadioGroup$1, Grid, Box, Slider as Slider$1, HStack, For, CheckboxCard as CheckboxCard$1, Input, Menu, createRecipeContext, createContext as createContext$1, Pagination as Pagination$1, usePaginationContext, Tooltip as Tooltip$1, Group, InputElement, Tag as Tag$1, Checkbox as Checkbox$1, Icon, VStack, Heading, EmptyState as EmptyState$2, List, Table as Table$1, Card, MenuRoot as MenuRoot$1, MenuTrigger as MenuTrigger$1, Clipboard, Badge, Link, Image, Alert, Field as Field$1, Popover, useFilter, useListCollection, Combobox, Tabs, useCombobox, Show, Skeleton, NumberInput, RadioCard, CheckboxGroup, Textarea as Textarea$1, InputGroup as InputGroup$1, Select, Center, Stack } from '@chakra-ui/react';
3
3
  import { AiOutlineColumnWidth } from 'react-icons/ai';
4
4
  import * as React from 'react';
5
5
  import { createContext, useContext, useState, useMemo, useCallback, useEffect, useRef } from 'react';
@@ -3178,19 +3178,31 @@ const TableSelector = () => {
3178
3178
  }, "aria-label": 'reset selection', children: jsx(MdClear, {}) }))] }));
3179
3179
  };
3180
3180
 
3181
+ const Tag = React.forwardRef(function Tag(props, ref) {
3182
+ const { startElement, endElement, onClose, closable = !!onClose, children, ...rest } = props;
3183
+ return (jsxs(Tag$1.Root, { ref: ref, ...rest, children: [startElement && (jsx(Tag$1.StartElement, { children: startElement })), jsx(Tag$1.Label, { children: children }), endElement && (jsx(Tag$1.EndElement, { children: endElement })), closable && (jsx(Tag$1.EndElement, { children: jsx(Tag$1.CloseTrigger, { onClick: onClose }) }))] }));
3184
+ });
3185
+
3181
3186
  const Checkbox = React.forwardRef(function Checkbox(props, ref) {
3182
3187
  const { icon, children, inputProps, rootRef, ...rest } = props;
3183
3188
  return (jsxs(Checkbox$1.Root, { ref: rootRef, ...rest, children: [jsx(Checkbox$1.HiddenInput, { ref: ref, ...inputProps }), jsx(Checkbox$1.Control, { children: icon || jsx(Checkbox$1.Indicator, {}) }), children != null && (jsx(Checkbox$1.Label, { children: children }))] }));
3184
3189
  });
3185
3190
 
3186
- const ColumnFilterMenu = ({ displayName, filterOptions, filterVariant, colorPalette, value: controlledValue, onChange, labels, }) => {
3191
+ const ColumnFilterMenu = ({ displayName, filterOptions, filterVariant, colorPalette, value: controlledValue, onChange, labels, open: controlledOpen, onOpenChange, }) => {
3187
3192
  const [searchTerm, setSearchTerm] = useState('');
3188
3193
  const debouncedSearchTerm = useDebounce(searchTerm, 300);
3189
- const [isOpen, setIsOpen] = useState(false);
3194
+ const [internalOpen, setInternalOpen] = useState(false);
3195
+ // Use controlled open state if provided, otherwise use internal state
3196
+ const isOpen = controlledOpen !== undefined ? controlledOpen : internalOpen;
3197
+ const handleOpenChange = (details) => {
3198
+ if (onOpenChange) {
3199
+ onOpenChange(details.open);
3200
+ }
3201
+ else {
3202
+ setInternalOpen(details.open);
3203
+ }
3204
+ };
3190
3205
  const [internalValue, setInternalValue] = useState(undefined);
3191
- const [pendingFilterValue, setPendingFilterValue] = useState(undefined);
3192
- const debouncedFilterValue = useDebounce(pendingFilterValue, 300);
3193
- const lastAppliedValueRef = useRef('__INITIAL__');
3194
3206
  // Use controlled value if provided, otherwise use internal state
3195
3207
  const currentFilterValue = controlledValue !== undefined ? controlledValue : internalValue;
3196
3208
  const isArrayFilter = filterVariant === 'tag';
@@ -3201,31 +3213,20 @@ const ColumnFilterMenu = ({ displayName, filterOptions, filterVariant, colorPale
3201
3213
  noFiltersMatchText: 'No filters match your search',
3202
3214
  };
3203
3215
  const finalLabels = { ...defaultLabels, ...labels };
3204
- // Apply debounced filter value via onChange callback
3216
+ // Reset search term when menu closes
3205
3217
  useEffect(() => {
3206
- const currentKey = JSON.stringify(debouncedFilterValue);
3207
- // Only apply if the value has changed from what we last applied
3208
- if (currentKey !== lastAppliedValueRef.current) {
3209
- if (onChange) {
3210
- onChange(debouncedFilterValue);
3211
- }
3212
- else {
3213
- setInternalValue(debouncedFilterValue);
3214
- }
3215
- lastAppliedValueRef.current = currentKey;
3218
+ if (!isOpen) {
3219
+ setSearchTerm('');
3220
+ }
3221
+ }, [isOpen]);
3222
+ // Filter update function
3223
+ const setFilterValue = (value) => {
3224
+ if (onChange) {
3225
+ onChange(value);
3226
+ }
3227
+ else {
3228
+ setInternalValue(value);
3216
3229
  }
3217
- }, [debouncedFilterValue, onChange]);
3218
- // Sync internal value when controlled value changes
3219
- useEffect(() => {
3220
- if (controlledValue !== undefined) {
3221
- setInternalValue(controlledValue);
3222
- setPendingFilterValue(controlledValue);
3223
- lastAppliedValueRef.current = JSON.stringify(controlledValue);
3224
- }
3225
- }, [controlledValue]);
3226
- // Debounced filter update function
3227
- const debouncedSetFilterValue = (value) => {
3228
- setPendingFilterValue(value);
3229
3230
  };
3230
3231
  // Get active count for this column
3231
3232
  const activeCount = useMemo(() => {
@@ -3244,7 +3245,7 @@ const ColumnFilterMenu = ({ displayName, filterOptions, filterVariant, colorPale
3244
3245
  const searchLower = debouncedSearchTerm.toLowerCase();
3245
3246
  return filterOptions.filter((option) => option.label.toLowerCase().includes(searchLower));
3246
3247
  }, [filterOptions, debouncedSearchTerm]);
3247
- return (jsxs(MenuRoot, { open: isOpen, onOpenChange: (details) => setIsOpen(details.open), children: [jsx(MenuTrigger, { asChild: true, children: jsxs(Button$1, { variant: "outline", size: "sm", gap: 2, children: [jsx(Icon, { as: MdFilterList }), jsxs(Text, { children: [displayName, " ", activeCount > 0 && `(${activeCount})`] })] }) }), jsx(MenuContent, { maxW: "20rem", minW: "18rem", children: jsxs(VStack, { align: "stretch", gap: 2, p: 2, children: [jsxs(Heading, { size: "sm", px: 2, children: [finalLabels.filterByLabel, " ", displayName] }), jsx(InputGroup, { startElement: jsx(Icon, { as: MdSearch }), children: jsx(Input, { placeholder: finalLabels.filterLabelsPlaceholder, value: searchTerm, onChange: (e) => setSearchTerm(e.target.value) }) }), jsx(Box, { maxH: "20rem", overflowY: "auto", css: {
3248
+ return (jsxs(MenuRoot, { open: isOpen, onOpenChange: handleOpenChange, children: [jsx(MenuTrigger, { asChild: true, children: jsxs(Button$1, { variant: "outline", size: "sm", gap: 2, children: [jsx(Icon, { as: MdFilterList }), jsxs(Text, { children: [displayName, " ", activeCount > 0 && `(${activeCount})`] })] }) }), jsx(MenuContent, { maxW: "20rem", minW: "18rem", children: jsxs(VStack, { align: "stretch", gap: 2, p: 2, children: [jsxs(Heading, { size: "sm", px: 2, children: [finalLabels.filterByLabel, " ", displayName] }), jsx(InputGroup, { startElement: jsx(Icon, { as: MdSearch }), children: jsx(Input, { placeholder: finalLabels.filterLabelsPlaceholder, value: searchTerm, onChange: (e) => setSearchTerm(e.target.value) }) }), jsx(Box, { maxH: "20rem", overflowY: "auto", css: {
3248
3249
  '&::-webkit-scrollbar': {
3249
3250
  width: '8px',
3250
3251
  },
@@ -3270,29 +3271,26 @@ const ColumnFilterMenu = ({ displayName, filterOptions, filterVariant, colorPale
3270
3271
  // Remove from filter
3271
3272
  const newArray = currentArray.filter((v) => v !== option.value);
3272
3273
  if (newArray.length === 0) {
3273
- debouncedSetFilterValue(undefined);
3274
+ setFilterValue(undefined);
3274
3275
  }
3275
3276
  else {
3276
- debouncedSetFilterValue(newArray);
3277
+ setFilterValue(newArray);
3277
3278
  }
3278
3279
  }
3279
3280
  else {
3280
3281
  // Add to filter
3281
3282
  if (!currentArray.includes(option.value)) {
3282
- debouncedSetFilterValue([
3283
- ...currentArray,
3284
- option.value,
3285
- ]);
3283
+ setFilterValue([...currentArray, option.value]);
3286
3284
  }
3287
3285
  }
3288
3286
  }
3289
3287
  else {
3290
3288
  // Handle single value filters (select variant)
3291
3289
  if (isActive) {
3292
- debouncedSetFilterValue(undefined);
3290
+ setFilterValue(undefined);
3293
3291
  }
3294
3292
  else {
3295
- debouncedSetFilterValue(option.value);
3293
+ setFilterValue(option.value);
3296
3294
  }
3297
3295
  }
3298
3296
  };
@@ -3307,7 +3305,7 @@ const ColumnFilterMenu = ({ displayName, filterOptions, filterVariant, colorPale
3307
3305
  if (details.checked) {
3308
3306
  // Add to filter
3309
3307
  if (!currentArray.includes(option.value)) {
3310
- debouncedSetFilterValue([
3308
+ setFilterValue([
3311
3309
  ...currentArray,
3312
3310
  option.value,
3313
3311
  ]);
@@ -3317,20 +3315,20 @@ const ColumnFilterMenu = ({ displayName, filterOptions, filterVariant, colorPale
3317
3315
  // Remove from filter
3318
3316
  const newArray = currentArray.filter((v) => v !== option.value);
3319
3317
  if (newArray.length === 0) {
3320
- debouncedSetFilterValue(undefined);
3318
+ setFilterValue(undefined);
3321
3319
  }
3322
3320
  else {
3323
- debouncedSetFilterValue(newArray);
3321
+ setFilterValue(newArray);
3324
3322
  }
3325
3323
  }
3326
3324
  }
3327
3325
  else {
3328
3326
  // Handle single value filters (select variant)
3329
3327
  if (details.checked) {
3330
- debouncedSetFilterValue(option.value);
3328
+ setFilterValue(option.value);
3331
3329
  }
3332
3330
  else {
3333
- debouncedSetFilterValue(undefined);
3331
+ setFilterValue(undefined);
3334
3332
  }
3335
3333
  }
3336
3334
  } }) }), jsx(Box, { flex: 1, minW: 0, children: jsxs(HStack, { gap: 2, align: "center", children: [jsx(Box, { w: 3, h: 3, borderRadius: "full", bg: `${colorPalette}.500`, flexShrink: 0 }), jsx(Text, { fontSize: "sm", fontWeight: "medium", truncate: true, children: option.label })] }) })] }) }, option.value));
@@ -3398,10 +3396,64 @@ const TableFilterTags = ({ filterTagsOptions = [], } = {}) => {
3398
3396
  }) }));
3399
3397
  };
3400
3398
 
3401
- const TableControls = ({ fitTableWidth = false, fitTableHeight = false, children = jsx(Fragment, {}), showGlobalFilter = false, showFilter = false, showFilterName = false, showFilterTags = false, showReload = false, showPagination = true, showPageSizeControl = true, showPageCountText = true, showView = true, filterTagsOptions = [], extraItems = jsx(Fragment, {}), loading = false, hasError = false, gridProps = {}, }) => {
3402
- const { tableLabel, table } = useDataTableContext();
3399
+ const TableControls = ({ fitTableWidth = false, fitTableHeight = false, children = jsx(Fragment, {}), showGlobalFilter = false, showFilter = false, showReload = false, showPagination = true, showPageSizeControl = true, showPageCountText = true, showView = true, filterTagsOptions = [], extraItems = jsx(Fragment, {}), loading = false, hasError = false, gridProps = {}, }) => {
3400
+ const { tableLabel, table, columnFilters, setColumnFilters } = useDataTableContext();
3403
3401
  const { hasErrorText } = tableLabel;
3404
- return (jsxs(Grid, { templateRows: 'auto 1fr', width: fitTableWidth ? 'fit-content' : '100%', height: fitTableHeight ? 'fit-content' : '100%', gap: '0.5rem', p: 1, ...gridProps, children: [jsxs(Flex, { flexFlow: 'column', gap: 2, children: [jsxs(Flex, { justifyContent: 'space-between', children: [jsx(Box, { children: showView && jsx(ViewDialog, { icon: jsx(MdOutlineViewColumn, {}) }) }), jsxs(Flex, { gap: '0.5rem', alignItems: 'center', justifySelf: 'end', children: [loading && jsx(Spinner, { size: 'sm' }), hasError && (jsx(Tooltip, { content: hasErrorText, children: jsx(Icon, { as: BsExclamationCircleFill, color: 'red.400' }) })), showGlobalFilter && jsx(GlobalFilter, {}), showFilter && jsx(FilterDialog, {}), showReload && jsx(ReloadButton, {}), extraItems] })] }), showFilterTags && (jsx(TableFilterTags, { filterTagsOptions: filterTagsOptions }))] }), jsx(Grid, { children: children }), (showPageSizeControl || showPageCountText || showPagination) && (jsxs(Flex, { justifyContent: 'space-between', children: [jsxs(Flex, { gap: '1rem', alignItems: 'center', children: [showPageSizeControl && jsx(PageSizeControl, {}), showPageCountText && jsx(RowCountText, {})] }), jsx(Box, { justifySelf: 'end', children: showPagination && jsx(Pagination, {}) })] }))] }));
3402
+ // Get applied filters with display information
3403
+ const appliedFilters = useMemo(() => {
3404
+ return columnFilters
3405
+ .map((filter) => {
3406
+ const column = table.getColumn(filter.id);
3407
+ if (!column)
3408
+ return null;
3409
+ const meta = column.columnDef.meta;
3410
+ const displayName = meta?.displayName ?? filter.id;
3411
+ const filterValue = filter.value;
3412
+ // Handle array values (tag filters)
3413
+ if (Array.isArray(filterValue)) {
3414
+ return {
3415
+ columnId: filter.id,
3416
+ displayName,
3417
+ values: filterValue,
3418
+ isArray: true,
3419
+ };
3420
+ }
3421
+ // Handle single values (select filters)
3422
+ if (filterValue !== undefined &&
3423
+ filterValue !== null &&
3424
+ filterValue !== '') {
3425
+ return {
3426
+ columnId: filter.id,
3427
+ displayName,
3428
+ value: String(filterValue),
3429
+ isArray: false,
3430
+ };
3431
+ }
3432
+ return null;
3433
+ })
3434
+ .filter((filter) => filter !== null);
3435
+ }, [columnFilters, table]);
3436
+ const handleRemoveFilter = (columnId) => {
3437
+ setColumnFilters(columnFilters.filter((f) => f.id !== columnId));
3438
+ };
3439
+ return (jsxs(Grid, { templateRows: 'auto 1fr', width: fitTableWidth ? 'fit-content' : '100%', height: fitTableHeight ? 'fit-content' : '100%', gap: '0.5rem', p: 1, ...gridProps, children: [jsx(Flex, { flexFlow: 'column', gap: 2, children: jsxs(Flex, { justifyContent: 'space-between', children: [jsxs(Flex, { gap: 2, alignItems: 'center', flexWrap: 'wrap', children: [showView && jsx(ViewDialog, { icon: jsx(MdOutlineViewColumn, {}) }), appliedFilters.length > 0 && (jsx(Flex, { gap: 1.5, alignItems: 'center', flexWrap: 'wrap', children: appliedFilters.map((filter) => {
3440
+ if (filter.isArray) {
3441
+ return filter.values.map((value, index) => (jsxs(Tag, { size: "sm", colorPalette: "blue", onClose: () => {
3442
+ const column = table.getColumn(filter.columnId);
3443
+ if (column) {
3444
+ const currentValue = column.getFilterValue() ?? [];
3445
+ const newValue = currentValue.filter((v) => v !== value);
3446
+ if (newValue.length === 0) {
3447
+ handleRemoveFilter(filter.columnId);
3448
+ }
3449
+ else {
3450
+ column.setFilterValue(newValue);
3451
+ }
3452
+ }
3453
+ }, children: [filter.displayName, ": ", value] }, `${filter.columnId}-${value}-${index}`)));
3454
+ }
3455
+ return (jsxs(Tag, { size: "sm", colorPalette: "blue", onClose: () => handleRemoveFilter(filter.columnId), children: [filter.displayName, ": ", filter.value] }, filter.columnId));
3456
+ }) }))] }), jsxs(Flex, { gap: '0.5rem', alignItems: 'center', justifySelf: 'end', children: [loading && jsx(Spinner, { size: 'sm' }), hasError && (jsx(Tooltip, { content: hasErrorText, children: jsx(Icon, { as: BsExclamationCircleFill, color: 'red.400' }) })), showGlobalFilter && jsx(GlobalFilter, {}), filterTagsOptions.length > 0 && (jsx(TableFilterTags, { filterTagsOptions: filterTagsOptions })), showFilter && jsx(FilterDialog, {}), showReload && jsx(ReloadButton, {}), extraItems] })] }) }), jsx(Grid, { children: children }), (showPageSizeControl || showPageCountText || showPagination) && (jsxs(Flex, { justifyContent: 'space-between', children: [jsxs(Flex, { gap: '1rem', alignItems: 'center', children: [showPageSizeControl && jsx(PageSizeControl, {}), showPageCountText && jsx(RowCountText, {})] }), jsx(Box, { justifySelf: 'end', children: showPagination && jsx(Pagination, {}) })] }))] }));
3405
3457
  };
3406
3458
 
3407
3459
  const EmptyState$1 = React.forwardRef(function EmptyState(props, ref) {
@@ -3969,11 +4021,6 @@ label, containerProps = {}, textProps = {}, children, }) => {
3969
4021
  return (jsx(Box, { textOverflow: "ellipsis", whiteSpace: "nowrap", wordBreak: "break-all", overflow: "auto", display: "flex", alignItems: "center", justifyContent: alignEnd ? 'flex-end' : undefined, height: "100%", textAlign: alignEnd ? 'right' : undefined, children: jsx(RenderValue, { text: displayValue, href: href, onClick: onClick, isCopyable: isCopyable, isBadge: isBadge, badgeColor: badgeColor, colorPalette: colorPalette, globalFilter: globalFilter, alignEnd: alignEnd }) }));
3970
4022
  };
3971
4023
 
3972
- const Tag = React.forwardRef(function Tag(props, ref) {
3973
- const { startElement, endElement, onClose, closable = !!onClose, children, ...rest } = props;
3974
- return (jsxs(Tag$1.Root, { ref: ref, ...rest, children: [startElement && (jsx(Tag$1.StartElement, { children: startElement })), jsx(Tag$1.Label, { children: children }), endElement && (jsx(Tag$1.EndElement, { children: endElement })), closable && (jsx(Tag$1.EndElement, { children: jsx(Tag$1.CloseTrigger, { onClick: onClose }) }))] }));
3975
- });
3976
-
3977
4024
  const CardHeader = ({ row, imageColumnId = undefined, titleColumnId = undefined, tagColumnId = undefined, tagIcon = undefined, showTag = true, imageProps = {}, }) => {
3978
4025
  if (!!row.original === false) {
3979
4026
  return jsx(Fragment, {});
@@ -8965,8 +9012,7 @@ const DefaultForm = ({ formConfig, }) => {
8965
9012
  return (jsx(FormRoot, { ...formConfig, children: jsxs(Grid, { gap: "2", children: [showTitle && jsx(FormTitle, {}), jsx(FormBody, {})] }) }));
8966
9013
  };
8967
9014
 
8968
- const useForm = ({ preLoadedValues, keyPrefix: _keyPrefix, // Deprecated: kept for backward compatibility
8969
- namespace: _namespace, // Deprecated: kept for backward compatibility
9015
+ const useForm = ({ preLoadedValues, namespace: _namespace, // Deprecated: kept for backward compatibility
8970
9016
  schema, }) => {
8971
9017
  const form = useForm$1({
8972
9018
  values: preLoadedValues,
@@ -9139,21 +9185,19 @@ const convertToAjvErrorsFormat = (errorMessages) => {
9139
9185
  * );
9140
9186
  * // Result: { username: "This field is required", email: "This field is required" }
9141
9187
  *
9142
- * // With keyPrefix for i18n
9188
+ * // With prefix in generator function
9143
9189
  * const required = buildRequiredErrors(
9144
9190
  * ["username", "email"],
9145
- * (field) => `${field}.field_required`,
9146
- * "user"
9191
+ * (field) => `user.${field}.field_required`
9147
9192
  * );
9148
9193
  * // Result: { username: "user.username.field_required", email: "user.email.field_required" }
9149
9194
  * ```
9150
9195
  */
9151
- const buildRequiredErrors = (fields, messageOrGenerator, keyPrefix = '') => {
9196
+ const buildRequiredErrors = (fields, messageOrGenerator) => {
9152
9197
  const result = {};
9153
9198
  fields.forEach((field) => {
9154
9199
  if (typeof messageOrGenerator === 'function') {
9155
- const message = messageOrGenerator(field);
9156
- result[field] = keyPrefix ? `${keyPrefix}.${message}` : message;
9200
+ result[field] = messageOrGenerator(field);
9157
9201
  }
9158
9202
  else {
9159
9203
  result[field] = messageOrGenerator;
@@ -14,5 +14,7 @@ export interface ColumnFilterMenuProps {
14
14
  value?: string[] | string | undefined;
15
15
  onChange?: (value: string[] | string | undefined) => void;
16
16
  labels?: ColumnFilterMenuLabels;
17
+ open?: boolean;
18
+ onOpenChange?: (open: boolean) => void;
17
19
  }
18
- export declare const ColumnFilterMenu: ({ displayName, filterOptions, filterVariant, colorPalette, value: controlledValue, onChange, labels, }: ColumnFilterMenuProps) => import("react/jsx-runtime").JSX.Element;
20
+ export declare const ColumnFilterMenu: ({ displayName, filterOptions, filterVariant, colorPalette, value: controlledValue, onChange, labels, open: controlledOpen, onOpenChange, }: ColumnFilterMenuProps) => import("react/jsx-runtime").JSX.Element;
@@ -7,8 +7,6 @@ export interface TableControlsProps {
7
7
  children?: ReactNode;
8
8
  showGlobalFilter?: boolean;
9
9
  showFilter?: boolean;
10
- showFilterName?: boolean;
11
- showFilterTags?: boolean;
12
10
  showReload?: boolean;
13
11
  showPagination?: boolean;
14
12
  showPageSizeControl?: boolean;
@@ -26,4 +24,4 @@ export interface TableControlsProps {
26
24
  hasError?: boolean;
27
25
  gridProps?: GridProps;
28
26
  }
29
- export declare const TableControls: ({ fitTableWidth, fitTableHeight, children, showGlobalFilter, showFilter, showFilterName, showFilterTags, showReload, showPagination, showPageSizeControl, showPageCountText, showView, filterTagsOptions, extraItems, loading, hasError, gridProps, }: TableControlsProps) => import("react/jsx-runtime").JSX.Element;
27
+ export declare const TableControls: ({ fitTableWidth, fitTableHeight, children, showGlobalFilter, showFilter, showReload, showPagination, showPageSizeControl, showPageCountText, showView, filterTagsOptions, extraItems, loading, hasError, gridProps, }: TableControlsProps) => import("react/jsx-runtime").JSX.Element;
@@ -1,7 +1,7 @@
1
1
  import { UseQueryResult } from '@tanstack/react-query';
2
2
  import { ColumnFiltersState, SortingState } from '@tanstack/react-table';
3
3
  import { UseDataTableProps, UseDataTableReturn } from './useDataTable';
4
- export interface UseDataTableServerProps<TData> extends Omit<UseDataTableProps, 'keyPrefix'> {
4
+ export interface UseDataTableServerProps<TData> extends UseDataTableProps {
5
5
  /**
6
6
  * Delay to send the request if the `refreshData` called multiple times
7
7
  *
@@ -8,11 +8,10 @@ export interface Translate {
8
8
  }
9
9
  export interface UseFormProps {
10
10
  preLoadedValues?: FieldValues | undefined;
11
- keyPrefix?: string;
12
11
  namespace?: string;
13
12
  schema?: JSONSchema7;
14
13
  }
15
- export declare const useForm: ({ preLoadedValues, keyPrefix: _keyPrefix, namespace: _namespace, schema, }: UseFormProps) => {
14
+ export declare const useForm: ({ preLoadedValues, namespace: _namespace, schema, }: UseFormProps) => {
16
15
  form: import("react-hook-form").UseFormReturn<FieldValues, any, undefined>;
17
16
  idMap: Record<string, object>;
18
17
  setIdMap: import("react").Dispatch<import("react").SetStateAction<Record<string, object>>>;
@@ -152,16 +152,15 @@ export declare const convertToAjvErrorsFormat: (errorMessages: ErrorMessageResul
152
152
  * );
153
153
  * // Result: { username: "This field is required", email: "This field is required" }
154
154
  *
155
- * // With keyPrefix for i18n
155
+ * // With prefix in generator function
156
156
  * const required = buildRequiredErrors(
157
157
  * ["username", "email"],
158
- * (field) => `${field}.field_required`,
159
- * "user"
158
+ * (field) => `user.${field}.field_required`
160
159
  * );
161
160
  * // Result: { username: "user.username.field_required", email: "user.email.field_required" }
162
161
  * ```
163
162
  */
164
- export declare const buildRequiredErrors: (fields: string[], messageOrGenerator: string | ((field: string) => string), keyPrefix?: string) => Record<string, string>;
163
+ export declare const buildRequiredErrors: (fields: string[], messageOrGenerator: string | ((field: string) => string)) => Record<string, string>;
165
164
  /**
166
165
  * Helper function to build field-specific validation errors
167
166
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bsol-oss/react-datatable5",
3
- "version": "13.0.1-beta.14",
3
+ "version": "13.0.1-beta.16",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",