form-craft-package 1.8.2-dev.1 → 1.8.2-dev.2

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 (32) hide show
  1. package/package.json +1 -1
  2. package/src/components/common/custom-hooks/index.ts +1 -0
  3. package/src/components/common/custom-hooks/use-login-handler.ts +3 -3
  4. package/src/components/common/custom-hooks/use-node-condition.hook/use-disabled-elements.hook.ts +62 -22
  5. package/src/components/common/custom-hooks/use-node-condition.hook/use-hidden-elements.hook.ts +54 -42
  6. package/src/components/common/custom-hooks/use-set-persistent-domain.hook.ts +20 -0
  7. package/src/components/companies/3-config-provider/index.tsx +27 -2
  8. package/src/components/form/2-details/index.tsx +14 -5
  9. package/src/components/form/layout-renderer/1-row/index.tsx +5 -1
  10. package/src/components/form/layout-renderer/1-row/repeatable-render.tsx +69 -28
  11. package/src/components/form/layout-renderer/3-element/10-currency.tsx +4 -2
  12. package/src/components/form/layout-renderer/3-element/11-breadcrumb.tsx +4 -2
  13. package/src/components/form/layout-renderer/3-element/12-picker-field.tsx +4 -7
  14. package/src/components/form/layout-renderer/3-element/2-field-element.tsx +203 -225
  15. package/src/components/form/layout-renderer/3-element/3-read-field-data.tsx +4 -6
  16. package/src/components/form/layout-renderer/3-element/4-rich-text-editor.tsx +4 -1
  17. package/src/components/form/layout-renderer/3-element/5-re-captcha.tsx +4 -7
  18. package/src/components/form/layout-renderer/3-element/6-signature.tsx +4 -2
  19. package/src/components/form/layout-renderer/3-element/7-file-upload.tsx +78 -26
  20. package/src/components/form/layout-renderer/3-element/8-fields-with-options.tsx +4 -2
  21. package/src/components/form/layout-renderer/3-element/9-form-data-render.tsx +4 -2
  22. package/src/components/form/layout-renderer/3-element/index.tsx +125 -86
  23. package/src/enums/form.enum.ts +4 -0
  24. package/src/enums/index.ts +1 -0
  25. package/src/functions/companies/index.tsx +12 -0
  26. package/src/functions/companies/use-company-config.tsx +14 -10
  27. package/src/functions/forms/data-render-functions.tsx +0 -1
  28. package/src/functions/forms/get-element-props.ts +2 -2
  29. package/src/functions/forms/index.ts +3 -1
  30. package/src/types/companies/site-layout/authenticated/index.tsx +5 -2
  31. package/src/types/forms/index.ts +9 -4
  32. package/src/types/forms/layout-elements/button.ts +1 -1
@@ -1,4 +1,4 @@
1
- import { Key, ReactNode, Fragment } from 'react'
1
+ import { Key, ReactNode, Fragment, memo } from 'react'
2
2
  import { FaCaretDown } from 'react-icons/fa'
3
3
  import dayjs, { Dayjs } from 'dayjs'
4
4
  import { CountryEnum, DataSanitizationTypeEnum, ElementTypeEnum } from '../../../../enums'
@@ -15,22 +15,24 @@ interface ILayoutRenderer_FieldElement {
15
15
  formRef?: FormInstance
16
16
  }
17
17
 
18
- export const LayoutRenderer_FieldElement = ({ children, formRef }: ILayoutRenderer_FieldElement): JSX.Element => {
19
- if (Array.isArray(children()))
18
+ export const LayoutRenderer_FieldElement = memo(({ children, formRef }: ILayoutRenderer_FieldElement): JSX.Element => {
19
+ const elems = children()
20
+ if (Array.isArray(elems)) {
20
21
  return (
21
22
  <>
22
- {(children() as IMapperFieldObj[])
23
+ {elems
23
24
  .filter(({ isHidden = false }) => !isHidden)
24
- .map((field: IMapperFieldObj, fieldIdx: Key) => (
25
- <FieldFormItemWrapper field={field} fieldIdx={fieldIdx} formRef={formRef} />
25
+ .map((field: IMapperFieldObj, idx: Key) => (
26
+ <FieldFormItemWrapper key={idx} field={field} fieldIdx={idx} formRef={formRef} />
26
27
  ))}
27
28
  </>
28
29
  )
30
+ }
29
31
 
30
- if ((children() as IMapperFieldObj).isHidden) return <></>
32
+ if (elems.isHidden) return <></>
31
33
 
32
- return <FieldFormItemWrapper field={children() as IMapperFieldObj} fieldIdx={1} formRef={formRef} />
33
- }
34
+ return <FieldFormItemWrapper field={elems} fieldIdx={1} formRef={formRef} />
35
+ })
34
36
 
35
37
  const FieldFormItemWrapper = ({
36
38
  field,
@@ -40,231 +42,204 @@ const FieldFormItemWrapper = ({
40
42
  field: IMapperFieldObj
41
43
  fieldIdx: Key
42
44
  formRef?: FormInstance
43
- }) => (
44
- <Fragment key={fieldIdx}>
45
- <Form.Item
46
- key={fieldIdx}
47
- name={field.name}
48
- label={field.hasNoLabel ? '' : field.label}
49
- labelAlign="left"
50
- messageVariables={{ [field.name as string]: formRef?.getFieldValue(field.name) }}
51
- valuePropName={
52
- field.type && [ElementTypeEnum.Checkbox, ElementTypeEnum.Switch].includes(field.type) ? 'checked' : 'value'
53
- }
54
- rules={mapToFormItemRules(field.validations ?? [], field.name as string)}
55
- normalize={(value) => {
56
- const sanitizationRule = field.sanitization
57
- if (!sanitizationRule || sanitizationRule.type === DataSanitizationTypeEnum.Default) return value
45
+ }) => {
46
+ const { name, nameFullPath, label, hasNoLabel, type, validations, sanitization, disabled } = field
58
47
 
59
- if (sanitizationRule.type === DataSanitizationTypeEnum.Predefined && sanitizationRule.pattern)
60
- return formatByPattern(value, sanitizationRule.pattern)
48
+ return (
49
+ <Fragment key={fieldIdx}>
50
+ <Form.Item
51
+ name={name}
52
+ label={hasNoLabel ? '' : label}
53
+ labelAlign="left"
54
+ messageVariables={{ [String(name)]: formRef?.getFieldValue(name) }}
55
+ valuePropName={type && [ElementTypeEnum.Checkbox, ElementTypeEnum.Switch].includes(type) ? 'checked' : 'value'}
56
+ rules={mapToFormItemRules(validations ?? [], String(name))}
57
+ normalize={(value) => {
58
+ if (!sanitization || sanitization.type === DataSanitizationTypeEnum.Default) return value
61
59
 
62
- if (sanitizationRule.type === DataSanitizationTypeEnum.Custom)
63
- return formatByPattern(value, sanitizationRule.pattern)
64
- }}
65
- >
66
- {field.type === ElementTypeEnum.ColorPicker ? (
67
- <CustomColorField formRef={formRef} name={field.name} disabled={field.disabled} />
68
- ) : (
69
- getField(field)
70
- )}
71
- </Form.Item>
72
- {field.disabled && field.type !== ElementTypeEnum.Checkbox && <DisabledFieldIndicator />}
73
- </Fragment>
74
- )
60
+ // Predefined or Custom both use pattern
61
+ if (sanitization.pattern) {
62
+ return formatByPattern(value, sanitization.pattern)
63
+ }
75
64
 
76
- const getField = ({
77
- disabled,
78
- options = [],
79
- type = ElementTypeEnum.ShortInput,
80
- label,
81
- allowClear = true,
82
- isMultiValue = false,
83
- placeholder,
84
- minRows = 3,
85
- numberFieldMin,
86
- numberFieldMax,
87
- isCustom,
88
- country = CountryEnum.US,
89
- decimalPoint = 0,
90
- mode,
91
- disabledDate,
92
- }: Partial<IMapperFieldObj>): JSX.Element => {
93
- switch (type) {
94
- case ElementTypeEnum.LongInput:
95
- return (
96
- <Input.TextArea
97
- autoSize={{ minRows }}
98
- placeholder={placeholder as string}
99
- disabled={disabled}
100
- autoComplete="off"
101
- className={ELEMENTS_DEFAULT_CLASS.Input}
102
- />
103
- )
104
- case ElementTypeEnum.Select:
105
- return (
106
- <Select
107
- placeholder={placeholder}
108
- suffixIcon={<FaCaretDown />}
109
- options={options}
110
- disabled={disabled}
111
- showSearch
112
- optionFilterProp="label"
113
- filterOption={(input, option) => {
114
- const noOtherField = !option?.field2 && !option?.field3 && !option?.field4
115
- const text = option
116
- ? typeof option.label === 'string' && noOtherField
117
- ? option.label
118
- : [option.label, option.field2 ?? '', option.field3 ?? '', option.field4 ?? ''].join(' ')
119
- : ''
120
-
121
- return text.toLowerCase().indexOf(input.toLowerCase()) >= 0
122
- }}
123
- optionRender={(option: any) => {
124
- const opData = option.data || {}
125
- const noOtherField = !opData.field2 && !opData.field3 && !opData.field4
65
+ return value
66
+ }}
67
+ >
68
+ {type === ElementTypeEnum.ColorPicker ? (
69
+ <CustomColorField formRef={formRef} name={nameFullPath} disabled={disabled} />
70
+ ) : (
71
+ getField(field)
72
+ )}
73
+ </Form.Item>
74
+ {disabled && type !== ElementTypeEnum.Checkbox && <DisabledFieldIndicator />}
75
+ </Fragment>
76
+ )
77
+ }
126
78
 
127
- if (noOtherField) return option.label
79
+ // Map each ElementTypeEnum to a renderer function
80
+ type FieldRenderer = (field: Partial<IMapperFieldObj>) => JSX.Element
128
81
 
129
- return (
130
- <div key={opData.value} className="flex flex-col gap-0.5">
131
- <div className="space-x-2">
132
- <span className="text-primary font-bold">{opData.label}</span>
133
- {opData.field2 && (
134
- <span className="text-12 italic font-normal">
135
- ({opData.field2_RC ? renderData(opData.field2, opData.field2_RC) : opData.field2})
136
- </span>
137
- )}
138
- </div>
139
- {opData.field3 && (
140
- <div className="text-12">
141
- {opData.field3_RC ? renderData(opData.field3, opData.field3_RC) : opData.field3}
142
- </div>
143
- )}
144
- {opData.field4 && opData.field4_RC ? renderData(opData.field4, opData.field4_RC) : opData.field4}
145
- </div>
146
- )
147
- }}
148
- allowClear={allowClear}
149
- className={`${ELEMENTS_DEFAULT_CLASS.Select} w-full`}
150
- mode={mode}
151
- />
152
- )
153
- case ElementTypeEnum.Checkbox:
154
- return (
155
- <Checkbox disabled={disabled} className={ElementTypeEnum.Checkbox}>
156
- {label}
157
- </Checkbox>
158
- )
159
- case ElementTypeEnum.Switch:
160
- return (
161
- <div className={`${ELEMENTS_DEFAULT_CLASS.SwitchContainer} flex items-center gap-2`}>
162
- <Switch disabled={disabled} className={ELEMENTS_DEFAULT_CLASS.Switch} />
163
- {label}
164
- </div>
165
- )
166
- case ElementTypeEnum.Radio:
167
- if (isMultiValue)
82
+ const fieldRenderers: Partial<Record<ElementTypeEnum, FieldRenderer>> = {
83
+ [ElementTypeEnum.LongInput]: ({ placeholder, disabled, minRows }) => (
84
+ <Input.TextArea
85
+ autoSize={{ minRows: minRows! }}
86
+ placeholder={placeholder as string}
87
+ disabled={disabled}
88
+ autoComplete="off"
89
+ className={ELEMENTS_DEFAULT_CLASS.Input}
90
+ />
91
+ ),
92
+ [ElementTypeEnum.Select]: ({ placeholder, options = [], disabled, allowClear = true, mode }) => (
93
+ <Select
94
+ placeholder={placeholder}
95
+ suffixIcon={<FaCaretDown />}
96
+ options={options}
97
+ disabled={disabled}
98
+ showSearch
99
+ optionFilterProp="label"
100
+ filterOption={(input, option) => {
101
+ const noOther = !option?.field2 && !option?.field3 && !option?.field4
102
+ const text = option
103
+ ? typeof option.label === 'string' && noOther
104
+ ? option.label
105
+ : [option.label, option.field2 ?? '', option.field3 ?? '', option.field4 ?? ''].join(' ')
106
+ : ''
107
+ return text.toLowerCase().includes(input.toLowerCase())
108
+ }}
109
+ optionRender={(opt: any) => {
110
+ const data = opt.data || {}
111
+ const simple = !data.field2 && !data.field3 && !data.field4
112
+ if (simple) return opt.label
168
113
  return (
169
- <Checkbox.Group disabled={disabled} className={ELEMENTS_DEFAULT_CLASS.CheckboxGroup}>
170
- <div className="flex items-center gap-1">
171
- {options?.map((o, oIdx) => (
172
- <Checkbox key={oIdx} value={o.value}>
173
- {o.label}
174
- </Checkbox>
175
- ))}
114
+ <div className="flex flex-col gap-0.5" key={data.value}>
115
+ <div className="space-x-2">
116
+ <span className="text-primary font-bold">{data.label}</span>
117
+ {data.field2 && (
118
+ <span className="text-12 italic font-normal">
119
+ ({data.field2_RC ? renderData(data.field2, data.field2_RC) : data.field2})
120
+ </span>
121
+ )}
176
122
  </div>
177
- </Checkbox.Group>
123
+ {data.field3 && (
124
+ <div className="text-12">{data.field3_RC ? renderData(data.field3, data.field3_RC) : data.field3}</div>
125
+ )}
126
+ {data.field4 && (data.field4_RC ? renderData(data.field4, data.field4_RC) : data.field4)}
127
+ </div>
178
128
  )
129
+ }}
130
+ allowClear={allowClear}
131
+ className={`${ELEMENTS_DEFAULT_CLASS.Select} w-full`}
132
+ mode={mode}
133
+ />
134
+ ),
135
+ [ElementTypeEnum.Checkbox]: ({ label, disabled }) => (
136
+ <Checkbox disabled={disabled} className={ElementTypeEnum.Checkbox}>
137
+ {label}
138
+ </Checkbox>
139
+ ),
140
+ [ElementTypeEnum.Switch]: ({ label, disabled }) => (
141
+ <div className={`${ELEMENTS_DEFAULT_CLASS.SwitchContainer} flex items-center gap-2`}>
142
+ <Switch disabled={disabled} className={ELEMENTS_DEFAULT_CLASS.Switch} />
143
+ {label}
144
+ </div>
145
+ ),
146
+ [ElementTypeEnum.Radio]: ({ options = [], disabled, isMultiValue, isCustom }) =>
147
+ isMultiValue ? (
148
+ <Checkbox.Group disabled={disabled} className={ELEMENTS_DEFAULT_CLASS.CheckboxGroup}>
149
+ <div className="flex items-center gap-1">
150
+ {options.map((o, i) => (
151
+ <Checkbox key={i} value={o.value}>
152
+ {o.label}
153
+ </Checkbox>
154
+ ))}
155
+ </div>
156
+ </Checkbox.Group>
157
+ ) : (
158
+ <Radio.Group
159
+ disabled={disabled}
160
+ className={`${ELEMENTS_DEFAULT_CLASS.RadioGroup} w-full ${isCustom ? 'fc-custom' : ''}`}
161
+ >
162
+ <div className="flex items-center gap-1">
163
+ {options.map((o, i) => (
164
+ <Radio key={i} value={o.value}>
165
+ {o.label}
166
+ </Radio>
167
+ ))}
168
+ </div>
169
+ </Radio.Group>
170
+ ),
171
+ [ElementTypeEnum.NumberInput]: ({ placeholder, disabled, numberFieldMin, numberFieldMax }) => (
172
+ <InputNumber
173
+ placeholder={placeholder as string}
174
+ disabled={disabled}
175
+ className={`${ELEMENTS_DEFAULT_CLASS.NumberInput} w-full`}
176
+ min={numberFieldMin}
177
+ max={numberFieldMax}
178
+ />
179
+ ),
180
+ [ElementTypeEnum.CurrencyInput]: ({ placeholder, disabled, country, decimalPoint }) => (
181
+ <CurrencyField
182
+ placeholder={placeholder as string}
183
+ disabled={disabled}
184
+ country={country!}
185
+ decimalPoint={decimalPoint!}
186
+ />
187
+ ),
188
+ [ElementTypeEnum.Password]: ({ placeholder, disabled }) => (
189
+ <Input.Password
190
+ className={ELEMENTS_DEFAULT_CLASS.PasswordInput}
191
+ placeholder={placeholder as string}
192
+ disabled={disabled}
193
+ />
194
+ ),
195
+ [ElementTypeEnum.DatePicker]: ({ placeholder, disabled, disabledDate }) => (
196
+ <DatePicker
197
+ format={datepickerFormats}
198
+ placeholder={placeholder as string}
199
+ disabled={disabled}
200
+ disabledDate={(now) => (disabledDate ? disabledDate(now) : dayjs(now).isBefore(dayjs('1900-01-01')))}
201
+ allowClear
202
+ className={`${ELEMENTS_DEFAULT_CLASS.DatePicker} w-full`}
203
+ onChange={(e) => {
204
+ if (dayjs(e).isBefore(dayjs('1900-01-01')))
205
+ Modal.error({ title: 'Invalid Date!', content: 'The year cannot be less than 1900!', centered: true })
206
+ }}
207
+ />
208
+ ),
209
+ [ElementTypeEnum.RangePicker]: ({ placeholder, disabled, disabledDate }) => (
210
+ <DatePicker.RangePicker
211
+ format={datepickerFormats}
212
+ placeholder={placeholder as [string, string]}
213
+ disabled={disabled}
214
+ disabledDate={(now) => (disabledDate ? disabledDate(now) : dayjs(now).isBefore(dayjs('1900-01-01')))}
215
+ allowClear
216
+ className={`${ELEMENTS_DEFAULT_CLASS.RangePicker} w-full`}
217
+ allowEmpty
218
+ />
219
+ ),
220
+ [ElementTypeEnum.TimePicker]: ({ disabled }) => (
221
+ <DatePicker.TimePicker
222
+ format={datepickerFormats}
223
+ disabled={disabled}
224
+ className={`${ELEMENTS_DEFAULT_CLASS.TimePicker} w-full`}
225
+ allowClear
226
+ />
227
+ ),
228
+ [ElementTypeEnum.ShortInput]: ({ placeholder, disabled, name }) => (
229
+ <Input
230
+ id={name as string}
231
+ className={ELEMENTS_DEFAULT_CLASS.Input}
232
+ placeholder={placeholder as string}
233
+ disabled={disabled}
234
+ autoComplete="off"
235
+ />
236
+ ),
237
+ }
179
238
 
180
- return (
181
- <Radio.Group
182
- disabled={disabled}
183
- className={`${ELEMENTS_DEFAULT_CLASS.RadioGroup} w-full ${isCustom ? 'fc-custom' : ''}`}
184
- >
185
- <div className="flex items-center gap-1">
186
- {options?.map((o, oIdx) => (
187
- <Radio key={oIdx} value={o.value}>
188
- {o.label}
189
- </Radio>
190
- ))}
191
- </div>
192
- </Radio.Group>
193
- )
194
- case ElementTypeEnum.NumberInput:
195
- return (
196
- <InputNumber
197
- placeholder={placeholder as string}
198
- disabled={disabled}
199
- className={`${ELEMENTS_DEFAULT_CLASS.NumberInput} w-full`}
200
- min={numberFieldMin}
201
- max={numberFieldMax}
202
- />
203
- )
204
- case ElementTypeEnum.CurrencyInput:
205
- return (
206
- <CurrencyField
207
- placeholder={placeholder as string}
208
- disabled={disabled}
209
- country={country}
210
- decimalPoint={decimalPoint}
211
- />
212
- )
213
- case ElementTypeEnum.Password:
214
- return (
215
- <Input.Password
216
- className={ELEMENTS_DEFAULT_CLASS.PasswordInput}
217
- placeholder={placeholder as string}
218
- disabled={disabled}
219
- />
220
- )
221
- case ElementTypeEnum.DatePicker:
222
- return (
223
- <DatePicker
224
- format={datepickerFormats}
225
- placeholder={placeholder as string}
226
- disabled={disabled}
227
- disabledDate={(now) => (disabledDate ? disabledDate(now) : dayjs(now) < dayjs('01/01/1900'))}
228
- allowClear={allowClear}
229
- className={`${ELEMENTS_DEFAULT_CLASS.DatePicker} w-full`}
230
- onChange={(e) => {
231
- if (dayjs(e) < dayjs('01/01/1900'))
232
- Modal.error({ title: 'Invalid Date!', content: 'The year cannot be less than 1900!', centered: true })
233
- }}
234
- />
235
- )
236
- case ElementTypeEnum.RangePicker:
237
- return (
238
- <DatePicker.RangePicker
239
- format={datepickerFormats}
240
- placeholder={placeholder as [string, string] | undefined}
241
- disabled={disabled}
242
- disabledDate={(now) => (disabledDate ? disabledDate(now) : dayjs(now) < dayjs('01/01/1900'))}
243
- allowClear={allowClear}
244
- className={`${ELEMENTS_DEFAULT_CLASS.RangePicker} w-full`}
245
- allowEmpty
246
- />
247
- )
248
- case ElementTypeEnum.TimePicker:
249
- return (
250
- <DatePicker.TimePicker
251
- format={datepickerFormats}
252
- disabled={disabled}
253
- className={`${ELEMENTS_DEFAULT_CLASS.TimePicker} w-full`}
254
- allowClear={allowClear}
255
- />
256
- )
257
- case ElementTypeEnum.ShortInput:
258
- default:
259
- return (
260
- <Input
261
- className={ELEMENTS_DEFAULT_CLASS.Input}
262
- placeholder={placeholder as string}
263
- disabled={disabled}
264
- autoComplete="off"
265
- />
266
- )
267
- }
239
+ const getField = (field: Partial<IMapperFieldObj>): JSX.Element => {
240
+ const type = field.type ?? ElementTypeEnum.ShortInput
241
+ const renderer = fieldRenderers[type] || fieldRenderers[ElementTypeEnum.ShortInput]
242
+ return renderer!(field)
268
243
  }
269
244
 
270
245
  interface IMapperFieldObj {
@@ -272,6 +247,7 @@ interface IMapperFieldObj {
272
247
  validations?: IValidationRule[]
273
248
  isHidden?: boolean
274
249
  name: string | (string | number)[]
250
+ nameFullPath?: string | (string | number)[]
275
251
  label?: string | ReactNode
276
252
  description?: string
277
253
  placeholder?: string | [string, string]
@@ -290,11 +266,13 @@ interface IMapperFieldObj {
290
266
  mode?: 'multiple' | 'tags'
291
267
  disabledDate?: (date: Dayjs) => boolean
292
268
  }
269
+
293
270
  interface ISelectOption {
294
271
  value: number | boolean | string
295
272
  label: string | ReactNode
296
273
  [key: string]: any
297
274
  }
275
+
298
276
  const datepickerFormats = [
299
277
  'MM/DD/YYYY',
300
278
  'MM/DD/YY',
@@ -1,18 +1,14 @@
1
1
  import { Form } from 'antd'
2
2
  import { renderData } from '../../../../functions/forms'
3
3
  import { useFormPreservedItemValues } from '../../../common/custom-hooks/use-preserved-form-items.hook'
4
- import { useMemo } from 'react'
4
+ import { memo, useMemo } from 'react'
5
5
  import { DataRenderTypeEnum, ReadFieldDataValueTypeEnum } from '../../../../enums'
6
6
  import { IReadFieldDataElementProps } from '../../../../types'
7
7
  import { IFormContext } from '../1-row'
8
8
  import { evaluateValue } from '../../../../functions/forms/evaluate-value'
9
9
  import { ELEMENTS_DEFAULT_CLASS } from '../../../../constants'
10
10
 
11
- export default function LayoutRenderer_ReadFieldData({
12
- formContext,
13
- elementProps,
14
- style = {},
15
- }: ILayoutRenderer_ReadFieldData) {
11
+ function LayoutRenderer_ReadFieldData({ formContext, elementProps, style = {} }: ILayoutRenderer_ReadFieldData) {
16
12
  const { formRef, companyKey } = formContext
17
13
  const fieldValue =
18
14
  elementProps.valueType === ReadFieldDataValueTypeEnum.Evaluated
@@ -54,6 +50,8 @@ export default function LayoutRenderer_ReadFieldData({
54
50
  )
55
51
  }
56
52
 
53
+ export default memo(LayoutRenderer_ReadFieldData)
54
+
57
55
  type ILayoutRenderer_ReadFieldData = {
58
56
  formContext: IFormContext
59
57
  elementProps: IReadFieldDataElementProps
@@ -7,8 +7,9 @@ import { IFormContext } from '../1-row'
7
7
  import { mapToFormItemRules } from '../../../../functions'
8
8
  import { FieldValidationEnum } from '../../../../enums'
9
9
  import { ELEMENTS_DEFAULT_CLASS, REGEX_PATTERNS } from '../../../../constants'
10
+ import { memo } from 'react'
10
11
 
11
- export default function LayoutRenderer_RichEditor({
12
+ function LayoutRenderer_RichEditor({
12
13
  formContext,
13
14
  elementProps,
14
15
  formItem,
@@ -53,6 +54,8 @@ export default function LayoutRenderer_RichEditor({
53
54
  )
54
55
  }
55
56
 
57
+ export default memo(LayoutRenderer_RichEditor)
58
+
56
59
  const formats = ['header', 'bold', 'italic', 'underline', 'align', 'list', 'indent', 'clean']
57
60
  const modules = {
58
61
  toolbar: [
@@ -1,4 +1,4 @@
1
- import { useCallback, useEffect, useRef, useState } from 'react'
1
+ import { memo, useCallback, useEffect, useRef, useState } from 'react'
2
2
  import ReCAPTCHA from 'react-google-recaptcha'
3
3
  import { cancelableClient } from '../../../../api/client'
4
4
  import { IElementBaseProps } from '.'
@@ -6,12 +6,7 @@ import { IReCaptchaElementProps } from '../../../../types'
6
6
  import { IFormContext } from '../1-row'
7
7
  import { ELEMENTS_DEFAULT_CLASS } from '../../../../constants'
8
8
 
9
- export default function LayoutRenderer_ReCaptcha({
10
- formContext,
11
- elementProps,
12
- formItem,
13
- isDisabled,
14
- }: ILayoutRenderer_RichEditor) {
9
+ function LayoutRenderer_ReCaptcha({ formContext, elementProps, formItem, isDisabled }: ILayoutRenderer_RichEditor) {
15
10
  const { formRef, formKey } = formContext
16
11
  const [tokenVerificationFailed, setTokenVerificationFailed] = useState(false)
17
12
  const verifyApiCancelFuncRef = useRef<() => void | undefined>()
@@ -57,6 +52,8 @@ export default function LayoutRenderer_ReCaptcha({
57
52
  )
58
53
  }
59
54
 
55
+ export default memo(LayoutRenderer_ReCaptcha)
56
+
60
57
  type ILayoutRenderer_RichEditor = {
61
58
  elementProps: IReCaptchaElementProps
62
59
  formContext: IFormContext
@@ -1,5 +1,5 @@
1
1
  import { Form } from 'antd'
2
- import { useEffect, useMemo, useRef } from 'react'
2
+ import { memo, useEffect, useMemo, useRef } from 'react'
3
3
  import SignatureCanvas from 'react-signature-canvas'
4
4
  import { FormPreservedItemKeys } from '../../../../enums'
5
5
  import { Button_FillerPortal } from '../../../common/button'
@@ -10,7 +10,7 @@ import { IFormContext } from '../1-row'
10
10
  import { isNewFormDataPage, mapToFormItemRules } from '../../../../functions'
11
11
  import { ELEMENTS_DEFAULT_CLASS } from '../../../../constants'
12
12
 
13
- export default function LayoutRenderer_Signature({
13
+ function LayoutRenderer_Signature({
14
14
  formItem,
15
15
  elementProps,
16
16
  isDisabled,
@@ -81,6 +81,8 @@ export default function LayoutRenderer_Signature({
81
81
  )
82
82
  }
83
83
 
84
+ export default memo(LayoutRenderer_Signature)
85
+
84
86
  type ILayoutRenderer_Signature = {
85
87
  elementProps: ISignatureElementProps
86
88
  formContext: IFormContext