tp-react-elements 2.0.4 → 2.0.5

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 (38) hide show
  1. package/dist/_virtual/index.esm11.js +2 -2
  2. package/dist/_virtual/index.esm12.js +2 -2
  3. package/dist/_virtual/index.esm14.js +2 -2
  4. package/dist/_virtual/index.esm4.js +2 -2
  5. package/dist/_virtual/index.esm6.js +2 -2
  6. package/dist/_virtual/index.esm7.js +2 -2
  7. package/dist/components/DateRangePicker/DateRangePicker.esm.js +49 -72
  8. package/dist/components/Form/FormRender.esm.js +1 -1
  9. package/dist/components/FormComponents/DatePicker/DatepickerWrapperV2.esm.js +10 -15
  10. package/dist/components/FormComponents/DatePicker/DatetimepickerWrapper.esm.js +53 -61
  11. package/dist/components/FormComponents/FileUpload/FormRenderFileUpload.esm.js +54 -68
  12. package/dist/components/FormComponents/FileUpload/FormRenderMultiFileUpload.esm.js +61 -76
  13. package/dist/components/FormComponents/FileUpload/MultiFileWithPreview.esm.js +103 -132
  14. package/dist/components/FormComponents/FormNumberField/FormNumberField.d.ts +0 -38
  15. package/dist/components/FormComponents/FormNumberField/FormNumberField.esm.js +32 -97
  16. package/dist/components/FormComponents/FormNumberField/FormNumberFieldDecimal.esm.js +44 -38
  17. package/dist/components/FormComponents/FormTextField/FormTextField.esm.js +3 -3
  18. package/dist/components/FormComponents/FormTextFieldWithSelect/FormTextFieldWithSelect.esm.js +3 -2
  19. package/dist/components/FormComponents/PasswordField/PasswordField.esm.js +4 -4
  20. package/dist/components/FormComponents/RichTextEditor/RichTextEditor.esm.js +23 -22
  21. package/dist/components/FormComponents/Select/SearchableSelect.esm.js +9 -9
  22. package/dist/components/FormComponents/TimePicker/TimePicker.esm.js +19 -19
  23. package/dist/components/FormComponents/index.esm.js +2 -2
  24. package/dist/components/ModalField/ConfirmationDialog.esm.js +3 -3
  25. package/dist/components/ModalField/ModalField.esm.js +5 -12
  26. package/dist/components/PaginatedGrid/DynamicFilterBar.d.ts +1 -1
  27. package/dist/components/PaginatedGrid/DynamicFilterBar.esm.js +27 -24
  28. package/dist/components/PaginatedGrid/GenericPaginatedGrid.d.ts +13 -1
  29. package/dist/components/PaginatedGrid/GenericPaginatedGrid.esm.js +102 -85
  30. package/dist/components/SelectField/MultiSelectFieldComponent.esm.js +3 -3
  31. package/dist/components/SessionTimeOut/SessionTimeOut.esm.js +33 -34
  32. package/dist/node_modules/react-date-range/dist/components/Calendar/index.esm.js +1 -1
  33. package/dist/node_modules/react-date-range/dist/components/DateRange/index.esm.js +1 -1
  34. package/dist/node_modules/react-date-range/dist/components/DateRangePicker/index.esm.js +1 -1
  35. package/dist/node_modules/react-date-range/dist/components/DayCell/index.esm.js +1 -1
  36. package/dist/node_modules/react-date-range/dist/components/InputRangeField/index.esm.js +1 -1
  37. package/dist/node_modules/react-date-range/dist/components/Month/index.esm.js +1 -1
  38. package/package.json +1 -1
@@ -1,108 +1,43 @@
1
- import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
1
+ import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
2
+ import { useCallback } from 'react';
2
3
  import { TextField } from '@mui/material';
3
- import { Controller } from 'react-hook-form';
4
+ import { useController } from 'react-hook-form';
4
5
  import FormBottomField from '../FormBottomField/FormBottomField.esm.js';
5
6
  import 'dayjs';
6
7
  import { renderLabel } from '../../../utils/Constants/FormConstants.esm.js';
7
8
 
8
- /**
9
- * FormNumberField Component
10
- *
11
- * A numeric input field component that integrates with react-hook-form.
12
- * This component is used for integer inputs, phone numbers, and pincodes.
13
- * It restricts input to numeric characters only.
14
- *
15
- * @component
16
- * @param {Object} props - The component props
17
- * @param {FormRenderProps} props.props - Form rendering properties from parent form
18
- * @param {VariantProps} props.variant - UI variant style ('standard', 'outlined', etc.)
19
- *
20
- * @example
21
- * // Basic usage in FormRender
22
- * <FormNumberField props={formRenderProps} variant="outlined" />
23
- *
24
- * @example
25
- * // Usage with specific configuration
26
- * const formItem = {
27
- * name: "phoneNumber",
28
- * label: "Phone Number",
29
- * inputType: "number",
30
- * required: true,
31
- * maxLength: 10
32
- * };
33
- * <FormNumberField
34
- * props={{
35
- * item: formItem,
36
- * control: formMethods.control,
37
- * errors: formMethods.formState.errors
38
- * }}
39
- * variant="outlined"
40
- * />
41
- */
42
9
  const FormNumberField = ({ props, variant }) => {
43
- /**
44
- * Determines if the field has an error based on form validation
45
- */
46
10
  const isError = !!props.errors?.[props.item.name];
47
- const isShowBorderError = isError;
48
- /**
49
- * Generates the field label based on variant type
50
- * For non-standard variants, appends an asterisk if the field is required
51
- */
52
11
  const label = variant !== 'standard' ? `${props.item.label}${props.item.required ? ' *' : ''}` : '';
53
- /**
54
- * Renders the numeric field component using react-hook-form's Controller
55
- * for controlled form state management
56
- */
57
- return (jsx(Fragment, { children: jsx(Controller, { control: props.control, name: props.item.name, render: ({ field }) => {
58
- return (jsxs(Fragment, { children: [renderLabel(variant, props), jsx(TextField, { ...field, size: "small", label: label, error: isShowBorderError, value: field.value ?? '',
59
- /**
60
- * Handles input events with numeric restrictions
61
- * - Removes non-numeric characters
62
- * - Sets empty value to null
63
- * - Calls custom onChange handler if provided
64
- * - Clears validation errors when value changes
65
- *
66
- * @param {any} e - The input event object
67
- */
68
- onChange: (e) => {
69
- const sanitized = String(e.target.value || '').replace(/[^0-9]/g, '');
70
- const nextValue = sanitized === '' ? null : sanitized;
71
- field.onChange(nextValue);
72
- props?.item?.onChangeFn && props?.item?.onChangeFn(nextValue);
73
- props?.clearErrors && props?.clearErrors(props.item.name);
74
- if (nextValue && props.item.maxValue && parseInt(nextValue) > props.item.maxValue) {
75
- field.onChange(props.item.maxValue);
76
- }
77
- },
78
- /**
79
- * Handles blur events
80
- * Calls custom onBlur handler if provided
81
- *
82
- * @param {any} e - The blur event object
83
- */
84
- onBlur: (e) => {
85
- props?.item?.onBlurFn && props?.item?.onBlurFn(e);
86
- }, sx: {
87
- '& .css-1holvmy,.css-lqj8pz-MuiFormLabel-root-MuiInputLabel-root,.css-kichxs-MuiFormLabel-root-MuiInputLabel-root': {
88
- top: '-10px',
89
- },
90
- }, placeholder: props.item.placeholder || '',
91
- /**
92
- * Additional input properties for the TextField
93
- * Controls input pattern, length restrictions, and additional input handling
94
- */
95
- onInput: (e) => {
96
- props.item.onInputProps && props.item.onInputProps(e);
97
- }, inputProps: {
98
- pattern: '[0-9]*',
99
- maxLength: props.item.maxLength || 20,
100
- maxValue: props.item.maxValue || 9999999999,
101
- 'aria-labelledby': `${props.item.name}-label`,
102
- 'aria-describedby': `${props.item.name}-helper ${props.item.name}-error`,
103
- 'aria-required': props.item.required ? true : undefined,
104
- }, disabled: props.item.disable }), jsx(FormBottomField, { ...props })] }));
105
- } }, props.item.name) }));
12
+ // useController gives a stable `field` reference outside any render prop,
13
+ // enabling proper useCallback usage for the event handlers below.
14
+ const { field } = useController({ control: props.control, name: props.item.name });
15
+ const handleChange = useCallback((e) => {
16
+ const sanitized = String(e.target.value || '').replace(/[^0-9]/g, '');
17
+ const nextValue = sanitized === '' ? null : sanitized;
18
+ field.onChange(nextValue);
19
+ props?.item?.onChangeFn && props?.item?.onChangeFn(nextValue);
20
+ props?.clearErrors && props?.clearErrors(props.item.name);
21
+ if (nextValue && props.item.maxValue && parseInt(nextValue) > props.item.maxValue) {
22
+ field.onChange(props.item.maxValue);
23
+ }
24
+ }, [field, props.item, props.clearErrors]);
25
+ const handleBlur = useCallback((e) => {
26
+ props?.item?.onBlurFn && props?.item?.onBlurFn(e);
27
+ }, [props.item.onBlurFn]);
28
+ const handleInput = useCallback((e) => {
29
+ props.item.onInputProps && props.item.onInputProps(e);
30
+ }, [props.item.onInputProps]);
31
+ return (jsxs(Fragment, { children: [renderLabel(variant, props), jsx(TextField, { ...field, size: "small", label: label, error: isError, value: field.value ?? '', onChange: handleChange, onBlur: handleBlur, onInput: handleInput, sx: {
32
+ '& .css-1holvmy,.css-lqj8pz-MuiFormLabel-root-MuiInputLabel-root,.css-kichxs-MuiFormLabel-root-MuiInputLabel-root': { top: '-10px' },
33
+ }, placeholder: props.item.placeholder || '', inputProps: {
34
+ pattern: '[0-9]*',
35
+ maxLength: props.item.maxLength || 20,
36
+ maxValue: props.item.maxValue || 9999999999,
37
+ 'aria-labelledby': `${props.item.name}-label`,
38
+ 'aria-describedby': `${props.item.name}-helper ${props.item.name}-error`,
39
+ 'aria-required': props.item.required ? true : undefined,
40
+ }, disabled: props.item.disable }), jsx(FormBottomField, { ...props })] }));
106
41
  };
107
42
 
108
43
  export { FormNumberField as default };
@@ -1,15 +1,22 @@
1
- import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
1
+ import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
2
+ import { useCallback } from 'react';
2
3
  import { TextField } from '@mui/material';
3
- import { Controller } from 'react-hook-form';
4
+ import { useController } from 'react-hook-form';
4
5
  import FormBottomField from '../FormBottomField/FormBottomField.esm.js';
5
6
  import 'dayjs';
6
7
  import { renderLabel } from '../../../utils/Constants/FormConstants.esm.js';
7
8
 
8
9
  const FormNumberFieldDecimal = ({ props, variant, }) => {
9
10
  const fixedLength = props.item.decimalFixedTo || 2;
10
- const sanitizeDecimal = (raw) => {
11
+ const label = variant !== 'standard' ? `${props.item.label}${props.item.required ? ' *' : ''}` : '';
12
+ const isError = !!props.errors?.[props.item.name];
13
+ const { field } = useController({
14
+ control: props.control,
15
+ name: props.item.name,
16
+ disabled: props.item?.disable,
17
+ });
18
+ const sanitizeDecimal = useCallback((raw) => {
11
19
  let next = (raw ?? '').replace(/[^0-9.-]/g, '');
12
- // Collapse multiple '-' to one at start
13
20
  next = next.replace(/(?!^)-/g, '');
14
21
  if (next.includes('.')) {
15
22
  const [intPart, decPart] = next.split('.');
@@ -17,40 +24,39 @@ const FormNumberFieldDecimal = ({ props, variant, }) => {
17
24
  next = `${intPart}.${clampedDec}`;
18
25
  }
19
26
  return next;
20
- };
21
- const label = variant !== 'standard' ? `${props.item.label}${props.item.required ? ' *' : ''}` : '';
22
- const isError = !!props.errors?.[props.item.name];
23
- const isShowBorderError = isError;
24
- return (jsx(Controller, { name: props.item.name, control: props.control, disabled: props.item?.disable, render: ({ field }) => (jsxs(Fragment, { children: [renderLabel(variant, props), jsx(TextField, { type: "text", size: "small", label: label, error: isShowBorderError, ...field, value: field.value ?? '', onChange: (e) => {
25
- const sanitized = sanitizeDecimal(e.target.value ?? '');
26
- const value = sanitized === '' ? null : sanitized;
27
- field.onChange(value);
28
- props?.clearErrors && props?.clearErrors(props.item.name);
29
- }, sx: {
30
- '& input': {
31
- textAlign: 'right',
32
- },
33
- '& input::placeholder': {
34
- textAlign: 'left',
35
- },
36
- '& .css-16hdwvj,.css-1idq7r3-MuiFormLabel-root-MuiInputLabel-root': {
37
- top: '-5px',
38
- },
39
- }, placeholder: props.item.placeholder || '', onBlur: (e) => {
40
- props?.item?.onBlurFn && props?.item?.onBlurFn(e);
41
- }, InputProps: {
42
- inputProps: {
43
- onInput: (e) => {
44
- props.item.onInputProps && props.item.onInputProps(e);
45
- },
46
- // allow digits, one dot and optional leading minus
47
- inputMode: 'decimal',
48
- maxLength: 20,
49
- 'aria-labelledby': `${props.item.name}-label`,
50
- 'aria-describedby': `${props.item.name}-helper ${props.item.name}-error`,
51
- 'aria-required': props.item.required ? true : undefined,
52
- },
53
- } }), jsx(FormBottomField, { ...props })] })) }, props.item.name));
27
+ }, [fixedLength]);
28
+ const handleChange = useCallback((e) => {
29
+ const sanitized = sanitizeDecimal(e.target.value ?? '');
30
+ const value = sanitized === '' ? null : sanitized;
31
+ field.onChange(value);
32
+ props?.clearErrors && props?.clearErrors(props.item.name);
33
+ }, [sanitizeDecimal, field, props.item.name, props.clearErrors]);
34
+ const handleBlur = useCallback((e) => {
35
+ props?.item?.onBlurFn && props?.item?.onBlurFn(e);
36
+ }, [props.item.onBlurFn]);
37
+ const handleInput = useCallback((e) => {
38
+ props.item.onInputProps && props.item.onInputProps(e);
39
+ }, [props.item.onInputProps]);
40
+ return (jsxs(Fragment, { children: [renderLabel(variant, props), jsx(TextField, { type: "text", size: "small", label: label, error: isError, ...field, value: field.value ?? '', onChange: handleChange, onBlur: handleBlur, sx: {
41
+ '& input': {
42
+ textAlign: 'right',
43
+ },
44
+ '& input::placeholder': {
45
+ textAlign: 'left',
46
+ },
47
+ '& .css-16hdwvj,.css-1idq7r3-MuiFormLabel-root-MuiInputLabel-root': {
48
+ top: '-5px',
49
+ },
50
+ }, placeholder: props.item.placeholder || '', InputProps: {
51
+ inputProps: {
52
+ onInput: handleInput,
53
+ inputMode: 'decimal',
54
+ maxLength: 20,
55
+ 'aria-labelledby': `${props.item.name}-label`,
56
+ 'aria-describedby': `${props.item.name}-helper ${props.item.name}-error`,
57
+ 'aria-required': props.item.required ? true : undefined,
58
+ },
59
+ } }), jsx(FormBottomField, { ...props })] }));
54
60
  };
55
61
 
56
62
  export { FormNumberFieldDecimal as default };
@@ -1,4 +1,5 @@
1
1
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
+ import { useCallback } from 'react';
2
3
  import { Controller } from 'react-hook-form';
3
4
  import { Tooltip, Box } from '@mui/material';
4
5
  import { FormTextFieldComponent } from './FormTextField.styles.esm.js';
@@ -58,7 +59,7 @@ const FormTextField = ({ props, variant }) => {
58
59
  * - Prevents input that starts with a space
59
60
  * - Calls custom onInputProps handler if provided
60
61
  */
61
- const onInput = (e) => {
62
+ const onInput = useCallback((e) => {
62
63
  if (props?.item?.donotAllowSpace) {
63
64
  const value = e.target.value;
64
65
  e.target.value = value.replace(' ', '');
@@ -79,12 +80,11 @@ const FormTextField = ({ props, variant }) => {
79
80
  const value = e.target.value;
80
81
  e.target.value = value.replace(/-/g, '');
81
82
  }
82
- // Allow only alphanumeric and space
83
83
  if (e.target.value.length === 1 && e.target.value === ' ') {
84
84
  e.target.value = '';
85
85
  }
86
86
  props.item.onInputProps && props.item.onInputProps(e);
87
- };
87
+ }, [props.item]);
88
88
  /**
89
89
  * Renders the text field component using react-hook-form's Controller
90
90
  * for controlled form state management
@@ -1,4 +1,5 @@
1
1
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
+ import { useCallback } from 'react';
2
3
  import { Controller } from 'react-hook-form';
3
4
  import FormBottomField from '../FormBottomField/FormBottomField.esm.js';
4
5
  import 'dayjs';
@@ -57,11 +58,11 @@ const FormTextFieldWithSelect = ({ props, variant, }) => {
57
58
  * - Prevents input that starts with a space
58
59
  * - Calls custom onInputProps handler if provided
59
60
  */
60
- const onInput = (e) => {
61
+ const onInput = useCallback((e) => {
61
62
  props.item.onInputProps && props.item.onInputProps(e);
62
63
  const filteredValue = e.target.value.replace(/[^a-zA-Z0-9._]/g, '');
63
64
  e.target.value = filteredValue;
64
- };
65
+ }, [props.item.onInputProps]);
65
66
  /**
66
67
  * Renders the text field component using react-hook-form's Controller
67
68
  * for controlled form state management
@@ -1,7 +1,7 @@
1
1
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
2
  import { Visibility, VisibilityOff } from '@mui/icons-material';
3
3
  import { Box, FormControl, TextField, IconButton } from '@mui/material';
4
- import { useState } from 'react';
4
+ import { useState, useCallback } from 'react';
5
5
  import { Controller } from 'react-hook-form';
6
6
  import FormBottomField from '../FormBottomField/FormBottomField.esm.js';
7
7
  import 'dayjs';
@@ -30,9 +30,9 @@ const PasswordField = ({ props, variant }) => {
30
30
  /**
31
31
  * Toggles password visibility between plain text and hidden
32
32
  */
33
- const handleTogglePasswordVisibility = () => {
34
- setShowPassword((prevShowPassword) => !prevShowPassword);
35
- };
33
+ const handleTogglePasswordVisibility = useCallback(() => {
34
+ setShowPassword((prev) => !prev);
35
+ }, []);
36
36
  /**
37
37
  * Generates the field label based on variant type
38
38
  * For non-standard variants, appends an asterisk if the field is required
@@ -1,5 +1,5 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
- import { useRef, useState, useEffect } from 'react';
2
+ import { useRef, useState, useEffect, useMemo, useCallback } from 'react';
3
3
  import { useWatch } from 'react-hook-form';
4
4
  import { getJoditEditor } from './jodit.index.esm.js';
5
5
 
@@ -13,10 +13,7 @@ const RichTextEditor = ({ props }) => {
13
13
  const loadJoditDependencies = async () => {
14
14
  try {
15
15
  const joditEditorModule = await getJoditEditor();
16
- // Extract the default export if present
17
- const Editor = joditEditorModule?.default
18
- ? joditEditorModule.default
19
- : joditEditorModule;
16
+ const Editor = joditEditorModule?.default ?? joditEditorModule;
20
17
  setJoditEditor(() => Editor);
21
18
  setIsLoading(false);
22
19
  }
@@ -26,7 +23,9 @@ const RichTextEditor = ({ props }) => {
26
23
  };
27
24
  loadJoditDependencies();
28
25
  }, []);
29
- const config = {
26
+ // Memoised Jodit config — only rebuilds when the item-level options change,
27
+ // not on every keystroke / re-render of the parent form.
28
+ const config = useMemo(() => ({
30
29
  readonly: false,
31
30
  placeholder: props.item.placeholder || 'Start typing...',
32
31
  statusbar: false,
@@ -36,8 +35,8 @@ const RichTextEditor = ({ props }) => {
36
35
  font: { list: { Arial: 'Arial', ...props.item?.FontFamily } },
37
36
  fontsize: {
38
37
  list: props.item.Fonts || [
39
- 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
40
- 25, 26, 27, 28, 29, 30,
38
+ 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
39
+ 24, 25, 26, 27, 28, 29, 30,
41
40
  ],
42
41
  },
43
42
  },
@@ -81,25 +80,27 @@ const RichTextEditor = ({ props }) => {
81
80
  },
82
81
  },
83
82
  ...props.item.sx,
84
- };
83
+ }),
84
+ // eslint-disable-next-line react-hooks/exhaustive-deps
85
+ [
86
+ props.item.placeholder,
87
+ props.item.removeButtons,
88
+ props.item.FontFamily,
89
+ props.item.Fonts,
90
+ props.item.sx,
91
+ ]);
85
92
  useEffect(() => {
86
93
  setContent(value);
87
94
  }, [value]);
88
- const handleBlur = (newContent) => {
89
- if (newContent === '<p><br></p>') {
90
- setContent(newContent);
91
- props.setValue(props.item.name, '');
92
- }
93
- else {
94
- setContent(newContent);
95
- props.setValue(props.item.name, newContent);
96
- }
97
- // eslint-disable-next-line @typescript-eslint/no-unused-expressions
95
+ const handleBlur = useCallback((newContent) => {
96
+ const normalized = newContent === '<p><br></p>' ? '' : newContent;
97
+ setContent(newContent);
98
+ props.setValue(props.item.name, normalized);
98
99
  props.item.onBlurFn && props.item.onBlurFn(newContent);
99
- };
100
- const handleChange = (newContent) => {
100
+ }, [props.setValue, props.item.name, props.item.onBlurFn]);
101
+ const handleChange = useCallback((newContent) => {
101
102
  props.item.onChangeFn && props.item.onChangeFn(newContent);
102
- };
103
+ }, [props.item.onChangeFn]);
103
104
  if (isLoading || !JoditEditor) {
104
105
  return jsx("div", { children: "Loading editor..." });
105
106
  }
@@ -1,5 +1,5 @@
1
1
  import { jsxs, jsx } from 'react/jsx-runtime';
2
- import { useState } from 'react';
2
+ import { useState, useCallback, useMemo } from 'react';
3
3
  import { FormControl, Box, TextField, InputAdornment, Popover, List, Typography, ListItemButton, ListItemText } from '@mui/material';
4
4
  import SearchIcon from '@mui/icons-material/Search';
5
5
  import CheckIcon from '@mui/icons-material/Check';
@@ -17,23 +17,23 @@ const SearchableSelect = ({ props, variant, }) => {
17
17
  // Find the label that corresponds to the currently selected value
18
18
  const selectedOption = options.find((o) => String(o.value) === String(value ?? ''));
19
19
  const displayValue = selectedOption ? String(selectedOption.label) : '';
20
- const handleOpen = (e) => {
20
+ const handleOpen = useCallback((e) => {
21
21
  if (props.item.disable)
22
22
  return;
23
23
  setSearch('');
24
24
  setAnchorEl(e.currentTarget);
25
- };
26
- const handleClose = () => setAnchorEl(null);
27
- const handleSelect = (val) => {
25
+ }, [props.item.disable]);
26
+ const handleClose = useCallback(() => setAnchorEl(null), []);
27
+ const handleSelect = useCallback((val) => {
28
28
  props.setValue(props.item.name, val);
29
29
  props.item.onChangeFn && props.item.onChangeFn(val);
30
30
  props.clearErrors && props.clearErrors(props.item.name);
31
- handleClose();
32
- };
31
+ setAnchorEl(null);
32
+ }, [props.setValue, props.item.name, props.item.onChangeFn, props.clearErrors]);
33
33
  // Case-insensitive substring filter across option labels
34
- const filtered = search
34
+ const filtered = useMemo(() => search
35
35
  ? options.filter((o) => String(o.label).toLowerCase().includes(search.toLowerCase()))
36
- : options;
36
+ : options, [search, options]);
37
37
  // Label shown inside the MUI TextField (suppressed in 'standard' variant)
38
38
  const muiLabel = variant !== 'standard'
39
39
  ? `${props.item.label}${props.item.required ? ' *' : ''}`
@@ -1,13 +1,13 @@
1
1
  import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
2
2
  import { ErrorMessage } from '@hookform/error-message';
3
- import { useState, useEffect } from 'react';
3
+ import { useState, useEffect, useCallback } from 'react';
4
4
  import { getTimePicker } from '../../../utils/Constants/date-pickers.esm.js';
5
5
  import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
6
6
  import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
7
7
  import { useWatch, Controller } from 'react-hook-form';
8
8
  import { ErrorMessageComponent } from '../../Form/Form.styles.esm.js';
9
9
  import 'dayjs';
10
- import { renderLabel, parseCustomTime, formatDayjsToCustomTime } from '../../../utils/Constants/FormConstants.esm.js';
10
+ import { parseCustomTime, formatDayjsToCustomTime, renderLabel } from '../../../utils/Constants/FormConstants.esm.js';
11
11
 
12
12
  function TimePickerFieldWrapper({ props, variant, }) {
13
13
  const [TimePicker, setTimePicker] = useState(null);
@@ -22,26 +22,26 @@ function TimePickerFieldWrapper({ props, variant, }) {
22
22
  loadComponents();
23
23
  }, []);
24
24
  const value = useWatch({ control: props.control, name: props.item.name });
25
- const isError = !!props.errors?.[props.item.name];
26
- const isShowBorderError = isError;
25
+ const isShowBorderError = !!props.errors?.[props.item.name];
26
+ const handleTimeChange = useCallback((newTime) => {
27
+ const parsedTime = parseCustomTime(formatDayjsToCustomTime(newTime));
28
+ const min = props.item.minTime ? parseCustomTime(props.item.minTime) : null;
29
+ const max = props.item.maxTime ? parseCustomTime(props.item.maxTime) : null;
30
+ let finalTime = parsedTime;
31
+ if (min && parsedTime?.isBefore(min)) {
32
+ finalTime = min;
33
+ }
34
+ else if (max && parsedTime?.isAfter(max)) {
35
+ finalTime = max;
36
+ }
37
+ const formatted = formatDayjsToCustomTime(finalTime);
38
+ props.setValue(props.item.name, formatted);
39
+ props.item.onChangeFn && props.item.onChangeFn(formatted);
40
+ }, [props.item.minTime, props.item.maxTime, props.item.name, props.item.onChangeFn, props.setValue]);
27
41
  if (isLoading) {
28
42
  return jsx("div", { style: { minHeight: '36px' }, children: "Loading..." });
29
43
  }
30
- return (jsx(Fragment, { children: TimePicker && (jsxs(LocalizationProvider, { dateAdapter: AdapterDayjs, children: [jsx(Controller, { name: props.item.name, control: props.control, render: ({ field }) => (jsxs(Fragment, { children: [renderLabel(variant, props), jsx(TimePicker, { ...field, value: value ? parseCustomTime(value) : null, onChange: (newTime) => {
31
- const parsedTime = parseCustomTime(formatDayjsToCustomTime(newTime));
32
- const min = props.item.minTime ? parseCustomTime(props.item.minTime) : null;
33
- const max = props.item.maxTime ? parseCustomTime(props.item.maxTime) : null;
34
- let finalTime = parsedTime;
35
- if (min && parsedTime?.isBefore(min)) {
36
- finalTime = min;
37
- }
38
- else if (max && parsedTime?.isAfter(max)) {
39
- finalTime = max;
40
- }
41
- const formatted = formatDayjsToCustomTime(finalTime);
42
- props.setValue(props.item.name, formatted);
43
- props.item.onChangeFn && props.item.onChangeFn(formatted);
44
- }, minTime: props.item.minTime
44
+ return (jsx(Fragment, { children: TimePicker && (jsxs(LocalizationProvider, { dateAdapter: AdapterDayjs, children: [jsx(Controller, { name: props.item.name, control: props.control, render: ({ field }) => (jsxs(Fragment, { children: [renderLabel(variant, props), jsx(TimePicker, { ...field, value: value ? parseCustomTime(value) : null, onChange: handleTimeChange, minTime: props.item.minTime
45
45
  ? parseCustomTime(props.item.minTime) || undefined
46
46
  : undefined, maxTime: props.item.maxTime
47
47
  ? parseCustomTime(props.item.maxTime) || undefined
@@ -1,7 +1,6 @@
1
1
  export { default as FormNumberField } from './FormNumberField/FormNumberField.esm.js';
2
2
  export { default as FormNumberFieldDecimal } from './FormNumberField/FormNumberFieldDecimal.esm.js';
3
3
  export { default as FormTextAreaField } from './FormTextAreaField/FormTextAreaField.esm.js';
4
- export { default as FormTextField } from './FormTextField/FormTextField.esm.js';
5
4
  export { default as PasswordField } from './PasswordField/PasswordField.esm.js';
6
5
  export { default as FormCheckBox } from './FormCheckBox/FormCheckBox.esm.js';
7
6
  export { default as SingleSelect } from './Select/SingleSelect.esm.js';
@@ -15,7 +14,6 @@ export { default as FormRadioGroup } from './FormRadioGroup/FormRadioGroup.esm.j
15
14
  export { default as DatepickerWrapperV2 } from './DatePicker/DatepickerWrapperV2.esm.js';
16
15
  export { default as Monthpickerrender } from './DatePicker/Monthpickerrender.esm.js';
17
16
  export { default as YearPickerField } from './YearPickerField/YearPickerField.esm.js';
18
- export { default as TimePicker } from './TimePicker/TimePicker.esm.js';
19
17
  export { default as FormRenderFileUpload } from './FileUpload/FormRenderFileUpload.esm.js';
20
18
  export { default as FormRenderMultiFileUpload } from './FileUpload/FormRenderMultiFileUpload.esm.js';
21
19
  import 'react/jsx-runtime';
@@ -34,6 +32,8 @@ import '@mui/icons-material/PictureAsPdf';
34
32
  import '@mui/icons-material/TableChart';
35
33
  import '@mui/icons-material/Description';
36
34
  export { default as FormErrorField } from './FormErrorField/FormErrorField.esm.js';
35
+ export { default as FormTextField } from './FormTextField/FormTextField.esm.js';
37
36
  export { default as HelperText } from './HelperText/HelperText.esm.js';
38
37
  export { default as RichTextEditor } from './RichTextEditor/RichTextEditor.esm.js';
39
38
  export { default as RichTextEditorWrapper } from './RichTextEditor/RichTextEditorWrapper.esm.js';
39
+ export { default as TimePicker } from './TimePicker/TimePicker.esm.js';
@@ -25,7 +25,7 @@ const ConfirmationDialog = ({ openConfirmDialog, handleCancel, onClickSubmit, te
25
25
  fontSize: '14px',
26
26
  cursor: 'move',
27
27
  borderBottom: '1px solid rgb(229 231 235 / 1)',
28
- }, children: [jsx("span", { children: title }), jsx(CloseIcon, { sx: { cursor: 'pointer' }, onClick: () => handleCancel() })] }), jsxs(DialogContent, { style: { paddingTop: '20px', paddingBottom: 0 }, sx: {
28
+ }, children: [jsx("span", { children: title }), jsx(CloseIcon, { sx: { cursor: 'pointer' }, onClick: handleCancel })] }), jsxs(DialogContent, { style: { paddingTop: '20px', paddingBottom: 0 }, sx: {
29
29
  '& .pt-0': {
30
30
  paddingTop: 0,
31
31
  },
@@ -33,14 +33,14 @@ const ConfirmationDialog = ({ openConfirmDialog, handleCancel, onClickSubmit, te
33
33
  display: 'flex',
34
34
  justifyContent: 'flex-end',
35
35
  gap: '8px',
36
- }, children: [jsx(SubmitButton, { variant: "contained", size: "small", type: "submit", onClick: () => onClickSubmit(), children: Submit }), jsx(Button, { variant: "text",
36
+ }, children: [jsx(SubmitButton, { variant: "contained", size: "small", type: "submit", onClick: onClickSubmit, children: Submit }), jsx(Button, { variant: "text",
37
37
  // color="error"
38
38
  size: "small", sx: {
39
39
  textTransform: 'none',
40
40
  color: '#000',
41
41
  background: '#ececee',
42
42
  ':hover': { background: '#0009', color: '#fff' },
43
- }, onClick: () => handleCancel(), children: Cancel })] }) })] }));
43
+ }, onClick: handleCancel, children: Cancel })] }) })] }));
44
44
  };
45
45
 
46
46
  export { ConfirmationDialog as default };
@@ -1,24 +1,17 @@
1
1
  import { jsxs, jsx } from 'react/jsx-runtime';
2
2
  import CloseIcon from '@mui/icons-material/Close';
3
- import { DialogContent, DialogActions, Slide } from '@mui/material';
3
+ import { Slide, DialogContent, DialogActions } from '@mui/material';
4
4
  import { DialogContainer, DialogTitleWrapper, SaveAsDraftButton, SubmitButton, CancelButton } from '../Global.styles.esm.js';
5
5
 
6
6
  const ModalField = ({ name, openModal, handleCancel, content, width = '900px', Transition = '', handleSubmit, styles = {}, saveButton: isSaveButton = false, submitButton = true, handleSaveButton = () => null, SubmitButtonName = 'Submit', }) => {
7
- const TransitionComponent = () => {
8
- switch (Transition) {
9
- case 'Slide':
10
- return Slide;
11
- default:
12
- return undefined;
13
- }
14
- };
15
- return (jsxs(DialogContainer, { open: openModal, TransitionComponent: TransitionComponent(), fullWidth: true, "aria-labelledby": "draggable-dialog-title", sx: {
7
+ const transitionComponent = Transition === 'Slide' ? Slide : undefined;
8
+ return (jsxs(DialogContainer, { open: openModal, TransitionComponent: transitionComponent, fullWidth: true, "aria-labelledby": "draggable-dialog-title", sx: {
16
9
  zIndex: 20,
17
10
  '& .css-tlc64q-MuiPaper-root-MuiDialog-paper,.css-mbdu2s': {
18
11
  maxWidth: width,
19
12
  },
20
13
  ...styles,
21
- }, children: [jsxs(DialogTitleWrapper, { children: [jsx("span", { children: name }), jsx(CloseIcon, { sx: { cursor: 'pointer' }, onClick: () => handleCancel() })] }), jsx(DialogContent, { style: { paddingTop: '20px', paddingBottom: 0 }, sx: {
14
+ }, children: [jsxs(DialogTitleWrapper, { children: [jsx("span", { children: name }), jsx(CloseIcon, { sx: { cursor: 'pointer' }, onClick: handleCancel })] }), jsx(DialogContent, { style: { paddingTop: '20px', paddingBottom: 0 }, sx: {
22
15
  '& .pt-0': {
23
16
  paddingTop: 0,
24
17
  },
@@ -26,7 +19,7 @@ const ModalField = ({ name, openModal, handleCancel, content, width = '900px', T
26
19
  display: 'flex',
27
20
  justifyContent: 'flex-end',
28
21
  gap: '8px',
29
- }, children: [isSaveButton && (jsx(SaveAsDraftButton, { variant: "contained", size: "small", onClick: () => handleSaveButton(), children: "Save" })), submitButton && (jsx(SubmitButton, { variant: "contained", size: "small", onClick: () => handleSubmit(), children: SubmitButtonName })), jsx(CancelButton, { variant: "text", size: "small", onClick: () => handleCancel(), children: "Cancel" })] }) })] }));
22
+ }, children: [isSaveButton && (jsx(SaveAsDraftButton, { variant: "contained", size: "small", onClick: handleSaveButton, children: "Save" })), submitButton && (jsx(SubmitButton, { variant: "contained", size: "small", onClick: handleSubmit, children: SubmitButtonName })), jsx(CancelButton, { variant: "text", size: "small", onClick: handleCancel, children: "Cancel" })] }) })] }));
30
23
  };
31
24
 
32
25
  export { ModalField as default };
@@ -132,7 +132,7 @@ export interface DynamicFilterBarProps {
132
132
  filterValues: Record<string, string>;
133
133
  onFilterValuesChange: (values: Record<string, string>) => void;
134
134
  columnFilters: MRT_ColumnFiltersState;
135
- onColumnFilterChange: (f: MRT_ColumnFiltersState) => void;
135
+ onColumnFilterChange: (f: MRT_ColumnFiltersState | ((prev: MRT_ColumnFiltersState) => MRT_ColumnFiltersState)) => void;
136
136
  availableColumns: AvailableColumn[];
137
137
  /** Maximum number of chips that may be visible at once. Default: 4. */
138
138
  maxVisibleFilters?: number;