@archbase/components 3.0.25 → 4.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/buttons/ArchbaseSpeedDial.d.ts +59 -0
- package/dist/buttons/index.d.ts +2 -0
- package/dist/charts/ArchbaseArcGauge.d.ts +55 -0
- package/dist/charts/ArchbaseGantt.d.ts +70 -0
- package/dist/charts/ArchbaseLinearGauge.d.ts +55 -0
- package/dist/charts/ArchbaseResourceTimeline.d.ts +61 -0
- package/dist/charts/ArchbaseSparkline.d.ts +45 -0
- package/dist/charts/index.d.ts +10 -0
- package/dist/containers/ArchbaseExpansionPanel.d.ts +60 -0
- package/dist/containers/ArchbaseFloatingPanel.d.ts +91 -0
- package/dist/containers/index.d.ts +4 -0
- package/dist/datagrid/export/ArchbaseDataGridExcelExport.d.ts +67 -0
- package/dist/datagrid/export/index.d.ts +2 -0
- package/dist/datagrid/index.d.ts +1 -0
- package/dist/display/ArchbaseAnimationWrapper.d.ts +73 -0
- package/dist/display/ArchbaseBarcodeGenerator.d.ts +50 -0
- package/dist/display/ArchbaseCarousel.d.ts +100 -0
- package/dist/display/ArchbaseCodeViewer.d.ts +63 -0
- package/dist/display/ArchbaseDiffViewer.d.ts +41 -0
- package/dist/display/ArchbaseJsonTree.d.ts +34 -0
- package/dist/display/ArchbaseLightbox.d.ts +89 -0
- package/dist/display/ArchbaseMarquee.d.ts +46 -0
- package/dist/display/ArchbasePhotoAlbum.d.ts +58 -0
- package/dist/display/ArchbaseQRCode.d.ts +44 -0
- package/dist/display/ArchbaseTooltipRich.d.ts +82 -0
- package/dist/display/ArchbaseVirtualList.d.ts +116 -0
- package/dist/display/index.d.ts +24 -0
- package/dist/editors/ArchbaseAIPromptInput.d.ts +69 -0
- package/dist/editors/ArchbaseAsyncMultiSelect.d.ts +1 -1
- package/dist/editors/ArchbaseAsyncSelect.d.ts +1 -1
- package/dist/editors/ArchbaseBarcodeScanner.d.ts +63 -0
- package/dist/editors/ArchbaseCepInput.d.ts +26 -0
- package/dist/editors/ArchbaseColorGradientPicker.d.ts +80 -0
- package/dist/editors/ArchbaseCpfCnpjInput.d.ts +21 -0
- package/dist/editors/ArchbaseCurrencyInput.d.ts +25 -0
- package/dist/editors/ArchbaseDualListbox.d.ts +61 -0
- package/dist/editors/ArchbaseInPlaceEditor.d.ts +67 -0
- package/dist/editors/ArchbaseLightGrid.d.ts +56 -0
- package/dist/editors/ArchbaseMentionInput.d.ts +75 -0
- package/dist/editors/ArchbaseMultiEmail.d.ts +53 -0
- package/dist/editors/ArchbaseMultiViewCalendar.d.ts +47 -0
- package/dist/editors/ArchbaseNumberStepper.d.ts +66 -0
- package/dist/editors/ArchbaseOTPInput.d.ts +27 -0
- package/dist/editors/ArchbasePhoneInput.d.ts +52 -0
- package/dist/editors/ArchbaseRangeSlider.d.ts +22 -0
- package/dist/editors/ArchbaseSignaturePad.d.ts +60 -0
- package/dist/editors/ArchbaseSpeechToTextInput.d.ts +106 -0
- package/dist/editors/ArchbaseSpreadsheet.d.ts +56 -0
- package/dist/editors/ArchbaseTagInput.d.ts +55 -0
- package/dist/editors/index.d.ts +40 -0
- package/dist/feedback/ArchbaseChunkProgressBar.d.ts +35 -0
- package/dist/feedback/ArchbaseRipple.d.ts +43 -0
- package/dist/feedback/ArchbaseSkeleton.d.ts +115 -0
- package/dist/feedback/index.d.ts +6 -0
- package/dist/filters/ArchbaseColumnSelector.d.ts +38 -0
- package/dist/filters/index.d.ts +2 -0
- package/dist/forms/ArchbaseFieldArray.d.ts +80 -0
- package/dist/forms/ArchbaseFormWizard.d.ts +73 -0
- package/dist/forms/ArchbaseStepper.d.ts +51 -0
- package/dist/forms/index.d.ts +8 -0
- package/dist/forms/useArchbaseFormWizard.d.ts +74 -0
- package/dist/hooks/index.d.ts +2 -0
- package/dist/hooks/useArchbaseConfirm.d.ts +59 -0
- package/dist/image/editor/index.d.ts +43 -4
- package/dist/image/index.d.ts +1 -0
- package/dist/index.css +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +22510 -13820
- package/dist/list/ArchbaseTreeList.d.ts +76 -0
- package/dist/list/index.d.ts +2 -0
- package/dist/navigation/ArchbaseActionSheet.d.ts +70 -0
- package/dist/navigation/ArchbaseAppBar.d.ts +63 -0
- package/dist/navigation/ArchbaseBottomNavigation.d.ts +61 -0
- package/dist/navigation/ArchbaseContextMenu.d.ts +76 -0
- package/dist/navigation/ArchbaseKeyboardShortcuts.d.ts +85 -0
- package/dist/navigation/ArchbaseSpotlight.d.ts +69 -0
- package/dist/navigation/index.d.ts +12 -0
- package/dist/notification/ArchbaseNotificationCenter.d.ts +56 -0
- package/dist/notification/index.d.ts +2 -0
- package/dist/onboarding/ArchbaseOnboardingTour.d.ts +27 -76
- package/dist/viewers/ArchbaseDocViewer.d.ts +40 -0
- package/dist/viewers/ArchbasePdfBuilder.d.ts +53 -0
- package/dist/viewers/ArchbaseXmlViewer.d.ts +36 -0
- package/dist/viewers/index.d.ts +6 -0
- package/package.json +41 -18
- package/src/buttons/ArchbaseSpeedDial.tsx +282 -0
- package/src/buttons/index.ts +3 -0
- package/src/charts/ArchbaseArcGauge.tsx +325 -0
- package/src/charts/ArchbaseGantt.tsx +494 -0
- package/src/charts/ArchbaseLinearGauge.tsx +288 -0
- package/src/charts/ArchbaseResourceTimeline.tsx +433 -0
- package/src/charts/ArchbaseSparkline.tsx +193 -0
- package/src/charts/index.ts +20 -1
- package/src/containers/ArchbaseExpansionPanel.tsx +208 -0
- package/src/containers/ArchbaseFloatingPanel.tsx +448 -0
- package/src/containers/index.ts +17 -0
- package/src/datagrid/components/pagination/grid-pagination.tsx +2 -2
- package/src/datagrid/export/ArchbaseDataGridExcelExport.tsx +293 -0
- package/src/datagrid/export/index.ts +8 -0
- package/src/datagrid/index.tsx +2 -0
- package/src/display/ArchbaseAnimationWrapper.tsx +272 -0
- package/src/display/ArchbaseBarcodeGenerator.tsx +303 -0
- package/src/display/ArchbaseCarousel.tsx +679 -0
- package/src/display/ArchbaseCodeViewer.tsx +271 -0
- package/src/display/ArchbaseDiffViewer.tsx +108 -0
- package/src/display/ArchbaseJsonTree.tsx +150 -0
- package/src/display/ArchbaseLightbox.tsx +279 -0
- package/src/display/ArchbaseMarquee.tsx +268 -0
- package/src/display/ArchbasePhotoAlbum.tsx +415 -0
- package/src/display/ArchbaseQRCode.tsx +137 -0
- package/src/display/ArchbaseTooltipRich.tsx +317 -0
- package/src/display/ArchbaseVirtualList.tsx +618 -0
- package/src/display/index.ts +94 -1
- package/src/editors/ArchbaseAIPromptInput.tsx +432 -0
- package/src/editors/ArchbaseBarcodeScanner.tsx +570 -0
- package/src/editors/ArchbaseCepInput.tsx +173 -0
- package/src/editors/ArchbaseColorGradientPicker.tsx +460 -0
- package/src/editors/ArchbaseCpfCnpjInput.tsx +193 -0
- package/src/editors/ArchbaseCurrencyInput.tsx +100 -0
- package/src/editors/ArchbaseDualListbox.tsx +671 -0
- package/src/editors/ArchbaseInPlaceEditor.tsx +406 -0
- package/src/editors/ArchbaseLightGrid.tsx +538 -0
- package/src/editors/ArchbaseMentionInput.tsx +384 -0
- package/src/editors/ArchbaseMultiEmail.tsx +367 -0
- package/src/editors/ArchbaseMultiViewCalendar.tsx +439 -0
- package/src/editors/ArchbaseNumberStepper.tsx +219 -0
- package/src/editors/ArchbaseOTPInput.tsx +133 -0
- package/src/editors/ArchbaseOperationHoursEditor.tsx +1 -1
- package/src/editors/ArchbasePhoneInput.tsx +355 -0
- package/src/editors/ArchbaseRangeSlider.tsx +109 -0
- package/src/editors/ArchbaseSignaturePad.tsx +425 -0
- package/src/editors/ArchbaseSpeechToTextInput.tsx +444 -0
- package/src/editors/ArchbaseSpreadsheet.tsx +388 -0
- package/src/editors/ArchbaseTagInput.tsx +326 -0
- package/src/editors/index.tsx +92 -0
- package/src/feedback/ArchbaseChunkProgressBar.tsx +156 -0
- package/src/feedback/ArchbaseRipple.tsx +278 -0
- package/src/feedback/ArchbaseSkeleton.tsx +419 -0
- package/src/feedback/index.ts +22 -1
- package/src/filters/ArchbaseColumnSelector.tsx +268 -0
- package/src/filters/index.ts +2 -0
- package/src/forms/ArchbaseFieldArray.tsx +305 -0
- package/src/forms/ArchbaseFormWizard.tsx +284 -0
- package/src/forms/ArchbaseStepper.tsx +137 -0
- package/src/forms/index.ts +24 -2
- package/src/forms/useArchbaseFormWizard.ts +283 -0
- package/src/hooks/index.ts +12 -0
- package/src/hooks/useArchbaseConfirm.ts +293 -0
- package/src/image/editor/functions/image-processing.ts +5 -0
- package/src/image/editor/index.tsx +305 -391
- package/src/image/index.ts +1 -0
- package/src/index.ts +3 -0
- package/src/list/ArchbaseTreeList.tsx +422 -0
- package/src/list/index.ts +3 -0
- package/src/navigation/ArchbaseActionSheet.tsx +301 -0
- package/src/navigation/ArchbaseAppBar.tsx +233 -0
- package/src/navigation/ArchbaseBottomNavigation.tsx +243 -0
- package/src/navigation/ArchbaseContextMenu.tsx +298 -0
- package/src/navigation/ArchbaseKeyboardShortcuts.tsx +472 -0
- package/src/navigation/ArchbaseSpotlight.tsx +483 -0
- package/src/navigation/index.ts +48 -1
- package/src/notification/ArchbaseNotificationCenter.tsx +502 -0
- package/src/notification/index.ts +2 -0
- package/src/onboarding/ArchbaseOnboardingTour.tsx +229 -102
- package/src/viewers/ArchbaseDocViewer.tsx +584 -0
- package/src/viewers/ArchbasePdfBuilder.tsx +291 -0
- package/src/viewers/ArchbaseXmlViewer.tsx +142 -0
- package/src/viewers/index.ts +12 -0
|
@@ -0,0 +1,425 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ArchbaseSignaturePad — captura de assinatura integrada ao DataSource (v1/v2).
|
|
3
|
+
* Armazena a assinatura como string base64 (data URL).
|
|
4
|
+
* @status stable
|
|
5
|
+
*/
|
|
6
|
+
import React, { CSSProperties, useCallback, useEffect, useRef, useState } from 'react';
|
|
7
|
+
import SignatureCanvas from 'react-signature-canvas';
|
|
8
|
+
import { Box, Button, Group, Input, MantineSize, useMantineTheme, useComputedColorScheme } from '@mantine/core';
|
|
9
|
+
import { useForceUpdate } from '@mantine/hooks';
|
|
10
|
+
import { IconEraser, IconCheck } from '@tabler/icons-react';
|
|
11
|
+
import type { DataSourceEvent, IArchbaseDataSourceBase } from '@archbase/data';
|
|
12
|
+
import { DataSourceEventNames, useArchbaseDidUpdate, useArchbaseV1V2Compatibility } from '@archbase/data';
|
|
13
|
+
import { useValidationErrors } from '@archbase/core';
|
|
14
|
+
|
|
15
|
+
export interface ArchbaseSignaturePadProps<T, ID> {
|
|
16
|
+
/** Fonte de dados onde sera atribuido o valor da assinatura (V1 ou V2) */
|
|
17
|
+
dataSource?: IArchbaseDataSourceBase<T>;
|
|
18
|
+
/** Campo onde devera ser atribuido o valor da assinatura na fonte de dados */
|
|
19
|
+
dataField?: string;
|
|
20
|
+
/** Valor controlado (base64 data URL) */
|
|
21
|
+
value?: string;
|
|
22
|
+
/** Valor padrao (base64 data URL) */
|
|
23
|
+
defaultValue?: string;
|
|
24
|
+
/** Titulo do campo */
|
|
25
|
+
label?: string;
|
|
26
|
+
/** Descricao do campo */
|
|
27
|
+
description?: string;
|
|
28
|
+
/** Ultimo erro ocorrido */
|
|
29
|
+
error?: string;
|
|
30
|
+
/** Indicador se o preenchimento e obrigatorio */
|
|
31
|
+
required?: boolean;
|
|
32
|
+
/** Indicador se esta desabilitado */
|
|
33
|
+
disabled?: boolean;
|
|
34
|
+
/** Indicador se e somente leitura */
|
|
35
|
+
readOnly?: boolean;
|
|
36
|
+
/** Cor da caneta */
|
|
37
|
+
penColor?: string;
|
|
38
|
+
/** Cor de fundo do canvas */
|
|
39
|
+
backgroundColor?: string;
|
|
40
|
+
/** Largura do canvas */
|
|
41
|
+
width?: number;
|
|
42
|
+
/** Altura do canvas */
|
|
43
|
+
height?: number;
|
|
44
|
+
/** Exibir botao limpar */
|
|
45
|
+
showClearButton?: boolean;
|
|
46
|
+
/** Exibir botao confirmar */
|
|
47
|
+
showConfirmButton?: boolean;
|
|
48
|
+
/** Texto do botao limpar */
|
|
49
|
+
clearLabel?: string;
|
|
50
|
+
/** Texto do botao confirmar */
|
|
51
|
+
confirmLabel?: string;
|
|
52
|
+
/** Evento quando o valor muda (retorna base64 data URL) */
|
|
53
|
+
onChangeValue?: (value: string | undefined) => void;
|
|
54
|
+
/** Evento quando o foco entra */
|
|
55
|
+
onFocusEnter?: React.FocusEventHandler<any>;
|
|
56
|
+
/** Evento quando o foco sai */
|
|
57
|
+
onFocusExit?: React.FocusEventHandler<any>;
|
|
58
|
+
/** Evento quando o usuario confirma a assinatura */
|
|
59
|
+
onConfirm?: (value: string | undefined) => void;
|
|
60
|
+
/** Estilo do componente */
|
|
61
|
+
style?: CSSProperties;
|
|
62
|
+
/** Classe CSS */
|
|
63
|
+
className?: string;
|
|
64
|
+
/** Formato da imagem gerada */
|
|
65
|
+
imageFormat?: 'png' | 'jpeg' | 'svg';
|
|
66
|
+
/** Tamanho do componente */
|
|
67
|
+
size?: MantineSize;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function ArchbaseSignaturePadInner<T, ID>(
|
|
71
|
+
{
|
|
72
|
+
dataSource,
|
|
73
|
+
dataField,
|
|
74
|
+
value: valueProp,
|
|
75
|
+
defaultValue,
|
|
76
|
+
label,
|
|
77
|
+
description,
|
|
78
|
+
error,
|
|
79
|
+
required = false,
|
|
80
|
+
disabled = false,
|
|
81
|
+
readOnly = false,
|
|
82
|
+
penColor = 'black',
|
|
83
|
+
backgroundColor,
|
|
84
|
+
width = 400,
|
|
85
|
+
height = 200,
|
|
86
|
+
showClearButton = true,
|
|
87
|
+
showConfirmButton = false,
|
|
88
|
+
clearLabel = 'Limpar',
|
|
89
|
+
confirmLabel = 'Confirmar',
|
|
90
|
+
onChangeValue,
|
|
91
|
+
onFocusEnter,
|
|
92
|
+
onFocusExit,
|
|
93
|
+
onConfirm,
|
|
94
|
+
style,
|
|
95
|
+
className,
|
|
96
|
+
imageFormat = 'png',
|
|
97
|
+
size,
|
|
98
|
+
}: ArchbaseSignaturePadProps<T, ID>,
|
|
99
|
+
) {
|
|
100
|
+
const theme = useMantineTheme();
|
|
101
|
+
const colorScheme = useComputedColorScheme('light');
|
|
102
|
+
const sigCanvasRef = useRef<SignatureCanvas | null>(null);
|
|
103
|
+
const containerRef = useRef<HTMLDivElement>(null);
|
|
104
|
+
const forceUpdate = useForceUpdate();
|
|
105
|
+
|
|
106
|
+
// Cor de fundo responsiva ao dark mode
|
|
107
|
+
const resolvedBackgroundColor =
|
|
108
|
+
backgroundColor ?? (colorScheme === 'dark' ? theme.colors.dark[6] : 'white');
|
|
109
|
+
|
|
110
|
+
// Hook de compatibilidade V1/V2
|
|
111
|
+
const v1v2Compatibility = useArchbaseV1V2Compatibility<string | undefined>(
|
|
112
|
+
'ArchbaseSignaturePad',
|
|
113
|
+
dataSource,
|
|
114
|
+
dataField,
|
|
115
|
+
valueProp ?? defaultValue ?? undefined,
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
// Contexto de validacao
|
|
119
|
+
const validationContext = useValidationErrors();
|
|
120
|
+
const fieldKey = `${dataField}`;
|
|
121
|
+
const contextError = validationContext?.getError(fieldKey);
|
|
122
|
+
|
|
123
|
+
const [internalError, setInternalError] = useState<string | undefined>(error);
|
|
124
|
+
const [localValue, setLocalValue] = useState<string | undefined>(
|
|
125
|
+
valueProp ?? defaultValue ?? undefined,
|
|
126
|
+
);
|
|
127
|
+
|
|
128
|
+
// Atualizar erro externo
|
|
129
|
+
useEffect(() => {
|
|
130
|
+
if (error !== undefined && error !== internalError) {
|
|
131
|
+
setInternalError(error);
|
|
132
|
+
}
|
|
133
|
+
}, [error]);
|
|
134
|
+
|
|
135
|
+
// Carregar valor do datasource
|
|
136
|
+
const loadDataSourceFieldValue = useCallback(() => {
|
|
137
|
+
let initialValue: string | undefined = valueProp ?? defaultValue ?? undefined;
|
|
138
|
+
|
|
139
|
+
if (dataSource && dataField) {
|
|
140
|
+
const fieldVal = dataSource.getFieldValue(dataField);
|
|
141
|
+
initialValue = fieldVal || undefined;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
setLocalValue(initialValue);
|
|
145
|
+
}, [dataSource, dataField, valueProp, defaultValue]);
|
|
146
|
+
|
|
147
|
+
const fieldChangedListener = useCallback(() => {
|
|
148
|
+
loadDataSourceFieldValue();
|
|
149
|
+
}, [loadDataSourceFieldValue]);
|
|
150
|
+
|
|
151
|
+
const dataSourceEvent = useCallback(
|
|
152
|
+
(event: DataSourceEvent<T>) => {
|
|
153
|
+
if (dataSource && dataField) {
|
|
154
|
+
if (
|
|
155
|
+
event.type === DataSourceEventNames.dataChanged ||
|
|
156
|
+
event.type === DataSourceEventNames.recordChanged ||
|
|
157
|
+
event.type === DataSourceEventNames.afterScroll ||
|
|
158
|
+
event.type === DataSourceEventNames.afterCancel ||
|
|
159
|
+
event.type === DataSourceEventNames.afterEdit
|
|
160
|
+
) {
|
|
161
|
+
loadDataSourceFieldValue();
|
|
162
|
+
if (!v1v2Compatibility.isDataSourceV2) {
|
|
163
|
+
forceUpdate();
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
if (
|
|
168
|
+
event.type === DataSourceEventNames.onFieldError &&
|
|
169
|
+
event.fieldName === dataField
|
|
170
|
+
) {
|
|
171
|
+
setInternalError(event.error);
|
|
172
|
+
validationContext?.setError(fieldKey, event.error);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
},
|
|
176
|
+
[
|
|
177
|
+
v1v2Compatibility.isDataSourceV2,
|
|
178
|
+
dataSource,
|
|
179
|
+
dataField,
|
|
180
|
+
loadDataSourceFieldValue,
|
|
181
|
+
forceUpdate,
|
|
182
|
+
validationContext,
|
|
183
|
+
fieldKey,
|
|
184
|
+
],
|
|
185
|
+
);
|
|
186
|
+
|
|
187
|
+
// Ref estavel para o callback
|
|
188
|
+
const dataSourceEventRef = useRef(dataSourceEvent);
|
|
189
|
+
useEffect(() => {
|
|
190
|
+
dataSourceEventRef.current = dataSourceEvent;
|
|
191
|
+
}, [dataSourceEvent]);
|
|
192
|
+
|
|
193
|
+
const stableDataSourceEvent = useCallback((event: DataSourceEvent<T>) => {
|
|
194
|
+
dataSourceEventRef.current(event);
|
|
195
|
+
}, []);
|
|
196
|
+
|
|
197
|
+
// Registrar listeners
|
|
198
|
+
useEffect(() => {
|
|
199
|
+
loadDataSourceFieldValue();
|
|
200
|
+
if (dataSource && dataField) {
|
|
201
|
+
const hasFieldListener =
|
|
202
|
+
typeof (dataSource as any).addFieldChangeListener === 'function';
|
|
203
|
+
dataSource.addListener(stableDataSourceEvent);
|
|
204
|
+
if (hasFieldListener) {
|
|
205
|
+
(dataSource as any).addFieldChangeListener(dataField, fieldChangedListener);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
return () => {
|
|
209
|
+
dataSource.removeListener(stableDataSourceEvent);
|
|
210
|
+
if (hasFieldListener) {
|
|
211
|
+
(dataSource as any).removeFieldChangeListener(dataField, fieldChangedListener);
|
|
212
|
+
}
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
}, [dataSource, dataField, stableDataSourceEvent, fieldChangedListener]);
|
|
216
|
+
|
|
217
|
+
useArchbaseDidUpdate(() => {
|
|
218
|
+
loadDataSourceFieldValue();
|
|
219
|
+
}, []);
|
|
220
|
+
|
|
221
|
+
// Carregar imagem no canvas quando o valor muda
|
|
222
|
+
useEffect(() => {
|
|
223
|
+
const sigCanvas = sigCanvasRef.current;
|
|
224
|
+
if (!sigCanvas) return;
|
|
225
|
+
|
|
226
|
+
if (localValue && localValue.startsWith('data:')) {
|
|
227
|
+
sigCanvas.fromDataURL(localValue, {
|
|
228
|
+
width,
|
|
229
|
+
height,
|
|
230
|
+
ratio: 1,
|
|
231
|
+
});
|
|
232
|
+
} else if (!localValue) {
|
|
233
|
+
sigCanvas.clear();
|
|
234
|
+
}
|
|
235
|
+
}, [localValue, width, height]);
|
|
236
|
+
|
|
237
|
+
const getMimeType = (): string => {
|
|
238
|
+
switch (imageFormat) {
|
|
239
|
+
case 'jpeg':
|
|
240
|
+
return 'image/jpeg';
|
|
241
|
+
case 'svg':
|
|
242
|
+
return 'image/svg+xml';
|
|
243
|
+
case 'png':
|
|
244
|
+
default:
|
|
245
|
+
return 'image/png';
|
|
246
|
+
}
|
|
247
|
+
};
|
|
248
|
+
|
|
249
|
+
const getDataURL = (): string | undefined => {
|
|
250
|
+
const sigCanvas = sigCanvasRef.current;
|
|
251
|
+
if (!sigCanvas || sigCanvas.isEmpty()) {
|
|
252
|
+
return undefined;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
if (imageFormat === 'svg') {
|
|
256
|
+
const dataUrl = sigCanvas.toDataURL('image/svg+xml');
|
|
257
|
+
return dataUrl;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
return sigCanvas.toDataURL(getMimeType());
|
|
261
|
+
};
|
|
262
|
+
|
|
263
|
+
const handleStrokeEnd = () => {
|
|
264
|
+
if (disabled || isReadOnly()) return;
|
|
265
|
+
|
|
266
|
+
// Limpar erros ao interagir
|
|
267
|
+
const hasError = internalError || contextError;
|
|
268
|
+
if (hasError) {
|
|
269
|
+
setInternalError(undefined);
|
|
270
|
+
validationContext?.clearError(fieldKey);
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
const base64Value = getDataURL();
|
|
274
|
+
setLocalValue(base64Value);
|
|
275
|
+
|
|
276
|
+
// Salvar no datasource
|
|
277
|
+
if (
|
|
278
|
+
dataSource &&
|
|
279
|
+
!dataSource.isBrowsing() &&
|
|
280
|
+
dataField &&
|
|
281
|
+
dataSource.getFieldValue(dataField) !== base64Value
|
|
282
|
+
) {
|
|
283
|
+
v1v2Compatibility.handleValueChange(base64Value);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
if (onChangeValue) {
|
|
287
|
+
onChangeValue(base64Value);
|
|
288
|
+
}
|
|
289
|
+
};
|
|
290
|
+
|
|
291
|
+
const handleClear = () => {
|
|
292
|
+
if (disabled || isReadOnly()) return;
|
|
293
|
+
|
|
294
|
+
const sigCanvas = sigCanvasRef.current;
|
|
295
|
+
if (sigCanvas) {
|
|
296
|
+
sigCanvas.clear();
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
// Limpar erros
|
|
300
|
+
const hasError = internalError || contextError;
|
|
301
|
+
if (hasError) {
|
|
302
|
+
setInternalError(undefined);
|
|
303
|
+
validationContext?.clearError(fieldKey);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
setLocalValue(undefined);
|
|
307
|
+
|
|
308
|
+
if (
|
|
309
|
+
dataSource &&
|
|
310
|
+
!dataSource.isBrowsing() &&
|
|
311
|
+
dataField
|
|
312
|
+
) {
|
|
313
|
+
v1v2Compatibility.handleValueChange(undefined);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
if (onChangeValue) {
|
|
317
|
+
onChangeValue(undefined);
|
|
318
|
+
}
|
|
319
|
+
};
|
|
320
|
+
|
|
321
|
+
const handleConfirm = () => {
|
|
322
|
+
const base64Value = getDataURL();
|
|
323
|
+
if (onConfirm) {
|
|
324
|
+
onConfirm(base64Value);
|
|
325
|
+
}
|
|
326
|
+
};
|
|
327
|
+
|
|
328
|
+
const isReadOnly = (): boolean => {
|
|
329
|
+
return readOnly || v1v2Compatibility.isReadOnly;
|
|
330
|
+
};
|
|
331
|
+
|
|
332
|
+
const handleFocusEnter = (event: React.FocusEvent<any>) => {
|
|
333
|
+
if (onFocusEnter) {
|
|
334
|
+
onFocusEnter(event);
|
|
335
|
+
}
|
|
336
|
+
};
|
|
337
|
+
|
|
338
|
+
const handleFocusExit = (event: React.FocusEvent<any>) => {
|
|
339
|
+
if (onFocusExit) {
|
|
340
|
+
onFocusExit(event);
|
|
341
|
+
}
|
|
342
|
+
};
|
|
343
|
+
|
|
344
|
+
const displayError = internalError || contextError;
|
|
345
|
+
const isDisabledOrReadOnly = disabled || isReadOnly();
|
|
346
|
+
|
|
347
|
+
return (
|
|
348
|
+
<Input.Wrapper
|
|
349
|
+
withAsterisk={required}
|
|
350
|
+
label={label}
|
|
351
|
+
description={description}
|
|
352
|
+
error={displayError}
|
|
353
|
+
size={size}
|
|
354
|
+
className={className}
|
|
355
|
+
style={style}
|
|
356
|
+
>
|
|
357
|
+
<Box
|
|
358
|
+
ref={containerRef}
|
|
359
|
+
onFocus={handleFocusEnter}
|
|
360
|
+
onBlur={handleFocusExit}
|
|
361
|
+
tabIndex={0}
|
|
362
|
+
style={{
|
|
363
|
+
border: `1px solid ${
|
|
364
|
+
displayError
|
|
365
|
+
? theme.colors.red[6]
|
|
366
|
+
: colorScheme === 'dark'
|
|
367
|
+
? theme.colors.dark[4]
|
|
368
|
+
: theme.colors.gray[4]
|
|
369
|
+
}`,
|
|
370
|
+
borderRadius: theme.radius.sm,
|
|
371
|
+
overflow: 'hidden',
|
|
372
|
+
width,
|
|
373
|
+
opacity: disabled ? 0.6 : 1,
|
|
374
|
+
cursor: isDisabledOrReadOnly ? 'not-allowed' : 'crosshair',
|
|
375
|
+
position: 'relative',
|
|
376
|
+
}}
|
|
377
|
+
>
|
|
378
|
+
<SignatureCanvas
|
|
379
|
+
ref={sigCanvasRef}
|
|
380
|
+
penColor={penColor}
|
|
381
|
+
backgroundColor={resolvedBackgroundColor}
|
|
382
|
+
canvasProps={{
|
|
383
|
+
width,
|
|
384
|
+
height,
|
|
385
|
+
style: {
|
|
386
|
+
display: 'block',
|
|
387
|
+
pointerEvents: isDisabledOrReadOnly ? 'none' : 'auto',
|
|
388
|
+
},
|
|
389
|
+
}}
|
|
390
|
+
onEnd={handleStrokeEnd}
|
|
391
|
+
/>
|
|
392
|
+
</Box>
|
|
393
|
+
{(showClearButton || showConfirmButton) && (
|
|
394
|
+
<Group gap="xs" mt="xs">
|
|
395
|
+
{showClearButton && (
|
|
396
|
+
<Button
|
|
397
|
+
variant="light"
|
|
398
|
+
size="xs"
|
|
399
|
+
leftSection={<IconEraser size={16} />}
|
|
400
|
+
onClick={handleClear}
|
|
401
|
+
disabled={isDisabledOrReadOnly}
|
|
402
|
+
>
|
|
403
|
+
{clearLabel}
|
|
404
|
+
</Button>
|
|
405
|
+
)}
|
|
406
|
+
{showConfirmButton && (
|
|
407
|
+
<Button
|
|
408
|
+
variant="filled"
|
|
409
|
+
size="xs"
|
|
410
|
+
leftSection={<IconCheck size={16} />}
|
|
411
|
+
onClick={handleConfirm}
|
|
412
|
+
disabled={isDisabledOrReadOnly}
|
|
413
|
+
>
|
|
414
|
+
{confirmLabel}
|
|
415
|
+
</Button>
|
|
416
|
+
)}
|
|
417
|
+
</Group>
|
|
418
|
+
)}
|
|
419
|
+
</Input.Wrapper>
|
|
420
|
+
);
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
export const ArchbaseSignaturePad = React.memo(ArchbaseSignaturePadInner) as typeof ArchbaseSignaturePadInner;
|
|
424
|
+
|
|
425
|
+
(ArchbaseSignaturePad as any).displayName = 'ArchbaseSignaturePad';
|