@archbase/components 3.0.23 → 4.0.0
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,293 @@
|
|
|
1
|
+
import React, { useCallback, useState } from 'react';
|
|
2
|
+
import { Button, ActionIcon, Tooltip, MantineSize, MantineColor } from '@mantine/core';
|
|
3
|
+
import { IconFileSpreadsheet, IconDownload } from '@tabler/icons-react';
|
|
4
|
+
import * as XLSX from 'xlsx';
|
|
5
|
+
import { getI18nextInstance } from '@archbase/core';
|
|
6
|
+
|
|
7
|
+
export interface ExcelExportColumn {
|
|
8
|
+
/** Campo/key do dado */
|
|
9
|
+
field: string;
|
|
10
|
+
/** Label do cabeçalho */
|
|
11
|
+
header: string;
|
|
12
|
+
/** Largura da coluna em caracteres */
|
|
13
|
+
width?: number;
|
|
14
|
+
/** Formatador de valor */
|
|
15
|
+
formatter?: (value: any, row: any) => string | number;
|
|
16
|
+
/** Se a coluna deve ser incluída na exportação */
|
|
17
|
+
visible?: boolean;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface ArchbaseDataGridExcelExportProps<T = any> {
|
|
21
|
+
/** Dados a serem exportados */
|
|
22
|
+
data: T[];
|
|
23
|
+
/** Colunas a serem exportadas */
|
|
24
|
+
columns: ExcelExportColumn[];
|
|
25
|
+
/** Nome do arquivo (sem extensão) */
|
|
26
|
+
filename?: string;
|
|
27
|
+
/** Nome da planilha */
|
|
28
|
+
sheetName?: string;
|
|
29
|
+
/** Se deve incluir apenas dados filtrados (se aplicável) */
|
|
30
|
+
includeFiltered?: boolean;
|
|
31
|
+
/** Formato de data para colunas de data */
|
|
32
|
+
dateFormat?: string;
|
|
33
|
+
/** Formato de número para colunas numéricas */
|
|
34
|
+
numberFormat?: string;
|
|
35
|
+
/** Se deve incluir cabeçalhos */
|
|
36
|
+
includeHeaders?: boolean;
|
|
37
|
+
/** Callback antes da exportação */
|
|
38
|
+
onBeforeExport?: (data: T[]) => T[] | Promise<T[]>;
|
|
39
|
+
/** Callback após exportação bem sucedida */
|
|
40
|
+
onExportSuccess?: () => void;
|
|
41
|
+
/** Callback em caso de erro */
|
|
42
|
+
onExportError?: (error: Error) => void;
|
|
43
|
+
/** Variante do botão */
|
|
44
|
+
variant?: 'button' | 'icon';
|
|
45
|
+
/** Label do botão */
|
|
46
|
+
label?: string;
|
|
47
|
+
/** Tamanho do botão */
|
|
48
|
+
size?: MantineSize;
|
|
49
|
+
/** Cor do botão */
|
|
50
|
+
color?: MantineColor;
|
|
51
|
+
/** Se o botão está desabilitado */
|
|
52
|
+
disabled?: boolean;
|
|
53
|
+
/** Tooltip */
|
|
54
|
+
tooltip?: string;
|
|
55
|
+
/** Classe CSS */
|
|
56
|
+
className?: string;
|
|
57
|
+
/** Estilo */
|
|
58
|
+
style?: React.CSSProperties;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export function ArchbaseDataGridExcelExport<T = any>({
|
|
62
|
+
data,
|
|
63
|
+
columns,
|
|
64
|
+
filename = 'export',
|
|
65
|
+
sheetName = 'Dados',
|
|
66
|
+
includeFiltered = true,
|
|
67
|
+
dateFormat = 'dd/mm/yyyy',
|
|
68
|
+
numberFormat,
|
|
69
|
+
includeHeaders = true,
|
|
70
|
+
onBeforeExport,
|
|
71
|
+
onExportSuccess,
|
|
72
|
+
onExportError,
|
|
73
|
+
variant = 'button',
|
|
74
|
+
label,
|
|
75
|
+
size = 'sm',
|
|
76
|
+
color,
|
|
77
|
+
disabled = false,
|
|
78
|
+
tooltip,
|
|
79
|
+
className,
|
|
80
|
+
style,
|
|
81
|
+
}: ArchbaseDataGridExcelExportProps<T>) {
|
|
82
|
+
const t = getI18nextInstance().t;
|
|
83
|
+
const [isExporting, setIsExporting] = useState(false);
|
|
84
|
+
|
|
85
|
+
const formatValue = useCallback(
|
|
86
|
+
(value: any, column: ExcelExportColumn, row: T): any => {
|
|
87
|
+
if (value === null || value === undefined) {
|
|
88
|
+
return '';
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Usa formatador customizado se disponível
|
|
92
|
+
if (column.formatter) {
|
|
93
|
+
return column.formatter(value, row);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Formata datas
|
|
97
|
+
if (value instanceof Date) {
|
|
98
|
+
return value.toLocaleDateString('pt-BR');
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Formata booleanos
|
|
102
|
+
if (typeof value === 'boolean') {
|
|
103
|
+
return value ? 'Sim' : 'Não';
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Retorna valor como está
|
|
107
|
+
return value;
|
|
108
|
+
},
|
|
109
|
+
[]
|
|
110
|
+
);
|
|
111
|
+
|
|
112
|
+
const exportToExcel = useCallback(async () => {
|
|
113
|
+
setIsExporting(true);
|
|
114
|
+
|
|
115
|
+
try {
|
|
116
|
+
// Filtra colunas visíveis
|
|
117
|
+
const visibleColumns = columns.filter((col) => col.visible !== false);
|
|
118
|
+
|
|
119
|
+
// Prepara dados
|
|
120
|
+
let exportData = data;
|
|
121
|
+
if (onBeforeExport) {
|
|
122
|
+
exportData = await onBeforeExport(data);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Cria array de arrays para o worksheet
|
|
126
|
+
const wsData: any[][] = [];
|
|
127
|
+
|
|
128
|
+
// Adiciona cabeçalhos
|
|
129
|
+
if (includeHeaders) {
|
|
130
|
+
wsData.push(visibleColumns.map((col) => col.header));
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Adiciona dados
|
|
134
|
+
exportData.forEach((row) => {
|
|
135
|
+
const rowData = visibleColumns.map((col) => {
|
|
136
|
+
const value = (row as any)[col.field];
|
|
137
|
+
return formatValue(value, col, row);
|
|
138
|
+
});
|
|
139
|
+
wsData.push(rowData);
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
// Cria worksheet
|
|
143
|
+
const ws = XLSX.utils.aoa_to_sheet(wsData);
|
|
144
|
+
|
|
145
|
+
// Define larguras das colunas
|
|
146
|
+
const colWidths = visibleColumns.map((col) => ({
|
|
147
|
+
wch: col.width || Math.max(col.header.length, 15),
|
|
148
|
+
}));
|
|
149
|
+
ws['!cols'] = colWidths;
|
|
150
|
+
|
|
151
|
+
// Cria workbook
|
|
152
|
+
const wb = XLSX.utils.book_new();
|
|
153
|
+
XLSX.utils.book_append_sheet(wb, ws, sheetName);
|
|
154
|
+
|
|
155
|
+
// Gera arquivo e faz download
|
|
156
|
+
const timestamp = new Date().toISOString().slice(0, 10);
|
|
157
|
+
const finalFilename = `${filename}_${timestamp}.xlsx`;
|
|
158
|
+
|
|
159
|
+
XLSX.writeFile(wb, finalFilename);
|
|
160
|
+
|
|
161
|
+
onExportSuccess?.();
|
|
162
|
+
} catch (error) {
|
|
163
|
+
const err = error instanceof Error ? error : new Error('Erro ao exportar');
|
|
164
|
+
onExportError?.(err);
|
|
165
|
+
} finally {
|
|
166
|
+
setIsExporting(false);
|
|
167
|
+
}
|
|
168
|
+
}, [
|
|
169
|
+
columns,
|
|
170
|
+
data,
|
|
171
|
+
filename,
|
|
172
|
+
formatValue,
|
|
173
|
+
includeHeaders,
|
|
174
|
+
onBeforeExport,
|
|
175
|
+
onExportError,
|
|
176
|
+
onExportSuccess,
|
|
177
|
+
sheetName,
|
|
178
|
+
]);
|
|
179
|
+
|
|
180
|
+
const buttonLabel = label || t('archbase:Exportar Excel');
|
|
181
|
+
const tooltipText = tooltip || t('archbase:Exportar dados para Excel');
|
|
182
|
+
|
|
183
|
+
if (variant === 'icon') {
|
|
184
|
+
return (
|
|
185
|
+
<Tooltip label={tooltipText}>
|
|
186
|
+
<ActionIcon
|
|
187
|
+
variant="subtle"
|
|
188
|
+
size={size}
|
|
189
|
+
color={color}
|
|
190
|
+
onClick={exportToExcel}
|
|
191
|
+
loading={isExporting}
|
|
192
|
+
disabled={disabled || data.length === 0}
|
|
193
|
+
className={className}
|
|
194
|
+
style={style}
|
|
195
|
+
aria-label={buttonLabel}
|
|
196
|
+
>
|
|
197
|
+
<IconFileSpreadsheet size={18} />
|
|
198
|
+
</ActionIcon>
|
|
199
|
+
</Tooltip>
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
return (
|
|
204
|
+
<Tooltip label={tooltipText} disabled={!tooltip}>
|
|
205
|
+
<Button
|
|
206
|
+
variant="light"
|
|
207
|
+
size={size}
|
|
208
|
+
color={color}
|
|
209
|
+
leftSection={<IconFileSpreadsheet size={18} />}
|
|
210
|
+
onClick={exportToExcel}
|
|
211
|
+
loading={isExporting}
|
|
212
|
+
disabled={disabled || data.length === 0}
|
|
213
|
+
className={className}
|
|
214
|
+
style={style}
|
|
215
|
+
>
|
|
216
|
+
{buttonLabel}
|
|
217
|
+
</Button>
|
|
218
|
+
</Tooltip>
|
|
219
|
+
);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
ArchbaseDataGridExcelExport.displayName = 'ArchbaseDataGridExcelExport';
|
|
223
|
+
|
|
224
|
+
// Hook para usar a exportação programaticamente
|
|
225
|
+
export function useArchbaseExcelExport<T = any>() {
|
|
226
|
+
const [isExporting, setIsExporting] = useState(false);
|
|
227
|
+
const [error, setError] = useState<Error | null>(null);
|
|
228
|
+
|
|
229
|
+
const exportToExcel = useCallback(
|
|
230
|
+
async (
|
|
231
|
+
data: T[],
|
|
232
|
+
columns: ExcelExportColumn[],
|
|
233
|
+
options: {
|
|
234
|
+
filename?: string;
|
|
235
|
+
sheetName?: string;
|
|
236
|
+
includeHeaders?: boolean;
|
|
237
|
+
} = {}
|
|
238
|
+
) => {
|
|
239
|
+
const { filename = 'export', sheetName = 'Dados', includeHeaders = true } = options;
|
|
240
|
+
|
|
241
|
+
setIsExporting(true);
|
|
242
|
+
setError(null);
|
|
243
|
+
|
|
244
|
+
try {
|
|
245
|
+
const visibleColumns = columns.filter((col) => col.visible !== false);
|
|
246
|
+
const wsData: any[][] = [];
|
|
247
|
+
|
|
248
|
+
if (includeHeaders) {
|
|
249
|
+
wsData.push(visibleColumns.map((col) => col.header));
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
data.forEach((row) => {
|
|
253
|
+
const rowData = visibleColumns.map((col) => {
|
|
254
|
+
const value = (row as any)[col.field];
|
|
255
|
+
if (col.formatter) {
|
|
256
|
+
return col.formatter(value, row);
|
|
257
|
+
}
|
|
258
|
+
if (value instanceof Date) {
|
|
259
|
+
return value.toLocaleDateString('pt-BR');
|
|
260
|
+
}
|
|
261
|
+
if (typeof value === 'boolean') {
|
|
262
|
+
return value ? 'Sim' : 'Não';
|
|
263
|
+
}
|
|
264
|
+
return value ?? '';
|
|
265
|
+
});
|
|
266
|
+
wsData.push(rowData);
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
const ws = XLSX.utils.aoa_to_sheet(wsData);
|
|
270
|
+
ws['!cols'] = visibleColumns.map((col) => ({
|
|
271
|
+
wch: col.width || Math.max(col.header.length, 15),
|
|
272
|
+
}));
|
|
273
|
+
|
|
274
|
+
const wb = XLSX.utils.book_new();
|
|
275
|
+
XLSX.utils.book_append_sheet(wb, ws, sheetName);
|
|
276
|
+
|
|
277
|
+
const timestamp = new Date().toISOString().slice(0, 10);
|
|
278
|
+
XLSX.writeFile(wb, `${filename}_${timestamp}.xlsx`);
|
|
279
|
+
|
|
280
|
+
return true;
|
|
281
|
+
} catch (err) {
|
|
282
|
+
const error = err instanceof Error ? err : new Error('Erro ao exportar');
|
|
283
|
+
setError(error);
|
|
284
|
+
return false;
|
|
285
|
+
} finally {
|
|
286
|
+
setIsExporting(false);
|
|
287
|
+
}
|
|
288
|
+
},
|
|
289
|
+
[]
|
|
290
|
+
);
|
|
291
|
+
|
|
292
|
+
return { exportToExcel, isExporting, error };
|
|
293
|
+
}
|
package/src/datagrid/index.tsx
CHANGED
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
import React, { forwardRef, ReactNode, Children, cloneElement, isValidElement } from 'react';
|
|
2
|
+
import { Transition, TransitionProps, Box } from '@mantine/core';
|
|
3
|
+
|
|
4
|
+
export type ArchbaseAnimationPreset =
|
|
5
|
+
| 'fade'
|
|
6
|
+
| 'scale'
|
|
7
|
+
| 'scale-y'
|
|
8
|
+
| 'scale-x'
|
|
9
|
+
| 'skew-up'
|
|
10
|
+
| 'skew-down'
|
|
11
|
+
| 'rotate-left'
|
|
12
|
+
| 'rotate-right'
|
|
13
|
+
| 'slide-down'
|
|
14
|
+
| 'slide-up'
|
|
15
|
+
| 'slide-left'
|
|
16
|
+
| 'slide-right'
|
|
17
|
+
| 'pop'
|
|
18
|
+
| 'pop-bottom-left'
|
|
19
|
+
| 'pop-bottom-right'
|
|
20
|
+
| 'pop-top-left'
|
|
21
|
+
| 'pop-top-right';
|
|
22
|
+
|
|
23
|
+
export interface ArchbaseAnimationWrapperProps {
|
|
24
|
+
/** Conteúdo a ser animado */
|
|
25
|
+
children: ReactNode;
|
|
26
|
+
/** Se o conteúdo está visível */
|
|
27
|
+
visible?: boolean;
|
|
28
|
+
/** Preset de animação */
|
|
29
|
+
preset?: ArchbaseAnimationPreset;
|
|
30
|
+
/** Duração da animação em ms */
|
|
31
|
+
duration?: number;
|
|
32
|
+
/** Delay antes de iniciar em ms */
|
|
33
|
+
delay?: number;
|
|
34
|
+
/** Função de timing */
|
|
35
|
+
timingFunction?: string;
|
|
36
|
+
/** Se deve manter montado quando invisível */
|
|
37
|
+
keepMounted?: boolean;
|
|
38
|
+
/** Callback quando a animação de entrada completa */
|
|
39
|
+
onEntered?: () => void;
|
|
40
|
+
/** Callback quando a animação de saída completa */
|
|
41
|
+
onExited?: () => void;
|
|
42
|
+
/** Callback quando a animação de entrada inicia */
|
|
43
|
+
onEnter?: () => void;
|
|
44
|
+
/** Callback quando a animação de saída inicia */
|
|
45
|
+
onExit?: () => void;
|
|
46
|
+
/** Classe CSS */
|
|
47
|
+
className?: string;
|
|
48
|
+
/** Estilo */
|
|
49
|
+
style?: React.CSSProperties;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export const ArchbaseAnimationWrapper = forwardRef<HTMLDivElement, ArchbaseAnimationWrapperProps>(
|
|
53
|
+
(
|
|
54
|
+
{
|
|
55
|
+
children,
|
|
56
|
+
visible = true,
|
|
57
|
+
preset = 'fade',
|
|
58
|
+
duration = 200,
|
|
59
|
+
delay = 0,
|
|
60
|
+
timingFunction = 'ease',
|
|
61
|
+
keepMounted = false,
|
|
62
|
+
onEntered,
|
|
63
|
+
onExited,
|
|
64
|
+
onEnter,
|
|
65
|
+
onExit,
|
|
66
|
+
className,
|
|
67
|
+
style,
|
|
68
|
+
},
|
|
69
|
+
ref
|
|
70
|
+
) => {
|
|
71
|
+
return (
|
|
72
|
+
<Transition
|
|
73
|
+
mounted={visible}
|
|
74
|
+
transition={preset}
|
|
75
|
+
duration={duration}
|
|
76
|
+
timingFunction={timingFunction}
|
|
77
|
+
keepMounted={keepMounted}
|
|
78
|
+
onEntered={onEntered}
|
|
79
|
+
onExited={onExited}
|
|
80
|
+
onEnter={onEnter}
|
|
81
|
+
onExit={onExit}
|
|
82
|
+
>
|
|
83
|
+
{(styles) => (
|
|
84
|
+
<Box
|
|
85
|
+
ref={ref}
|
|
86
|
+
className={className}
|
|
87
|
+
style={{
|
|
88
|
+
...style,
|
|
89
|
+
...styles,
|
|
90
|
+
transitionDelay: delay ? `${delay}ms` : undefined,
|
|
91
|
+
}}
|
|
92
|
+
>
|
|
93
|
+
{children}
|
|
94
|
+
</Box>
|
|
95
|
+
)}
|
|
96
|
+
</Transition>
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
ArchbaseAnimationWrapper.displayName = 'ArchbaseAnimationWrapper';
|
|
102
|
+
|
|
103
|
+
// ================== Animated List ==================
|
|
104
|
+
|
|
105
|
+
export interface ArchbaseAnimatedListProps {
|
|
106
|
+
/** Itens da lista */
|
|
107
|
+
children: ReactNode;
|
|
108
|
+
/** Se os itens estão visíveis */
|
|
109
|
+
visible?: boolean;
|
|
110
|
+
/** Preset de animação */
|
|
111
|
+
preset?: ArchbaseAnimationPreset;
|
|
112
|
+
/** Duração da animação em ms */
|
|
113
|
+
duration?: number;
|
|
114
|
+
/** Delay base em ms */
|
|
115
|
+
baseDelay?: number;
|
|
116
|
+
/** Delay incremental entre itens em ms */
|
|
117
|
+
staggerDelay?: number;
|
|
118
|
+
/** Função de timing */
|
|
119
|
+
timingFunction?: string;
|
|
120
|
+
/** Se deve animar na ordem reversa */
|
|
121
|
+
reverse?: boolean;
|
|
122
|
+
/** Classe CSS do container */
|
|
123
|
+
className?: string;
|
|
124
|
+
/** Estilo do container */
|
|
125
|
+
style?: React.CSSProperties;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export const ArchbaseAnimatedList = forwardRef<HTMLDivElement, ArchbaseAnimatedListProps>(
|
|
129
|
+
(
|
|
130
|
+
{
|
|
131
|
+
children,
|
|
132
|
+
visible = true,
|
|
133
|
+
preset = 'slide-up',
|
|
134
|
+
duration = 200,
|
|
135
|
+
baseDelay = 0,
|
|
136
|
+
staggerDelay = 50,
|
|
137
|
+
timingFunction = 'ease',
|
|
138
|
+
reverse = false,
|
|
139
|
+
className,
|
|
140
|
+
style,
|
|
141
|
+
},
|
|
142
|
+
ref
|
|
143
|
+
) => {
|
|
144
|
+
const childArray = Children.toArray(children);
|
|
145
|
+
const count = childArray.length;
|
|
146
|
+
|
|
147
|
+
return (
|
|
148
|
+
<Box ref={ref} className={className} style={style}>
|
|
149
|
+
{childArray.map((child, index) => {
|
|
150
|
+
const itemIndex = reverse ? count - 1 - index : index;
|
|
151
|
+
const delay = baseDelay + itemIndex * staggerDelay;
|
|
152
|
+
|
|
153
|
+
return (
|
|
154
|
+
<Transition
|
|
155
|
+
key={index}
|
|
156
|
+
mounted={visible}
|
|
157
|
+
transition={preset}
|
|
158
|
+
duration={duration}
|
|
159
|
+
timingFunction={timingFunction}
|
|
160
|
+
>
|
|
161
|
+
{(styles) => (
|
|
162
|
+
<Box
|
|
163
|
+
style={{
|
|
164
|
+
...styles,
|
|
165
|
+
transitionDelay: `${delay}ms`,
|
|
166
|
+
}}
|
|
167
|
+
>
|
|
168
|
+
{child}
|
|
169
|
+
</Box>
|
|
170
|
+
)}
|
|
171
|
+
</Transition>
|
|
172
|
+
);
|
|
173
|
+
})}
|
|
174
|
+
</Box>
|
|
175
|
+
);
|
|
176
|
+
}
|
|
177
|
+
);
|
|
178
|
+
|
|
179
|
+
ArchbaseAnimatedList.displayName = 'ArchbaseAnimatedList';
|
|
180
|
+
|
|
181
|
+
// ================== Fade In When Visible ==================
|
|
182
|
+
|
|
183
|
+
export interface ArchbaseFadeInWhenVisibleProps {
|
|
184
|
+
/** Conteúdo a ser animado */
|
|
185
|
+
children: ReactNode;
|
|
186
|
+
/** Preset de animação */
|
|
187
|
+
preset?: ArchbaseAnimationPreset;
|
|
188
|
+
/** Duração da animação em ms */
|
|
189
|
+
duration?: number;
|
|
190
|
+
/** Delay antes de iniciar em ms */
|
|
191
|
+
delay?: number;
|
|
192
|
+
/** Threshold de visibilidade (0-1) */
|
|
193
|
+
threshold?: number;
|
|
194
|
+
/** Se deve animar apenas uma vez */
|
|
195
|
+
once?: boolean;
|
|
196
|
+
/** Classe CSS */
|
|
197
|
+
className?: string;
|
|
198
|
+
/** Estilo */
|
|
199
|
+
style?: React.CSSProperties;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
export const ArchbaseFadeInWhenVisible = forwardRef<HTMLDivElement, ArchbaseFadeInWhenVisibleProps>(
|
|
203
|
+
(
|
|
204
|
+
{
|
|
205
|
+
children,
|
|
206
|
+
preset = 'fade',
|
|
207
|
+
duration = 400,
|
|
208
|
+
delay = 0,
|
|
209
|
+
threshold = 0.1,
|
|
210
|
+
once = true,
|
|
211
|
+
className,
|
|
212
|
+
style,
|
|
213
|
+
},
|
|
214
|
+
ref
|
|
215
|
+
) => {
|
|
216
|
+
const [isVisible, setIsVisible] = React.useState(false);
|
|
217
|
+
const elementRef = React.useRef<HTMLDivElement>(null);
|
|
218
|
+
|
|
219
|
+
React.useEffect(() => {
|
|
220
|
+
const observer = new IntersectionObserver(
|
|
221
|
+
([entry]) => {
|
|
222
|
+
if (entry.isIntersecting) {
|
|
223
|
+
setIsVisible(true);
|
|
224
|
+
if (once && elementRef.current) {
|
|
225
|
+
observer.unobserve(elementRef.current);
|
|
226
|
+
}
|
|
227
|
+
} else if (!once) {
|
|
228
|
+
setIsVisible(false);
|
|
229
|
+
}
|
|
230
|
+
},
|
|
231
|
+
{ threshold }
|
|
232
|
+
);
|
|
233
|
+
|
|
234
|
+
if (elementRef.current) {
|
|
235
|
+
observer.observe(elementRef.current);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
return () => {
|
|
239
|
+
if (elementRef.current) {
|
|
240
|
+
observer.unobserve(elementRef.current);
|
|
241
|
+
}
|
|
242
|
+
};
|
|
243
|
+
}, [once, threshold]);
|
|
244
|
+
|
|
245
|
+
return (
|
|
246
|
+
<Box ref={elementRef}>
|
|
247
|
+
<Transition
|
|
248
|
+
mounted={isVisible}
|
|
249
|
+
transition={preset}
|
|
250
|
+
duration={duration}
|
|
251
|
+
timingFunction="ease"
|
|
252
|
+
>
|
|
253
|
+
{(styles) => (
|
|
254
|
+
<Box
|
|
255
|
+
ref={ref}
|
|
256
|
+
className={className}
|
|
257
|
+
style={{
|
|
258
|
+
...style,
|
|
259
|
+
...styles,
|
|
260
|
+
transitionDelay: delay ? `${delay}ms` : undefined,
|
|
261
|
+
}}
|
|
262
|
+
>
|
|
263
|
+
{children}
|
|
264
|
+
</Box>
|
|
265
|
+
)}
|
|
266
|
+
</Transition>
|
|
267
|
+
</Box>
|
|
268
|
+
);
|
|
269
|
+
}
|
|
270
|
+
);
|
|
271
|
+
|
|
272
|
+
ArchbaseFadeInWhenVisible.displayName = 'ArchbaseFadeInWhenVisible';
|