@aspprev/versi-ds 0.2.0 → 0.3.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/README.md +31 -2
- package/dist/{chunk-H4BBKKRZ.js → chunk-7JI5637G.js} +231 -60
- package/dist/chunk-7JI5637G.js.map +1 -0
- package/dist/{chunk-JSPXVXUY.js → chunk-DO5C67KS.js} +309 -141
- package/dist/chunk-DO5C67KS.js.map +1 -0
- package/dist/{chunk-PIXRKI25.js → chunk-EPV6UNUQ.js} +226 -128
- package/dist/chunk-EPV6UNUQ.js.map +1 -0
- package/dist/{chunk-ET2BGHTO.js → chunk-FTRF27XF.js} +28 -31
- package/dist/chunk-FTRF27XF.js.map +1 -0
- package/dist/{chunk-FR5W52XU.js → chunk-OQECJKGA.js} +229 -105
- package/dist/chunk-OQECJKGA.js.map +1 -0
- package/dist/core.d.ts +24 -2
- package/dist/core.js +10 -2
- package/dist/documents.d.ts +28 -7
- package/dist/documents.js +5 -3
- package/dist/forms.d.ts +3 -0
- package/dist/forms.js +2 -2
- package/dist/index.d.ts +3 -3
- package/dist/index.js +26 -8
- package/dist/manifest.json +6 -6
- package/dist/overlays.d.ts +30 -1
- package/dist/overlays.js +11 -3
- package/dist/styles.css +1 -1
- package/package.json +1 -1
- package/dist/chunk-ET2BGHTO.js.map +0 -1
- package/dist/chunk-FR5W52XU.js.map +0 -1
- package/dist/chunk-H4BBKKRZ.js.map +0 -1
- package/dist/chunk-JSPXVXUY.js.map +0 -1
- package/dist/chunk-PIXRKI25.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
#
|
|
1
|
+
# VERSI Design System
|
|
2
2
|
|
|
3
|
-
Biblioteca React de componentes, tokens, temas e utilitários para padronizar as interfaces dos produtos
|
|
3
|
+
Biblioteca React de componentes, tokens, temas e utilitários para padronizar as interfaces dos produtos VERSI.
|
|
4
4
|
|
|
5
5
|
O [Storybook](#storybook) é a documentação visual oficial: nele você pode explorar componentes, foundations, temas, padrões de composição e estados acessíveis.
|
|
6
6
|
|
|
7
|
+
Site oficial: [versitec.com.br](https://versitec.com.br/) · [Storybook online](https://versi-design-system.vercel.app/)
|
|
8
|
+
|
|
7
9
|
## Instalação
|
|
8
10
|
|
|
9
11
|
```bash
|
|
@@ -16,6 +18,9 @@ Requisitos do pacote:
|
|
|
16
18
|
- React `>=18.2.0 <20`;
|
|
17
19
|
- React DOM `>=18.2.0 <20`.
|
|
18
20
|
|
|
21
|
+
O identificador npm `@aspprev/versi-ds` é mantido por compatibilidade com as
|
|
22
|
+
aplicações consumidoras e não representa o nome visual atual da marca.
|
|
23
|
+
|
|
19
24
|
As integrações abaixo são opcionais e só precisam ser instaladas pelas entradas que as utilizam: `@headlessui/react`, `apexcharts`, `date-fns`, `formik`, `jsbarcode`, `react-apexcharts` e `react-number-format`.
|
|
20
25
|
|
|
21
26
|
## Uso
|
|
@@ -62,6 +67,30 @@ export function Resumo() {
|
|
|
62
67
|
|
|
63
68
|
Evite deep imports. Use somente os entrypoints públicos documentados no `package.json`.
|
|
64
69
|
|
|
70
|
+
### APIs desta versão
|
|
71
|
+
|
|
72
|
+
```tsx
|
|
73
|
+
import { DatePicker, DomainStatusBadge, Table } from "@aspprev/versi-ds";
|
|
74
|
+
import { OtpCodeInput } from "@aspprev/versi-ds/forms";
|
|
75
|
+
import {
|
|
76
|
+
FileDropzone,
|
|
77
|
+
FileList,
|
|
78
|
+
FileUploadProgress,
|
|
79
|
+
FileViewer,
|
|
80
|
+
QRCode,
|
|
81
|
+
validateFiles,
|
|
82
|
+
} from "@aspprev/versi-ds/documents";
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
- `OtpCodeInput` suporta `onComplete`, colagem de código, máscara, erro e controle por `value`/`values`.
|
|
86
|
+
- `QRCode` suporta `description`, `ariaLabel`, `loading`, `error`, `size` e nível de correção.
|
|
87
|
+
- Upload e `FileViewer` são controlados pelo consumidor; transporte, autenticação, persistência e download não fazem parte do pacote.
|
|
88
|
+
- `DatePicker` aceita `selectionMode="year"` e mantém `selectionMode="day"` como padrão.
|
|
89
|
+
- `DomainStatusBadge` aceita `statusMap` para vocabulário específico do produto.
|
|
90
|
+
- `Table` preserva os modos `fit`, `adaptive` e `scroll`; filtros e paginação respondem ao espaço do container.
|
|
91
|
+
|
|
92
|
+
Consulte [`docs/API-NOVOS-COMPONENTES.md`](docs/API-NOVOS-COMPONENTES.md) e o Storybook para exemplos completos, estados de erro/carregamento e contratos de acessibilidade.
|
|
93
|
+
|
|
65
94
|
## Organização do Design System
|
|
66
95
|
|
|
67
96
|
- **Components**: controles de ação, formulários, feedback, navegação, dados, documentos, overlays e layout.
|
|
@@ -45,24 +45,61 @@ function BoletoBarCode({ linhaDigitavel }) {
|
|
|
45
45
|
] });
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
// src/components/file-upload/
|
|
49
|
-
|
|
50
|
-
import { useId, useRef as useRef2, useState } from "react";
|
|
51
|
-
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
52
|
-
var acceptsFile = (file, accept) => {
|
|
48
|
+
// src/components/file-upload/validation.ts
|
|
49
|
+
function acceptsFile(file, accept) {
|
|
53
50
|
if (!(accept == null ? void 0 : accept.trim())) return true;
|
|
54
51
|
return accept.split(",").map((item) => item.trim().toLowerCase()).some((rule) => {
|
|
55
52
|
if (rule.endsWith("/*")) return file.type.toLowerCase().startsWith(rule.slice(0, -1));
|
|
56
53
|
if (rule.startsWith(".")) return file.name.toLowerCase().endsWith(rule);
|
|
57
54
|
return file.type.toLowerCase() === rule;
|
|
58
55
|
});
|
|
59
|
-
}
|
|
56
|
+
}
|
|
57
|
+
function rejectionMessage(reason) {
|
|
58
|
+
if (reason === "type") return "Tipo de arquivo n\xE3o permitido.";
|
|
59
|
+
if (reason === "size") return "O arquivo excede o tamanho m\xE1ximo permitido.";
|
|
60
|
+
return "Quantidade m\xE1xima de arquivos excedida.";
|
|
61
|
+
}
|
|
62
|
+
function normalizeMaxFiles(options) {
|
|
63
|
+
if (options.multiple === false) return 1;
|
|
64
|
+
if (options.maxFiles === void 0 || !Number.isFinite(options.maxFiles)) {
|
|
65
|
+
return Number.POSITIVE_INFINITY;
|
|
66
|
+
}
|
|
67
|
+
return Math.max(1, Math.floor(options.maxFiles));
|
|
68
|
+
}
|
|
69
|
+
function normalizeMaxSize(maxSize) {
|
|
70
|
+
if (maxSize === void 0 || !Number.isFinite(maxSize)) return void 0;
|
|
71
|
+
return Math.max(0, maxSize);
|
|
72
|
+
}
|
|
73
|
+
function validateFiles(files, options = {}) {
|
|
74
|
+
const selected = Array.from(files);
|
|
75
|
+
const maxFiles = normalizeMaxFiles(options);
|
|
76
|
+
const maxSize = normalizeMaxSize(options.maxSize);
|
|
77
|
+
const accepted = [];
|
|
78
|
+
const rejected = [];
|
|
79
|
+
selected.forEach((file, index) => {
|
|
80
|
+
const reason = !acceptsFile(file, options.accept) ? "type" : maxSize !== void 0 && file.size > maxSize ? "size" : index >= maxFiles ? "count" : void 0;
|
|
81
|
+
if (reason) {
|
|
82
|
+
rejected.push({ file, reason, message: rejectionMessage(reason) });
|
|
83
|
+
} else {
|
|
84
|
+
accepted.push(file);
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
return { accepted, rejected };
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// src/components/file-upload/FileDropzone.tsx
|
|
91
|
+
import classNames from "classnames";
|
|
92
|
+
import { useId, useRef as useRef2, useState } from "react";
|
|
93
|
+
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
60
94
|
function FileDropzone({
|
|
61
95
|
accept,
|
|
62
96
|
multiple = false,
|
|
63
97
|
maxFiles = multiple ? Number.POSITIVE_INFINITY : 1,
|
|
64
98
|
maxSize,
|
|
65
99
|
disabled = false,
|
|
100
|
+
id,
|
|
101
|
+
name,
|
|
102
|
+
required = false,
|
|
66
103
|
label = "Selecionar arquivos",
|
|
67
104
|
hint = "Arraste e solte os arquivos aqui ou use o teclado para selecionar.",
|
|
68
105
|
error,
|
|
@@ -70,24 +107,21 @@ function FileDropzone({
|
|
|
70
107
|
onFilesAccepted,
|
|
71
108
|
onFilesRejected
|
|
72
109
|
}) {
|
|
73
|
-
const
|
|
110
|
+
const generatedInputId = useId();
|
|
111
|
+
const inputId = id != null ? id : generatedInputId;
|
|
74
112
|
const messageId = `${inputId}-message`;
|
|
75
113
|
const inputRef = useRef2(null);
|
|
76
114
|
const [isDragging, setIsDragging] = useState(false);
|
|
115
|
+
const [rejectionMessage2, setRejectionMessage] = useState();
|
|
77
116
|
const processFiles = (fileList) => {
|
|
78
117
|
if (disabled) return;
|
|
79
|
-
const
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
if (!reason) accepted.push(file);
|
|
85
|
-
else {
|
|
86
|
-
const message2 = reason === "type" ? "Tipo de arquivo n\xE3o permitido." : reason === "size" ? "O arquivo excede o tamanho m\xE1ximo permitido." : "Quantidade m\xE1xima de arquivos excedida.";
|
|
87
|
-
rejected.push({ file, reason, message: message2 });
|
|
88
|
-
}
|
|
118
|
+
const { accepted, rejected } = validateFiles(fileList, {
|
|
119
|
+
accept,
|
|
120
|
+
maxFiles,
|
|
121
|
+
maxSize,
|
|
122
|
+
multiple
|
|
89
123
|
});
|
|
90
|
-
|
|
124
|
+
setRejectionMessage(rejected.length ? rejected.map((item) => item.message).join(" ") : void 0);
|
|
91
125
|
if (accepted.length) onFilesAccepted == null ? void 0 : onFilesAccepted(accepted);
|
|
92
126
|
if (rejected.length) onFilesRejected == null ? void 0 : onFilesRejected(rejected);
|
|
93
127
|
};
|
|
@@ -100,7 +134,8 @@ function FileDropzone({
|
|
|
100
134
|
setIsDragging(false);
|
|
101
135
|
processFiles(event.dataTransfer.files);
|
|
102
136
|
};
|
|
103
|
-
const
|
|
137
|
+
const hasError = Boolean(error || rejectionMessage2);
|
|
138
|
+
const message = error || rejectionMessage2 || hint;
|
|
104
139
|
return /* @__PURE__ */ jsxs2(
|
|
105
140
|
"div",
|
|
106
141
|
{
|
|
@@ -117,7 +152,7 @@ function FileDropzone({
|
|
|
117
152
|
"flex min-h-32 w-full cursor-pointer flex-col items-center justify-center rounded-sm border-2 border-dashed p-6 text-center transition-colors focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-focus-ring",
|
|
118
153
|
isDragging ? "border-action-primary bg-primary-1/10" : "border-border-default bg-surface-card hover:border-border-strong",
|
|
119
154
|
disabled && "cursor-not-allowed opacity-60",
|
|
120
|
-
|
|
155
|
+
hasError && "border-field-border-error",
|
|
121
156
|
className
|
|
122
157
|
),
|
|
123
158
|
children: [
|
|
@@ -129,16 +164,19 @@ function FileDropzone({
|
|
|
129
164
|
ref: inputRef,
|
|
130
165
|
id: inputId,
|
|
131
166
|
type: "file",
|
|
167
|
+
name,
|
|
132
168
|
accept,
|
|
133
169
|
multiple,
|
|
134
170
|
disabled,
|
|
171
|
+
required,
|
|
135
172
|
onChange: handleInputChange,
|
|
136
173
|
"aria-describedby": message ? messageId : void 0,
|
|
174
|
+
"aria-invalid": hasError ? true : void 0,
|
|
137
175
|
className: "sr-only"
|
|
138
176
|
}
|
|
139
177
|
)
|
|
140
178
|
] }),
|
|
141
|
-
message && /* @__PURE__ */ jsx2("span", { id: messageId, className: classNames("mt-1 text-sm",
|
|
179
|
+
message && /* @__PURE__ */ jsx2("span", { id: messageId, role: hasError ? "alert" : void 0, className: classNames("mt-1 text-sm", hasError ? "text-field-assistive-error" : "text-content-secondary"), children: message })
|
|
142
180
|
]
|
|
143
181
|
}
|
|
144
182
|
);
|
|
@@ -198,18 +236,28 @@ var fileId = (item, index) => {
|
|
|
198
236
|
var _a;
|
|
199
237
|
return (_a = item.id) != null ? _a : `${item.file.name}-${item.file.size}-${item.file.lastModified}-${index}`;
|
|
200
238
|
};
|
|
239
|
+
var statusDescription = (status) => {
|
|
240
|
+
if (status === "uploading") return "Enviando";
|
|
241
|
+
if (status === "success") return "Enviado";
|
|
242
|
+
if (status === "error") return "Erro no envio";
|
|
243
|
+
return "Aguardando envio";
|
|
244
|
+
};
|
|
201
245
|
function FileList({ files, accessibleName = "Arquivos selecionados", onRemove, onRetry, className }) {
|
|
202
246
|
return /* @__PURE__ */ jsx4("ul", { "aria-label": accessibleName, className: classNames3("w-full space-y-2", className), children: files.map((item, index) => {
|
|
203
247
|
var _a;
|
|
204
248
|
const status = (_a = item.status) != null ? _a : "pending";
|
|
205
249
|
const progressStatus = status === "pending" ? "idle" : status;
|
|
206
|
-
return /* @__PURE__ */ jsxs4("li", { className: "flex min-w-0 flex-wrap items-center gap-3 rounded-sm border border-border-default bg-surface-card p-3", children: [
|
|
250
|
+
return /* @__PURE__ */ jsxs4("li", { "aria-busy": status === "uploading" || void 0, className: "flex min-w-0 flex-wrap items-center gap-3 rounded-sm border border-border-default bg-surface-card p-3", children: [
|
|
207
251
|
/* @__PURE__ */ jsxs4("div", { className: "min-w-0 flex-1", children: [
|
|
208
252
|
/* @__PURE__ */ jsx4("p", { className: "truncate font-semibold text-content-primary", title: item.file.name, children: item.file.name }),
|
|
209
253
|
/* @__PURE__ */ jsxs4("p", { className: "text-xs text-content-secondary", children: [
|
|
210
254
|
Math.ceil(item.file.size / 1024),
|
|
211
255
|
" KB"
|
|
212
256
|
] }),
|
|
257
|
+
/* @__PURE__ */ jsxs4("span", { className: "sr-only", children: [
|
|
258
|
+
"Status: ",
|
|
259
|
+
statusDescription(status)
|
|
260
|
+
] }),
|
|
213
261
|
(status === "uploading" || status === "success" || status === "error") && /* @__PURE__ */ jsx4(FileUploadProgress_default, { value: item.progress, status: progressStatus, label: `Progresso de ${item.file.name}` }),
|
|
214
262
|
item.error && /* @__PURE__ */ jsx4("p", { role: "alert", className: "mt-1 text-sm text-field-assistive-error", children: item.error })
|
|
215
263
|
] }),
|
|
@@ -224,65 +272,153 @@ var FileList_default = FileList;
|
|
|
224
272
|
|
|
225
273
|
// src/components/file-upload/FileViewer.tsx
|
|
226
274
|
import classNames4 from "classnames";
|
|
227
|
-
import { useEffect as useEffect2,
|
|
275
|
+
import { useEffect as useEffect2, useRef as useRef3, useState as useState2 } from "react";
|
|
228
276
|
import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
229
277
|
var extensionType = (fileName) => {
|
|
230
278
|
var _a;
|
|
231
279
|
const extension = (_a = fileName == null ? void 0 : fileName.split(".").pop()) == null ? void 0 : _a.toLowerCase();
|
|
232
280
|
if (extension === "pdf") return "application/pdf";
|
|
233
|
-
if (["png", "jpg", "jpeg", "gif", "webp", "svg"].includes(extension != null ? extension : ""))
|
|
281
|
+
if (["png", "jpg", "jpeg", "gif", "webp", "svg"].includes(extension != null ? extension : "")) {
|
|
282
|
+
return `image/${extension === "jpg" ? "jpeg" : extension}`;
|
|
283
|
+
}
|
|
234
284
|
if (["txt", "csv", "json", "xml", "md"].includes(extension != null ? extension : "")) return "text/plain";
|
|
235
285
|
return "application/octet-stream";
|
|
236
286
|
};
|
|
237
|
-
|
|
238
|
-
|
|
287
|
+
var normalizeContentType = (contentType) => contentType.split(";", 1)[0].trim().toLowerCase();
|
|
288
|
+
var toError = (cause) => cause instanceof Error ? cause : new Error("N\xE3o foi poss\xEDvel ler o arquivo.");
|
|
289
|
+
function FileViewer({
|
|
290
|
+
source,
|
|
291
|
+
fileName,
|
|
292
|
+
contentType,
|
|
293
|
+
loading = false,
|
|
294
|
+
error,
|
|
295
|
+
onLoad,
|
|
296
|
+
onError,
|
|
297
|
+
onDownload,
|
|
298
|
+
fallback,
|
|
299
|
+
title = fileName != null ? fileName : "Visualiza\xE7\xE3o do arquivo",
|
|
300
|
+
className
|
|
301
|
+
}) {
|
|
239
302
|
const [objectUrl, setObjectUrl] = useState2();
|
|
240
303
|
const [textContent, setTextContent] = useState2();
|
|
304
|
+
const [readError, setReadError] = useState2(null);
|
|
305
|
+
const onLoadRef = useRef3(onLoad);
|
|
306
|
+
const onErrorRef = useRef3(onError);
|
|
241
307
|
const resolved = typeof source === "object" && source !== null && !(source instanceof Blob) ? source : void 0;
|
|
242
308
|
const blob = source instanceof Blob ? source : resolved == null ? void 0 : resolved.blob;
|
|
243
309
|
const url = typeof source === "string" ? source : resolved == null ? void 0 : resolved.url;
|
|
244
310
|
const resolvedName = fileName != null ? fileName : resolved == null ? void 0 : resolved.fileName;
|
|
245
|
-
const
|
|
311
|
+
const rawType = (contentType == null ? void 0 : contentType.trim()) || (resolved == null ? void 0 : resolved.contentType) || (blob == null ? void 0 : blob.type) || extensionType(resolvedName);
|
|
312
|
+
const resolvedType = normalizeContentType(rawType);
|
|
313
|
+
const isText = resolvedType.startsWith("text/") || resolvedType === "application/json";
|
|
314
|
+
const displayError = error != null ? error : readError == null ? void 0 : readError.message;
|
|
246
315
|
useEffect2(() => {
|
|
316
|
+
onLoadRef.current = onLoad;
|
|
317
|
+
}, [onLoad]);
|
|
318
|
+
useEffect2(() => {
|
|
319
|
+
onErrorRef.current = onError;
|
|
320
|
+
}, [onError]);
|
|
321
|
+
useEffect2(() => {
|
|
322
|
+
var _a;
|
|
323
|
+
let active = true;
|
|
324
|
+
setReadError(null);
|
|
325
|
+
setTextContent(void 0);
|
|
247
326
|
if (!blob) {
|
|
248
327
|
setObjectUrl(void 0);
|
|
249
|
-
|
|
250
|
-
|
|
328
|
+
return () => {
|
|
329
|
+
active = false;
|
|
330
|
+
};
|
|
251
331
|
}
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
332
|
+
let nextUrl;
|
|
333
|
+
try {
|
|
334
|
+
nextUrl = URL.createObjectURL(blob);
|
|
335
|
+
setObjectUrl(nextUrl);
|
|
336
|
+
} catch (cause) {
|
|
337
|
+
const nextError = toError(cause);
|
|
338
|
+
setReadError(nextError);
|
|
339
|
+
(_a = onErrorRef.current) == null ? void 0 : _a.call(onErrorRef, nextError);
|
|
340
|
+
return () => {
|
|
341
|
+
active = false;
|
|
342
|
+
};
|
|
343
|
+
}
|
|
344
|
+
if (isText) {
|
|
256
345
|
blob.text().then((text) => {
|
|
257
|
-
|
|
346
|
+
var _a2;
|
|
347
|
+
if (!active) return;
|
|
348
|
+
setTextContent(text);
|
|
349
|
+
(_a2 = onLoadRef.current) == null ? void 0 : _a2.call(onLoadRef);
|
|
350
|
+
}).catch((cause) => {
|
|
351
|
+
var _a2;
|
|
352
|
+
if (!active) return;
|
|
353
|
+
const nextError = toError(cause);
|
|
354
|
+
setReadError(nextError);
|
|
355
|
+
(_a2 = onErrorRef.current) == null ? void 0 : _a2.call(onErrorRef, nextError);
|
|
258
356
|
});
|
|
259
|
-
} else {
|
|
260
|
-
setTextContent(void 0);
|
|
261
357
|
}
|
|
262
358
|
return () => {
|
|
263
359
|
active = false;
|
|
264
360
|
URL.revokeObjectURL(nextUrl);
|
|
265
361
|
};
|
|
266
|
-
}, [blob,
|
|
362
|
+
}, [blob, isText]);
|
|
363
|
+
const handleMediaError = () => {
|
|
364
|
+
var _a;
|
|
365
|
+
const nextError = new Error("N\xE3o foi poss\xEDvel carregar a visualiza\xE7\xE3o do arquivo.");
|
|
366
|
+
setReadError(nextError);
|
|
367
|
+
(_a = onErrorRef.current) == null ? void 0 : _a.call(onErrorRef, nextError);
|
|
368
|
+
};
|
|
369
|
+
const handleLoad = () => {
|
|
370
|
+
var _a;
|
|
371
|
+
return (_a = onLoadRef.current) == null ? void 0 : _a.call(onLoadRef);
|
|
372
|
+
};
|
|
373
|
+
if (loading) {
|
|
374
|
+
return /* @__PURE__ */ jsx5(
|
|
375
|
+
"div",
|
|
376
|
+
{
|
|
377
|
+
className: classNames4("flex min-h-32 items-center justify-center rounded-sm border border-border-default bg-surface-card p-6 text-content-secondary", className),
|
|
378
|
+
role: "status",
|
|
379
|
+
"aria-busy": "true",
|
|
380
|
+
"aria-live": "polite",
|
|
381
|
+
children: "Carregando arquivo\u2026"
|
|
382
|
+
}
|
|
383
|
+
);
|
|
384
|
+
}
|
|
385
|
+
if (displayError) {
|
|
386
|
+
return /* @__PURE__ */ jsx5("div", { className: classNames4("rounded-sm border border-field-border-error bg-surface-card p-4 text-field-assistive-error", className), role: "alert", children: displayError });
|
|
387
|
+
}
|
|
267
388
|
const displayUrl = objectUrl != null ? objectUrl : url;
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
389
|
+
if (!displayUrl && !textContent) {
|
|
390
|
+
return /* @__PURE__ */ jsx5(
|
|
391
|
+
"div",
|
|
392
|
+
{
|
|
393
|
+
className: classNames4("rounded-sm border border-border-default bg-surface-card p-4 text-content-secondary", className),
|
|
394
|
+
role: "region",
|
|
395
|
+
"aria-label": title,
|
|
396
|
+
children: fallback != null ? fallback : "Arquivo indispon\xEDvel."
|
|
397
|
+
}
|
|
398
|
+
);
|
|
399
|
+
}
|
|
400
|
+
const download = onDownload ? /* @__PURE__ */ jsx5("button", { type: "button", onClick: onDownload, className: "min-h-11 rounded-sm border border-border-default px-3 text-sm font-semibold text-content-primary focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-focus-ring", children: "Baixar arquivo" }) : displayUrl ? /* @__PURE__ */ jsx5("a", { href: displayUrl, download: resolvedName, className: "inline-flex min-h-11 items-center rounded-sm border border-border-default px-3 text-sm font-semibold text-content-primary focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-focus-ring", children: "Baixar arquivo" }) : null;
|
|
401
|
+
return /* @__PURE__ */ jsxs5(
|
|
402
|
+
"div",
|
|
403
|
+
{
|
|
404
|
+
className: classNames4("flex min-w-0 flex-col gap-3 rounded-sm border border-border-default bg-surface-card p-3", className),
|
|
405
|
+
role: "region",
|
|
406
|
+
"aria-label": title,
|
|
407
|
+
children: [
|
|
408
|
+
resolvedType.startsWith("image/") && displayUrl && /* @__PURE__ */ jsx5("img", { src: displayUrl, alt: title, onLoad: handleLoad, onError: handleMediaError, className: "max-h-[70vh] max-w-full object-contain" }),
|
|
409
|
+
resolvedType === "application/pdf" && displayUrl && /* @__PURE__ */ jsx5("iframe", { src: displayUrl, title, onLoad: handleLoad, onError: handleMediaError, sandbox: "", className: "min-h-[32rem] w-full border-0" }),
|
|
410
|
+
isText && (textContent !== void 0 ? /* @__PURE__ */ jsx5("pre", { className: "max-h-[70vh] overflow-auto whitespace-pre-wrap break-words text-sm text-content-primary", children: textContent }) : displayUrl && /* @__PURE__ */ jsx5("iframe", { src: displayUrl, title, onLoad: handleLoad, onError: handleMediaError, sandbox: "", className: "min-h-64 w-full border-0" })),
|
|
411
|
+
!resolvedType.startsWith("image/") && resolvedType !== "application/pdf" && !isText && (fallback != null ? fallback : /* @__PURE__ */ jsx5("p", { className: "text-content-secondary", children: "Este tipo de arquivo n\xE3o possui visualiza\xE7\xE3o dispon\xEDvel." })),
|
|
412
|
+
download && /* @__PURE__ */ jsx5("div", { className: "flex justify-end", children: download })
|
|
413
|
+
]
|
|
414
|
+
}
|
|
415
|
+
);
|
|
280
416
|
}
|
|
281
417
|
var FileViewer_default = FileViewer;
|
|
282
418
|
|
|
283
419
|
// src/components/qr-code/QRCode.tsx
|
|
284
420
|
import QRCodeGenerator from "qrcode";
|
|
285
|
-
import { useEffect as useEffect3, useState as useState3 } from "react";
|
|
421
|
+
import { useEffect as useEffect3, useId as useId2, useMemo, useRef as useRef4, useState as useState3 } from "react";
|
|
286
422
|
import classNames5 from "classnames";
|
|
287
423
|
import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
288
424
|
function getRelativeLuminance(color) {
|
|
@@ -313,6 +449,9 @@ function QRCode(_a) {
|
|
|
313
449
|
bgColor = "#FFFFFF",
|
|
314
450
|
ariaLabel = "C\xF3digo QR",
|
|
315
451
|
description,
|
|
452
|
+
loading = false,
|
|
453
|
+
error,
|
|
454
|
+
onError,
|
|
316
455
|
className
|
|
317
456
|
} = _b, rest = __objRest(_b, [
|
|
318
457
|
"value",
|
|
@@ -323,43 +462,74 @@ function QRCode(_a) {
|
|
|
323
462
|
"bgColor",
|
|
324
463
|
"ariaLabel",
|
|
325
464
|
"description",
|
|
465
|
+
"loading",
|
|
466
|
+
"error",
|
|
467
|
+
"onError",
|
|
326
468
|
"className"
|
|
327
469
|
]);
|
|
328
470
|
var _a2;
|
|
329
471
|
const [dataUrl, setDataUrl] = useState3(null);
|
|
330
|
-
const
|
|
331
|
-
const
|
|
472
|
+
const [generationError, setGenerationError] = useState3(null);
|
|
473
|
+
const onErrorRef = useRef4(onError);
|
|
474
|
+
const generatedId = useId2();
|
|
475
|
+
const resolvedSize = Math.max(1, Number.isFinite(size) ? Math.floor(size) : 192);
|
|
476
|
+
const descriptionId = description ? `${(_a2 = rest.id) != null ? _a2 : generatedId}-description` : void 0;
|
|
477
|
+
const colors = useMemo(
|
|
478
|
+
() => resolveAccessibleColors(fgColor, bgColor),
|
|
479
|
+
[bgColor, fgColor]
|
|
480
|
+
);
|
|
481
|
+
const describedBy = [rest["aria-describedby"], descriptionId].filter(Boolean).join(" ") || void 0;
|
|
482
|
+
const displayError = error != null ? error : generationError == null ? void 0 : generationError.message;
|
|
483
|
+
const isLoading = loading || !dataUrl && !displayError;
|
|
484
|
+
useEffect3(() => {
|
|
485
|
+
onErrorRef.current = onError;
|
|
486
|
+
}, [onError]);
|
|
332
487
|
useEffect3(() => {
|
|
333
488
|
let active = true;
|
|
489
|
+
if (error) {
|
|
490
|
+
setDataUrl(null);
|
|
491
|
+
setGenerationError(null);
|
|
492
|
+
return () => {
|
|
493
|
+
active = false;
|
|
494
|
+
};
|
|
495
|
+
}
|
|
334
496
|
setDataUrl(null);
|
|
497
|
+
setGenerationError(null);
|
|
335
498
|
QRCodeGenerator.toDataURL(value, {
|
|
336
|
-
width:
|
|
499
|
+
width: resolvedSize,
|
|
337
500
|
margin: includeMargin ? 4 : 0,
|
|
338
501
|
errorCorrectionLevel: level,
|
|
339
502
|
color: colors
|
|
340
503
|
}).then((url) => {
|
|
341
504
|
if (active) setDataUrl(url);
|
|
342
|
-
}).catch(() => {
|
|
343
|
-
|
|
505
|
+
}).catch((cause) => {
|
|
506
|
+
var _a3;
|
|
507
|
+
if (!active) return;
|
|
508
|
+
const nextError = cause instanceof Error ? cause : new Error("N\xE3o foi poss\xEDvel gerar o c\xF3digo QR.");
|
|
509
|
+
setDataUrl(null);
|
|
510
|
+
setGenerationError(nextError);
|
|
511
|
+
(_a3 = onErrorRef.current) == null ? void 0 : _a3.call(onErrorRef, nextError);
|
|
344
512
|
});
|
|
345
513
|
return () => {
|
|
346
514
|
active = false;
|
|
347
515
|
};
|
|
348
|
-
}, [
|
|
516
|
+
}, [colors, error, includeMargin, level, resolvedSize, value]);
|
|
349
517
|
return /* @__PURE__ */ jsxs6(
|
|
350
518
|
"div",
|
|
351
519
|
__spreadProps(__spreadValues({}, rest), {
|
|
352
520
|
role: "img",
|
|
353
521
|
"aria-label": ariaLabel,
|
|
354
|
-
"aria-describedby":
|
|
522
|
+
"aria-describedby": describedBy,
|
|
523
|
+
"aria-busy": isLoading || void 0,
|
|
524
|
+
"aria-invalid": displayError ? true : void 0,
|
|
355
525
|
className: classNames5("inline-flex max-w-full flex-col items-center gap-2", className),
|
|
356
526
|
children: [
|
|
357
|
-
dataUrl ? /* @__PURE__ */ jsx6("img", { src: dataUrl, alt: "", width:
|
|
527
|
+
displayError ? /* @__PURE__ */ jsx6("span", { role: "alert", className: "rounded-sm border border-field-border-error p-3 text-sm text-field-assistive-error", children: displayError }) : dataUrl ? /* @__PURE__ */ jsx6("img", { src: dataUrl, alt: "", width: resolvedSize, height: resolvedSize, className: "h-auto max-w-full" }) : /* @__PURE__ */ jsx6(
|
|
358
528
|
"span",
|
|
359
529
|
{
|
|
360
530
|
"aria-hidden": "true",
|
|
361
531
|
className: "inline-block animate-pulse rounded-sm bg-surface-muted",
|
|
362
|
-
style: { width:
|
|
532
|
+
style: { width: resolvedSize, height: resolvedSize, maxWidth: "100%" }
|
|
363
533
|
}
|
|
364
534
|
),
|
|
365
535
|
description && /* @__PURE__ */ jsx6("span", { id: descriptionId, className: "sr-only", children: description })
|
|
@@ -371,10 +541,11 @@ var QRCode_default = QRCode;
|
|
|
371
541
|
|
|
372
542
|
export {
|
|
373
543
|
BoletoBarCode,
|
|
544
|
+
validateFiles,
|
|
374
545
|
FileDropzone_default,
|
|
375
546
|
FileUploadProgress_default,
|
|
376
547
|
FileList_default,
|
|
377
548
|
FileViewer_default,
|
|
378
549
|
QRCode_default
|
|
379
550
|
};
|
|
380
|
-
//# sourceMappingURL=chunk-
|
|
551
|
+
//# sourceMappingURL=chunk-7JI5637G.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/barcode/barcode.tsx","../src/components/file-upload/validation.ts","../src/components/file-upload/FileDropzone.tsx","../src/components/file-upload/FileUploadProgress.tsx","../src/components/file-upload/FileList.tsx","../src/components/file-upload/FileViewer.tsx","../src/components/qr-code/QRCode.tsx"],"sourcesContent":["\"use client\";\n\nimport JsBarcode from \"jsbarcode\";\nimport { useEffect, useRef } from \"react\";\n\nconst linhaDigitavelParaCodigoBarras = (linha: string): string => {\n const d = linha.replace(/\\D/g, \"\");\n\n const banco = d.substring(0, 3);\n const moeda = d.substring(3, 4);\n const campo1 = d.substring(4, 9);\n const campo2 = d.substring(10, 20);\n const campo3 = d.substring(21, 31);\n const digitoGeral = d.substring(32, 33);\n const vencimento = d.substring(33, 37);\n const valor = d.substring(37, 47);\n\n return (\n banco + moeda + digitoGeral + vencimento + valor + campo1 + campo2 + campo3\n );\n};\n\nexport interface BoletoBarCodeProps {\n linhaDigitavel: string;\n}\n\nexport function BoletoBarCode({ linhaDigitavel }: BoletoBarCodeProps) {\n const svgRef = useRef<SVGSVGElement>(null);\n\n useEffect(() => {\n if (!svgRef.current) return;\n\n try {\n const codigoBarras = linhaDigitavelParaCodigoBarras(linhaDigitavel);\n\n JsBarcode(svgRef.current, codigoBarras, {\n format: \"ITF\",\n lineColor: \"#000000\",\n background: \"#FFFFFF\",\n displayValue: false,\n width: 2,\n height: 80,\n margin: 0,\n });\n } catch (error) {\n console.error(\"Erro ao gerar código de barras:\", error);\n }\n }, [linhaDigitavel]);\n\n return (\n <div className=\"w-full space-y-3 bg-surface-card\">\n <svg ref={svgRef} className=\"w-full\" />\n <p className=\"text-center font-mono text-sm tracking-widest text-content-primary\">\n {linhaDigitavel}\n </p>\n </div>\n );\n}\n\n","export type FileValidationReason = \"type\" | \"size\" | \"count\";\n\nexport interface FileRejection {\n file: File;\n reason: FileValidationReason;\n message: string;\n}\n\nexport interface FileValidationOptions {\n accept?: string;\n multiple?: boolean;\n maxFiles?: number;\n maxSize?: number;\n}\n\nexport interface FileValidationResult {\n accepted: File[];\n rejected: FileRejection[];\n}\n\nfunction acceptsFile(file: File, accept?: string) {\n if (!accept?.trim()) return true;\n\n return accept.split(\",\").map((item) => item.trim().toLowerCase()).some((rule) => {\n if (rule.endsWith(\"/*\")) return file.type.toLowerCase().startsWith(rule.slice(0, -1));\n if (rule.startsWith(\".\")) return file.name.toLowerCase().endsWith(rule);\n return file.type.toLowerCase() === rule;\n });\n}\n\nfunction rejectionMessage(reason: FileValidationReason) {\n if (reason === \"type\") return \"Tipo de arquivo não permitido.\";\n if (reason === \"size\") return \"O arquivo excede o tamanho máximo permitido.\";\n return \"Quantidade máxima de arquivos excedida.\";\n}\n\nfunction normalizeMaxFiles(options: FileValidationOptions) {\n if (options.multiple === false) return 1;\n if (options.maxFiles === undefined || !Number.isFinite(options.maxFiles)) {\n return Number.POSITIVE_INFINITY;\n }\n return Math.max(1, Math.floor(options.maxFiles));\n}\n\nfunction normalizeMaxSize(maxSize?: number) {\n if (maxSize === undefined || !Number.isFinite(maxSize)) return undefined;\n return Math.max(0, maxSize);\n}\n\nexport function validateFiles(\n files: readonly File[] | FileList,\n options: FileValidationOptions = {},\n): FileValidationResult {\n const selected = Array.from(files);\n const maxFiles = normalizeMaxFiles(options);\n const maxSize = normalizeMaxSize(options.maxSize);\n const accepted: File[] = [];\n const rejected: FileRejection[] = [];\n\n selected.forEach((file, index) => {\n const reason: FileValidationReason | undefined = !acceptsFile(file, options.accept)\n ? \"type\"\n : maxSize !== undefined && file.size > maxSize\n ? \"size\"\n : index >= maxFiles\n ? \"count\"\n : undefined;\n\n if (reason) {\n rejected.push({ file, reason, message: rejectionMessage(reason) });\n } else {\n accepted.push(file);\n }\n });\n\n return { accepted, rejected };\n}\n","\"use client\";\n\nimport classNames from \"classnames\";\nimport { useId, useRef, useState, type ChangeEvent, type DragEvent, type ReactNode } from \"react\";\nimport { validateFiles, type FileRejection } from \"./validation\";\n\nexport type { FileRejection } from \"./validation\";\n\nexport interface FileDropzoneProps {\n accept?: string;\n multiple?: boolean;\n maxFiles?: number;\n maxSize?: number;\n disabled?: boolean;\n id?: string;\n name?: string;\n required?: boolean;\n label?: ReactNode;\n hint?: ReactNode;\n error?: ReactNode;\n className?: string;\n onFilesAccepted?: (files: File[]) => void;\n onFilesRejected?: (rejections: FileRejection[]) => void;\n}\n\nexport function FileDropzone({\n accept,\n multiple = false,\n maxFiles = multiple ? Number.POSITIVE_INFINITY : 1,\n maxSize,\n disabled = false,\n id,\n name,\n required = false,\n label = \"Selecionar arquivos\",\n hint = \"Arraste e solte os arquivos aqui ou use o teclado para selecionar.\",\n error,\n className,\n onFilesAccepted,\n onFilesRejected,\n}: FileDropzoneProps) {\n const generatedInputId = useId();\n const inputId = id ?? generatedInputId;\n const messageId = `${inputId}-message`;\n const inputRef = useRef<HTMLInputElement>(null);\n const [isDragging, setIsDragging] = useState(false);\n const [rejectionMessage, setRejectionMessage] = useState<string>();\n\n const processFiles = (fileList: FileList | File[]) => {\n if (disabled) return;\n const { accepted, rejected } = validateFiles(fileList, {\n accept,\n maxFiles,\n maxSize,\n multiple,\n });\n setRejectionMessage(rejected.length ? rejected.map((item) => item.message).join(\" \") : undefined);\n if (accepted.length) onFilesAccepted?.(accepted);\n if (rejected.length) onFilesRejected?.(rejected);\n };\n\n const handleInputChange = (event: ChangeEvent<HTMLInputElement>) => {\n if (event.target.files) processFiles(event.target.files);\n event.target.value = \"\";\n };\n const handleDrop = (event: DragEvent<HTMLDivElement>) => {\n event.preventDefault();\n setIsDragging(false);\n processFiles(event.dataTransfer.files);\n };\n const hasError = Boolean(error || rejectionMessage);\n const message = error || rejectionMessage || hint;\n\n return (\n <div\n onDragEnter={(event) => { event.preventDefault(); if (!disabled) setIsDragging(true); }}\n onDragOver={(event) => event.preventDefault()}\n onDragLeave={(event) => { if (event.currentTarget === event.target) setIsDragging(false); }}\n onDrop={handleDrop}\n className={classNames(\n \"flex min-h-32 w-full cursor-pointer flex-col items-center justify-center rounded-sm border-2 border-dashed p-6 text-center transition-colors focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-focus-ring\",\n isDragging ? \"border-action-primary bg-primary-1/10\" : \"border-border-default bg-surface-card hover:border-border-strong\",\n disabled && \"cursor-not-allowed opacity-60\",\n hasError && \"border-field-border-error\",\n className,\n )}\n >\n <label htmlFor={inputId} className=\"flex cursor-pointer flex-col items-center focus-within:outline focus-within:outline-2 focus-within:outline-offset-2 focus-within:outline-focus-ring\">\n <span className=\"font-semibold text-content-primary\">{label}</span>\n <input\n ref={inputRef}\n id={inputId}\n type=\"file\"\n name={name}\n accept={accept}\n multiple={multiple}\n disabled={disabled}\n required={required}\n onChange={handleInputChange}\n aria-describedby={message ? messageId : undefined}\n aria-invalid={hasError ? true : undefined}\n className=\"sr-only\"\n />\n </label>\n {message && <span id={messageId} role={hasError ? \"alert\" : undefined} className={classNames(\"mt-1 text-sm\", hasError ? \"text-field-assistive-error\" : \"text-content-secondary\")}>{message}</span>}\n </div>\n );\n}\n\nexport default FileDropzone;\n","\"use client\";\n\nimport classNames from \"classnames\";\n\nexport type FileUploadProgressStatus = \"idle\" | \"uploading\" | \"success\" | \"error\";\n\nexport interface FileUploadProgressProps {\n value?: number | null;\n label?: string;\n status?: FileUploadProgressStatus;\n showValue?: boolean;\n className?: string;\n}\n\nexport function FileUploadProgress({\n value,\n label = \"Progresso do upload\",\n status = \"uploading\",\n showValue = true,\n className,\n}: FileUploadProgressProps) {\n const resolvedValue = typeof value === \"number\"\n ? Math.min(100, Math.max(0, value))\n : undefined;\n const statusText = status === \"success\"\n ? \"Concluído\"\n : status === \"error\"\n ? \"Erro\"\n : resolvedValue === undefined\n ? \"Em andamento\"\n : `${Math.round(resolvedValue)}%`;\n\n return (\n <div className={classNames(\"w-full\", className)}>\n <div className=\"mb-1 flex items-center justify-between gap-2 text-xs text-content-secondary\">\n <span>{label}</span>\n {showValue && <span aria-hidden=\"true\">{statusText}</span>}\n </div>\n <div\n role=\"progressbar\"\n aria-label={label}\n aria-valuemin={resolvedValue === undefined ? undefined : 0}\n aria-valuemax={resolvedValue === undefined ? undefined : 100}\n aria-valuenow={resolvedValue}\n aria-valuetext={statusText}\n className=\"h-2 w-full overflow-hidden rounded-full bg-surface-muted\"\n >\n <div\n className={classNames(\n \"h-full rounded-full transition-[width] duration-200\",\n status === \"error\" ? \"bg-feedback-danger-strong\" : \"bg-action-primary\",\n resolvedValue === undefined ? \"w-1/2 animate-pulse\" : undefined,\n )}\n style={resolvedValue === undefined ? undefined : { width: `${resolvedValue}%` }}\n />\n </div>\n <span className=\"sr-only\" role=\"status\" aria-live=\"polite\">{statusText}</span>\n </div>\n );\n}\n\nexport default FileUploadProgress;\n","\"use client\";\n\nimport classNames from \"classnames\";\nimport { MdClose, MdRefresh } from \"react-icons/md\";\nimport FileUploadProgress, { type FileUploadProgressStatus } from \"./FileUploadProgress\";\n\nexport type FileUploadItemStatus = FileUploadProgressStatus | \"pending\";\n\nexport interface FileUploadItem {\n id?: string;\n file: File;\n progress?: number | null;\n status?: FileUploadItemStatus;\n error?: string;\n}\n\nexport interface FileListProps {\n files: FileUploadItem[];\n accessibleName?: string;\n onRemove?: (item: FileUploadItem, index: number) => void;\n onRetry?: (item: FileUploadItem, index: number) => void;\n className?: string;\n}\n\nconst fileId = (item: FileUploadItem, index: number) => item.id ?? `${item.file.name}-${item.file.size}-${item.file.lastModified}-${index}`;\n\nconst statusDescription = (status: FileUploadItemStatus) => {\n if (status === \"uploading\") return \"Enviando\";\n if (status === \"success\") return \"Enviado\";\n if (status === \"error\") return \"Erro no envio\";\n return \"Aguardando envio\";\n};\n\nexport function FileList({ files, accessibleName = \"Arquivos selecionados\", onRemove, onRetry, className }: FileListProps) {\n return (\n <ul aria-label={accessibleName} className={classNames(\"w-full space-y-2\", className)}>\n {files.map((item, index) => {\n const status = item.status ?? \"pending\";\n const progressStatus: FileUploadProgressStatus = status === \"pending\" ? \"idle\" : status;\n return (\n <li key={fileId(item, index)} aria-busy={status === \"uploading\" || undefined} className=\"flex min-w-0 flex-wrap items-center gap-3 rounded-sm border border-border-default bg-surface-card p-3\">\n <div className=\"min-w-0 flex-1\">\n <p className=\"truncate font-semibold text-content-primary\" title={item.file.name}>{item.file.name}</p>\n <p className=\"text-xs text-content-secondary\">{Math.ceil(item.file.size / 1024)} KB</p>\n <span className=\"sr-only\">Status: {statusDescription(status)}</span>\n {(status === \"uploading\" || status === \"success\" || status === \"error\") && (\n <FileUploadProgress value={item.progress} status={progressStatus} label={`Progresso de ${item.file.name}`} />\n )}\n {item.error && <p role=\"alert\" className=\"mt-1 text-sm text-field-assistive-error\">{item.error}</p>}\n </div>\n <div className=\"flex shrink-0 items-center gap-1\">\n {status === \"error\" && onRetry && <button type=\"button\" onClick={() => onRetry(item, index)} aria-label={`Tentar novamente ${item.file.name}`} className=\"flex h-11 w-11 items-center justify-center rounded-sm text-content-secondary hover:bg-surface-muted focus-visible:outline focus-visible:outline-2 focus-visible:outline-focus-ring\"><MdRefresh aria-hidden=\"true\" className=\"h-5 w-5\" /></button>}\n {onRemove && <button type=\"button\" onClick={() => onRemove(item, index)} aria-label={`Remover ${item.file.name}`} className=\"flex h-11 w-11 items-center justify-center rounded-sm text-content-secondary hover:bg-surface-muted focus-visible:outline focus-visible:outline-2 focus-visible:outline-focus-ring\"><MdClose aria-hidden=\"true\" className=\"h-5 w-5\" /></button>}\n </div>\n </li>\n );\n })}\n </ul>\n );\n}\n\nexport default FileList;\n","\"use client\";\n\nimport classNames from \"classnames\";\nimport { useEffect, useRef, useState, type ReactNode } from \"react\";\n\nexport type FileViewerSource = string | Blob | {\n url?: string;\n blob?: Blob;\n contentType?: string;\n fileName?: string;\n};\n\nexport interface FileViewerProps {\n source?: FileViewerSource;\n fileName?: string;\n contentType?: string;\n loading?: boolean;\n error?: ReactNode;\n onLoad?: () => void;\n onError?: (error: Error) => void;\n onDownload?: () => void;\n fallback?: ReactNode;\n title?: string;\n className?: string;\n}\n\nconst extensionType = (fileName?: string) => {\n const extension = fileName?.split(\".\").pop()?.toLowerCase();\n if (extension === \"pdf\") return \"application/pdf\";\n if ([\"png\", \"jpg\", \"jpeg\", \"gif\", \"webp\", \"svg\"].includes(extension ?? \"\")) {\n return `image/${extension === \"jpg\" ? \"jpeg\" : extension}`;\n }\n if ([\"txt\", \"csv\", \"json\", \"xml\", \"md\"].includes(extension ?? \"\")) return \"text/plain\";\n return \"application/octet-stream\";\n};\n\nconst normalizeContentType = (contentType: string) => contentType.split(\";\", 1)[0].trim().toLowerCase();\n\nconst toError = (cause: unknown) => (\n cause instanceof Error ? cause : new Error(\"Não foi possível ler o arquivo.\")\n);\n\nexport function FileViewer({\n source,\n fileName,\n contentType,\n loading = false,\n error,\n onLoad,\n onError,\n onDownload,\n fallback,\n title = fileName ?? \"Visualização do arquivo\",\n className,\n}: FileViewerProps) {\n const [objectUrl, setObjectUrl] = useState<string>();\n const [textContent, setTextContent] = useState<string>();\n const [readError, setReadError] = useState<Error | null>(null);\n const onLoadRef = useRef(onLoad);\n const onErrorRef = useRef(onError);\n const resolved = typeof source === \"object\" && source !== null && !(source instanceof Blob) ? source : undefined;\n const blob = source instanceof Blob ? source : resolved?.blob;\n const url = typeof source === \"string\" ? source : resolved?.url;\n const resolvedName = fileName ?? resolved?.fileName;\n const rawType = contentType?.trim() || resolved?.contentType || blob?.type || extensionType(resolvedName);\n const resolvedType = normalizeContentType(rawType);\n const isText = resolvedType.startsWith(\"text/\") || resolvedType === \"application/json\";\n const displayError = error ?? readError?.message;\n\n useEffect(() => {\n onLoadRef.current = onLoad;\n }, [onLoad]);\n\n useEffect(() => {\n onErrorRef.current = onError;\n }, [onError]);\n\n useEffect(() => {\n let active = true;\n setReadError(null);\n setTextContent(undefined);\n\n if (!blob) {\n setObjectUrl(undefined);\n return () => { active = false; };\n }\n\n let nextUrl: string;\n try {\n nextUrl = URL.createObjectURL(blob);\n setObjectUrl(nextUrl);\n } catch (cause) {\n const nextError = toError(cause);\n setReadError(nextError);\n onErrorRef.current?.(nextError);\n return () => { active = false; };\n }\n\n if (isText) {\n blob.text()\n .then((text) => {\n if (!active) return;\n setTextContent(text);\n onLoadRef.current?.();\n })\n .catch((cause: unknown) => {\n if (!active) return;\n const nextError = toError(cause);\n setReadError(nextError);\n onErrorRef.current?.(nextError);\n });\n }\n\n return () => {\n active = false;\n URL.revokeObjectURL(nextUrl);\n };\n }, [blob, isText]);\n\n const handleMediaError = () => {\n const nextError = new Error(\"Não foi possível carregar a visualização do arquivo.\");\n setReadError(nextError);\n onErrorRef.current?.(nextError);\n };\n const handleLoad = () => onLoadRef.current?.();\n\n if (loading) {\n return (\n <div\n className={classNames(\"flex min-h-32 items-center justify-center rounded-sm border border-border-default bg-surface-card p-6 text-content-secondary\", className)}\n role=\"status\"\n aria-busy=\"true\"\n aria-live=\"polite\"\n >\n Carregando arquivo…\n </div>\n );\n }\n\n if (displayError) {\n return (\n <div className={classNames(\"rounded-sm border border-field-border-error bg-surface-card p-4 text-field-assistive-error\", className)} role=\"alert\">\n {displayError}\n </div>\n );\n }\n\n const displayUrl = objectUrl ?? url;\n if (!displayUrl && !textContent) {\n return (\n <div\n className={classNames(\"rounded-sm border border-border-default bg-surface-card p-4 text-content-secondary\", className)}\n role=\"region\"\n aria-label={title}\n >\n {fallback ?? \"Arquivo indisponível.\"}\n </div>\n );\n }\n\n const download = onDownload\n ? <button type=\"button\" onClick={onDownload} className=\"min-h-11 rounded-sm border border-border-default px-3 text-sm font-semibold text-content-primary focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-focus-ring\">Baixar arquivo</button>\n : displayUrl\n ? <a href={displayUrl} download={resolvedName} className=\"inline-flex min-h-11 items-center rounded-sm border border-border-default px-3 text-sm font-semibold text-content-primary focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-focus-ring\">Baixar arquivo</a>\n : null;\n\n return (\n <div\n className={classNames(\"flex min-w-0 flex-col gap-3 rounded-sm border border-border-default bg-surface-card p-3\", className)}\n role=\"region\"\n aria-label={title}\n >\n {resolvedType.startsWith(\"image/\") && displayUrl && (\n <img src={displayUrl} alt={title} onLoad={handleLoad} onError={handleMediaError} className=\"max-h-[70vh] max-w-full object-contain\" />\n )}\n {resolvedType === \"application/pdf\" && displayUrl && (\n <iframe src={displayUrl} title={title} onLoad={handleLoad} onError={handleMediaError} sandbox=\"\" className=\"min-h-[32rem] w-full border-0\" />\n )}\n {isText && (textContent !== undefined\n ? <pre className=\"max-h-[70vh] overflow-auto whitespace-pre-wrap break-words text-sm text-content-primary\">{textContent}</pre>\n : displayUrl && <iframe src={displayUrl} title={title} onLoad={handleLoad} onError={handleMediaError} sandbox=\"\" className=\"min-h-64 w-full border-0\" />)}\n {!resolvedType.startsWith(\"image/\") && resolvedType !== \"application/pdf\" && !isText && (\n fallback ?? <p className=\"text-content-secondary\">Este tipo de arquivo não possui visualização disponível.</p>\n )}\n {download && <div className=\"flex justify-end\">{download}</div>}\n </div>\n );\n}\n\nexport default FileViewer;\n","\"use client\";\n\nimport QRCodeGenerator from \"qrcode\";\nimport { useEffect, useId, useMemo, useRef, useState, type HTMLAttributes, type ReactNode } from \"react\";\nimport classNames from \"classnames\";\n\nexport type QRCodeErrorCorrectionLevel = \"L\" | \"M\" | \"Q\" | \"H\";\n\nexport interface QRCodeProps extends Omit<HTMLAttributes<HTMLDivElement>, \"color\" | \"onError\"> {\n value: string;\n size?: number;\n level?: QRCodeErrorCorrectionLevel;\n includeMargin?: boolean;\n fgColor?: string;\n bgColor?: string;\n ariaLabel?: string;\n description?: string;\n loading?: boolean;\n error?: ReactNode;\n onError?: (error: Error) => void;\n}\n\nfunction getRelativeLuminance(color: string) {\n const match = color.trim().match(/^#([\\da-f]{6})$/i);\n if (!match) return null;\n\n const channels = [0, 2, 4].map((offset) => Number.parseInt(match[1].slice(offset, offset + 2), 16) / 255);\n const linear = channels.map((channel) => (\n channel <= 0.03928 ? channel / 12.92 : ((channel + 0.055) / 1.055) ** 2.4\n ));\n\n return 0.2126 * linear[0] + 0.7152 * linear[1] + 0.0722 * linear[2];\n}\n\nfunction resolveAccessibleColors(fgColor: string, bgColor: string) {\n const foregroundLuminance = getRelativeLuminance(fgColor);\n const backgroundLuminance = getRelativeLuminance(bgColor);\n\n if (foregroundLuminance === null || backgroundLuminance === null) {\n return { dark: fgColor, light: bgColor };\n }\n\n const lighter = Math.max(foregroundLuminance, backgroundLuminance);\n const darker = Math.min(foregroundLuminance, backgroundLuminance);\n const contrastRatio = (lighter + 0.05) / (darker + 0.05);\n\n return contrastRatio >= 3\n ? { dark: fgColor, light: bgColor }\n : { dark: \"#000000\", light: \"#FFFFFF\" };\n}\n\nexport function QRCode({\n value,\n size = 192,\n level = \"M\",\n includeMargin = true,\n fgColor = \"#000000\",\n bgColor = \"#FFFFFF\",\n ariaLabel = \"Código QR\",\n description,\n loading = false,\n error,\n onError,\n className,\n ...rest\n}: QRCodeProps) {\n const [dataUrl, setDataUrl] = useState<string | null>(null);\n const [generationError, setGenerationError] = useState<Error | null>(null);\n const onErrorRef = useRef(onError);\n const generatedId = useId();\n const resolvedSize = Math.max(1, Number.isFinite(size) ? Math.floor(size) : 192);\n const descriptionId = description\n ? `${rest.id ?? generatedId}-description`\n : undefined;\n const colors = useMemo(\n () => resolveAccessibleColors(fgColor, bgColor),\n [bgColor, fgColor],\n );\n const describedBy = [rest[\"aria-describedby\"], descriptionId].filter(Boolean).join(\" \") || undefined;\n const displayError = error ?? generationError?.message;\n const isLoading = loading || (!dataUrl && !displayError);\n\n useEffect(() => {\n onErrorRef.current = onError;\n }, [onError]);\n\n useEffect(() => {\n let active = true;\n if (error) {\n setDataUrl(null);\n setGenerationError(null);\n return () => { active = false; };\n }\n setDataUrl(null);\n setGenerationError(null);\n QRCodeGenerator.toDataURL(value, {\n width: resolvedSize,\n margin: includeMargin ? 4 : 0,\n errorCorrectionLevel: level,\n color: colors,\n })\n .then((url) => { if (active) setDataUrl(url); })\n .catch((cause: unknown) => {\n if (!active) return;\n const nextError = cause instanceof Error\n ? cause\n : new Error(\"Não foi possível gerar o código QR.\");\n setDataUrl(null);\n setGenerationError(nextError);\n onErrorRef.current?.(nextError);\n });\n return () => { active = false; };\n }, [colors, error, includeMargin, level, resolvedSize, value]);\n\n return (\n <div\n {...rest}\n role=\"img\"\n aria-label={ariaLabel}\n aria-describedby={describedBy}\n aria-busy={isLoading || undefined}\n aria-invalid={displayError ? true : undefined}\n className={classNames(\"inline-flex max-w-full flex-col items-center gap-2\", className)}\n >\n {displayError ? (\n <span role=\"alert\" className=\"rounded-sm border border-field-border-error p-3 text-sm text-field-assistive-error\">\n {displayError}\n </span>\n ) : dataUrl ? (\n <img src={dataUrl} alt=\"\" width={resolvedSize} height={resolvedSize} className=\"h-auto max-w-full\" />\n ) : (\n <span\n aria-hidden=\"true\"\n className=\"inline-block animate-pulse rounded-sm bg-surface-muted\"\n style={{ width: resolvedSize, height: resolvedSize, maxWidth: \"100%\" }}\n />\n )}\n {description && <span id={descriptionId} className=\"sr-only\">{description}</span>}\n </div>\n );\n}\n\nexport default QRCode;\n"],"mappings":"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","names":["useRef","jsx","jsxs","useRef","rejectionMessage","classNames","jsx","jsxs","classNames","jsx","jsxs","classNames","classNames","useEffect","useRef","useState","jsx","jsxs","_a","useEffect","useId","useRef","useState","classNames","jsx","jsxs","_a","useState","useRef","useId","useEffect","classNames"]}
|