@controleonline/ui-default 1.0.263 → 1.0.265

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 (61) hide show
  1. package/AGENTS.md +47 -45
  2. package/package.json +20 -20
  3. package/src/react/components/errors/DefaultErrors.js +307 -325
  4. package/src/react/components/files/DefaultFile.js +46 -46
  5. package/src/react/components/filters/CompactFilterSelector.js +78 -24
  6. package/src/react/components/filters/CompactFilterSelector.styles.js +17 -5
  7. package/src/react/components/filters/DefaultColumnFilter.js +191 -57
  8. package/src/react/components/filters/DefaultExternalFilters.js +245 -182
  9. package/src/react/components/filters/DefaultSearch.js +131 -92
  10. package/src/react/components/filters/DefaultSearch.styles.js +65 -70
  11. package/src/react/components/form/DefaultForm.js +172 -151
  12. package/src/react/components/form/DefaultForm.styles.js +71 -66
  13. package/src/react/components/help/DefaultTooltip.js +87 -87
  14. package/src/react/components/help/DefaultTooltip.styles.js +61 -61
  15. package/src/react/components/inputs/DefaultDateInput.js +150 -0
  16. package/src/react/components/inputs/DefaultInput.js +162 -127
  17. package/src/react/components/inputs/DefaultInput.styles.js +6 -0
  18. package/src/react/components/inputs/DefaultSelect.js +320 -152
  19. package/src/react/components/inputs/defaultInputUtils.js +40 -19
  20. package/src/react/components/map/DefaultGoogleMap.styles.js +115 -9
  21. package/src/react/components/map/DefaultGoogleMap.web.js +560 -446
  22. package/src/react/components/map/DefaultMap.native.js +73 -71
  23. package/src/react/components/map/DefaultMap.styles.js +16 -16
  24. package/src/react/components/map/DefaultMap.web.js +68 -66
  25. package/src/react/components/map/DefaultNativeMap.native.js +307 -183
  26. package/src/react/components/map/DefaultNativeMap.shared.js +439 -340
  27. package/src/react/components/map/DefaultNativeMap.styles.js +156 -122
  28. package/src/react/components/table/DefaultColumnMenu.js +108 -0
  29. package/src/react/components/table/DefaultDebug.js +233 -0
  30. package/src/react/components/table/DefaultFiltersModal.js +142 -0
  31. package/src/react/components/table/DefaultModalButton.js +18 -0
  32. package/src/react/components/table/DefaultSearchModal.js +49 -0
  33. package/src/react/components/table/DefaultTable.js +345 -1846
  34. package/src/react/components/table/DefaultTable.styles.js +247 -136
  35. package/src/react/components/table/DefaultTable.utils.js +502 -0
  36. package/src/react/components/table/DefaultTableBody.js +26 -0
  37. package/src/react/components/table/DefaultTableCards.js +171 -0
  38. package/src/react/components/table/DefaultTableControls.js +208 -0
  39. package/src/react/components/table/DefaultTableEmptyState.js +22 -0
  40. package/src/react/components/table/DefaultTableFooter.js +172 -0
  41. package/src/react/components/table/DefaultTableInput.js +145 -0
  42. package/src/react/components/table/DefaultTableRows.js +340 -0
  43. package/src/react/components/table/DefaultTableSearch.js +100 -0
  44. package/src/react/components/table/DefaultTableToolbar.js +98 -0
  45. package/src/react/components/table/DefaultToolbarAction.js +56 -0
  46. package/src/react/components/table/useDefaultTablePagination.js +370 -0
  47. package/src/react/components/table/useDefaultTableSorting.js +126 -0
  48. package/src/react/components/table/useDefaultTableTheme.js +58 -0
  49. package/src/react/index.js +10 -10
  50. package/src/react/utils/tableVisibleColumnsPreferences.js +239 -211
  51. package/src/store/default/actions.js +51 -13
  52. package/src/store/default/getters.js +10 -8
  53. package/src/store/default/mutation_types.js +4 -2
  54. package/src/store/default/mutations.js +10 -1
  55. package/src/tests/react/components/errors/DefaultErrors.test.js +162 -162
  56. package/src/tests/react/components/files/DefaultFile.test.js +80 -80
  57. package/src/tests/react/components/form/DefaultForm.test.js +81 -0
  58. package/src/tests/react/components/inputs/DefaultSelect.test.js +185 -0
  59. package/src/tests/react/components/table/DefaultTable.test.js +1183 -0
  60. package/src/tests/react/store/defaultActions.test.js +59 -0
  61. package/src/tests/react/utils/tableVisibleColumnsPreferences.test.js +247 -168
@@ -1,87 +1,87 @@
1
- import React, {useCallback, useState} from 'react';
2
- import {Modal, Pressable, Text, TouchableOpacity, View} from 'react-native';
3
- import styles from './DefaultTooltip.styles';
4
-
5
- const DefaultTooltip = ({
6
- accentColor = '#0EA5E9',
7
- label = '?',
8
- message = '',
9
- style = null,
10
- textStyle = null,
11
- title = 'Ajuda',
12
- }) => {
13
- const [visible, setVisible] = useState(false);
14
-
15
- const openTooltip = useCallback(() => {
16
- if (!message) {
17
- return;
18
- }
19
-
20
- setVisible(true);
21
- }, [message]);
22
-
23
- const closeTooltip = useCallback(() => {
24
- setVisible(false);
25
- }, []);
26
-
27
- return (
28
- <>
29
- <TouchableOpacity
30
- accessibilityRole="button"
31
- activeOpacity={0.85}
32
- disabled={!message}
33
- onPress={openTooltip}
34
- style={[
35
- styles.button,
36
- {
37
- borderColor: accentColor,
38
- backgroundColor: `${accentColor}14`,
39
- },
40
- !message && {opacity: 0.55},
41
- style,
42
- ]}>
43
- <Text style={[styles.label, {color: accentColor}, textStyle]}>
44
- {label}
45
- </Text>
46
- </TouchableOpacity>
47
-
48
- <Modal
49
- animationType="fade"
50
- onRequestClose={closeTooltip}
51
- transparent
52
- visible={visible}>
53
- <Pressable style={styles.overlay} onPress={closeTooltip}>
54
- <View
55
- onStartShouldSetResponder={() => true}
56
- style={[
57
- styles.card,
58
- {
59
- borderColor: accentColor,
60
- },
61
- ]}>
62
- <View style={styles.cardHeader}>
63
- <Text style={[styles.title, {color: accentColor}]}>{title}</Text>
64
- <TouchableOpacity
65
- accessibilityRole="button"
66
- activeOpacity={0.8}
67
- onPress={closeTooltip}
68
- style={[
69
- styles.closeButton,
70
- {
71
- borderColor: accentColor,
72
- },
73
- ]}>
74
- <Text style={[styles.closeButtonText, {color: accentColor}]}>
75
- Fechar
76
- </Text>
77
- </TouchableOpacity>
78
- </View>
79
- <Text style={styles.message}>{message}</Text>
80
- </View>
81
- </Pressable>
82
- </Modal>
83
- </>
84
- );
85
- };
86
-
87
- export default DefaultTooltip;
1
+ import React, {useCallback, useState} from 'react';
2
+ import {Modal, Pressable, Text, TouchableOpacity, View} from 'react-native';
3
+ import styles from './DefaultTooltip.styles';
4
+
5
+ const DefaultTooltip = ({
6
+ accentColor = '#0EA5E9',
7
+ label = '?',
8
+ message = '',
9
+ style = null,
10
+ textStyle = null,
11
+ title = 'Ajuda',
12
+ }) => {
13
+ const [visible, setVisible] = useState(false);
14
+
15
+ const openTooltip = useCallback(() => {
16
+ if (!message) {
17
+ return;
18
+ }
19
+
20
+ setVisible(true);
21
+ }, [message]);
22
+
23
+ const closeTooltip = useCallback(() => {
24
+ setVisible(false);
25
+ }, []);
26
+
27
+ return (
28
+ <>
29
+ <TouchableOpacity
30
+ accessibilityRole="button"
31
+ activeOpacity={0.85}
32
+ disabled={!message}
33
+ onPress={openTooltip}
34
+ style={[
35
+ styles.button,
36
+ {
37
+ borderColor: accentColor,
38
+ backgroundColor: `${accentColor}14`,
39
+ },
40
+ !message && {opacity: 0.55},
41
+ style,
42
+ ]}>
43
+ <Text style={[styles.label, {color: accentColor}, textStyle]}>
44
+ {label}
45
+ </Text>
46
+ </TouchableOpacity>
47
+
48
+ <Modal
49
+ animationType="fade"
50
+ onRequestClose={closeTooltip}
51
+ transparent
52
+ visible={visible}>
53
+ <Pressable style={styles.overlay} onPress={closeTooltip}>
54
+ <View
55
+ onStartShouldSetResponder={() => true}
56
+ style={[
57
+ styles.card,
58
+ {
59
+ borderColor: accentColor,
60
+ },
61
+ ]}>
62
+ <View style={styles.cardHeader}>
63
+ <Text style={[styles.title, {color: accentColor}]}>{title}</Text>
64
+ <TouchableOpacity
65
+ accessibilityRole="button"
66
+ activeOpacity={0.8}
67
+ onPress={closeTooltip}
68
+ style={[
69
+ styles.closeButton,
70
+ {
71
+ borderColor: accentColor,
72
+ },
73
+ ]}>
74
+ <Text style={[styles.closeButtonText, {color: accentColor}]}>
75
+ Fechar
76
+ </Text>
77
+ </TouchableOpacity>
78
+ </View>
79
+ <Text style={styles.message}>{message}</Text>
80
+ </View>
81
+ </Pressable>
82
+ </Modal>
83
+ </>
84
+ );
85
+ };
86
+
87
+ export default DefaultTooltip;
@@ -1,61 +1,61 @@
1
- import {StyleSheet} from 'react-native';
2
-
3
- const styles = StyleSheet.create({
4
- button: {
5
- alignItems: 'center',
6
- borderRadius: 999,
7
- borderWidth: 1,
8
- height: 22,
9
- justifyContent: 'center',
10
- width: 22,
11
- },
12
- label: {
13
- fontSize: 12,
14
- fontWeight: '800',
15
- lineHeight: 12,
16
- },
17
- overlay: {
18
- alignItems: 'center',
19
- backgroundColor: 'rgba(15, 23, 42, 0.55)',
20
- flex: 1,
21
- justifyContent: 'center',
22
- padding: 18,
23
- },
24
- card: {
25
- backgroundColor: '#FFFFFF',
26
- borderRadius: 16,
27
- borderWidth: 1,
28
- maxWidth: 420,
29
- padding: 16,
30
- width: '100%',
31
- },
32
- cardHeader: {
33
- alignItems: 'center',
34
- flexDirection: 'row',
35
- gap: 10,
36
- justifyContent: 'space-between',
37
- marginBottom: 12,
38
- },
39
- title: {
40
- flex: 1,
41
- fontSize: 15,
42
- fontWeight: '800',
43
- },
44
- message: {
45
- color: '#334155',
46
- fontSize: 13,
47
- lineHeight: 19,
48
- },
49
- closeButton: {
50
- borderRadius: 999,
51
- borderWidth: 1,
52
- paddingHorizontal: 10,
53
- paddingVertical: 6,
54
- },
55
- closeButtonText: {
56
- fontSize: 12,
57
- fontWeight: '700',
58
- },
59
- });
60
-
61
- export default styles;
1
+ import {StyleSheet} from 'react-native';
2
+
3
+ const styles = StyleSheet.create({
4
+ button: {
5
+ alignItems: 'center',
6
+ borderRadius: 999,
7
+ borderWidth: 1,
8
+ height: 22,
9
+ justifyContent: 'center',
10
+ width: 22,
11
+ },
12
+ label: {
13
+ fontSize: 12,
14
+ fontWeight: '800',
15
+ lineHeight: 12,
16
+ },
17
+ overlay: {
18
+ alignItems: 'center',
19
+ backgroundColor: 'rgba(15, 23, 42, 0.55)',
20
+ flex: 1,
21
+ justifyContent: 'center',
22
+ padding: 18,
23
+ },
24
+ card: {
25
+ backgroundColor: '#FFFFFF',
26
+ borderRadius: 16,
27
+ borderWidth: 1,
28
+ maxWidth: 420,
29
+ padding: 16,
30
+ width: '100%',
31
+ },
32
+ cardHeader: {
33
+ alignItems: 'center',
34
+ flexDirection: 'row',
35
+ gap: 10,
36
+ justifyContent: 'space-between',
37
+ marginBottom: 12,
38
+ },
39
+ title: {
40
+ flex: 1,
41
+ fontSize: 15,
42
+ fontWeight: '800',
43
+ },
44
+ message: {
45
+ color: '#334155',
46
+ fontSize: 13,
47
+ lineHeight: 19,
48
+ },
49
+ closeButton: {
50
+ borderRadius: 999,
51
+ borderWidth: 1,
52
+ paddingHorizontal: 10,
53
+ paddingVertical: 6,
54
+ },
55
+ closeButtonText: {
56
+ fontSize: 12,
57
+ fontWeight: '700',
58
+ },
59
+ });
60
+
61
+ export default styles;
@@ -0,0 +1,150 @@
1
+ import React, { useEffect, useMemo, useState } from 'react';
2
+ import { Text, TextInput, TouchableOpacity, View } from 'react-native';
3
+ import Icon from 'react-native-vector-icons/Feather';
4
+ import Formatter from '@controleonline/ui-common/src/utils/formatter.js';
5
+ import {
6
+ getColumnKey,
7
+ isEditableColumn,
8
+ normalizeText,
9
+ resolveCellText,
10
+ resolveEditValue,
11
+ } from './defaultInputUtils';
12
+ import styles from './DefaultInput.styles';
13
+
14
+ const normalizeDateDraft = value => {
15
+ const text = normalizeText(value);
16
+ if (!text) return '';
17
+
18
+ return Formatter.formatDateToBR(text);
19
+ };
20
+
21
+ const DefaultDateInput = ({
22
+ accentColor = '#2563EB',
23
+ autoFocus = true,
24
+ autoSave = true,
25
+ column,
26
+ columns = [],
27
+ containerStyle = null,
28
+ displayValue,
29
+ editing = false,
30
+ inputStyle = null,
31
+ label = '',
32
+ numberOfLines = 1,
33
+ onCancelEditing = null,
34
+ onChangeValue = null,
35
+ onSave = null,
36
+ onStartEditing = null,
37
+ readTextStyle = null,
38
+ row = {},
39
+ saving = false,
40
+ showLabel = false,
41
+ storeName = '',
42
+ value,
43
+ variant = 'cell',
44
+ }) => {
45
+ const fieldName = getColumnKey(column);
46
+ const isForm = variant === 'form';
47
+ const canEdit = isEditableColumn(column) && typeof onStartEditing === 'function';
48
+ const editValue = useMemo(
49
+ () => normalizeDateDraft(value ?? resolveEditValue(column, row)),
50
+ [column, row, value],
51
+ );
52
+ const [draftValue, setDraftValue] = useState(editValue);
53
+ const [validationMessage, setValidationMessage] = useState('');
54
+ const resolvedLabel =
55
+ displayValue ?? resolveCellText({ column, columns, row, storeName, value });
56
+
57
+ useEffect(() => {
58
+ setDraftValue(editValue);
59
+ setValidationMessage('');
60
+ }, [editValue, editing]);
61
+
62
+ const saveDraft = () => {
63
+ const validationResult = Formatter.validateBRDate(draftValue);
64
+
65
+ if (validationResult !== true) {
66
+ setValidationMessage(validationResult);
67
+ return;
68
+ }
69
+
70
+ setValidationMessage('');
71
+
72
+ if (autoSave) {
73
+ onSave?.(draftValue);
74
+ return;
75
+ }
76
+
77
+ onChangeValue?.(draftValue);
78
+ };
79
+
80
+ const updateDraft = nextValue => {
81
+ setDraftValue(nextValue);
82
+ if (validationMessage) setValidationMessage('');
83
+ if (!autoSave) onChangeValue?.(nextValue);
84
+ };
85
+
86
+ if (!editing && !isForm) {
87
+ return (
88
+ <View style={[styles.wrap, containerStyle]}>
89
+ {showLabel ? <Text style={styles.fieldLabel}>{label || column?.label || fieldName}</Text> : null}
90
+ <TouchableOpacity
91
+ style={styles.readButton}
92
+ activeOpacity={canEdit ? 0.78 : 1}
93
+ disabled={!canEdit}
94
+ onPress={() => onStartEditing?.()}
95
+ >
96
+ <Text
97
+ style={[
98
+ styles.readText,
99
+ resolvedLabel === '-' ? styles.mutedText : null,
100
+ readTextStyle,
101
+ ]}
102
+ numberOfLines={numberOfLines}
103
+ >
104
+ {resolvedLabel || '-'}
105
+ </Text>
106
+ {saving ? (
107
+ <Text style={[styles.savingText, { color: accentColor }]}>Salvando</Text>
108
+ ) : canEdit ? (
109
+ <Icon style={styles.editIcon} name="calendar" size={13} color="#64748B" />
110
+ ) : null}
111
+ </TouchableOpacity>
112
+ </View>
113
+ );
114
+ }
115
+
116
+ return (
117
+ <View style={[styles.wrap, containerStyle]}>
118
+ {showLabel ? <Text style={styles.fieldLabel}>{label || column?.label || fieldName}</Text> : null}
119
+ <View style={styles.editingWrap}>
120
+ <View style={styles.editingRow}>
121
+ <TextInput
122
+ style={[
123
+ styles.input,
124
+ isForm ? styles.formInput : null,
125
+ inputStyle,
126
+ ]}
127
+ value={draftValue}
128
+ keyboardType="numeric"
129
+ placeholder="DD/MM/YYYY"
130
+ onBlur={autoSave ? saveDraft : undefined}
131
+ onChangeText={updateDraft}
132
+ onSubmitEditing={saveDraft}
133
+ autoFocus={autoFocus && !isForm}
134
+ selectTextOnFocus
135
+ />
136
+ <Icon name="calendar" size={15} color="#64748B" />
137
+ {!isForm ? (
138
+ <TouchableOpacity style={styles.cancelButton} activeOpacity={0.8} onPress={onCancelEditing}>
139
+ <Icon name="x" size={14} color="#64748B" />
140
+ </TouchableOpacity>
141
+ ) : null}
142
+ </View>
143
+ {!!validationMessage && <Text style={styles.validationText}>{validationMessage}</Text>}
144
+ {saving ? <Text style={styles.savingText}>Salvando</Text> : null}
145
+ </View>
146
+ </View>
147
+ );
148
+ };
149
+
150
+ export default DefaultDateInput;