@controleonline/ui-default 1.0.280 → 1.0.281

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.
@@ -1,414 +1,417 @@
1
- import React, { useEffect, useMemo, useState } from 'react';
2
- import { Image, Text, TextInput, TouchableOpacity, View } from 'react-native';
3
- import DefaultExtraData from '../extra-data/DefaultExtraData';
4
- import DefaultFileColumn from '../files/DefaultFileColumn';
5
- import Icon from 'react-native-vector-icons/Feather';
6
- import {
7
- buildReadPresentationStyles,
8
- getColumnKey,
9
- isColorColumn,
10
- isDateLikeColumn,
11
- isEditableColumn,
12
- isExtraDataColumn,
13
- isFileColumn,
14
- isIconColumn,
15
- isValidFeatherIcon,
16
- normalizeText,
17
- resolveCellPresentation,
18
- resolveCellText,
19
- resolveEditValue,
20
- } from './defaultInputUtils';
21
- import DefaultColorInput from './DefaultColorInput';
22
- import DefaultDateInput from './DefaultDateInput';
23
- import DefaultFeatherIconPicker, {
24
- normalizeFeatherIconName,
25
- } from './DefaultFeatherIconPicker';
26
- import DefaultSelect from './DefaultSelect';
27
- import styles from './DefaultInput.styles';
28
-
29
- const DefaultInput = ({
30
- accentColor = '#2563EB',
31
- autoFocus = true,
32
- autoSave = true,
33
- column,
34
- columns = [],
35
- containerStyle = null,
36
- displayValue,
37
- defaultColor = '',
38
- editing = false,
39
- getOptionsForColumn = null,
40
- inputStyle = null,
41
- label = '',
42
- numberOfLines = 1,
43
- onBeforeOpen = null,
44
- onCancelEditing = null,
45
- onChangeValue = null,
46
- onSave = null,
47
- onSearchChange = null,
48
- onStartEditing = null,
49
- readTextStyle = null,
50
- row = {},
51
- saving = false,
52
- showLabel = false,
53
- storeName = '',
54
- value,
55
- variant = 'cell',
56
- }) => {
57
- const fieldName = getColumnKey(column);
58
- const isExtraDataField = isExtraDataColumn(column) || ['extradata', 'extra_data'].includes(
59
- normalizeText(fieldName).replace(/[^a-zA-Z0-9_]/g, '').toLowerCase(),
60
- );
61
- const isForm = variant === 'form';
62
- const canEdit = isEditableColumn(column) && typeof onStartEditing === 'function';
63
- const editValue = useMemo(
64
- () => normalizeText(value ?? resolveEditValue(column, row)),
65
- [column, row, value],
66
- );
67
- const [draftValue, setDraftValue] = useState(editValue);
68
- const resolvedLabel =
69
- displayValue ?? resolveCellText({ column, columns, row, storeName, value });
70
- const readPresentation = useMemo(
71
- () => resolveCellPresentation({ column, columns, row, storeName, value }),
72
- [column, columns, row, storeName, value],
73
- );
74
- const readPresentationStyles = useMemo(
75
- () => buildReadPresentationStyles({
76
- ...readPresentation,
77
- label: resolvedLabel,
78
- }),
79
- [readPresentation, resolvedLabel],
80
- );
81
-
82
- useEffect(() => {
83
- setDraftValue(editValue);
84
- }, [editValue, editing]);
85
-
86
- if (column?.list) {
87
- return (
88
- <DefaultSelect
89
- accentColor={accentColor}
90
- autoSave={autoSave}
91
- column={column}
92
- columns={columns}
93
- containerStyle={containerStyle}
94
- displayValue={displayValue}
95
- editing={editing}
96
- getOptionsForColumn={getOptionsForColumn}
97
- label={label}
98
- numberOfLines={numberOfLines}
99
- onBeforeOpen={onBeforeOpen}
100
- onCancelEditing={onCancelEditing}
101
- onChangeValue={onChangeValue}
102
- onSave={onSave}
103
- onStartEditing={onStartEditing}
104
- readTextStyle={readTextStyle}
105
- row={row}
106
- saving={saving}
107
- showLabel={showLabel}
108
- storeName={storeName}
109
- value={value}
110
- variant={variant}
111
- />
112
- );
113
- }
114
-
115
- if (isColorColumn(column)) {
116
- return (
117
- <DefaultColorInput
118
- accentColor={accentColor}
119
- autoFocus={autoFocus}
120
- autoSave={autoSave}
121
- column={column}
122
- containerStyle={containerStyle}
123
- defaultColor={defaultColor}
124
- editing={editing}
125
- inputStyle={inputStyle}
126
- label={label}
127
- onCancelEditing={onCancelEditing}
128
- onChangeValue={onChangeValue}
129
- onSave={onSave}
130
- onStartEditing={onStartEditing}
131
- row={row}
132
- saving={saving}
133
- showLabel={showLabel}
134
- storeName={storeName}
135
- value={value}
136
- variant={variant}
137
- />
138
- );
139
- }
140
-
141
- if (isIconColumn(column)) {
142
- const fieldNameIcon = getColumnKey(column);
143
- const rawIconValue = value ?? row?.[fieldNameIcon];
144
- const selectedIcon = normalizeFeatherIconName(rawIconValue);
145
- const isFormIcon = variant === 'form';
146
- const canEditIcon = isEditableColumn(column) && typeof onStartEditing === 'function';
147
-
148
- const commitIcon = nextIcon => {
149
- const normalized = normalizeFeatherIconName(nextIcon);
150
- if (autoSave) {
151
- onSave?.(normalized);
152
- return;
153
- }
154
- onChangeValue?.(normalized);
155
- };
156
-
157
- if (!editing && !isFormIcon) {
158
- return (
159
- <View style={[styles.wrap, containerStyle]}>
160
- {showLabel ? (
161
- <Text style={styles.fieldLabel}>{label || column?.label || fieldNameIcon}</Text>
162
- ) : null}
163
- <TouchableOpacity
164
- style={styles.readButton}
165
- activeOpacity={canEditIcon ? 0.78 : 1}
166
- disabled={!canEditIcon}
167
- onPress={() => onStartEditing?.()}
168
- >
169
- <View style={styles.readValueWrap}>
170
- <Icon
171
- name={selectedIcon || 'search'}
172
- size={14}
173
- color={selectedIcon ? '#0F172A' : '#94A3B8'}
174
- />
175
- <Text
176
- style={[
177
- styles.readText,
178
- !selectedIcon ? styles.mutedText : null,
179
- readTextStyle,
180
- ]}
181
- numberOfLines={numberOfLines}
182
- >
183
- {selectedIcon || '-'}
184
- </Text>
185
- </View>
186
- {saving ? (
187
- <Text style={[styles.savingText, { color: accentColor }]}>Salvando</Text>
188
- ) : canEditIcon ? (
189
- <Icon style={styles.editIcon} name="edit-2" size={13} color="#64748B" />
190
- ) : null}
191
- </TouchableOpacity>
192
- </View>
193
- );
194
- }
195
-
196
- return (
197
- <View style={[styles.wrap, containerStyle]}>
198
- {showLabel ? (
199
- <Text style={styles.fieldLabel}>{label || column?.label || fieldNameIcon}</Text>
200
- ) : null}
201
- <View style={styles.editingWrap}>
202
- <View style={styles.editingRow}>
203
- <DefaultFeatherIconPicker
204
- value={selectedIcon}
205
- onChange={commitIcon}
206
- placeholder={
207
- global.t?.t(storeName, 'input', column?.label || fieldNameIcon) ||
208
- 'Buscar icone'
209
- }
210
- style={[isFormIcon ? styles.formInput : null, inputStyle, { flex: 1 }]}
211
- />
212
- {!isFormIcon ? (
213
- <TouchableOpacity
214
- style={styles.cancelButton}
215
- activeOpacity={0.8}
216
- onPress={onCancelEditing}
217
- >
218
- <Icon name="x" size={14} color="#64748B" />
219
- </TouchableOpacity>
220
- ) : null}
221
- </View>
222
- {saving ? <Text style={styles.savingText}>Salvando</Text> : null}
223
- </View>
224
- </View>
225
- );
226
- }
227
-
228
- if (isDateLikeColumn(column)) {
229
- return (
230
- <DefaultDateInput
231
- accentColor={accentColor}
232
- autoFocus={autoFocus}
233
- autoSave={autoSave}
234
- column={column}
235
- columns={columns}
236
- containerStyle={containerStyle}
237
- displayValue={displayValue}
238
- editing={editing}
239
- inputStyle={inputStyle}
240
- label={label}
241
- numberOfLines={numberOfLines}
242
- onCancelEditing={onCancelEditing}
243
- onChangeValue={onChangeValue}
244
- onSave={onSave}
245
- onSearchChange={onSearchChange}
246
- onStartEditing={onStartEditing}
247
- readTextStyle={readTextStyle}
248
- row={row}
249
- saving={saving}
250
- showLabel={showLabel}
251
- storeName={storeName}
252
- value={value}
253
- variant={variant}
254
- />
255
- );
256
- }
257
-
258
- const saveDraft = () => {
259
- if (autoSave) {
260
- onSave?.(draftValue);
261
- return;
262
- }
263
-
264
- onChangeValue?.(draftValue);
265
- };
266
-
267
- const updateDraft = nextValue => {
268
- setDraftValue(nextValue);
269
- if (!autoSave) onChangeValue?.(nextValue);
270
- };
271
-
272
- if (!editing && !isForm) {
273
- if (isExtraDataField) {
274
- return (
275
- <View style={[styles.wrap, containerStyle]}>
276
- {showLabel ? <Text style={styles.fieldLabel}>{label || column?.label || fieldName}</Text> : null}
277
- <DefaultExtraData
278
- column={column}
279
- row={row}
280
- value={value ?? row?.[fieldName]}
281
- variant={variant}
282
- />
283
- </View>
284
- );
285
- }
286
-
287
- if (isFileColumn(column)) {
288
- return (
289
- <View style={[styles.wrap, containerStyle]}>
290
- {showLabel ? <Text style={styles.fieldLabel}>{label || column?.label || fieldName}</Text> : null}
291
- <DefaultFileColumn
292
- column={column}
293
- row={row}
294
- value={value}
295
- variant={variant}
296
- />
297
- </View>
298
- );
299
- }
300
-
301
- const readIconName = isValidFeatherIcon(readPresentation.icon)
302
- ? readPresentation.icon
303
- : '';
304
- const shouldRenderIconFallbackText = Boolean(
305
- readPresentationStyles.hasDecoration &&
306
- !readIconName &&
307
- readPresentationStyles.color &&
308
- normalizeText(resolvedLabel) &&
309
- resolvedLabel !== '-',
310
- );
311
-
312
- return (
313
- <View style={[styles.wrap, containerStyle]}>
314
- {showLabel ? <Text style={styles.fieldLabel}>{label || column?.label || fieldName}</Text> : null}
315
- <TouchableOpacity
316
- style={styles.readButton}
317
- activeOpacity={canEdit ? 0.78 : 1}
318
- disabled={!canEdit}
319
- onPress={() => onStartEditing?.()}
320
- >
321
- {shouldRenderIconFallbackText ? (
322
- <Text
323
- style={[
324
- styles.readText,
325
- styles.readTextBadge,
326
- readPresentationStyles.color ? { color: readPresentationStyles.color } : null,
327
- readTextStyle,
328
- ]}
329
- numberOfLines={numberOfLines}
330
- >
331
- {resolvedLabel}
332
- </Text>
333
- ) : (
334
- <View
335
- style={[
336
- styles.readValueWrap,
337
- readPresentationStyles.hasDecoration ? styles.readBadge : null,
338
- readPresentationStyles.badgeStyle,
339
- ]}
340
- >
341
- {readPresentation.image ? (
342
- <Image
343
- source={readPresentation.image}
344
- style={styles.readImage}
345
- resizeMode="contain"
346
- />
347
- ) : null}
348
- {readPresentationStyles.hasDecoration && readIconName && readPresentationStyles.color ? (
349
- <Icon
350
- style={styles.readBadgeIcon}
351
- name={readIconName}
352
- size={12}
353
- color={readPresentationStyles.color}
354
- />
355
- ) : null}
356
- <Text
357
- style={[
358
- styles.readText,
359
- readPresentationStyles.hasDecoration ? styles.readBadgeText : null,
360
- resolvedLabel === '-' ? styles.mutedText : null,
361
- readPresentationStyles.color ? { color: readPresentationStyles.color } : null,
362
- readTextStyle,
363
- ]}
364
- numberOfLines={numberOfLines}
365
- >
366
- {column?.prefix || ''}
367
- {resolvedLabel || '-'}
368
- {column?.sufix || column?.suffix || ''}
369
- </Text>
370
- </View>
371
- )}
372
- {saving ? (
373
- <Text style={[styles.savingText, { color: accentColor }]}>Salvando</Text>
374
- ) : canEdit ? (
375
- <Icon style={styles.editIcon} name="edit-2" size={13} color="#64748B" />
376
- ) : null}
377
- </TouchableOpacity>
378
- </View>
379
- );
380
- }
381
-
382
- return (
383
- <View style={[styles.wrap, containerStyle]}>
384
- {showLabel ? <Text style={styles.fieldLabel}>{label || column?.label || fieldName}</Text> : null}
385
- <View style={styles.editingWrap}>
386
- <View style={styles.editingRow}>
387
- <TextInput
388
- style={[
389
- styles.input,
390
- isForm ? styles.formInput : null,
391
- inputStyle,
392
- ]}
393
- value={draftValue}
394
- keyboardType={column?.inputType === 'number' || column?.inputType === 'float' ? 'numeric' : 'default'}
395
- placeholder={global.t?.t(storeName, 'input', column?.label || fieldName)}
396
- onBlur={autoSave ? saveDraft : undefined}
397
- onChangeText={updateDraft}
398
- onSubmitEditing={saveDraft}
399
- autoFocus={autoFocus && !isForm}
400
- selectTextOnFocus
401
- />
402
- {!isForm ? (
403
- <TouchableOpacity style={styles.cancelButton} activeOpacity={0.8} onPress={onCancelEditing}>
404
- <Icon name="x" size={14} color="#64748B" />
405
- </TouchableOpacity>
406
- ) : null}
407
- </View>
408
- {saving ? <Text style={styles.savingText}>Salvando</Text> : null}
409
- </View>
410
- </View>
411
- );
412
- };
413
-
414
- export default DefaultInput;
1
+ import React, { useEffect, useMemo, useState } from 'react';
2
+ import { Image, Text, TextInput, TouchableOpacity, View } from 'react-native';
3
+ import DefaultExtraData from '../extra-data/DefaultExtraData';
4
+ import DefaultFileColumn from '../files/DefaultFileColumn';
5
+ import Icon from 'react-native-vector-icons/Feather';
6
+ import {
7
+ buildReadPresentationStyles,
8
+ getColumnKey,
9
+ isColorColumn,
10
+ isDateLikeColumn,
11
+ isEditableColumn,
12
+ isExtraDataColumn,
13
+ isFileColumn,
14
+ isIconColumn,
15
+ isValidFeatherIcon,
16
+ normalizeText,
17
+ resolveCellPresentation,
18
+ resolveCellText,
19
+ resolveEditValue,
20
+ } from './defaultInputUtils';
21
+ import DefaultColorInput from './DefaultColorInput';
22
+ import DefaultDateInput from './DefaultDateInput';
23
+ import DefaultFeatherIconPicker, {
24
+ normalizeFeatherIconName,
25
+ } from './DefaultFeatherIconPicker';
26
+ import DefaultSelect from './DefaultSelect';
27
+ import styles from './DefaultInput.styles';
28
+
29
+ const DefaultInput = ({
30
+ accentColor = '#2563EB',
31
+ autoFocus = true,
32
+ autoSave = true,
33
+ column,
34
+ columns = [],
35
+ containerStyle = null,
36
+ displayValue,
37
+ defaultColor = '',
38
+ editing = false,
39
+ getOptionsForColumn = null,
40
+ inputStyle = null,
41
+ label = '',
42
+ maxLength,
43
+ onSubmitEditing = null,
44
+ numberOfLines = 1,
45
+ onBeforeOpen = null,
46
+ onCancelEditing = null,
47
+ onChangeValue = null,
48
+ onSave = null,
49
+ onSearchChange = null,
50
+ onStartEditing = null,
51
+ readTextStyle = null,
52
+ row = {},
53
+ saving = false,
54
+ showLabel = false,
55
+ storeName = '',
56
+ value,
57
+ variant = 'cell',
58
+ }) => {
59
+ const fieldName = getColumnKey(column);
60
+ const isExtraDataField = isExtraDataColumn(column) || ['extradata', 'extra_data'].includes(
61
+ normalizeText(fieldName).replace(/[^a-zA-Z0-9_]/g, '').toLowerCase(),
62
+ );
63
+ const isForm = variant === 'form';
64
+ const canEdit = isEditableColumn(column) && typeof onStartEditing === 'function';
65
+ const editValue = useMemo(
66
+ () => normalizeText(value ?? resolveEditValue(column, row)),
67
+ [column, row, value],
68
+ );
69
+ const [draftValue, setDraftValue] = useState(editValue);
70
+ const resolvedLabel =
71
+ displayValue ?? resolveCellText({ column, columns, row, storeName, value });
72
+ const readPresentation = useMemo(
73
+ () => resolveCellPresentation({ column, columns, row, storeName, value }),
74
+ [column, columns, row, storeName, value],
75
+ );
76
+ const readPresentationStyles = useMemo(
77
+ () => buildReadPresentationStyles({
78
+ ...readPresentation,
79
+ label: resolvedLabel,
80
+ }),
81
+ [readPresentation, resolvedLabel],
82
+ );
83
+
84
+ useEffect(() => {
85
+ setDraftValue(editValue);
86
+ }, [editValue, editing]);
87
+
88
+ if (column?.list) {
89
+ return (
90
+ <DefaultSelect
91
+ accentColor={accentColor}
92
+ autoSave={autoSave}
93
+ column={column}
94
+ columns={columns}
95
+ containerStyle={containerStyle}
96
+ displayValue={displayValue}
97
+ editing={editing}
98
+ getOptionsForColumn={getOptionsForColumn}
99
+ label={label}
100
+ numberOfLines={numberOfLines}
101
+ onBeforeOpen={onBeforeOpen}
102
+ onCancelEditing={onCancelEditing}
103
+ onChangeValue={onChangeValue}
104
+ onSave={onSave}
105
+ onStartEditing={onStartEditing}
106
+ readTextStyle={readTextStyle}
107
+ row={row}
108
+ saving={saving}
109
+ showLabel={showLabel}
110
+ storeName={storeName}
111
+ value={value}
112
+ variant={variant}
113
+ />
114
+ );
115
+ }
116
+
117
+ if (isColorColumn(column)) {
118
+ return (
119
+ <DefaultColorInput
120
+ accentColor={accentColor}
121
+ autoFocus={autoFocus}
122
+ autoSave={autoSave}
123
+ column={column}
124
+ containerStyle={containerStyle}
125
+ defaultColor={defaultColor}
126
+ editing={editing}
127
+ inputStyle={inputStyle}
128
+ label={label}
129
+ onCancelEditing={onCancelEditing}
130
+ onChangeValue={onChangeValue}
131
+ onSave={onSave}
132
+ onStartEditing={onStartEditing}
133
+ row={row}
134
+ saving={saving}
135
+ showLabel={showLabel}
136
+ storeName={storeName}
137
+ value={value}
138
+ variant={variant}
139
+ />
140
+ );
141
+ }
142
+
143
+ if (isIconColumn(column)) {
144
+ const fieldNameIcon = getColumnKey(column);
145
+ const rawIconValue = value ?? row?.[fieldNameIcon];
146
+ const selectedIcon = normalizeFeatherIconName(rawIconValue);
147
+ const isFormIcon = variant === 'form';
148
+ const canEditIcon = isEditableColumn(column) && typeof onStartEditing === 'function';
149
+
150
+ const commitIcon = nextIcon => {
151
+ const normalized = normalizeFeatherIconName(nextIcon);
152
+ if (autoSave) {
153
+ onSave?.(normalized);
154
+ return;
155
+ }
156
+ onChangeValue?.(normalized);
157
+ };
158
+
159
+ if (!editing && !isFormIcon) {
160
+ return (
161
+ <View style={[styles.wrap, containerStyle]}>
162
+ {showLabel ? (
163
+ <Text style={styles.fieldLabel}>{label || column?.label || fieldNameIcon}</Text>
164
+ ) : null}
165
+ <TouchableOpacity
166
+ style={styles.readButton}
167
+ activeOpacity={canEditIcon ? 0.78 : 1}
168
+ disabled={!canEditIcon}
169
+ onPress={() => onStartEditing?.()}
170
+ >
171
+ <View style={styles.readValueWrap}>
172
+ <Icon
173
+ name={selectedIcon || 'search'}
174
+ size={14}
175
+ color={selectedIcon ? '#0F172A' : '#94A3B8'}
176
+ />
177
+ <Text
178
+ style={[
179
+ styles.readText,
180
+ !selectedIcon ? styles.mutedText : null,
181
+ readTextStyle,
182
+ ]}
183
+ numberOfLines={numberOfLines}
184
+ >
185
+ {selectedIcon || '-'}
186
+ </Text>
187
+ </View>
188
+ {saving ? (
189
+ <Text style={[styles.savingText, { color: accentColor }]}>Salvando</Text>
190
+ ) : canEditIcon ? (
191
+ <Icon style={styles.editIcon} name="edit-2" size={13} color="#64748B" />
192
+ ) : null}
193
+ </TouchableOpacity>
194
+ </View>
195
+ );
196
+ }
197
+
198
+ return (
199
+ <View style={[styles.wrap, containerStyle]}>
200
+ {showLabel ? (
201
+ <Text style={styles.fieldLabel}>{label || column?.label || fieldNameIcon}</Text>
202
+ ) : null}
203
+ <View style={styles.editingWrap}>
204
+ <View style={styles.editingRow}>
205
+ <DefaultFeatherIconPicker
206
+ value={selectedIcon}
207
+ onChange={commitIcon}
208
+ placeholder={
209
+ global.t?.t(storeName, 'input', column?.label || fieldNameIcon) ||
210
+ 'Buscar icone'
211
+ }
212
+ style={[isFormIcon ? styles.formInput : null, inputStyle, { flex: 1 }]}
213
+ />
214
+ {!isFormIcon ? (
215
+ <TouchableOpacity
216
+ style={styles.cancelButton}
217
+ activeOpacity={0.8}
218
+ onPress={onCancelEditing}
219
+ >
220
+ <Icon name="x" size={14} color="#64748B" />
221
+ </TouchableOpacity>
222
+ ) : null}
223
+ </View>
224
+ {saving ? <Text style={styles.savingText}>Salvando</Text> : null}
225
+ </View>
226
+ </View>
227
+ );
228
+ }
229
+
230
+ if (isDateLikeColumn(column)) {
231
+ return (
232
+ <DefaultDateInput
233
+ accentColor={accentColor}
234
+ autoFocus={autoFocus}
235
+ autoSave={autoSave}
236
+ column={column}
237
+ columns={columns}
238
+ containerStyle={containerStyle}
239
+ displayValue={displayValue}
240
+ editing={editing}
241
+ inputStyle={inputStyle}
242
+ label={label}
243
+ numberOfLines={numberOfLines}
244
+ onCancelEditing={onCancelEditing}
245
+ onChangeValue={onChangeValue}
246
+ onSave={onSave}
247
+ onSearchChange={onSearchChange}
248
+ onStartEditing={onStartEditing}
249
+ readTextStyle={readTextStyle}
250
+ row={row}
251
+ saving={saving}
252
+ showLabel={showLabel}
253
+ storeName={storeName}
254
+ value={value}
255
+ variant={variant}
256
+ />
257
+ );
258
+ }
259
+
260
+ const saveDraft = () => {
261
+ if (autoSave) {
262
+ onSave?.(draftValue);
263
+ return;
264
+ }
265
+
266
+ onChangeValue?.(draftValue);
267
+ };
268
+
269
+ const updateDraft = nextValue => {
270
+ setDraftValue(nextValue);
271
+ if (!autoSave) onChangeValue?.(nextValue);
272
+ };
273
+
274
+ if (!editing && !isForm) {
275
+ if (isExtraDataField) {
276
+ return (
277
+ <View style={[styles.wrap, containerStyle]}>
278
+ {showLabel ? <Text style={styles.fieldLabel}>{label || column?.label || fieldName}</Text> : null}
279
+ <DefaultExtraData
280
+ column={column}
281
+ row={row}
282
+ value={value ?? row?.[fieldName]}
283
+ variant={variant}
284
+ />
285
+ </View>
286
+ );
287
+ }
288
+
289
+ if (isFileColumn(column)) {
290
+ return (
291
+ <View style={[styles.wrap, containerStyle]}>
292
+ {showLabel ? <Text style={styles.fieldLabel}>{label || column?.label || fieldName}</Text> : null}
293
+ <DefaultFileColumn
294
+ column={column}
295
+ row={row}
296
+ value={value}
297
+ variant={variant}
298
+ />
299
+ </View>
300
+ );
301
+ }
302
+
303
+ const readIconName = isValidFeatherIcon(readPresentation.icon)
304
+ ? readPresentation.icon
305
+ : '';
306
+ const shouldRenderIconFallbackText = Boolean(
307
+ readPresentationStyles.hasDecoration &&
308
+ !readIconName &&
309
+ readPresentationStyles.color &&
310
+ normalizeText(resolvedLabel) &&
311
+ resolvedLabel !== '-',
312
+ );
313
+
314
+ return (
315
+ <View style={[styles.wrap, containerStyle]}>
316
+ {showLabel ? <Text style={styles.fieldLabel}>{label || column?.label || fieldName}</Text> : null}
317
+ <TouchableOpacity
318
+ style={styles.readButton}
319
+ activeOpacity={canEdit ? 0.78 : 1}
320
+ disabled={!canEdit}
321
+ onPress={() => onStartEditing?.()}
322
+ >
323
+ {shouldRenderIconFallbackText ? (
324
+ <Text
325
+ style={[
326
+ styles.readText,
327
+ styles.readTextBadge,
328
+ readPresentationStyles.color ? { color: readPresentationStyles.color } : null,
329
+ readTextStyle,
330
+ ]}
331
+ numberOfLines={numberOfLines}
332
+ >
333
+ {resolvedLabel}
334
+ </Text>
335
+ ) : (
336
+ <View
337
+ style={[
338
+ styles.readValueWrap,
339
+ readPresentationStyles.hasDecoration ? styles.readBadge : null,
340
+ readPresentationStyles.badgeStyle,
341
+ ]}
342
+ >
343
+ {readPresentation.image ? (
344
+ <Image
345
+ source={readPresentation.image}
346
+ style={styles.readImage}
347
+ resizeMode="contain"
348
+ />
349
+ ) : null}
350
+ {readPresentationStyles.hasDecoration && readIconName && readPresentationStyles.color ? (
351
+ <Icon
352
+ style={styles.readBadgeIcon}
353
+ name={readIconName}
354
+ size={12}
355
+ color={readPresentationStyles.color}
356
+ />
357
+ ) : null}
358
+ <Text
359
+ style={[
360
+ styles.readText,
361
+ readPresentationStyles.hasDecoration ? styles.readBadgeText : null,
362
+ resolvedLabel === '-' ? styles.mutedText : null,
363
+ readPresentationStyles.color ? { color: readPresentationStyles.color } : null,
364
+ readTextStyle,
365
+ ]}
366
+ numberOfLines={numberOfLines}
367
+ >
368
+ {column?.prefix || ''}
369
+ {resolvedLabel || '-'}
370
+ {column?.sufix || column?.suffix || ''}
371
+ </Text>
372
+ </View>
373
+ )}
374
+ {saving ? (
375
+ <Text style={[styles.savingText, { color: accentColor }]}>Salvando</Text>
376
+ ) : canEdit ? (
377
+ <Icon style={styles.editIcon} name="edit-2" size={13} color="#64748B" />
378
+ ) : null}
379
+ </TouchableOpacity>
380
+ </View>
381
+ );
382
+ }
383
+
384
+ return (
385
+ <View style={[styles.wrap, containerStyle]}>
386
+ {showLabel ? <Text style={styles.fieldLabel}>{label || column?.label || fieldName}</Text> : null}
387
+ <View style={styles.editingWrap}>
388
+ <View style={styles.editingRow}>
389
+ <TextInput
390
+ style={[
391
+ styles.input,
392
+ isForm ? styles.formInput : null,
393
+ inputStyle,
394
+ ]}
395
+ value={draftValue}
396
+ keyboardType={column?.inputType === 'number' || column?.inputType === 'float' ? 'numeric' : 'default'}
397
+ placeholder={global.t?.t(storeName, 'input', column?.label || fieldName)}
398
+ onBlur={autoSave ? saveDraft : undefined}
399
+ onChangeText={updateDraft}
400
+ maxLength={maxLength}
401
+ onSubmitEditing={() => { saveDraft(); onSubmitEditing?.(draftValue); }}
402
+ autoFocus={autoFocus && !isForm}
403
+ selectTextOnFocus
404
+ />
405
+ {!isForm ? (
406
+ <TouchableOpacity style={styles.cancelButton} activeOpacity={0.8} onPress={onCancelEditing}>
407
+ <Icon name="x" size={14} color="#64748B" />
408
+ </TouchableOpacity>
409
+ ) : null}
410
+ </View>
411
+ {saving ? <Text style={styles.savingText}>Salvando</Text> : null}
412
+ </View>
413
+ </View>
414
+ );
415
+ };
416
+
417
+ export default DefaultInput;