@aspprev/versi-ds 0.4.3 → 0.4.6
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 +10 -0
- package/dist/charts.d.ts +11 -2
- package/dist/charts.js +1 -1
- package/dist/{chunk-JGCZAVYV.js → chunk-5LJGBVPA.js} +138 -85
- package/dist/chunk-5LJGBVPA.js.map +1 -0
- package/dist/{chunk-MC4MSOCM.js → chunk-CLXCB6LY.js} +93 -1
- package/dist/chunk-CLXCB6LY.js.map +1 -0
- package/dist/{chunk-YIUITJ4V.js → chunk-CVTBM4I6.js} +112 -33
- package/dist/chunk-CVTBM4I6.js.map +1 -0
- package/dist/{chunk-5MRS4PDD.js → chunk-HKCVDOGK.js} +25 -21
- package/dist/chunk-HKCVDOGK.js.map +1 -0
- package/dist/core.d.ts +19 -4
- package/dist/core.js +1 -1
- package/dist/documents.d.ts +35 -7
- package/dist/documents.js +1 -1
- package/dist/forms.d.ts +10 -3
- package/dist/forms.js +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js +4 -4
- package/dist/manifest.json +5 -5
- package/dist/styles.css +1 -1
- package/package.json +1 -1
- package/dist/chunk-5MRS4PDD.js.map +0 -1
- package/dist/chunk-JGCZAVYV.js.map +0 -1
- package/dist/chunk-MC4MSOCM.js.map +0 -1
- package/dist/chunk-YIUITJ4V.js.map +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// src/components/barcode/barcode.tsx
|
|
2
2
|
import JsBarcode from "jsbarcode";
|
|
3
|
-
import { useEffect, useRef } from "react";
|
|
3
|
+
import { useEffect, useRef, useState } from "react";
|
|
4
4
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
5
|
var linhaDigitavelParaCodigoBarras = (linha) => {
|
|
6
6
|
const d = linha.replace(/\D/g, "");
|
|
@@ -14,10 +14,19 @@ var linhaDigitavelParaCodigoBarras = (linha) => {
|
|
|
14
14
|
const valor = d.substring(37, 47);
|
|
15
15
|
return banco + moeda + digitoGeral + vencimento + valor + campo1 + campo2 + campo3;
|
|
16
16
|
};
|
|
17
|
-
function BoletoBarCode({
|
|
17
|
+
function BoletoBarCode({
|
|
18
|
+
linhaDigitavel,
|
|
19
|
+
width = 2,
|
|
20
|
+
height = 80,
|
|
21
|
+
quietZone = 0,
|
|
22
|
+
error,
|
|
23
|
+
onError
|
|
24
|
+
}) {
|
|
18
25
|
const svgRef = useRef(null);
|
|
26
|
+
const [generationError, setGenerationError] = useState(null);
|
|
19
27
|
useEffect(() => {
|
|
20
28
|
if (!svgRef.current) return;
|
|
29
|
+
setGenerationError(null);
|
|
21
30
|
try {
|
|
22
31
|
const codigoBarras = linhaDigitavelParaCodigoBarras(linhaDigitavel);
|
|
23
32
|
JsBarcode(svgRef.current, codigoBarras, {
|
|
@@ -25,16 +34,19 @@ function BoletoBarCode({ linhaDigitavel }) {
|
|
|
25
34
|
lineColor: "#000000",
|
|
26
35
|
background: "#FFFFFF",
|
|
27
36
|
displayValue: false,
|
|
28
|
-
width
|
|
29
|
-
height
|
|
30
|
-
margin:
|
|
37
|
+
width,
|
|
38
|
+
height,
|
|
39
|
+
margin: quietZone
|
|
31
40
|
});
|
|
32
|
-
} catch (
|
|
33
|
-
|
|
41
|
+
} catch (cause) {
|
|
42
|
+
const nextError = cause instanceof Error ? cause : new Error("N\xE3o foi poss\xEDvel gerar o c\xF3digo de barras.");
|
|
43
|
+
setGenerationError(nextError);
|
|
44
|
+
onError?.(nextError);
|
|
34
45
|
}
|
|
35
|
-
}, [linhaDigitavel]);
|
|
46
|
+
}, [height, linhaDigitavel, onError, quietZone, width]);
|
|
47
|
+
const displayError = error ?? generationError?.message;
|
|
36
48
|
return /* @__PURE__ */ jsxs("div", { className: "w-full space-y-3 bg-surface-card", children: [
|
|
37
|
-
/* @__PURE__ */ jsx("svg", { ref: svgRef, className: "w-full" }),
|
|
49
|
+
displayError ? /* @__PURE__ */ jsx("p", { role: "alert", className: "text-sm text-field-assistive-error", children: displayError }) : /* @__PURE__ */ jsx("svg", { ref: svgRef, className: "w-full" }),
|
|
38
50
|
/* @__PURE__ */ jsx("p", { className: "text-center font-mono text-sm tracking-widest text-content-primary", children: linhaDigitavel })
|
|
39
51
|
] });
|
|
40
52
|
}
|
|
@@ -43,14 +55,27 @@ function BoletoBarCode({ linhaDigitavel }) {
|
|
|
43
55
|
function acceptsFile(file, accept) {
|
|
44
56
|
if (!accept?.trim()) return true;
|
|
45
57
|
return accept.split(",").map((item) => item.trim().toLowerCase()).some((rule) => {
|
|
46
|
-
if (rule.endsWith("/*"))
|
|
47
|
-
|
|
58
|
+
if (rule.endsWith("/*")) {
|
|
59
|
+
return file.type.toLowerCase().startsWith(rule.slice(0, -1));
|
|
60
|
+
}
|
|
61
|
+
if (rule.startsWith(".")) {
|
|
62
|
+
return file.name.toLowerCase().endsWith(rule);
|
|
63
|
+
}
|
|
48
64
|
return file.type.toLowerCase() === rule;
|
|
49
65
|
});
|
|
50
66
|
}
|
|
51
|
-
function
|
|
67
|
+
function getExtension(fileName) {
|
|
68
|
+
const extension = fileName.split(".").pop()?.trim().toLowerCase();
|
|
69
|
+
return extension && extension !== fileName.toLowerCase() ? extension : "";
|
|
70
|
+
}
|
|
71
|
+
function rejectionMessage(reason, context, messages) {
|
|
72
|
+
const customMessage = messages?.[reason];
|
|
73
|
+
if (typeof customMessage === "function") return customMessage(context);
|
|
74
|
+
if (typeof customMessage === "string") return customMessage;
|
|
52
75
|
if (reason === "type") return "Tipo de arquivo n\xE3o permitido.";
|
|
53
76
|
if (reason === "size") return "O arquivo excede o tamanho m\xE1ximo permitido.";
|
|
77
|
+
if (reason === "empty") return "O arquivo est\xE1 vazio.";
|
|
78
|
+
if (reason === "invalid") return "O arquivo n\xE3o \xE9 v\xE1lido.";
|
|
54
79
|
return "Quantidade m\xE1xima de arquivos excedida.";
|
|
55
80
|
}
|
|
56
81
|
function normalizeMaxFiles(options) {
|
|
@@ -71,9 +96,24 @@ function validateFiles(files, options = {}) {
|
|
|
71
96
|
const accepted = [];
|
|
72
97
|
const rejected = [];
|
|
73
98
|
selected.forEach((file, index) => {
|
|
74
|
-
const
|
|
99
|
+
const isInvalid = !file || typeof file.name !== "string" || !file.name.trim() || typeof file.size !== "number" || !Number.isFinite(file.size) || file.size < 0;
|
|
100
|
+
const reason = isInvalid ? "invalid" : file.size === 0 ? "empty" : !acceptsFile(file, options.accept) ? "type" : maxSize !== void 0 && file.size > maxSize ? "size" : index >= maxFiles ? "count" : void 0;
|
|
75
101
|
if (reason) {
|
|
76
|
-
|
|
102
|
+
const fileName = typeof file?.name === "string" ? file.name : "";
|
|
103
|
+
const size = typeof file?.size === "number" && Number.isFinite(file.size) ? file.size : 0;
|
|
104
|
+
const context = {
|
|
105
|
+
code: reason,
|
|
106
|
+
fileName,
|
|
107
|
+
extension: getExtension(fileName),
|
|
108
|
+
size,
|
|
109
|
+
maxSize
|
|
110
|
+
};
|
|
111
|
+
rejected.push({
|
|
112
|
+
file,
|
|
113
|
+
...context,
|
|
114
|
+
reason,
|
|
115
|
+
message: rejectionMessage(reason, context, options.messages)
|
|
116
|
+
});
|
|
77
117
|
} else {
|
|
78
118
|
accepted.push(file);
|
|
79
119
|
}
|
|
@@ -83,7 +123,7 @@ function validateFiles(files, options = {}) {
|
|
|
83
123
|
|
|
84
124
|
// src/components/file-upload/FileDropzone.tsx
|
|
85
125
|
import classNames from "classnames";
|
|
86
|
-
import { useId, useRef as useRef2, useState } from "react";
|
|
126
|
+
import { useId, useRef as useRef2, useState as useState2 } from "react";
|
|
87
127
|
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
88
128
|
function FileDropzone({
|
|
89
129
|
accept,
|
|
@@ -97,6 +137,8 @@ function FileDropzone({
|
|
|
97
137
|
label = "Selecionar arquivos",
|
|
98
138
|
hint = "Arraste e solte os arquivos aqui ou use o teclado para selecionar.",
|
|
99
139
|
error,
|
|
140
|
+
messages,
|
|
141
|
+
actions,
|
|
100
142
|
className,
|
|
101
143
|
onFilesAccepted,
|
|
102
144
|
onFilesRejected
|
|
@@ -105,15 +147,16 @@ function FileDropzone({
|
|
|
105
147
|
const inputId = id ?? generatedInputId;
|
|
106
148
|
const messageId = `${inputId}-message`;
|
|
107
149
|
const inputRef = useRef2(null);
|
|
108
|
-
const [isDragging, setIsDragging] =
|
|
109
|
-
const [rejectionMessage2, setRejectionMessage] =
|
|
150
|
+
const [isDragging, setIsDragging] = useState2(false);
|
|
151
|
+
const [rejectionMessage2, setRejectionMessage] = useState2();
|
|
110
152
|
const processFiles = (fileList) => {
|
|
111
153
|
if (disabled) return;
|
|
112
154
|
const { accepted, rejected } = validateFiles(fileList, {
|
|
113
155
|
accept,
|
|
114
156
|
maxFiles,
|
|
115
157
|
maxSize,
|
|
116
|
-
multiple
|
|
158
|
+
multiple,
|
|
159
|
+
messages
|
|
117
160
|
});
|
|
118
161
|
setRejectionMessage(rejected.length ? rejected.map((item) => item.message).join(" ") : void 0);
|
|
119
162
|
if (accepted.length) onFilesAccepted?.(accepted);
|
|
@@ -170,7 +213,8 @@ function FileDropzone({
|
|
|
170
213
|
}
|
|
171
214
|
)
|
|
172
215
|
] }),
|
|
173
|
-
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 })
|
|
216
|
+
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 }),
|
|
217
|
+
actions && /* @__PURE__ */ jsx2("div", { className: "mt-3 flex flex-wrap justify-center gap-2", children: actions })
|
|
174
218
|
]
|
|
175
219
|
}
|
|
176
220
|
);
|
|
@@ -233,7 +277,7 @@ var statusDescription = (status) => {
|
|
|
233
277
|
if (status === "error") return "Erro no envio";
|
|
234
278
|
return "Aguardando envio";
|
|
235
279
|
};
|
|
236
|
-
function FileList({ files, accessibleName = "Arquivos selecionados", onRemove, onRetry, className }) {
|
|
280
|
+
function FileList({ files, accessibleName = "Arquivos selecionados", onRemove, onRetry, actions, className }) {
|
|
237
281
|
return /* @__PURE__ */ jsx4("ul", { "aria-label": accessibleName, className: classNames3("w-full space-y-2", className), children: files.map((item, index) => {
|
|
238
282
|
const status = item.status ?? "pending";
|
|
239
283
|
const progressStatus = status === "pending" ? "idle" : status;
|
|
@@ -252,6 +296,7 @@ function FileList({ files, accessibleName = "Arquivos selecionados", onRemove, o
|
|
|
252
296
|
item.error && /* @__PURE__ */ jsx4("p", { role: "alert", className: "mt-1 text-sm text-field-assistive-error", children: item.error })
|
|
253
297
|
] }),
|
|
254
298
|
/* @__PURE__ */ jsxs4("div", { className: "flex shrink-0 items-center gap-1", children: [
|
|
299
|
+
actions?.(item, index),
|
|
255
300
|
status === "error" && onRetry && /* @__PURE__ */ jsx4("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", children: /* @__PURE__ */ jsx4(MdRefresh, { "aria-hidden": "true", className: "h-5 w-5" }) }),
|
|
256
301
|
onRemove && /* @__PURE__ */ jsx4("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", children: /* @__PURE__ */ jsx4(MdClose, { "aria-hidden": "true", className: "h-5 w-5" }) })
|
|
257
302
|
] })
|
|
@@ -262,7 +307,7 @@ var FileList_default = FileList;
|
|
|
262
307
|
|
|
263
308
|
// src/components/file-upload/FileViewer.tsx
|
|
264
309
|
import classNames4 from "classnames";
|
|
265
|
-
import { useEffect as useEffect2, useRef as useRef3, useState as
|
|
310
|
+
import { useEffect as useEffect2, useRef as useRef3, useState as useState3 } from "react";
|
|
266
311
|
import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
267
312
|
var extensionType = (fileName) => {
|
|
268
313
|
const extension = fileName?.split(".").pop()?.toLowerCase();
|
|
@@ -284,18 +329,49 @@ function FileViewer({
|
|
|
284
329
|
onLoad,
|
|
285
330
|
onError,
|
|
286
331
|
onDownload,
|
|
332
|
+
actions,
|
|
287
333
|
fallback,
|
|
288
334
|
title = fileName ?? "Visualiza\xE7\xE3o do arquivo",
|
|
289
335
|
className
|
|
290
336
|
}) {
|
|
291
|
-
const [objectUrl, setObjectUrl] =
|
|
292
|
-
const [textContent, setTextContent] =
|
|
293
|
-
const [readError, setReadError] =
|
|
337
|
+
const [objectUrl, setObjectUrl] = useState3();
|
|
338
|
+
const [textContent, setTextContent] = useState3();
|
|
339
|
+
const [readError, setReadError] = useState3(null);
|
|
340
|
+
const [asyncSource, setAsyncSource] = useState3();
|
|
341
|
+
const [sourceLoading, setSourceLoading] = useState3(false);
|
|
294
342
|
const onLoadRef = useRef3(onLoad);
|
|
295
343
|
const onErrorRef = useRef3(onError);
|
|
296
|
-
const
|
|
297
|
-
|
|
298
|
-
|
|
344
|
+
const isAsyncSource = Boolean(
|
|
345
|
+
source && typeof source === "object" && "then" in source && typeof source.then === "function"
|
|
346
|
+
);
|
|
347
|
+
useEffect2(() => {
|
|
348
|
+
if (!isAsyncSource) {
|
|
349
|
+
setAsyncSource(void 0);
|
|
350
|
+
setSourceLoading(false);
|
|
351
|
+
return;
|
|
352
|
+
}
|
|
353
|
+
let active = true;
|
|
354
|
+
setSourceLoading(true);
|
|
355
|
+
setReadError(null);
|
|
356
|
+
Promise.resolve(source).then((nextSource) => {
|
|
357
|
+
if (!active) return;
|
|
358
|
+
setAsyncSource(nextSource ?? void 0);
|
|
359
|
+
setSourceLoading(false);
|
|
360
|
+
}).catch((cause) => {
|
|
361
|
+
if (!active) return;
|
|
362
|
+
const nextError = toError(cause);
|
|
363
|
+
setReadError(nextError);
|
|
364
|
+
setSourceLoading(false);
|
|
365
|
+
onErrorRef.current?.(nextError);
|
|
366
|
+
});
|
|
367
|
+
return () => {
|
|
368
|
+
active = false;
|
|
369
|
+
};
|
|
370
|
+
}, [isAsyncSource, source]);
|
|
371
|
+
const resolvedSource = isAsyncSource ? asyncSource : source;
|
|
372
|
+
const resolved = typeof resolvedSource === "object" && resolvedSource !== null && !(resolvedSource instanceof Blob) ? resolvedSource : void 0;
|
|
373
|
+
const blob = resolvedSource instanceof Blob ? resolvedSource : resolved?.blob;
|
|
374
|
+
const url = typeof resolvedSource === "string" ? resolvedSource : resolved?.url;
|
|
299
375
|
const resolvedName = fileName ?? resolved?.fileName;
|
|
300
376
|
const rawType = contentType?.trim() || resolved?.contentType || blob?.type || extensionType(resolvedName);
|
|
301
377
|
const resolvedType = normalizeContentType(rawType);
|
|
@@ -352,7 +428,7 @@ function FileViewer({
|
|
|
352
428
|
onErrorRef.current?.(nextError);
|
|
353
429
|
};
|
|
354
430
|
const handleLoad = () => onLoadRef.current?.();
|
|
355
|
-
if (loading) {
|
|
431
|
+
if (loading || sourceLoading) {
|
|
356
432
|
return /* @__PURE__ */ jsx5(
|
|
357
433
|
"div",
|
|
358
434
|
{
|
|
@@ -391,7 +467,10 @@ function FileViewer({
|
|
|
391
467
|
resolvedType === "application/pdf" && displayUrl && /* @__PURE__ */ jsx5("iframe", { src: displayUrl, title, onLoad: handleLoad, onError: handleMediaError, sandbox: "", className: "min-h-[32rem] w-full border-0" }),
|
|
392
468
|
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" })),
|
|
393
469
|
!resolvedType.startsWith("image/") && resolvedType !== "application/pdf" && !isText && (fallback ?? /* @__PURE__ */ jsx5("p", { className: "text-content-secondary", children: "Este tipo de arquivo n\xE3o possui visualiza\xE7\xE3o dispon\xEDvel." })),
|
|
394
|
-
download && /* @__PURE__ */
|
|
470
|
+
(download || actions) && /* @__PURE__ */ jsxs5("div", { className: "flex flex-wrap justify-end gap-2", children: [
|
|
471
|
+
actions,
|
|
472
|
+
download
|
|
473
|
+
] })
|
|
395
474
|
]
|
|
396
475
|
}
|
|
397
476
|
);
|
|
@@ -400,7 +479,7 @@ var FileViewer_default = FileViewer;
|
|
|
400
479
|
|
|
401
480
|
// src/components/qr-code/QRCode.tsx
|
|
402
481
|
import QRCodeGenerator from "qrcode";
|
|
403
|
-
import { useEffect as useEffect3, useId as useId2, useMemo, useRef as useRef4, useState as
|
|
482
|
+
import { useEffect as useEffect3, useId as useId2, useMemo, useRef as useRef4, useState as useState4 } from "react";
|
|
404
483
|
import classNames5 from "classnames";
|
|
405
484
|
import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
406
485
|
function getRelativeLuminance(color) {
|
|
@@ -436,8 +515,8 @@ function QRCode({
|
|
|
436
515
|
className,
|
|
437
516
|
...rest
|
|
438
517
|
}) {
|
|
439
|
-
const [dataUrl, setDataUrl] =
|
|
440
|
-
const [generationError, setGenerationError] =
|
|
518
|
+
const [dataUrl, setDataUrl] = useState4(null);
|
|
519
|
+
const [generationError, setGenerationError] = useState4(null);
|
|
441
520
|
const onErrorRef = useRef4(onError);
|
|
442
521
|
const generatedId = useId2();
|
|
443
522
|
const resolvedSize = Math.max(1, Number.isFinite(size) ? Math.floor(size) : 192);
|
|
@@ -516,4 +595,4 @@ export {
|
|
|
516
595
|
FileViewer_default,
|
|
517
596
|
QRCode_default
|
|
518
597
|
};
|
|
519
|
-
//# sourceMappingURL=chunk-
|
|
598
|
+
//# sourceMappingURL=chunk-CVTBM4I6.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, useState, type ReactNode } 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 banco + moeda + digitoGeral + vencimento + valor + campo1 + campo2 + campo3;\n};\n\nexport interface BoletoBarCodeProps {\n linhaDigitavel: string;\n /** Bar width passed to JsBarcode. */\n width?: number;\n /** Bar height in pixels. */\n height?: number;\n /** Quiet zone/margin in pixels. */\n quietZone?: number;\n error?: ReactNode;\n onError?: (error: Error) => void;\n}\n\nexport function BoletoBarCode({\n linhaDigitavel,\n width = 2,\n height = 80,\n quietZone = 0,\n error,\n onError,\n}: BoletoBarCodeProps) {\n const svgRef = useRef<SVGSVGElement>(null);\n const [generationError, setGenerationError] = useState<Error | null>(null);\n\n useEffect(() => {\n if (!svgRef.current) return;\n setGenerationError(null);\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,\n height,\n margin: quietZone,\n });\n } catch (cause: unknown) {\n const nextError = cause instanceof Error\n ? cause\n : new Error(\"Não foi possível gerar o código de barras.\");\n setGenerationError(nextError);\n onError?.(nextError);\n }\n }, [height, linhaDigitavel, onError, quietZone, width]);\n\n const displayError = error ?? generationError?.message;\n\n return (\n <div className=\"w-full space-y-3 bg-surface-card\">\n {displayError ? (\n <p role=\"alert\" className=\"text-sm text-field-assistive-error\">\n {displayError}\n </p>\n ) : (\n <svg ref={svgRef} className=\"w-full\" />\n )}\n <p className=\"text-center font-mono text-sm tracking-widest text-content-primary\">\n {linhaDigitavel}\n </p>\n </div>\n );\n}\n","export type FileValidationReason =\n | \"type\"\n | \"size\"\n | \"count\"\n | \"empty\"\n | \"invalid\";\n\nexport interface FileRejectionContext {\n code: FileValidationReason;\n fileName: string;\n extension: string;\n size: number;\n maxSize?: number;\n}\n\nexport type FileValidationMessage =\n | string\n | ((context: FileRejectionContext) => string);\n\nexport interface FileRejection {\n file: File;\n code: FileValidationReason;\n reason: FileValidationReason;\n fileName: string;\n extension: string;\n size: number;\n maxSize?: number;\n message: string;\n}\n\nexport interface FileValidationOptions {\n accept?: string;\n multiple?: boolean;\n maxFiles?: number;\n maxSize?: number;\n messages?: Partial<Record<FileValidationReason, FileValidationMessage>>;\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\n .split(\",\")\n .map((item) => item.trim().toLowerCase())\n .some((rule) => {\n if (rule.endsWith(\"/*\")) {\n return file.type.toLowerCase().startsWith(rule.slice(0, -1));\n }\n if (rule.startsWith(\".\")) {\n return file.name.toLowerCase().endsWith(rule);\n }\n return file.type.toLowerCase() === rule;\n });\n}\n\nfunction getExtension(fileName: string) {\n const extension = fileName.split(\".\").pop()?.trim().toLowerCase();\n return extension && extension !== fileName.toLowerCase() ? extension : \"\";\n}\n\nfunction rejectionMessage(\n reason: FileValidationReason,\n context: FileRejectionContext,\n messages?: FileValidationOptions[\"messages\"],\n) {\n const customMessage = messages?.[reason];\n if (typeof customMessage === \"function\") return customMessage(context);\n if (typeof customMessage === \"string\") return customMessage;\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 if (reason === \"empty\") return \"O arquivo está vazio.\";\n if (reason === \"invalid\") return \"O arquivo não é válido.\";\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 isInvalid =\n !file ||\n typeof file.name !== \"string\" ||\n !file.name.trim() ||\n typeof file.size !== \"number\" ||\n !Number.isFinite(file.size) ||\n file.size < 0;\n const reason: FileValidationReason | undefined = isInvalid\n ? \"invalid\"\n : file.size === 0\n ? \"empty\"\n : !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 const fileName = typeof file?.name === \"string\" ? file.name : \"\";\n const size = typeof file?.size === \"number\" && Number.isFinite(file.size)\n ? file.size\n : 0;\n const context: FileRejectionContext = {\n code: reason,\n fileName,\n extension: getExtension(fileName),\n size,\n maxSize,\n };\n rejected.push({\n file,\n ...context,\n reason,\n message: rejectionMessage(reason, context, options.messages),\n });\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, type FileValidationMessage } 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 messages?: Partial<Record<\"type\" | \"size\" | \"count\" | \"empty\" | \"invalid\", FileValidationMessage>>;\n actions?: 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 messages,\n actions,\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 messages,\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 {actions && <div className=\"mt-3 flex flex-wrap justify-center gap-2\">{actions}</div>}\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 type { ReactNode } from \"react\";\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 actions?: (item: FileUploadItem, index: number) => ReactNode;\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, actions, 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 {actions?.(item, index)}\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 type FileViewerSourceInput =\n | FileViewerSource\n | Promise<FileViewerSource | null | undefined>;\n\nexport interface FileViewerProps {\n source?: FileViewerSourceInput;\n fileName?: string;\n contentType?: string;\n loading?: boolean;\n error?: ReactNode;\n onLoad?: () => void;\n onError?: (error: Error) => void;\n onDownload?: () => void;\n /** Consumer-owned actions such as retry, share or remove. */\n actions?: ReactNode;\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 actions,\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 [asyncSource, setAsyncSource] = useState<FileViewerSource>();\n const [sourceLoading, setSourceLoading] = useState(false);\n const onLoadRef = useRef(onLoad);\n const onErrorRef = useRef(onError);\n const isAsyncSource = Boolean(\n source &&\n typeof source === \"object\" &&\n \"then\" in source &&\n typeof source.then === \"function\",\n );\n\n useEffect(() => {\n if (!isAsyncSource) {\n setAsyncSource(undefined);\n setSourceLoading(false);\n return;\n }\n\n let active = true;\n setSourceLoading(true);\n setReadError(null);\n\n Promise.resolve(source as Promise<FileViewerSource | null | undefined>)\n .then((nextSource) => {\n if (!active) return;\n setAsyncSource(nextSource ?? undefined);\n setSourceLoading(false);\n })\n .catch((cause: unknown) => {\n if (!active) return;\n const nextError = toError(cause);\n setReadError(nextError);\n setSourceLoading(false);\n onErrorRef.current?.(nextError);\n });\n\n return () => {\n active = false;\n };\n }, [isAsyncSource, source]);\n\n const resolvedSource: FileViewerSource | undefined = isAsyncSource\n ? asyncSource\n : (source as FileViewerSource | undefined);\n const resolved = typeof resolvedSource === \"object\" && resolvedSource !== null && !(resolvedSource instanceof Blob) ? resolvedSource : undefined;\n const blob = resolvedSource instanceof Blob ? resolvedSource : resolved?.blob;\n const url = typeof resolvedSource === \"string\" ? resolvedSource : 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: string) => {\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 || sourceLoading) {\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 || actions) && (\n <div className=\"flex flex-wrap justify-end gap-2\">\n {actions}\n {download}\n </div>\n )}\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","useState","jsx","jsxs","useRef","useState","rejectionMessage","classNames","jsx","jsxs","classNames","jsx","jsxs","classNames","classNames","useEffect","useRef","useState","jsx","jsxs","useEffect","useId","useRef","useState","classNames","jsx","jsxs"]}
|
|
@@ -156,6 +156,10 @@ import { jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
|
156
156
|
function InteractiveDonutChart({
|
|
157
157
|
options = {},
|
|
158
158
|
series,
|
|
159
|
+
loading = false,
|
|
160
|
+
loadingMessage = "Carregando gr\xE1fico\u2026",
|
|
161
|
+
error,
|
|
162
|
+
emptyMessage = "Nenhum dado dispon\xEDvel.",
|
|
159
163
|
colors,
|
|
160
164
|
mutedColors,
|
|
161
165
|
valueFormatter = (value) => new Intl.NumberFormat("pt-BR", {
|
|
@@ -394,7 +398,7 @@ function InteractiveDonutChart({
|
|
|
394
398
|
onKeyDown: handleKeyDown,
|
|
395
399
|
className: `chart-keyboard-focus-ring relative min-w-0 rounded-sm ${className ?? ""}`.trim(),
|
|
396
400
|
children: [
|
|
397
|
-
/* @__PURE__ */ jsx2(
|
|
401
|
+
loading ? /* @__PURE__ */ jsx2("div", { role: "status", "aria-busy": "true", "aria-live": "polite", className: "flex min-h-32 items-center justify-center text-sm text-content-secondary", children: loadingMessage }) : error ? /* @__PURE__ */ jsx2("div", { role: "alert", className: "flex min-h-32 items-center justify-center text-sm text-field-assistive-error", children: error }) : series.length === 0 ? /* @__PURE__ */ jsx2("div", { role: "status", className: "flex min-h-32 items-center justify-center text-sm text-content-secondary", children: emptyMessage }) : /* @__PURE__ */ jsx2(
|
|
398
402
|
LazyApexChart,
|
|
399
403
|
{
|
|
400
404
|
...rest,
|
|
@@ -437,6 +441,10 @@ import { jsx as jsx3 } from "react/jsx-runtime";
|
|
|
437
441
|
function TimeSeriesChart({
|
|
438
442
|
options,
|
|
439
443
|
ariaLabel,
|
|
444
|
+
loading = false,
|
|
445
|
+
loadingMessage = "Carregando gr\xE1fico\u2026",
|
|
446
|
+
error,
|
|
447
|
+
emptyMessage = "Nenhum dado dispon\xEDvel.",
|
|
440
448
|
className,
|
|
441
449
|
chartClassName,
|
|
442
450
|
responsiveHeight = false,
|
|
@@ -498,6 +506,11 @@ function TimeSeriesChart({
|
|
|
498
506
|
}, [chartProps.height, responsiveHeight]);
|
|
499
507
|
const renderedHeight = responsiveHeight && measuredHeight ? measuredHeight : chartProps.height;
|
|
500
508
|
const renderedWidth = responsiveHeight && measuredWidth ? measuredWidth : chartProps.width;
|
|
509
|
+
const hasSeriesData = Array.isArray(chartProps.series) && chartProps.series.some((entry) => {
|
|
510
|
+
if (!entry || typeof entry !== "object") return false;
|
|
511
|
+
const data = entry.data;
|
|
512
|
+
return Array.isArray(data) ? data.length > 0 : data !== void 0;
|
|
513
|
+
});
|
|
501
514
|
const xAxis = options.xaxis;
|
|
502
515
|
const xAxisCategories = Array.isArray(xAxis?.categories) ? xAxis.categories : [];
|
|
503
516
|
const availableWidth = typeof renderedWidth === "number" ? renderedWidth : 720;
|
|
@@ -656,26 +669,17 @@ function TimeSeriesChart({
|
|
|
656
669
|
}
|
|
657
670
|
}
|
|
658
671
|
};
|
|
659
|
-
return /* @__PURE__ */ jsx3(
|
|
660
|
-
|
|
672
|
+
return /* @__PURE__ */ jsx3("div", { ref: containerRef, role: "img", "aria-label": ariaLabel, className, children: loading ? /* @__PURE__ */ jsx3("div", { role: "status", "aria-busy": "true", "aria-live": "polite", className: "flex min-h-32 items-center justify-center text-sm text-content-secondary", children: loadingMessage }) : error ? /* @__PURE__ */ jsx3("div", { role: "alert", className: "flex min-h-32 items-center justify-center text-sm text-field-assistive-error", children: error }) : !hasSeriesData ? /* @__PURE__ */ jsx3("div", { role: "status", className: "flex min-h-32 items-center justify-center text-sm text-content-secondary", children: emptyMessage }) : /* @__PURE__ */ jsx3(
|
|
673
|
+
LazyApexChart,
|
|
661
674
|
{
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
className: chartClassName,
|
|
671
|
-
width: renderedWidth,
|
|
672
|
-
height: renderedHeight,
|
|
673
|
-
options: sharedOptions
|
|
674
|
-
},
|
|
675
|
-
renderKey
|
|
676
|
-
)
|
|
677
|
-
}
|
|
678
|
-
);
|
|
675
|
+
...chartProps,
|
|
676
|
+
className: chartClassName,
|
|
677
|
+
width: renderedWidth,
|
|
678
|
+
height: renderedHeight,
|
|
679
|
+
options: sharedOptions
|
|
680
|
+
},
|
|
681
|
+
renderKey
|
|
682
|
+
) });
|
|
679
683
|
}
|
|
680
684
|
|
|
681
685
|
// src/components/chart/TimeRangeSelector.tsx
|
|
@@ -755,4 +759,4 @@ export {
|
|
|
755
759
|
normalizeTimeSeriesTooltipColor,
|
|
756
760
|
buildTimeSeriesTooltip
|
|
757
761
|
};
|
|
758
|
-
//# sourceMappingURL=chunk-
|
|
762
|
+
//# sourceMappingURL=chunk-HKCVDOGK.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/chart/LazyApexChart.tsx","../src/utils/chart-theme.ts","../src/components/chart/interactive-donut-utils.ts","../src/hooks/useHighContrastPreference.ts","../src/components/chart/InteractiveDonutChart.tsx","../src/components/chart/TimeSeriesChart.tsx","../src/components/chart/TimeRangeSelector.tsx","../src/components/chart/time-series-chart-utils.ts"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useState } from \"react\";\nimport type { Props as ReactApexChartProps } from \"react-apexcharts\";\n\nexport type Props = ReactApexChartProps;\n\nexport default function LazyApexChart(props: Props) {\n const [ApexChart, setApexChart] = useState<\n React.ComponentType<Props> | null\n >(null);\n\n useEffect(() => {\n let active = true;\n import(\"react-apexcharts\").then(({ default: component }) => {\n if (active) setApexChart(() => component);\n });\n return () => {\n active = false;\n };\n }, []);\n\n if (!ApexChart) {\n return (\n <div\n className=\"flex min-h-40 items-center justify-center text-sm text-content-muted\"\n role=\"status\"\n aria-label=\"Carregando grafico\"\n >\n Carregando grafico...\n </div>\n );\n }\n\n return <ApexChart {...props} />;\n}\n","const SERIES_FALLBACKS = [\n \"#0f62c1\",\n \"#16d39a\",\n \"#feb019\",\n \"#ff4560\",\n \"#775dd0\",\n \"#00b8d9\",\n \"#ff8f00\",\n \"#26a69a\",\n \"#ec407a\",\n \"#7cb342\",\n \"#5c6bc0\",\n \"#8d6e63\",\n] as const;\n\nconst DONUT_SERIES_FALLBACKS = [\n \"#66d288\",\n \"#3182f6\",\n \"#ffc25c\",\n \"#7c58e8\",\n \"#ff6b6b\",\n ...SERIES_FALLBACKS.slice(5),\n] as const;\n\nconst MUTED_SERIES_FALLBACKS = [\n \"#c5cad0\",\n \"#d9dde1\",\n \"#eceef0\",\n \"#aeb5bd\",\n] as const;\n\nconst readColorToken = (token: string, fallback: string): string => {\n if (typeof window === \"undefined\") return fallback;\n const value = window\n .getComputedStyle(document.body ?? document.documentElement)\n .getPropertyValue(token)\n .trim();\n return value ? `rgb(${value})` : fallback;\n};\n\nexport const getChartTheme = () => ({\n series: SERIES_FALLBACKS.map((fallback, index) =>\n readColorToken(`--chart-${index + 1}`, fallback),\n ),\n donutSeries: DONUT_SERIES_FALLBACKS.map((fallback, index) =>\n readColorToken(`--chart-donut-${index + 1}`, fallback),\n ),\n mutedSeries: MUTED_SERIES_FALLBACKS.map((fallback, index) =>\n readColorToken(`--chart-muted-${index + 1}`, fallback),\n ),\n balance: readColorToken(\"--chart-balance\", \"#00a76f\"),\n invested: readColorToken(\"--chart-invested\", \"#1e90ff\"),\n grid: readColorToken(\"--chart-grid\", \"#e5e7eb\"),\n axis: readColorToken(\"--chart-axis\", \"#6b7280\"),\n axisBorder: readColorToken(\"--chart-axis-border\", \"#d1d5db\"),\n tooltipText: readColorToken(\"--chart-tooltip-text\", \"#111827\"),\n neutralLine: readColorToken(\"--chart-line-neutral\", \"#181818\"),\n surface: readColorToken(\"--surface-card\", \"#ffffff\"),\n});\n\nexport const getChartSeriesRecord = (\n backendColors?: Record<number, string>,\n count = 5,\n): Record<number, string> => {\n const { series } = getChartTheme();\n const fallbackColors = Object.fromEntries(\n Array.from({ length: count }, (_, index) => [index + 1, series[index]]),\n );\n\n const isDarkSchemeActive =\n typeof document !== \"undefined\" &&\n document.documentElement.dataset.colorScheme === \"dark\";\n\n const highContrastActive =\n typeof document !== \"undefined\" &&\n document.documentElement.dataset.contrast === \"high\";\n\n return highContrastActive || isDarkSchemeActive\n ? fallbackColors\n : { ...fallbackColors, ...backendColors };\n};\n","export function resolveInteractiveDonutColors({\n count,\n colors,\n mutedColors,\n selectedIndex,\n}: {\n count: number;\n colors: string[];\n mutedColors: string[];\n selectedIndex: number | null;\n}) {\n if (colors.length === 0 || mutedColors.length === 0) return [];\n\n return Array.from({ length: count }, (_, index) => {\n const color = colors[index % colors.length];\n\n if (selectedIndex === null || index === selectedIndex) return color;\n\n return mutedColors[index % mutedColors.length];\n });\n}\n\nexport function resolveRelativeDonutSelection({\n currentIndex,\n direction,\n count,\n}: {\n currentIndex: number | null;\n direction: -1 | 1;\n count: number;\n}) {\n if (count <= 0) return null;\n if (currentIndex === null) return direction > 0 ? 0 : count - 1;\n\n return (currentIndex + direction + count) % count;\n}\n\nconst TOOLTIP_ENTITIES: Record<string, string> = {\n \"&\": \"&\",\n \"<\": \"<\",\n \">\": \">\",\n '\"': \""\",\n \"'\": \"'\",\n};\n\nexport function escapeDonutTooltipText(value: unknown) {\n return String(value ?? \"\").replace(\n /[&<>\"']/g,\n (character) => TOOLTIP_ENTITIES[character],\n );\n}\n","\"use client\";\n\nimport { useEffect, useState } from \"react\";\n\nexport function useHighContrastPreference() {\n const [highContrast, setHighContrast] = useState(false);\n\n useEffect(() => {\n const root = document.documentElement;\n const read = () => setHighContrast(root.dataset.contrast === \"high\");\n read();\n\n const observer = new MutationObserver(read);\n observer.observe(root, {\n attributes: true,\n attributeFilter: [\"data-contrast\"],\n });\n return () => observer.disconnect();\n }, []);\n\n return highContrast;\n}\n","\"use client\";\n\nimport { useHighContrastPreference } from \"../../hooks/useHighContrastPreference\";\nimport { getChartTheme } from \"../../utils/chart-theme\";\nimport {\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n type KeyboardEvent,\n type ReactNode,\n} from \"react\";\nimport Chart, { type Props as DonutChartProps } from \"./LazyApexChart\";\nimport {\n escapeDonutTooltipText,\n resolveInteractiveDonutColors,\n resolveRelativeDonutSelection,\n} from \"./interactive-donut-utils\";\n\nexport type InteractiveDonutOptions = NonNullable<DonutChartProps[\"options\"]>;\n\nexport type InteractiveDonutProps = Omit<\n DonutChartProps,\n \"options\" | \"series\" | \"type\"\n> & {\n options?: InteractiveDonutOptions;\n series: number[];\n loading?: boolean;\n loadingMessage?: ReactNode;\n error?: ReactNode;\n emptyMessage?: ReactNode;\n colors?: string[];\n mutedColors?: string[];\n valueFormatter?: (value: number) => string;\n ariaLabel?: string;\n className?: string;\n chartClassName?: string;\n responsiveHeight?: boolean;\n highContrastOverride?: boolean;\n};\n\nexport default function InteractiveDonutChart({\n options = {},\n series,\n loading = false,\n loadingMessage = \"Carregando gráfico…\",\n error,\n emptyMessage = \"Nenhum dado disponível.\",\n colors,\n mutedColors,\n valueFormatter = (value) =>\n new Intl.NumberFormat(\"pt-BR\", {\n style: \"currency\",\n currency: \"BRL\",\n }).format(value),\n ariaLabel = \"Gráfico de distribuição\",\n className,\n chartClassName,\n responsiveHeight = false,\n highContrastOverride,\n ...rest\n}: InteractiveDonutProps) {\n const storedHighContrast = useHighContrastPreference();\n const highContrast = highContrastOverride ?? storedHighContrast;\n const [selectedIndex, setSelectedIndex] = useState<number | null>(null);\n const [legendSelectedIndex, setLegendSelectedIndex] = useState<number | null>(\n null,\n );\n const containerRef = useRef<HTMLDivElement>(null);\n const instructionsId = useId();\n const chartTheme = getChartTheme();\n const baseColors =\n !highContrast && colors?.length ? colors : chartTheme.donutSeries;\n const neutralColors = !highContrast && mutedColors?.length\n ? mutedColors\n : chartTheme.mutedSeries;\n const labels = useMemo(() => options.labels ?? [], [options.labels]);\n\n useEffect(() => {\n setSelectedIndex((current) =>\n current !== null && current >= series.length ? null : current,\n );\n setLegendSelectedIndex((current) =>\n current !== null && current >= series.length ? null : current,\n );\n }, [series.length]);\n\n useEffect(() => {\n const resetOnOutsideClick = (event: PointerEvent) => {\n if (containerRef.current?.contains(event.target as Node)) return;\n\n setSelectedIndex(null);\n setLegendSelectedIndex(null);\n };\n\n document.addEventListener(\"pointerdown\", resetOnOutsideClick);\n return () =>\n document.removeEventListener(\"pointerdown\", resetOnOutsideClick);\n }, []);\n\n const [pieCircle, setPieCircle] = useState<{\n cx: number;\n cy: number;\n diameter: number;\n } | null>(null);\n const [measuredChartHeight, setMeasuredChartHeight] = useState<number | null>(\n null,\n );\n\n useEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n\n const measure = () => {\n const containerRect = container.getBoundingClientRect();\n\n if (responsiveHeight) {\n const fallbackHeight =\n typeof rest.height === \"number\" ? rest.height : 0;\n const nextHeight = Math.max(\n fallbackHeight,\n Math.floor(containerRect.height),\n );\n\n if (nextHeight > 0) {\n setMeasuredChartHeight((current) =>\n current === nextHeight ? current : nextHeight,\n );\n }\n }\n\n const areas = container.querySelectorAll<SVGPathElement>(\n \".apexcharts-pie-area\",\n );\n if (!areas.length) return;\n\n let minX = Infinity;\n let minY = Infinity;\n let maxX = -Infinity;\n let maxY = -Infinity;\n\n areas.forEach((area) => {\n const rect = area.getBoundingClientRect();\n minX = Math.min(minX, rect.left);\n minY = Math.min(minY, rect.top);\n maxX = Math.max(maxX, rect.right);\n maxY = Math.max(maxY, rect.bottom);\n });\n\n setPieCircle({\n cx: (minX + maxX) / 2 - containerRect.left,\n cy: (minY + maxY) / 2 - containerRect.top,\n diameter: Math.min(maxX - minX, maxY - minY),\n });\n };\n\n measure();\n\n const resizeObserver = new ResizeObserver(measure);\n resizeObserver.observe(container);\n\n const mutationObserver = new MutationObserver(measure);\n mutationObserver.observe(container, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: [\"d\"],\n });\n\n return () => {\n resizeObserver.disconnect();\n mutationObserver.disconnect();\n };\n }, [responsiveHeight, rest.height, series.length]);\n\n const donutSizeRatio = useMemo(() => {\n const size = options.plotOptions?.pie?.donut?.size ?? \"65%\";\n const parsed = parseFloat(String(size));\n return Number.isFinite(parsed) ? parsed / 100 : 0.65;\n }, [options.plotOptions?.pie?.donut?.size]);\n\n const displayColors = resolveInteractiveDonutColors({\n count: series.length,\n colors: baseColors,\n mutedColors: neutralColors,\n selectedIndex,\n });\n\n const legendValue =\n legendSelectedIndex !== null\n ? {\n label:\n labels[legendSelectedIndex] ??\n `Categoria ${legendSelectedIndex + 1}`,\n value: Number(series[legendSelectedIndex] ?? 0),\n }\n : null;\n\n const interactiveOptions = useMemo<InteractiveDonutOptions>(() => {\n const originalSelection = options.chart?.events?.dataPointSelection;\n const originalLegendClick = options.chart?.events?.legendClick;\n\n return {\n ...options,\n colors: displayColors,\n fill: highContrast\n ? {\n type: \"pattern\",\n pattern: {\n style: [\n \"verticalLines\",\n \"horizontalLines\",\n \"slantedLines\",\n \"squares\",\n \"circles\",\n ],\n width: 6,\n height: 6,\n strokeWidth: 2,\n },\n }\n : {\n ...options.fill,\n type: options.fill?.type ?? \"solid\",\n opacity: options.fill?.opacity ?? 1,\n },\n stroke: highContrast\n ? { ...options.stroke, colors: [\"#ffffff\"], width: 2 }\n : options.stroke,\n chart: {\n ...options.chart,\n events: {\n ...options.chart?.events,\n dataPointSelection(event, chart, config) {\n originalSelection?.(event, chart, config);\n const nextIndex = Number(config?.dataPointIndex);\n\n if (!Number.isInteger(nextIndex) || nextIndex < 0) return;\n\n setSelectedIndex((current) =>\n current === nextIndex ? null : nextIndex,\n );\n },\n legendClick(chartContext, seriesIndex, config) {\n originalLegendClick?.(chartContext, seriesIndex, config);\n\n if (typeof seriesIndex !== \"number\" || seriesIndex < 0) return;\n\n setLegendSelectedIndex((current) =>\n current === seriesIndex ? null : seriesIndex,\n );\n },\n },\n },\n legend: {\n ...options.legend,\n labels: {\n ...options.legend?.labels,\n colors: chartTheme.axis,\n },\n onItemClick: {\n ...options.legend?.onItemClick,\n toggleDataSeries: false,\n },\n },\n states: {\n ...options.states,\n hover: {\n ...options.states?.hover,\n filter: { type: \"none\" },\n },\n active: {\n ...options.states?.active,\n allowMultipleDataPointsSelection: false,\n filter: { type: \"none\" },\n },\n },\n tooltip: {\n ...options.tooltip,\n enabled: true,\n followCursor: true,\n custom({ series: tooltipSeries, seriesIndex }) {\n const value = Number(tooltipSeries?.[seriesIndex] ?? 0);\n const label = escapeDonutTooltipText(\n labels[seriesIndex] ?? `Categoria ${seriesIndex + 1}`,\n );\n const formattedValue = escapeDonutTooltipText(valueFormatter(value));\n\n return `<div class=\"donut-chart-tooltip\"><span class=\"donut-chart-tooltip-label\">${label}</span><strong class=\"donut-chart-tooltip-value\">${formattedValue}</strong></div>`;\n },\n },\n };\n }, [\n chartTheme.axis,\n displayColors,\n highContrast,\n labels,\n options,\n valueFormatter,\n ]);\n\n const selectedLabel =\n selectedIndex === null\n ? \"Nenhuma categoria selecionada\"\n : `${labels[selectedIndex] ?? `Categoria ${selectedIndex + 1}`}: ${valueFormatter(\n Number(series[selectedIndex] ?? 0),\n )}`;\n\n const legendValueLabel =\n legendSelectedIndex === null\n ? \"\"\n : `Valor em destaque: ${\n labels[legendSelectedIndex] ?? `Categoria ${legendSelectedIndex + 1}`\n }: ${valueFormatter(Number(series[legendSelectedIndex] ?? 0))}`;\n\n const handleKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {\n if (\n [\"ArrowRight\", \"ArrowDown\", \"ArrowLeft\", \"ArrowUp\"].includes(event.key)\n ) {\n event.preventDefault();\n const direction =\n event.key === \"ArrowRight\" || event.key === \"ArrowDown\" ? 1 : -1;\n setSelectedIndex((current) =>\n resolveRelativeDonutSelection({\n currentIndex: current,\n direction,\n count: series.length,\n }),\n );\n }\n\n if (event.key === \"Escape\") {\n setSelectedIndex(null);\n setLegendSelectedIndex(null);\n }\n };\n\n return (\n <div\n ref={containerRef}\n role=\"group\"\n tabIndex={0}\n aria-label={ariaLabel}\n aria-describedby={instructionsId}\n onKeyDown={handleKeyDown}\n className={`chart-keyboard-focus-ring relative min-w-0 rounded-sm ${className ?? \"\"}`.trim()}\n >\n {loading ? (\n <div role=\"status\" aria-busy=\"true\" aria-live=\"polite\" className=\"flex min-h-32 items-center justify-center text-sm text-content-secondary\">\n {loadingMessage}\n </div>\n ) : error ? (\n <div role=\"alert\" className=\"flex min-h-32 items-center justify-center text-sm text-field-assistive-error\">\n {error}\n </div>\n ) : series.length === 0 ? (\n <div role=\"status\" className=\"flex min-h-32 items-center justify-center text-sm text-content-secondary\">\n {emptyMessage}\n </div>\n ) : (\n <Chart\n key={highContrast ? \"donut-high-contrast\" : \"donut-standard\"}\n {...rest}\n className={chartClassName}\n height={\n responsiveHeight && measuredChartHeight\n ? measuredChartHeight\n : rest.height\n }\n options={interactiveOptions}\n series={series}\n type=\"donut\"\n />\n )}\n {legendValue && pieCircle && (\n <div\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute flex flex-col items-center justify-center text-center\"\n style={{\n left: pieCircle.cx,\n top: pieCircle.cy,\n width: pieCircle.diameter * donutSizeRatio * 0.94,\n transform: \"translate(-50%, -50%)\",\n }}\n >\n <span className=\"w-full truncate text-xs leading-tight text-content-secondary\">\n {legendValue.label}\n </span>\n <span className=\"w-full break-words text-md font-bold leading-tight text-content-primary\">\n {valueFormatter(legendValue.value)}\n </span>\n </div>\n )}\n <span className=\"sr-only\" aria-live=\"polite\">\n {selectedLabel}\n </span>\n <span className=\"sr-only\" aria-live=\"polite\">\n {legendValueLabel}\n </span>\n <span id={instructionsId} className=\"sr-only\">\n Use as setas para navegar pelas categorias e Escape para limpar a\n seleção.\n </span>\n </div>\n );\n}\n","\"use client\";\n\nimport { useHighContrastPreference } from \"../../hooks/useHighContrastPreference\";\nimport { getChartTheme } from \"../../utils/chart-theme\";\nimport { useEffect, useRef, useState, type ReactNode } from \"react\";\nimport Chart, { type Props as ApexChartProps } from \"./LazyApexChart\";\n\nexport type TimeSeriesChartOptions = NonNullable<ApexChartProps[\"options\"]>;\n\nexport type TimeSeriesChartProps = Omit<ApexChartProps, \"options\"> & {\n options: TimeSeriesChartOptions;\n ariaLabel: string;\n loading?: boolean;\n loadingMessage?: ReactNode;\n error?: ReactNode;\n emptyMessage?: ReactNode;\n className?: string;\n chartClassName?: string;\n responsiveHeight?: boolean;\n highContrastOverride?: boolean;\n};\n\nexport default function TimeSeriesChart({\n options,\n ariaLabel,\n loading = false,\n loadingMessage = \"Carregando gráfico…\",\n error,\n emptyMessage = \"Nenhum dado disponível.\",\n className,\n chartClassName,\n responsiveHeight = false,\n highContrastOverride,\n ...chartProps\n}: TimeSeriesChartProps) {\n const storedHighContrast = useHighContrastPreference();\n const highContrast = highContrastOverride ?? storedHighContrast;\n const theme = getChartTheme();\n const containerRef = useRef<HTMLDivElement>(null);\n const [measuredHeight, setMeasuredHeight] = useState<number | null>(null);\n const [measuredWidth, setMeasuredWidth] = useState<number | null>(null);\n const themeKey = [\n highContrast ? \"high-contrast\" : \"standard\",\n theme.axis,\n theme.axisBorder,\n theme.grid,\n theme.surface,\n ...theme.series,\n ].join(\"|\");\n\n useEffect(() => {\n if (!responsiveHeight) {\n setMeasuredHeight(null);\n setMeasuredWidth(null);\n return;\n }\n\n const container = containerRef.current;\n if (!container || typeof ResizeObserver === \"undefined\") return;\n\n const fallbackHeight =\n typeof chartProps.height === \"number\" ? chartProps.height : 0;\n let frame = 0;\n const measure = () => {\n cancelAnimationFrame(frame);\n frame = requestAnimationFrame(() => {\n const bounds = container.getBoundingClientRect();\n const nextWidth = Math.floor(bounds.width);\n const nextHeight = Math.max(\n fallbackHeight,\n Math.floor(bounds.height),\n );\n\n if (nextWidth > 0) {\n setMeasuredWidth((current) =>\n current === nextWidth ? current : nextWidth,\n );\n }\n\n if (nextHeight > 0) {\n setMeasuredHeight((current) =>\n current === nextHeight ? current : nextHeight,\n );\n }\n });\n };\n\n measure();\n const resizeObserver = new ResizeObserver(measure);\n resizeObserver.observe(container);\n return () => {\n cancelAnimationFrame(frame);\n resizeObserver.disconnect();\n };\n }, [chartProps.height, responsiveHeight]);\n\n const renderedHeight =\n responsiveHeight && measuredHeight ? measuredHeight : chartProps.height;\n const renderedWidth =\n responsiveHeight && measuredWidth ? measuredWidth : chartProps.width;\n const hasSeriesData =\n Array.isArray(chartProps.series) &&\n chartProps.series.some((entry) => {\n if (!entry || typeof entry !== \"object\") return false;\n const data = (entry as { data?: unknown }).data;\n return Array.isArray(data) ? data.length > 0 : data !== undefined;\n });\n const xAxis = options.xaxis;\n const xAxisCategories = Array.isArray(xAxis?.categories)\n ? xAxis.categories\n : [];\n const availableWidth =\n typeof renderedWidth === \"number\" ? renderedWidth : 720;\n const maxVisibleXAxisLabels = Math.max(\n 4,\n Math.min(12, Math.floor(availableWidth / 88)),\n );\n const xAxisLabelStep = Math.max(\n 1,\n Math.ceil(xAxisCategories.length / maxVisibleXAxisLabels),\n );\n const hasDenseXAxis = xAxisCategories.length > maxVisibleXAxisLabels;\n const xAxisCategoriesKey = JSON.stringify(xAxisCategories);\n const responsiveXAxisFormatter = xAxisCategories.length\n ? (\n value: string | number,\n _timestamp?: number,\n opts?: { dataPointIndex?: number },\n ) => {\n const fallbackIndex = xAxisCategories.findIndex(\n (category) => String(category) === String(value),\n );\n const index =\n opts?.dataPointIndex ?? (fallbackIndex >= 0 ? fallbackIndex : 0);\n const isLast = index === xAxisCategories.length - 1;\n\n return index % xAxisLabelStep === 0 || isLast\n ? String(xAxisCategories[index] ?? value)\n : \"\";\n }\n : xAxis?.labels?.formatter;\n const renderKey = [\n themeKey,\n renderedWidth ?? \"auto-width\",\n renderedHeight ?? \"auto-height\",\n xAxisCategoriesKey,\n ].join(\"|\");\n\n const yAxis = Array.isArray(options.yaxis)\n ? options.yaxis.map((axis) => ({\n ...axis,\n labels: {\n ...axis.labels,\n show: true,\n style: {\n fontSize: \"11px\",\n fontWeight: 500,\n ...axis.labels?.style,\n colors: theme.axis,\n },\n },\n }))\n : {\n ...options.yaxis,\n labels: {\n ...options.yaxis?.labels,\n show: true,\n style: {\n fontSize: \"11px\",\n fontWeight: 500,\n ...options.yaxis?.labels?.style,\n colors: theme.axis,\n },\n },\n };\n\n const sharedOptions: TimeSeriesChartOptions = {\n ...options,\n colors: highContrast ? [...theme.series] : options.colors,\n chart: {\n toolbar: { show: false },\n zoom: { enabled: false },\n parentHeightOffset: 0,\n redrawOnParentResize: true,\n redrawOnWindowResize: true,\n ...options.chart,\n foreColor: theme.axis,\n },\n dataLabels: {\n enabled: false,\n ...options.dataLabels,\n },\n grid: {\n show: true,\n borderColor: theme.grid,\n strokeDashArray: 0,\n ...options.grid,\n xaxis: {\n lines: {\n ...options.grid?.xaxis?.lines,\n show: hasDenseXAxis\n ? false\n : (options.grid?.xaxis?.lines?.show ?? true),\n },\n },\n yaxis: {\n lines: { show: true, ...options.grid?.yaxis?.lines },\n },\n padding: {\n top: 0,\n right: 8,\n bottom: 8,\n left: 8,\n ...options.grid?.padding,\n },\n },\n stroke: {\n width: 2,\n curve: \"straight\",\n ...options.stroke,\n colors: highContrast ? [...theme.series] : options.stroke?.colors,\n dashArray: highContrast\n ? [0, 6, 2, 8, 4, 10, 1, 7, 3, 9, 5, 11]\n : (options.stroke?.dashArray ?? 0),\n },\n markers: {\n strokeWidth: 1,\n strokeColors: [theme.surface],\n ...options.markers,\n size: highContrast ? 4 : (options.markers?.size ?? 3),\n hover: { size: 4, ...options.markers?.hover },\n },\n annotations: highContrast\n ? {\n ...options.annotations,\n xaxis: options.annotations?.xaxis?.map((annotation, index) => ({\n ...annotation,\n fillColor: theme.series[index % theme.series.length],\n opacity: 0.28,\n })),\n }\n : options.annotations,\n xaxis: {\n tooltip: { enabled: false },\n axisBorder: { color: theme.axisBorder },\n ...xAxis,\n tickAmount: xAxisCategories.length ? undefined : xAxis?.tickAmount,\n axisTicks: {\n color: theme.axisBorder,\n ...xAxis?.axisTicks,\n show: hasDenseXAxis ? false : (xAxis?.axisTicks?.show ?? true),\n },\n labels: {\n ...xAxis?.labels,\n show: true,\n formatter: responsiveXAxisFormatter,\n style: {\n fontSize: \"11px\",\n fontWeight: 500,\n ...xAxis?.labels?.style,\n colors: theme.axis,\n },\n },\n },\n yaxis: yAxis,\n tooltip: {\n shared: true,\n intersect: false,\n followCursor: true,\n ...options.tooltip,\n },\n legend: {\n ...options.legend,\n labels: {\n ...options.legend?.labels,\n colors: theme.axis,\n },\n },\n noData: {\n text: \"Nenhum dado disponível no período selecionado\",\n ...options.noData,\n style: {\n fontSize: \"15px\",\n ...options.noData?.style,\n color: theme.axis,\n },\n },\n };\n\n return (\n <div ref={containerRef} role=\"img\" aria-label={ariaLabel} className={className}>\n {loading ? (\n <div role=\"status\" aria-busy=\"true\" aria-live=\"polite\" className=\"flex min-h-32 items-center justify-center text-sm text-content-secondary\">\n {loadingMessage}\n </div>\n ) : error ? (\n <div role=\"alert\" className=\"flex min-h-32 items-center justify-center text-sm text-field-assistive-error\">\n {error}\n </div>\n ) : !hasSeriesData ? (\n <div role=\"status\" className=\"flex min-h-32 items-center justify-center text-sm text-content-secondary\">\n {emptyMessage}\n </div>\n ) : (\n <Chart\n key={renderKey}\n {...chartProps}\n className={chartClassName}\n width={renderedWidth}\n height={renderedHeight}\n options={sharedOptions}\n />\n )}\n </div>\n );\n}\n","\"use client\";\n\nexport type TimeRangeSelectorProps<T extends string | number> = {\n options: readonly T[];\n selected: T;\n onSelect: (range: T) => void;\n ariaLabel?: string;\n className?: string;\n};\n\nexport default function TimeRangeSelector<T extends string | number>({\n options,\n selected,\n onSelect,\n ariaLabel = \"Período do gráfico\",\n className,\n}: TimeRangeSelectorProps<T>) {\n return (\n <div\n role=\"group\"\n aria-label={ariaLabel}\n className={`flex min-w-0 flex-wrap justify-start gap-1.5 ${className ?? \"\"}`.trim()}\n >\n {options.map((range) => {\n const isSelected = selected === range;\n\n return (\n <button\n key={range}\n type=\"button\"\n aria-pressed={isSelected}\n onClick={() => onSelect(range)}\n className={`shrink-0 whitespace-nowrap rounded-sm border px-2.5 py-1 text-sm font-semibold transition-colors ${\n isSelected\n ? \"border-selection-border bg-selection-background text-selection-content\"\n : \"border-primary-1 text-primary-1 hover:bg-primary-5\"\n }`}\n >\n {range}\n </button>\n );\n })}\n </div>\n );\n}\n","const TOOLTIP_ENTITIES: Record<string, string> = {\n \"&\": \"&\",\n \"<\": \"<\",\n \">\": \">\",\n '\"': \""\",\n \"'\": \"'\",\n};\n\nexport function escapeTimeSeriesTooltipText(value: unknown) {\n return String(value ?? \"\").replace(\n /[&<>\"']/g,\n (character) => TOOLTIP_ENTITIES[character],\n );\n}\n\nconst SAFE_TOOLTIP_COLOR =\n /^(?:#[\\da-f]{3,8}|rgba?\\([\\d\\s.,%]+\\)|hsla?\\([\\d\\s.,%]+\\)|var\\(--[\\w-]+\\)|[a-z]+)$/i;\n\nexport function normalizeTimeSeriesTooltipColor(value?: string) {\n const color = String(value ?? \"\").trim();\n return SAFE_TOOLTIP_COLOR.test(color) ? color : \"currentColor\";\n}\n\nexport type TimeSeriesTooltipRow = {\n label: string;\n value: string;\n color?: string;\n};\n\nexport function buildTimeSeriesTooltip({\n reference,\n rows,\n}: {\n reference: string;\n rows: TimeSeriesTooltipRow[];\n}) {\n const content = rows\n .map(({ label, value, color }) => {\n const marker = color\n ? `<span class=\"time-series-chart-tooltip-marker\" style=\"background-color:${normalizeTimeSeriesTooltipColor(color)}\"></span>`\n : \"\";\n\n return `<div class=\"time-series-chart-tooltip-row\"><span class=\"time-series-chart-tooltip-name\">${marker}${escapeTimeSeriesTooltipText(label)}</span><strong>${escapeTimeSeriesTooltipText(value)}</strong></div>`;\n })\n .join(\"\");\n\n return `<div class=\"time-series-chart-tooltip\"><div class=\"time-series-chart-tooltip-reference\">${escapeTimeSeriesTooltipText(reference)}</div>${content}</div>`;\n}\n"],"mappings":"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","names":["useEffect","useState","useEffect","useState","jsx","useState","useEffect","useEffect","useRef","useState","jsx","useRef","useState","useEffect","jsx","TOOLTIP_ENTITIES"]}
|