@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,419 @@
|
|
|
1
|
+
import React, { forwardRef } from 'react';
|
|
2
|
+
import { Skeleton, Stack, Group, Box, MantineRadius } from '@mantine/core';
|
|
3
|
+
|
|
4
|
+
// ================== DataGrid Skeleton ==================
|
|
5
|
+
|
|
6
|
+
export interface ArchbaseDataGridSkeletonProps {
|
|
7
|
+
/** Número de linhas */
|
|
8
|
+
rows?: number;
|
|
9
|
+
/** Número de colunas */
|
|
10
|
+
columns?: number;
|
|
11
|
+
/** Se deve mostrar header */
|
|
12
|
+
showHeader?: boolean;
|
|
13
|
+
/** Altura da linha */
|
|
14
|
+
rowHeight?: number;
|
|
15
|
+
/** Espaçamento entre linhas */
|
|
16
|
+
gap?: number;
|
|
17
|
+
/** Raio das bordas */
|
|
18
|
+
radius?: MantineRadius;
|
|
19
|
+
/** Se deve animar */
|
|
20
|
+
animate?: boolean;
|
|
21
|
+
/** Classe CSS */
|
|
22
|
+
className?: string;
|
|
23
|
+
/** Estilo */
|
|
24
|
+
style?: React.CSSProperties;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export const ArchbaseDataGridSkeleton = forwardRef<HTMLDivElement, ArchbaseDataGridSkeletonProps>(
|
|
28
|
+
(
|
|
29
|
+
{
|
|
30
|
+
rows = 5,
|
|
31
|
+
columns = 4,
|
|
32
|
+
showHeader = true,
|
|
33
|
+
rowHeight = 40,
|
|
34
|
+
gap = 8,
|
|
35
|
+
radius = 'sm',
|
|
36
|
+
animate = true,
|
|
37
|
+
className,
|
|
38
|
+
style,
|
|
39
|
+
},
|
|
40
|
+
ref
|
|
41
|
+
) => {
|
|
42
|
+
const columnWidths = Array.from({ length: columns }, (_, i) => {
|
|
43
|
+
// Primeira coluna menor (checkbox), última maior
|
|
44
|
+
if (i === 0) return '40px';
|
|
45
|
+
if (i === columns - 1) return '1fr';
|
|
46
|
+
return `${Math.floor(Math.random() * 50) + 100}px`;
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
return (
|
|
50
|
+
<Stack ref={ref} gap={gap} className={className} style={style}>
|
|
51
|
+
{/* Header */}
|
|
52
|
+
{showHeader && (
|
|
53
|
+
<Group gap={gap} style={{ display: 'grid', gridTemplateColumns: columnWidths.join(' ') }}>
|
|
54
|
+
{Array.from({ length: columns }).map((_, i) => (
|
|
55
|
+
<Skeleton key={i} height={rowHeight} radius={radius} animate={animate} />
|
|
56
|
+
))}
|
|
57
|
+
</Group>
|
|
58
|
+
)}
|
|
59
|
+
|
|
60
|
+
{/* Rows */}
|
|
61
|
+
{Array.from({ length: rows }).map((_, rowIndex) => (
|
|
62
|
+
<Group
|
|
63
|
+
key={rowIndex}
|
|
64
|
+
gap={gap}
|
|
65
|
+
style={{ display: 'grid', gridTemplateColumns: columnWidths.join(' ') }}
|
|
66
|
+
>
|
|
67
|
+
{Array.from({ length: columns }).map((_, colIndex) => (
|
|
68
|
+
<Skeleton key={colIndex} height={rowHeight} radius={radius} animate={animate} />
|
|
69
|
+
))}
|
|
70
|
+
</Group>
|
|
71
|
+
))}
|
|
72
|
+
</Stack>
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
ArchbaseDataGridSkeleton.displayName = 'ArchbaseDataGridSkeleton';
|
|
78
|
+
|
|
79
|
+
// ================== Form Skeleton ==================
|
|
80
|
+
|
|
81
|
+
export interface ArchbaseFormSkeletonProps {
|
|
82
|
+
/** Número de campos */
|
|
83
|
+
fields?: number;
|
|
84
|
+
/** Número de colunas do form */
|
|
85
|
+
columns?: number;
|
|
86
|
+
/** Se deve mostrar labels */
|
|
87
|
+
showLabels?: boolean;
|
|
88
|
+
/** Altura do input */
|
|
89
|
+
inputHeight?: number;
|
|
90
|
+
/** Altura do label */
|
|
91
|
+
labelHeight?: number;
|
|
92
|
+
/** Espaçamento */
|
|
93
|
+
gap?: number;
|
|
94
|
+
/** Raio das bordas */
|
|
95
|
+
radius?: MantineRadius;
|
|
96
|
+
/** Se deve animar */
|
|
97
|
+
animate?: boolean;
|
|
98
|
+
/** Se deve mostrar botões de ação */
|
|
99
|
+
showActions?: boolean;
|
|
100
|
+
/** Classe CSS */
|
|
101
|
+
className?: string;
|
|
102
|
+
/** Estilo */
|
|
103
|
+
style?: React.CSSProperties;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export const ArchbaseFormSkeleton = forwardRef<HTMLDivElement, ArchbaseFormSkeletonProps>(
|
|
107
|
+
(
|
|
108
|
+
{
|
|
109
|
+
fields = 6,
|
|
110
|
+
columns = 2,
|
|
111
|
+
showLabels = true,
|
|
112
|
+
inputHeight = 36,
|
|
113
|
+
labelHeight = 14,
|
|
114
|
+
gap = 16,
|
|
115
|
+
radius = 'sm',
|
|
116
|
+
animate = true,
|
|
117
|
+
showActions = true,
|
|
118
|
+
className,
|
|
119
|
+
style,
|
|
120
|
+
},
|
|
121
|
+
ref
|
|
122
|
+
) => {
|
|
123
|
+
const fieldGroups = Math.ceil(fields / columns);
|
|
124
|
+
|
|
125
|
+
return (
|
|
126
|
+
<Stack ref={ref} gap={gap} className={className} style={style}>
|
|
127
|
+
{Array.from({ length: fieldGroups }).map((_, groupIndex) => (
|
|
128
|
+
<Group key={groupIndex} gap={gap} grow>
|
|
129
|
+
{Array.from({ length: Math.min(columns, fields - groupIndex * columns) }).map(
|
|
130
|
+
(_, fieldIndex) => (
|
|
131
|
+
<Stack key={fieldIndex} gap={4}>
|
|
132
|
+
{showLabels && (
|
|
133
|
+
<Skeleton
|
|
134
|
+
height={labelHeight}
|
|
135
|
+
width={`${Math.floor(Math.random() * 30) + 40}%`}
|
|
136
|
+
radius={radius}
|
|
137
|
+
animate={animate}
|
|
138
|
+
/>
|
|
139
|
+
)}
|
|
140
|
+
<Skeleton height={inputHeight} radius={radius} animate={animate} />
|
|
141
|
+
</Stack>
|
|
142
|
+
)
|
|
143
|
+
)}
|
|
144
|
+
</Group>
|
|
145
|
+
))}
|
|
146
|
+
|
|
147
|
+
{/* Actions */}
|
|
148
|
+
{showActions && (
|
|
149
|
+
<Group justify="flex-end" gap={gap} mt="md">
|
|
150
|
+
<Skeleton height={36} width={100} radius={radius} animate={animate} />
|
|
151
|
+
<Skeleton height={36} width={100} radius={radius} animate={animate} />
|
|
152
|
+
</Group>
|
|
153
|
+
)}
|
|
154
|
+
</Stack>
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
);
|
|
158
|
+
|
|
159
|
+
ArchbaseFormSkeleton.displayName = 'ArchbaseFormSkeleton';
|
|
160
|
+
|
|
161
|
+
// ================== Card Skeleton ==================
|
|
162
|
+
|
|
163
|
+
export interface ArchbaseCardSkeletonProps {
|
|
164
|
+
/** Se deve mostrar avatar */
|
|
165
|
+
showAvatar?: boolean;
|
|
166
|
+
/** Tamanho do avatar */
|
|
167
|
+
avatarSize?: number;
|
|
168
|
+
/** Número de linhas de texto */
|
|
169
|
+
lines?: number;
|
|
170
|
+
/** Se deve mostrar imagem no topo */
|
|
171
|
+
showImage?: boolean;
|
|
172
|
+
/** Altura da imagem */
|
|
173
|
+
imageHeight?: number;
|
|
174
|
+
/** Se deve mostrar ações */
|
|
175
|
+
showActions?: boolean;
|
|
176
|
+
/** Raio das bordas */
|
|
177
|
+
radius?: MantineRadius;
|
|
178
|
+
/** Se deve animar */
|
|
179
|
+
animate?: boolean;
|
|
180
|
+
/** Classe CSS */
|
|
181
|
+
className?: string;
|
|
182
|
+
/** Estilo */
|
|
183
|
+
style?: React.CSSProperties;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
export const ArchbaseCardSkeleton = forwardRef<HTMLDivElement, ArchbaseCardSkeletonProps>(
|
|
187
|
+
(
|
|
188
|
+
{
|
|
189
|
+
showAvatar = true,
|
|
190
|
+
avatarSize = 40,
|
|
191
|
+
lines = 3,
|
|
192
|
+
showImage = false,
|
|
193
|
+
imageHeight = 160,
|
|
194
|
+
showActions = false,
|
|
195
|
+
radius = 'md',
|
|
196
|
+
animate = true,
|
|
197
|
+
className,
|
|
198
|
+
style,
|
|
199
|
+
},
|
|
200
|
+
ref
|
|
201
|
+
) => {
|
|
202
|
+
return (
|
|
203
|
+
<Box
|
|
204
|
+
ref={ref}
|
|
205
|
+
className={className}
|
|
206
|
+
style={{
|
|
207
|
+
...style,
|
|
208
|
+
border: '1px solid var(--mantine-color-gray-3)',
|
|
209
|
+
borderRadius: `var(--mantine-radius-${radius})`,
|
|
210
|
+
padding: 16,
|
|
211
|
+
backgroundColor: 'var(--mantine-color-body)',
|
|
212
|
+
}}
|
|
213
|
+
>
|
|
214
|
+
<Stack gap="sm">
|
|
215
|
+
{/* Image */}
|
|
216
|
+
{showImage && (
|
|
217
|
+
<Skeleton height={imageHeight} radius={radius} animate={animate} mb="sm" />
|
|
218
|
+
)}
|
|
219
|
+
|
|
220
|
+
{/* Avatar + Title */}
|
|
221
|
+
<Group gap="sm">
|
|
222
|
+
{showAvatar && (
|
|
223
|
+
<Skeleton height={avatarSize} width={avatarSize} circle animate={animate} />
|
|
224
|
+
)}
|
|
225
|
+
<Stack gap={4} style={{ flex: 1 }}>
|
|
226
|
+
<Skeleton height={16} width="60%" radius={radius} animate={animate} />
|
|
227
|
+
<Skeleton height={12} width="40%" radius={radius} animate={animate} />
|
|
228
|
+
</Stack>
|
|
229
|
+
</Group>
|
|
230
|
+
|
|
231
|
+
{/* Content lines */}
|
|
232
|
+
<Stack gap={8}>
|
|
233
|
+
{Array.from({ length: lines }).map((_, i) => (
|
|
234
|
+
<Skeleton
|
|
235
|
+
key={i}
|
|
236
|
+
height={12}
|
|
237
|
+
width={i === lines - 1 ? `${Math.floor(Math.random() * 30) + 50}%` : '100%'}
|
|
238
|
+
radius={radius}
|
|
239
|
+
animate={animate}
|
|
240
|
+
/>
|
|
241
|
+
))}
|
|
242
|
+
</Stack>
|
|
243
|
+
|
|
244
|
+
{/* Actions */}
|
|
245
|
+
{showActions && (
|
|
246
|
+
<Group gap="sm" mt="sm">
|
|
247
|
+
<Skeleton height={32} width={80} radius={radius} animate={animate} />
|
|
248
|
+
<Skeleton height={32} width={80} radius={radius} animate={animate} />
|
|
249
|
+
</Group>
|
|
250
|
+
)}
|
|
251
|
+
</Stack>
|
|
252
|
+
</Box>
|
|
253
|
+
);
|
|
254
|
+
}
|
|
255
|
+
);
|
|
256
|
+
|
|
257
|
+
ArchbaseCardSkeleton.displayName = 'ArchbaseCardSkeleton';
|
|
258
|
+
|
|
259
|
+
// ================== Kanban Skeleton ==================
|
|
260
|
+
|
|
261
|
+
export interface ArchbaseKanbanSkeletonProps {
|
|
262
|
+
/** Número de colunas */
|
|
263
|
+
columns?: number;
|
|
264
|
+
/** Número de cards por coluna */
|
|
265
|
+
cardsPerColumn?: number;
|
|
266
|
+
/** Largura da coluna */
|
|
267
|
+
columnWidth?: number;
|
|
268
|
+
/** Altura do card */
|
|
269
|
+
cardHeight?: number;
|
|
270
|
+
/** Espaçamento */
|
|
271
|
+
gap?: number;
|
|
272
|
+
/** Raio das bordas */
|
|
273
|
+
radius?: MantineRadius;
|
|
274
|
+
/** Se deve animar */
|
|
275
|
+
animate?: boolean;
|
|
276
|
+
/** Classe CSS */
|
|
277
|
+
className?: string;
|
|
278
|
+
/** Estilo */
|
|
279
|
+
style?: React.CSSProperties;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
export const ArchbaseKanbanSkeleton = forwardRef<HTMLDivElement, ArchbaseKanbanSkeletonProps>(
|
|
283
|
+
(
|
|
284
|
+
{
|
|
285
|
+
columns = 3,
|
|
286
|
+
cardsPerColumn = 3,
|
|
287
|
+
columnWidth = 280,
|
|
288
|
+
cardHeight = 100,
|
|
289
|
+
gap = 16,
|
|
290
|
+
radius = 'md',
|
|
291
|
+
animate = true,
|
|
292
|
+
className,
|
|
293
|
+
style,
|
|
294
|
+
},
|
|
295
|
+
ref
|
|
296
|
+
) => {
|
|
297
|
+
return (
|
|
298
|
+
<Group ref={ref} gap={gap} align="flex-start" className={className} style={style}>
|
|
299
|
+
{Array.from({ length: columns }).map((_, colIndex) => (
|
|
300
|
+
<Box
|
|
301
|
+
key={colIndex}
|
|
302
|
+
style={{
|
|
303
|
+
width: columnWidth,
|
|
304
|
+
backgroundColor: 'var(--mantine-color-gray-1)',
|
|
305
|
+
borderRadius: `var(--mantine-radius-${radius})`,
|
|
306
|
+
padding: 12,
|
|
307
|
+
}}
|
|
308
|
+
>
|
|
309
|
+
<Stack gap={gap}>
|
|
310
|
+
{/* Column header */}
|
|
311
|
+
<Group justify="space-between">
|
|
312
|
+
<Skeleton height={20} width={100} radius={radius} animate={animate} />
|
|
313
|
+
<Skeleton height={20} width={24} radius="xl" animate={animate} />
|
|
314
|
+
</Group>
|
|
315
|
+
|
|
316
|
+
{/* Cards */}
|
|
317
|
+
{Array.from({ length: cardsPerColumn }).map((_, cardIndex) => (
|
|
318
|
+
<Box
|
|
319
|
+
key={cardIndex}
|
|
320
|
+
style={{
|
|
321
|
+
backgroundColor: 'var(--mantine-color-body)',
|
|
322
|
+
borderRadius: `var(--mantine-radius-${radius})`,
|
|
323
|
+
padding: 12,
|
|
324
|
+
boxShadow: 'var(--mantine-shadow-xs)',
|
|
325
|
+
}}
|
|
326
|
+
>
|
|
327
|
+
<Stack gap={8}>
|
|
328
|
+
<Skeleton height={14} width="80%" radius={radius} animate={animate} />
|
|
329
|
+
<Skeleton height={12} width="60%" radius={radius} animate={animate} />
|
|
330
|
+
<Group gap={8} mt={4}>
|
|
331
|
+
<Skeleton height={24} width={24} circle animate={animate} />
|
|
332
|
+
<Skeleton height={16} width={60} radius={radius} animate={animate} />
|
|
333
|
+
</Group>
|
|
334
|
+
</Stack>
|
|
335
|
+
</Box>
|
|
336
|
+
))}
|
|
337
|
+
</Stack>
|
|
338
|
+
</Box>
|
|
339
|
+
))}
|
|
340
|
+
</Group>
|
|
341
|
+
);
|
|
342
|
+
}
|
|
343
|
+
);
|
|
344
|
+
|
|
345
|
+
ArchbaseKanbanSkeleton.displayName = 'ArchbaseKanbanSkeleton';
|
|
346
|
+
|
|
347
|
+
// ================== List Skeleton ==================
|
|
348
|
+
|
|
349
|
+
export interface ArchbaseListSkeletonProps {
|
|
350
|
+
/** Número de itens */
|
|
351
|
+
items?: number;
|
|
352
|
+
/** Se deve mostrar avatar */
|
|
353
|
+
showAvatar?: boolean;
|
|
354
|
+
/** Tamanho do avatar */
|
|
355
|
+
avatarSize?: number;
|
|
356
|
+
/** Se deve mostrar descrição */
|
|
357
|
+
showDescription?: boolean;
|
|
358
|
+
/** Se deve mostrar ação à direita */
|
|
359
|
+
showAction?: boolean;
|
|
360
|
+
/** Espaçamento */
|
|
361
|
+
gap?: number;
|
|
362
|
+
/** Raio das bordas */
|
|
363
|
+
radius?: MantineRadius;
|
|
364
|
+
/** Se deve animar */
|
|
365
|
+
animate?: boolean;
|
|
366
|
+
/** Classe CSS */
|
|
367
|
+
className?: string;
|
|
368
|
+
/** Estilo */
|
|
369
|
+
style?: React.CSSProperties;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
export const ArchbaseListSkeleton = forwardRef<HTMLDivElement, ArchbaseListSkeletonProps>(
|
|
373
|
+
(
|
|
374
|
+
{
|
|
375
|
+
items = 5,
|
|
376
|
+
showAvatar = true,
|
|
377
|
+
avatarSize = 40,
|
|
378
|
+
showDescription = true,
|
|
379
|
+
showAction = false,
|
|
380
|
+
gap = 12,
|
|
381
|
+
radius = 'sm',
|
|
382
|
+
animate = true,
|
|
383
|
+
className,
|
|
384
|
+
style,
|
|
385
|
+
},
|
|
386
|
+
ref
|
|
387
|
+
) => {
|
|
388
|
+
return (
|
|
389
|
+
<Stack ref={ref} gap={gap} className={className} style={style}>
|
|
390
|
+
{Array.from({ length: items }).map((_, i) => (
|
|
391
|
+
<Group key={i} gap="sm" wrap="nowrap">
|
|
392
|
+
{showAvatar && (
|
|
393
|
+
<Skeleton height={avatarSize} width={avatarSize} circle animate={animate} />
|
|
394
|
+
)}
|
|
395
|
+
<Stack gap={4} style={{ flex: 1 }}>
|
|
396
|
+
<Skeleton
|
|
397
|
+
height={14}
|
|
398
|
+
width={`${Math.floor(Math.random() * 30) + 50}%`}
|
|
399
|
+
radius={radius}
|
|
400
|
+
animate={animate}
|
|
401
|
+
/>
|
|
402
|
+
{showDescription && (
|
|
403
|
+
<Skeleton
|
|
404
|
+
height={12}
|
|
405
|
+
width={`${Math.floor(Math.random() * 20) + 30}%`}
|
|
406
|
+
radius={radius}
|
|
407
|
+
animate={animate}
|
|
408
|
+
/>
|
|
409
|
+
)}
|
|
410
|
+
</Stack>
|
|
411
|
+
{showAction && <Skeleton height={32} width={32} radius={radius} animate={animate} />}
|
|
412
|
+
</Group>
|
|
413
|
+
))}
|
|
414
|
+
</Stack>
|
|
415
|
+
);
|
|
416
|
+
}
|
|
417
|
+
);
|
|
418
|
+
|
|
419
|
+
ArchbaseListSkeleton.displayName = 'ArchbaseListSkeleton';
|
package/src/feedback/index.ts
CHANGED
|
@@ -2,4 +2,25 @@
|
|
|
2
2
|
export { Alert as ArchbaseMantineAlert } from '@mantine/core';
|
|
3
3
|
export { Notification as ArchbaseNotification } from '@mantine/core';
|
|
4
4
|
export { Loader as ArchbaseLoader } from '@mantine/core';
|
|
5
|
-
export { Progress as ArchbaseProgress } from '@mantine/core';
|
|
5
|
+
export { Progress as ArchbaseProgress } from '@mantine/core';
|
|
6
|
+
|
|
7
|
+
export { ArchbaseChunkProgressBar } from './ArchbaseChunkProgressBar';
|
|
8
|
+
export type { ArchbaseChunkProgressBarProps } from './ArchbaseChunkProgressBar';
|
|
9
|
+
|
|
10
|
+
export {
|
|
11
|
+
ArchbaseDataGridSkeleton,
|
|
12
|
+
ArchbaseFormSkeleton,
|
|
13
|
+
ArchbaseCardSkeleton,
|
|
14
|
+
ArchbaseKanbanSkeleton,
|
|
15
|
+
ArchbaseListSkeleton,
|
|
16
|
+
} from './ArchbaseSkeleton';
|
|
17
|
+
export type {
|
|
18
|
+
ArchbaseDataGridSkeletonProps,
|
|
19
|
+
ArchbaseFormSkeletonProps,
|
|
20
|
+
ArchbaseCardSkeletonProps,
|
|
21
|
+
ArchbaseKanbanSkeletonProps,
|
|
22
|
+
ArchbaseListSkeletonProps,
|
|
23
|
+
} from './ArchbaseSkeleton';
|
|
24
|
+
|
|
25
|
+
export { ArchbaseRipple, useArchbaseRipple } from './ArchbaseRipple';
|
|
26
|
+
export type { ArchbaseRippleProps, UseArchbaseRippleOptions, UseArchbaseRippleReturn } from './ArchbaseRipple';
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
import React, { useState, useCallback, useMemo } from 'react';
|
|
2
|
+
import {
|
|
3
|
+
Paper,
|
|
4
|
+
Text,
|
|
5
|
+
TextInput,
|
|
6
|
+
Checkbox,
|
|
7
|
+
Group,
|
|
8
|
+
Button,
|
|
9
|
+
ActionIcon,
|
|
10
|
+
ScrollArea,
|
|
11
|
+
Stack,
|
|
12
|
+
Box,
|
|
13
|
+
} from '@mantine/core';
|
|
14
|
+
import {
|
|
15
|
+
IconSearch,
|
|
16
|
+
IconArrowUp,
|
|
17
|
+
IconArrowDown,
|
|
18
|
+
IconGripVertical,
|
|
19
|
+
} from '@tabler/icons-react';
|
|
20
|
+
|
|
21
|
+
export interface ArchbaseColumnItem {
|
|
22
|
+
field: string;
|
|
23
|
+
label: string;
|
|
24
|
+
visible: boolean;
|
|
25
|
+
order?: number;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface ArchbaseColumnSelectorProps {
|
|
29
|
+
/** Lista de colunas com configuração de visibilidade e ordem */
|
|
30
|
+
columns: ArchbaseColumnItem[];
|
|
31
|
+
/** Callback chamado quando a configuração de colunas muda */
|
|
32
|
+
onChange: (columns: Array<{ field: string; label: string; visible: boolean; order: number }>) => void;
|
|
33
|
+
/** Rótulo exibido no topo do componente */
|
|
34
|
+
label?: string;
|
|
35
|
+
/** Descrição exibida abaixo do rótulo */
|
|
36
|
+
description?: string;
|
|
37
|
+
/** Exibir campo de busca */
|
|
38
|
+
showSearch?: boolean;
|
|
39
|
+
/** Exibir botões Selecionar Todos / Desmarcar Todos */
|
|
40
|
+
showSelectAll?: boolean;
|
|
41
|
+
/** Altura máxima da lista de colunas */
|
|
42
|
+
maxHeight?: number;
|
|
43
|
+
/** Estilos inline */
|
|
44
|
+
style?: React.CSSProperties;
|
|
45
|
+
/** Classe CSS */
|
|
46
|
+
className?: string;
|
|
47
|
+
/** Largura do componente */
|
|
48
|
+
width?: number | string;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function normalizeColumns(columns: ArchbaseColumnItem[]): Array<{ field: string; label: string; visible: boolean; order: number }> {
|
|
52
|
+
return columns.map((col, index) => ({
|
|
53
|
+
field: col.field,
|
|
54
|
+
label: col.label,
|
|
55
|
+
visible: col.visible,
|
|
56
|
+
order: col.order ?? index,
|
|
57
|
+
}));
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function sortByOrder<T extends { order: number }>(items: T[]): T[] {
|
|
61
|
+
return [...items].sort((a, b) => a.order - b.order);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function ArchbaseColumnSelector({
|
|
65
|
+
columns,
|
|
66
|
+
onChange,
|
|
67
|
+
label,
|
|
68
|
+
description,
|
|
69
|
+
showSearch = true,
|
|
70
|
+
showSelectAll = true,
|
|
71
|
+
maxHeight = 400,
|
|
72
|
+
style,
|
|
73
|
+
className,
|
|
74
|
+
width,
|
|
75
|
+
}: ArchbaseColumnSelectorProps) {
|
|
76
|
+
const [internalColumns, setInternalColumns] = useState(() =>
|
|
77
|
+
sortByOrder(normalizeColumns(columns)),
|
|
78
|
+
);
|
|
79
|
+
const [search, setSearch] = useState('');
|
|
80
|
+
|
|
81
|
+
const filteredColumns = useMemo(() => {
|
|
82
|
+
if (!search.trim()) return internalColumns;
|
|
83
|
+
const term = search.toLowerCase();
|
|
84
|
+
return internalColumns.filter((col) =>
|
|
85
|
+
col.label.toLowerCase().includes(term),
|
|
86
|
+
);
|
|
87
|
+
}, [internalColumns, search]);
|
|
88
|
+
|
|
89
|
+
const emitChange = useCallback(
|
|
90
|
+
(updated: Array<{ field: string; label: string; visible: boolean; order: number }>) => {
|
|
91
|
+
setInternalColumns(updated);
|
|
92
|
+
onChange(updated);
|
|
93
|
+
},
|
|
94
|
+
[onChange],
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
const handleToggle = useCallback(
|
|
98
|
+
(field: string) => {
|
|
99
|
+
const updated = internalColumns.map((col) =>
|
|
100
|
+
col.field === field ? { ...col, visible: !col.visible } : col,
|
|
101
|
+
);
|
|
102
|
+
emitChange(updated);
|
|
103
|
+
},
|
|
104
|
+
[internalColumns, emitChange],
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
const handleSelectAll = useCallback(() => {
|
|
108
|
+
const updated = internalColumns.map((col) => ({ ...col, visible: true }));
|
|
109
|
+
emitChange(updated);
|
|
110
|
+
}, [internalColumns, emitChange]);
|
|
111
|
+
|
|
112
|
+
const handleDeselectAll = useCallback(() => {
|
|
113
|
+
const updated = internalColumns.map((col) => ({ ...col, visible: false }));
|
|
114
|
+
emitChange(updated);
|
|
115
|
+
}, [internalColumns, emitChange]);
|
|
116
|
+
|
|
117
|
+
const handleMoveUp = useCallback(
|
|
118
|
+
(field: string) => {
|
|
119
|
+
const index = internalColumns.findIndex((col) => col.field === field);
|
|
120
|
+
if (index <= 0) return;
|
|
121
|
+
const updated = [...internalColumns];
|
|
122
|
+
const prevOrder = updated[index - 1].order;
|
|
123
|
+
updated[index - 1] = { ...updated[index - 1], order: updated[index].order };
|
|
124
|
+
updated[index] = { ...updated[index], order: prevOrder };
|
|
125
|
+
emitChange(sortByOrder(updated));
|
|
126
|
+
},
|
|
127
|
+
[internalColumns, emitChange],
|
|
128
|
+
);
|
|
129
|
+
|
|
130
|
+
const handleMoveDown = useCallback(
|
|
131
|
+
(field: string) => {
|
|
132
|
+
const index = internalColumns.findIndex((col) => col.field === field);
|
|
133
|
+
if (index < 0 || index >= internalColumns.length - 1) return;
|
|
134
|
+
const updated = [...internalColumns];
|
|
135
|
+
const nextOrder = updated[index + 1].order;
|
|
136
|
+
updated[index + 1] = { ...updated[index + 1], order: updated[index].order };
|
|
137
|
+
updated[index] = { ...updated[index], order: nextOrder };
|
|
138
|
+
emitChange(sortByOrder(updated));
|
|
139
|
+
},
|
|
140
|
+
[internalColumns, emitChange],
|
|
141
|
+
);
|
|
142
|
+
|
|
143
|
+
const allSelected = internalColumns.every((col) => col.visible);
|
|
144
|
+
const noneSelected = internalColumns.every((col) => !col.visible);
|
|
145
|
+
|
|
146
|
+
return (
|
|
147
|
+
<Paper
|
|
148
|
+
shadow="xs"
|
|
149
|
+
p="md"
|
|
150
|
+
withBorder
|
|
151
|
+
style={{ width, ...style }}
|
|
152
|
+
className={className}
|
|
153
|
+
>
|
|
154
|
+
<Stack gap="sm">
|
|
155
|
+
{label && (
|
|
156
|
+
<Box>
|
|
157
|
+
<Text fw={600} size="sm">
|
|
158
|
+
{label}
|
|
159
|
+
</Text>
|
|
160
|
+
{description && (
|
|
161
|
+
<Text size="xs" c="dimmed">
|
|
162
|
+
{description}
|
|
163
|
+
</Text>
|
|
164
|
+
)}
|
|
165
|
+
</Box>
|
|
166
|
+
)}
|
|
167
|
+
|
|
168
|
+
{showSearch && (
|
|
169
|
+
<TextInput
|
|
170
|
+
placeholder="Buscar colunas..."
|
|
171
|
+
leftSection={<IconSearch size={16} />}
|
|
172
|
+
value={search}
|
|
173
|
+
onChange={(e) => setSearch(e.currentTarget.value)}
|
|
174
|
+
size="sm"
|
|
175
|
+
/>
|
|
176
|
+
)}
|
|
177
|
+
|
|
178
|
+
{showSelectAll && (
|
|
179
|
+
<Group gap="xs">
|
|
180
|
+
<Button
|
|
181
|
+
variant="subtle"
|
|
182
|
+
size="xs"
|
|
183
|
+
onClick={handleSelectAll}
|
|
184
|
+
disabled={allSelected}
|
|
185
|
+
>
|
|
186
|
+
Selecionar todos
|
|
187
|
+
</Button>
|
|
188
|
+
<Button
|
|
189
|
+
variant="subtle"
|
|
190
|
+
size="xs"
|
|
191
|
+
onClick={handleDeselectAll}
|
|
192
|
+
disabled={noneSelected}
|
|
193
|
+
>
|
|
194
|
+
Desmarcar todos
|
|
195
|
+
</Button>
|
|
196
|
+
</Group>
|
|
197
|
+
)}
|
|
198
|
+
|
|
199
|
+
<ScrollArea.Autosize mah={maxHeight}>
|
|
200
|
+
<Stack gap={4}>
|
|
201
|
+
{filteredColumns.map((col, idx) => {
|
|
202
|
+
const isFirst = idx === 0;
|
|
203
|
+
const isLast = idx === filteredColumns.length - 1;
|
|
204
|
+
const isSearching = search.trim().length > 0;
|
|
205
|
+
|
|
206
|
+
return (
|
|
207
|
+
<Group
|
|
208
|
+
key={col.field}
|
|
209
|
+
gap="xs"
|
|
210
|
+
wrap="nowrap"
|
|
211
|
+
p={4}
|
|
212
|
+
style={{
|
|
213
|
+
borderRadius: 'var(--mantine-radius-sm)',
|
|
214
|
+
cursor: 'default',
|
|
215
|
+
}}
|
|
216
|
+
>
|
|
217
|
+
<IconGripVertical
|
|
218
|
+
size={16}
|
|
219
|
+
style={{ color: 'var(--mantine-color-dimmed)', flexShrink: 0 }}
|
|
220
|
+
/>
|
|
221
|
+
|
|
222
|
+
<Checkbox
|
|
223
|
+
checked={col.visible}
|
|
224
|
+
onChange={() => handleToggle(col.field)}
|
|
225
|
+
label={col.label}
|
|
226
|
+
size="sm"
|
|
227
|
+
style={{ flex: 1 }}
|
|
228
|
+
/>
|
|
229
|
+
|
|
230
|
+
{!isSearching && (
|
|
231
|
+
<Group gap={2} wrap="nowrap" style={{ flexShrink: 0 }}>
|
|
232
|
+
<ActionIcon
|
|
233
|
+
variant="subtle"
|
|
234
|
+
size="sm"
|
|
235
|
+
disabled={isFirst}
|
|
236
|
+
onClick={() => handleMoveUp(col.field)}
|
|
237
|
+
aria-label={`Mover ${col.label} para cima`}
|
|
238
|
+
>
|
|
239
|
+
<IconArrowUp size={14} />
|
|
240
|
+
</ActionIcon>
|
|
241
|
+
<ActionIcon
|
|
242
|
+
variant="subtle"
|
|
243
|
+
size="sm"
|
|
244
|
+
disabled={isLast}
|
|
245
|
+
onClick={() => handleMoveDown(col.field)}
|
|
246
|
+
aria-label={`Mover ${col.label} para baixo`}
|
|
247
|
+
>
|
|
248
|
+
<IconArrowDown size={14} />
|
|
249
|
+
</ActionIcon>
|
|
250
|
+
</Group>
|
|
251
|
+
)}
|
|
252
|
+
</Group>
|
|
253
|
+
);
|
|
254
|
+
})}
|
|
255
|
+
|
|
256
|
+
{filteredColumns.length === 0 && (
|
|
257
|
+
<Text size="sm" c="dimmed" ta="center" py="md">
|
|
258
|
+
Nenhuma coluna encontrada
|
|
259
|
+
</Text>
|
|
260
|
+
)}
|
|
261
|
+
</Stack>
|
|
262
|
+
</ScrollArea.Autosize>
|
|
263
|
+
</Stack>
|
|
264
|
+
</Paper>
|
|
265
|
+
);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
ArchbaseColumnSelector.displayName = 'ArchbaseColumnSelector';
|