@grazziotin/react-components 1.0.3 → 1.0.4

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.
Files changed (74) hide show
  1. package/README.md +34 -24
  2. package/dist/150.index.js +1 -0
  3. package/dist/815.index.js +1 -0
  4. package/dist/908.index.js +2 -0
  5. package/dist/908.index.js.LICENSE.txt +9 -0
  6. package/dist/988.index.js +1 -0
  7. package/dist/assets/fonts/Montserrat-Black.ttf +0 -0
  8. package/dist/assets/fonts/Montserrat-BlackItalic.ttf +0 -0
  9. package/dist/assets/fonts/Montserrat-Bold.ttf +0 -0
  10. package/dist/assets/fonts/Montserrat-BoldItalic.ttf +0 -0
  11. package/dist/assets/fonts/Montserrat-ExtraBold.ttf +0 -0
  12. package/dist/assets/fonts/Montserrat-ExtraBoldItalic.ttf +0 -0
  13. package/dist/assets/fonts/Montserrat-ExtraLight.ttf +0 -0
  14. package/dist/assets/fonts/Montserrat-ExtraLightItalic.ttf +0 -0
  15. package/dist/assets/fonts/Montserrat-Italic.ttf +0 -0
  16. package/dist/assets/fonts/Montserrat-Light.ttf +0 -0
  17. package/dist/assets/fonts/Montserrat-LightItalic.ttf +0 -0
  18. package/dist/assets/fonts/Montserrat-Medium.ttf +0 -0
  19. package/dist/assets/fonts/Montserrat-MediumItalic.ttf +0 -0
  20. package/dist/assets/fonts/Montserrat-Regular.ttf +0 -0
  21. package/dist/assets/fonts/Montserrat-SemiBold.ttf +0 -0
  22. package/dist/assets/fonts/Montserrat-SemiBoldItalic.ttf +0 -0
  23. package/dist/assets/fonts/Montserrat-Thin.ttf +0 -0
  24. package/dist/assets/fonts/Montserrat-ThinItalic.ttf +0 -0
  25. package/dist/components/Inputs/Input/index.d.ts +39 -18
  26. package/dist/components/Inputs/Input/index.js +122 -28
  27. package/dist/components/Inputs/Input/utils/input-styled.d.ts +4 -0
  28. package/dist/components/Inputs/Input/utils/input-styled.js +63 -0
  29. package/dist/components/Inputs/Input/utils/interface.d.ts +21 -0
  30. package/dist/components/Inputs/Input/utils/interface.js +1 -0
  31. package/dist/components/Inputs/Input/utils/mask-custom.d.ts +4 -0
  32. package/dist/components/Inputs/Input/utils/mask-custom.js +30 -0
  33. package/dist/components/Inputs/input-select/index.d.ts +42 -0
  34. package/dist/components/Inputs/input-select/index.js +84 -0
  35. package/dist/components/Inputs/input-select/utils/interface.d.ts +43 -0
  36. package/dist/components/Inputs/input-select/utils/interface.js +1 -0
  37. package/dist/components/Loader/index.d.ts +5 -0
  38. package/dist/components/Loader/index.js +7 -0
  39. package/dist/components/barcode/BarcodeScanner.d.ts +26 -0
  40. package/dist/components/barcode/barcode-scanner.d.ts +26 -0
  41. package/dist/components/barcode/barcode-scanner.js +433 -0
  42. package/dist/components/barcode/index.d.ts +36 -0
  43. package/dist/components/barcode/index.js +65 -0
  44. package/dist/components/barcode/utils/constants.d.ts +139 -0
  45. package/dist/components/barcode/utils/constants.js +224 -0
  46. package/dist/components/barcode/utils/interface.d.ts +50 -0
  47. package/dist/components/barcode/utils/interface.js +1 -0
  48. package/dist/components/button/button-excel/index.d.ts +32 -0
  49. package/dist/components/button/button-excel/index.js +143 -0
  50. package/dist/components/button/index.d.ts +21 -0
  51. package/dist/components/button/index.js +101 -0
  52. package/dist/components/card/index.d.ts +21 -0
  53. package/dist/components/card/index.js +48 -0
  54. package/dist/components/datatable/index.d.ts +8 -0
  55. package/dist/components/datatable/index.js +103 -0
  56. package/dist/components/datatable/utils/constants.d.ts +8 -0
  57. package/dist/components/datatable/utils/constants.js +42 -0
  58. package/dist/components/filtro/components/card.d.ts +24 -0
  59. package/dist/components/filtro/components/card.js +49 -0
  60. package/dist/components/filtro/components/filtros.d.ts +19 -0
  61. package/dist/components/filtro/components/filtros.js +77 -0
  62. package/dist/components/filtro/index.d.ts +28 -0
  63. package/dist/components/filtro/index.js +38 -0
  64. package/dist/components/filtro/utils/interface.d.ts +105 -0
  65. package/dist/components/filtro/utils/interface.js +1 -0
  66. package/dist/components/icons/index.d.ts +21 -0
  67. package/dist/components/icons/index.js +39 -0
  68. package/dist/components/tabs/index.d.ts +24 -0
  69. package/dist/components/tabs/index.js +39 -0
  70. package/dist/functions/mascaras/index.js +1 -1
  71. package/dist/index.d.ts +12 -8
  72. package/dist/index.js +1 -1
  73. package/dist/theme.css +1039 -98
  74. package/package.json +24 -14
@@ -0,0 +1,433 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ var __generator = (this && this.__generator) || function (thisArg, body) {
11
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
12
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
13
+ function verb(n) { return function (v) { return step([n, v]); }; }
14
+ function step(op) {
15
+ if (f) throw new TypeError("Generator is already executing.");
16
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
17
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
18
+ if (y = 0, t) op = [op[0] & 2, t.value];
19
+ switch (op[0]) {
20
+ case 0: case 1: t = op; break;
21
+ case 4: _.label++; return { value: op[1], done: false };
22
+ case 5: _.label++; y = op[1]; op = [0]; continue;
23
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
24
+ default:
25
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
26
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
27
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
28
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
29
+ if (t[2]) _.ops.pop();
30
+ _.trys.pop(); continue;
31
+ }
32
+ op = body.call(thisArg, _);
33
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
34
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
35
+ }
36
+ };
37
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
38
+ import { TIMEOUTS, VALIDACAO, getQuaggaConfig, verificarSuporteCamera, solicitarPermissaoCamera, } from './utils/constants';
39
+ import Button from 'src/components/button';
40
+ import CustomLoaders from 'src/components/loader';
41
+ import { useEffect, useState, useRef, useCallback } from 'react';
42
+ /**
43
+ * Componente scanner de código de barras que utiliza a biblioteca Quagga.js
44
+ * para capturar códigos de barras através da câmera do dispositivo.
45
+ *
46
+ * @component
47
+ * @param props - Propriedades do componente
48
+ * @param props.setCode - Função callback para definir o código lido
49
+ * @param props.open - Estado que controla se o scanner está aberto/ativo
50
+ * @param props.setOpen - Função para controlar o estado de abertura do scanner
51
+ *
52
+ * @example
53
+ * ```tsx
54
+ * const [code, setCode] = useState('')
55
+ * const [scannerOpen, setScannerOpen] = useState(false)
56
+ *
57
+ * return (
58
+ * <BarcodeScanner
59
+ * setCode={setCode}
60
+ * open={scannerOpen}
61
+ * setOpen={setScannerOpen}
62
+ * />
63
+ * )
64
+ * ```
65
+ */
66
+ export function BarcodeScanner(_a) {
67
+ var _this = this;
68
+ var setCode = _a.setCode, open = _a.open, setOpen = _a.setOpen;
69
+ var _b = useState(true), loading = _b[0], setLoading = _b[1];
70
+ var _c = useState(null), error = _c[0], setError = _c[1];
71
+ var _d = useState(''), lastCode = _d[0], setLastCode = _d[1];
72
+ var scannerRef = useRef(null);
73
+ var isInitialized = useRef(false);
74
+ var isInitializing = useRef(false);
75
+ var detectionTimeout = useRef();
76
+ var consecutiveReads = useRef(new Map());
77
+ var initTimeout = useRef();
78
+ var quaggaRef = useRef(null);
79
+ var getQuagga = useCallback(function () { return __awaiter(_this, void 0, void 0, function () {
80
+ var module_1, quagga, err_1;
81
+ var _a;
82
+ return __generator(this, function (_b) {
83
+ switch (_b.label) {
84
+ case 0:
85
+ if (quaggaRef.current)
86
+ return [2 /*return*/, quaggaRef.current];
87
+ _b.label = 1;
88
+ case 1:
89
+ _b.trys.push([1, 3, , 4]);
90
+ return [4 /*yield*/, import('quagga')];
91
+ case 2:
92
+ module_1 = _b.sent();
93
+ quagga = ((_a = module_1.default) !== null && _a !== void 0 ? _a : module_1);
94
+ quaggaRef.current = quagga;
95
+ return [2 /*return*/, quagga];
96
+ case 3:
97
+ err_1 = _b.sent();
98
+ console.error('Erro ao carregar biblioteca Quagga:', err_1);
99
+ setError('Biblioteca de scanner não disponível neste ambiente');
100
+ setLoading(false);
101
+ return [2 /*return*/, null];
102
+ case 4: return [2 /*return*/];
103
+ }
104
+ });
105
+ }); }, []);
106
+ /**
107
+ * Verifica se o dispositivo suporta câmera
108
+ *
109
+ * @async
110
+ * @function checkCameraSupport
111
+ * @returns {Promise<void>} Promise que resolve quando a verificação é concluída
112
+ */
113
+ var checkCameraSupport = useCallback(function () { return __awaiter(_this, void 0, void 0, function () {
114
+ return __generator(this, function (_a) {
115
+ switch (_a.label) {
116
+ case 0: return [4 /*yield*/, verificarSuporteCamera()];
117
+ case 1:
118
+ _a.sent();
119
+ return [2 /*return*/];
120
+ }
121
+ });
122
+ }); }, []);
123
+ /**
124
+ * Solicita permissão para uso da câmera
125
+ *
126
+ * @async
127
+ * @function requestCameraPermission
128
+ * @returns {Promise<void>} Promise que resolve quando a permissão é concedida ou rejeitada
129
+ */
130
+ var requestCameraPermission = useCallback(function () { return __awaiter(_this, void 0, void 0, function () {
131
+ return __generator(this, function (_a) {
132
+ switch (_a.label) {
133
+ case 0: return [4 /*yield*/, solicitarPermissaoCamera()];
134
+ case 1:
135
+ _a.sent();
136
+ return [2 /*return*/];
137
+ }
138
+ });
139
+ }); }, []);
140
+ /**
141
+ * Valida se o código de barras lido é válido
142
+ *
143
+ * @function validateBarcode
144
+ * @param {string} code - Código de barras para validar
145
+ * @returns {boolean} true se o código é válido, false caso contrário
146
+ *
147
+ * @description
148
+ * Verifica se o código:
149
+ * - Não está vazio
150
+ * - Tem tamanho mínimo adequado
151
+ * - Não possui caracteres repetidos em excesso
152
+ */
153
+ var validateBarcode = function (code) {
154
+ var cleanCode = code.trim();
155
+ if (!cleanCode || cleanCode.length < VALIDACAO.TAMANHO_MINIMO_CODIGO)
156
+ return false;
157
+ if (VALIDACAO.REGEX_CARACTERES_REPETIDOS.test(cleanCode))
158
+ return false;
159
+ return true;
160
+ };
161
+ /**
162
+ * Limpa e para o scanner Quagga, liberando recursos
163
+ *
164
+ * @function cleanupQuagga
165
+ * @returns {void}
166
+ *
167
+ * @description
168
+ * - Remove listeners de detecção
169
+ * - Para o scanner
170
+ * - Reseta estados de inicialização
171
+ * - Limpa contadores de leituras consecutivas
172
+ */
173
+ var cleanupQuagga = useCallback(function () {
174
+ try {
175
+ var quagga = quaggaRef.current;
176
+ if (isInitialized.current && quagga) {
177
+ quagga.offDetected();
178
+ quagga.stop();
179
+ }
180
+ }
181
+ catch (err) {
182
+ console.error('Erro ao limpar scanner:', err);
183
+ }
184
+ isInitialized.current = false;
185
+ isInitializing.current = false;
186
+ consecutiveReads.current.clear();
187
+ }, []);
188
+ /**
189
+ * Confirma a leitura de um código após múltiplas detecções consecutivas
190
+ *
191
+ * @function confirmReading
192
+ * @param {string} code - Código detectado para confirmar
193
+ * @returns {void}
194
+ *
195
+ * @description
196
+ * Implementa um sistema de confirmação que requer múltiplas leituras
197
+ * consecutivas do mesmo código antes de considerá-lo válido.
198
+ * Isso reduz falsos positivos e melhora a precisão.
199
+ */
200
+ var confirmReading = useCallback(function (code) {
201
+ var count = consecutiveReads.current.get(code) || 0;
202
+ consecutiveReads.current.set(code, count + 1);
203
+ var newCount = consecutiveReads.current.get(code);
204
+ setLastCode(code);
205
+ for (var _i = 0, _a = Array.from(consecutiveReads.current.entries()); _i < _a.length; _i++) {
206
+ var _b = _a[_i], key = _b[0], value = _b[1];
207
+ if (key !== code && value < TIMEOUTS.CONFIRMACAO_THRESHOLD) {
208
+ consecutiveReads.current.delete(key);
209
+ }
210
+ }
211
+ if (newCount >= TIMEOUTS.CONFIRMACAO_THRESHOLD) {
212
+ cleanupQuagga();
213
+ consecutiveReads.current.clear();
214
+ setTimeout(function () {
215
+ setCode(code);
216
+ setOpen(false);
217
+ }, TIMEOUTS.FECHAMENTO_MODAL);
218
+ }
219
+ else {
220
+ setTimeout(function () {
221
+ if (consecutiveReads.current.get(code) === newCount) {
222
+ consecutiveReads.current.delete(code);
223
+ if (lastCode === code)
224
+ setLastCode('');
225
+ }
226
+ }, TIMEOUTS.LIMPEZA_CONTADOR);
227
+ }
228
+ },
229
+ // eslint-disable-next-line react-hooks/exhaustive-deps
230
+ [cleanupQuagga, setCode, setOpen]);
231
+ /**
232
+ * Manipula a detecção de códigos de barras pelo Quagga
233
+ *
234
+ * @function handleQuaggaDetected
235
+ * @param {QuaggaResult} result - Resultado da detecção do Quagga
236
+ * @returns {void}
237
+ *
238
+ * @description
239
+ * Processa os resultados da detecção:
240
+ * - Extrai o código e formato
241
+ * - Valida o código detectado
242
+ * - Inicia o processo de confirmação
243
+ */
244
+ var handleQuaggaDetected = useCallback(function (result) {
245
+ var _a;
246
+ try {
247
+ if (!((_a = result === null || result === void 0 ? void 0 : result.codeResult) === null || _a === void 0 ? void 0 : _a.code))
248
+ return;
249
+ var code = result.codeResult.code.trim();
250
+ if (!validateBarcode(code))
251
+ return;
252
+ confirmReading(code);
253
+ }
254
+ catch (err) {
255
+ console.error('Erro ao processar detecção:', err);
256
+ }
257
+ }, [confirmReading]);
258
+ /**
259
+ * Inicializa o scanner Quagga com configurações apropriadas
260
+ *
261
+ * @async
262
+ * @function initializeScanner
263
+ * @returns {Promise<void>} Promise que resolve quando a inicialização é concluída
264
+ *
265
+ * @description
266
+ * Processo de inicialização:
267
+ * 1. Verifica suporte à câmera
268
+ * 2. Solicita permissões
269
+ * 3. Configura o Quagga com base no dispositivo
270
+ * 4. Inicia o scanner
271
+ * 5. Configura listeners de detecção
272
+ */
273
+ var initializeScanner = useCallback(function () { return __awaiter(_this, void 0, void 0, function () {
274
+ var err_2, isMobile, config, quagga;
275
+ return __generator(this, function (_a) {
276
+ switch (_a.label) {
277
+ case 0:
278
+ if (!scannerRef.current || isInitialized.current || isInitializing.current)
279
+ return [2 /*return*/];
280
+ isInitializing.current = true;
281
+ _a.label = 1;
282
+ case 1:
283
+ _a.trys.push([1, 4, , 5]);
284
+ return [4 /*yield*/, checkCameraSupport()];
285
+ case 2:
286
+ _a.sent();
287
+ return [4 /*yield*/, requestCameraPermission()];
288
+ case 3:
289
+ _a.sent();
290
+ return [3 /*break*/, 5];
291
+ case 4:
292
+ err_2 = _a.sent();
293
+ isInitializing.current = false;
294
+ setError(err_2.message);
295
+ setLoading(false);
296
+ return [2 /*return*/];
297
+ case 5:
298
+ isMobile = /Android|iPhone|iPad|iPod/i.test(navigator.userAgent);
299
+ config = getQuaggaConfig(scannerRef.current, isMobile);
300
+ return [4 /*yield*/, getQuagga()];
301
+ case 6:
302
+ quagga = _a.sent();
303
+ if (!quagga)
304
+ return [2 /*return*/];
305
+ quagga.init(config, function (err) {
306
+ if (err) {
307
+ var message = typeof err === 'object' && err !== null && 'message' in err
308
+ ? String(err.message)
309
+ : JSON.stringify(err);
310
+ console.error('Erro na inicialização do Quagga:', err);
311
+ setError("Erro ao inicializar scanner: ".concat(message));
312
+ setLoading(false);
313
+ return;
314
+ }
315
+ try {
316
+ quagga.start();
317
+ isInitialized.current = true;
318
+ isInitializing.current = false;
319
+ setError(null);
320
+ consecutiveReads.current.clear();
321
+ quagga.onDetected(handleQuaggaDetected);
322
+ setTimeout(function () { return setLoading(false); }, TIMEOUTS.LOADING_DELAY);
323
+ }
324
+ catch (error_) {
325
+ console.error('Erro ao iniciar Quagga:', error_);
326
+ setError('Erro ao iniciar scanner');
327
+ setLoading(false);
328
+ }
329
+ });
330
+ return [2 /*return*/];
331
+ }
332
+ });
333
+ }); }, [
334
+ checkCameraSupport,
335
+ requestCameraPermission,
336
+ handleQuaggaDetected,
337
+ getQuagga,
338
+ ]);
339
+ /**
340
+ * Effect principal que gerencia o ciclo de vida do scanner
341
+ *
342
+ * @description
343
+ * - Inicializa o scanner quando `open` se torna true
344
+ * - Limpa recursos quando `open` se torna false
345
+ * - Gerencia timeouts de inicialização
346
+ */
347
+ useEffect(function () {
348
+ var currentTimeout = detectionTimeout.current;
349
+ if (initTimeout.current)
350
+ clearTimeout(initTimeout.current);
351
+ if (open && !isInitialized.current && !isInitializing.current) {
352
+ setLoading(true);
353
+ setError(null);
354
+ setLastCode('');
355
+ consecutiveReads.current.clear();
356
+ initTimeout.current = setTimeout(function () {
357
+ initializeScanner();
358
+ }, TIMEOUTS.INICIALIZACAO);
359
+ return function () {
360
+ if (initTimeout.current)
361
+ clearTimeout(initTimeout.current);
362
+ };
363
+ }
364
+ else if (!open && isInitialized.current) {
365
+ isInitialized.current = false;
366
+ isInitializing.current = false;
367
+ cleanupQuagga();
368
+ if (currentTimeout)
369
+ clearTimeout(currentTimeout);
370
+ if (initTimeout.current)
371
+ clearTimeout(initTimeout.current);
372
+ }
373
+ // eslint-disable-next-line react-hooks/exhaustive-deps
374
+ }, [open]);
375
+ /**
376
+ * Effect de limpeza executado na desmontagem do componente
377
+ *
378
+ * @description
379
+ * Garante que todos os recursos sejam liberados quando o componente
380
+ * é desmontado, evitando vazamentos de memória.
381
+ */
382
+ useEffect(function () {
383
+ var currentTimeout = detectionTimeout.current;
384
+ return function () {
385
+ cleanupQuagga();
386
+ if (currentTimeout)
387
+ clearTimeout(currentTimeout);
388
+ };
389
+ // eslint-disable-next-line react-hooks/exhaustive-deps
390
+ }, []);
391
+ /**
392
+ * Renderização condicional quando há erro no scanner
393
+ *
394
+ * @description
395
+ * Exibe uma interface de erro completa com:
396
+ * - Mensagem de erro principal
397
+ * - Informações de debug (se disponíveis)
398
+ * - Alertas sobre contexto de segurança
399
+ * - Instruções para resolução de problemas
400
+ * - Botão para tentar novamente
401
+ *
402
+ * Trata especificamente:
403
+ * - Problemas de HTTPS/contexto seguro
404
+ * - Permissões de câmera
405
+ * - Acesso externo vs local
406
+ */
407
+ if (error) {
408
+ return (_jsx("div", { className: "overflow-hidden", children: _jsxs("div", { className: "p-2 text-center", children: [_jsx("p", { className: "mb-2 font-semibold", children: "\u26A0\uFE0F Erro no scanner" }), _jsx("p", { className: "text-xs text-gray-600 mb-4", children: error }), error.toLowerCase().includes('permissão') && (_jsxs("div", { className: "bg-light-blue-50 border border-blue-200 rounded p-3 mb-4 text-left", children: [_jsx("p", { className: "text-xs font-semibold mb-2", children: "\uD83D\uDD12 Permiss\u00F5es da c\u00E2mera:" }), _jsxs("ul", { className: "text-xs text-blue-700 list-disc list-inside space-y-1", children: [_jsx("li", { children: "Clique no \u00EDcone de cadeado na barra de endere\u00E7o" }), _jsx("li", { children: "Encontre \"C\u00E2mera\" nas configura\u00E7\u00F5es" }), _jsx("li", { children: "Mude para \"Permitir\"" }), _jsx("li", { children: "Recarregue a p\u00E1gina" })] })] })), _jsx(Button, { size: "small", variant: "text", className: "mt-2", onClick: function () {
409
+ setError(null);
410
+ setLoading(true);
411
+ setTimeout(initializeScanner, TIMEOUTS.TENTAR_NOVAMENTE);
412
+ }, children: "Tentar novamente" })] }) }));
413
+ }
414
+ /**
415
+ * Renderização principal do scanner quando não há erro
416
+ *
417
+ * @description
418
+ * Estrutura principal do componente:
419
+ * 1. Container do scanner (div com ref) - onde o Quagga renderiza o vídeo
420
+ * 2. Loader customizado - exibido durante inicialização
421
+ * 3. Dicas de uso - instruções para melhor leitura
422
+ *
423
+ * O container do scanner:
424
+ * - Tem altura dinâmica baseada no estado de loading
425
+ * - Fica oculto durante carregamento
426
+ * - Possui bordas estilizadas para indicar área de captura
427
+ */
428
+ return (_jsxs("div", { children: [_jsx("div", { ref: scannerRef, id: "barcode-scanner", className: "mb-2 relative overflow-hidden border-2 border-dashed border-blue-300 rounded-lg", style: {
429
+ maxHeight: loading ? '0px' : '400px',
430
+ minHeight: loading ? '0px' : '300px',
431
+ visibility: loading ? 'hidden' : 'visible',
432
+ } }), _jsx(CustomLoaders, { open: loading }), !loading && (_jsx("div", { className: "text-center text-sm text-gray-600 mt-2", children: _jsxs("div", { className: "mt-3 text-xs text-gray-500", children: [_jsx("p", { className: "mb-1", children: "\uD83D\uDCA1 Dicas para melhor leitura:" }), _jsxs("ul", { className: "text-left space-y-1", children: [_jsx("li", { children: "\u2022 Mantenha o c\u00F3digo de barras bem iluminado" }), _jsx("li", { children: "\u2022 Aproxime ou afaste at\u00E9 focar bem" }), _jsx("li", { children: "\u2022 Mantenha o celular est\u00E1vel" }), _jsx("li", { children: "\u2022 Certifique-se que o c\u00F3digo n\u00E3o est\u00E1 danificado" })] })] }) }))] }));
433
+ }
@@ -0,0 +1,36 @@
1
+ import React from 'react';
2
+ import { BarcodeDialogProps } from './utils/interface';
3
+ /**
4
+ * Componente modal para leitura de código de barras usando câmera
5
+ *
6
+ * @description
7
+ * Este componente exibe um dialog modal que permite a leitura de códigos de barras
8
+ * através da câmera do dispositivo. A funcionalidade só está disponível em
9
+ * contextos seguros (HTTPS) ou em desenvolvimento local.
10
+ *
11
+ * @example
12
+ * ```tsx
13
+ * const [isOpen, setIsOpen] = useState(false)
14
+ * const [barcode, setBarcode] = useState('')
15
+ *
16
+ * return (
17
+ * <BarcodeDialog
18
+ * open={isOpen}
19
+ * setOpen={setIsOpen}
20
+ * setCode={setBarcode}
21
+ * />
22
+ * )
23
+ * ```
24
+ *
25
+ * @param {BarcodeDialogProps} props - As propriedades do componente
26
+ * @param {boolean} props.open - Estado que controla se o dialog está visível
27
+ * @param {function} props.setOpen - Função para alterar a visibilidade do dialog
28
+ * @param {function} props.setCode - Callback executado quando um código é lido
29
+ *
30
+ * @returns {React.ReactElement} Elemento React do dialog de leitura de barcode
31
+ *
32
+ * @version 1.2.0
33
+ * @author Flaviasoz
34
+ * @since 1.0.0
35
+ */
36
+ export declare function BarcodeDialog({ open, setOpen, setCode, }: Readonly<BarcodeDialogProps>): React.ReactElement;
@@ -0,0 +1,65 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import Dialog from 'src/components/dialog';
3
+ import { BarcodeScanner } from './barcode-scanner';
4
+ import { useCallback, useMemo } from 'react';
5
+ import { contextoSeguro, MENSAGENS, style } from './utils/constants';
6
+ /**
7
+ * Componente modal para leitura de código de barras usando câmera
8
+ *
9
+ * @description
10
+ * Este componente exibe um dialog modal que permite a leitura de códigos de barras
11
+ * através da câmera do dispositivo. A funcionalidade só está disponível em
12
+ * contextos seguros (HTTPS) ou em desenvolvimento local.
13
+ *
14
+ * @example
15
+ * ```tsx
16
+ * const [isOpen, setIsOpen] = useState(false)
17
+ * const [barcode, setBarcode] = useState('')
18
+ *
19
+ * return (
20
+ * <BarcodeDialog
21
+ * open={isOpen}
22
+ * setOpen={setIsOpen}
23
+ * setCode={setBarcode}
24
+ * />
25
+ * )
26
+ * ```
27
+ *
28
+ * @param {BarcodeDialogProps} props - As propriedades do componente
29
+ * @param {boolean} props.open - Estado que controla se o dialog está visível
30
+ * @param {function} props.setOpen - Função para alterar a visibilidade do dialog
31
+ * @param {function} props.setCode - Callback executado quando um código é lido
32
+ *
33
+ * @returns {React.ReactElement} Elemento React do dialog de leitura de barcode
34
+ *
35
+ * @version 1.2.0
36
+ * @author Flaviasoz
37
+ * @since 1.0.0
38
+ */
39
+ export function BarcodeDialog(_a) {
40
+ var open = _a.open, setOpen = _a.setOpen, setCode = _a.setCode;
41
+ /**
42
+ * Manipula o fechamento do dialog
43
+ * @function handleClose
44
+ * @description Fecha o dialog definindo o estado 'open' como false
45
+ */
46
+ var handleClose = useCallback(function () {
47
+ setOpen(false);
48
+ }, [setOpen]);
49
+ /**
50
+ * Verifica se o contexto é seguro para usar a câmera
51
+ * @description Memoriza o resultado da verificação de segurança para evitar re-cálculos
52
+ */
53
+ var isContextSecure = useMemo(function () { return contextoSeguro(); }, []);
54
+ /**
55
+ * Componente de conteúdo do dialog baseado no contexto de segurança
56
+ * @description Renderiza o scanner ou mensagem de erro baseado na segurança do contexto
57
+ */
58
+ var dialogContent = useMemo(function () {
59
+ if (!isContextSecure) {
60
+ return (_jsx("div", { role: "alert", "aria-live": "polite", className: "text-xs", style: style, children: MENSAGENS.HTTPS_REQUERIDO }));
61
+ }
62
+ return _jsx(BarcodeScanner, { setCode: setCode, open: open, setOpen: setOpen });
63
+ }, [isContextSecure, setCode, open, setOpen]);
64
+ return (_jsx(Dialog, { open: open, maxWidth: "xs", onClose: handleClose, "aria-labelledby": "barcode-dialog-title", "aria-describedby": "barcode-dialog-description", children: _jsx("div", { id: "barcode-dialog-description", children: dialogContent }) }));
65
+ }
@@ -0,0 +1,139 @@
1
+ import { CSSProperties } from 'react';
2
+ /**
3
+ * Mensagens de erro e informação para o componente
4
+ */
5
+ export declare const MENSAGENS: {
6
+ HTTPS_REQUERIDO: string;
7
+ TITULO: string;
8
+ };
9
+ /**
10
+ * Mapa de mensagens de erro para diferentes tipos de erro de câmera
11
+ */
12
+ export declare const MENSAGENS_ERRO_CAMERA: Map<string, string>;
13
+ /**
14
+ * Configurações de timeout e delays
15
+ */
16
+ export declare const TIMEOUTS: {
17
+ CONFIRMACAO_THRESHOLD: number;
18
+ LIMPEZA_CONTADOR: number;
19
+ INICIALIZACAO: number;
20
+ LOADING_DELAY: number;
21
+ FECHAMENTO_MODAL: number;
22
+ TENTAR_NOVAMENTE: number;
23
+ };
24
+ /**
25
+ * Configurações de validação
26
+ */
27
+ export declare const VALIDACAO: {
28
+ TAMANHO_MINIMO_CODIGO: number;
29
+ REGEX_CARACTERES_REPETIDOS: RegExp;
30
+ };
31
+ /**
32
+ * Configurações da câmera
33
+ */
34
+ export declare const CONFIG_CAMERA: {
35
+ CONSTRAINTS: {
36
+ WIDTH: {
37
+ min: number;
38
+ ideal: number;
39
+ max: number;
40
+ };
41
+ HEIGHT: {
42
+ min: number;
43
+ ideal: number;
44
+ max: number;
45
+ };
46
+ ASPECT_RATIO: {
47
+ ideal: number;
48
+ };
49
+ };
50
+ AREA_SCANNER: {
51
+ top: string;
52
+ right: string;
53
+ left: string;
54
+ bottom: string;
55
+ };
56
+ WORKERS: {
57
+ MOBILE: number;
58
+ DESKTOP: number;
59
+ };
60
+ };
61
+ /**
62
+ * Readers suportados pelo Quagga
63
+ */
64
+ export declare const READERS_SUPORTADOS: string[];
65
+ /**
66
+ * Configuração padrão do Quagga
67
+ */
68
+ export declare const getQuaggaConfig: (target: HTMLElement, isMobile: boolean) => {
69
+ inputStream: {
70
+ name: string;
71
+ type: string;
72
+ constraints: {
73
+ width: {
74
+ min: number;
75
+ ideal: number;
76
+ max: number;
77
+ };
78
+ height: {
79
+ min: number;
80
+ ideal: number;
81
+ max: number;
82
+ };
83
+ facingMode: string;
84
+ aspectRatio: {
85
+ ideal: number;
86
+ };
87
+ };
88
+ target: HTMLElement;
89
+ area: {
90
+ top: string;
91
+ right: string;
92
+ left: string;
93
+ bottom: string;
94
+ };
95
+ };
96
+ locator: {
97
+ halfSample: boolean;
98
+ patchSize: string;
99
+ debug: {
100
+ showCanvas: boolean;
101
+ showPatches: boolean;
102
+ showFoundPatches: boolean;
103
+ showSkeleton: boolean;
104
+ showLabels: boolean;
105
+ showPatchLabels: boolean;
106
+ showRemainingPatchLabels: boolean;
107
+ boxFromPatches: {
108
+ showTransformed: boolean;
109
+ showTransformedBox: boolean;
110
+ showBB: boolean;
111
+ };
112
+ };
113
+ };
114
+ numOfWorkers: number;
115
+ decoder: {
116
+ readers: string[];
117
+ multiple: boolean;
118
+ };
119
+ locate: boolean;
120
+ debug: boolean;
121
+ frequency: number;
122
+ };
123
+ /**
124
+ * Verifica se o protocolo atual é HTTPS ou se está em desenvolvimento local
125
+ * @returns {boolean} True se for HTTPS ou localhost, false caso contrário
126
+ */
127
+ export declare const contextoSeguro: () => boolean;
128
+ /**
129
+ * Verifica se o navegador suporta acesso à câmera
130
+ * @throws {Error} Quando o navegador não suporta câmera ou não está em contexto seguro
131
+ */
132
+ export declare const verificarSuporteCamera: () => Promise<void>;
133
+ /**
134
+ * Solicita permissão para acessar a câmera
135
+ * @returns {Promise<boolean>} True se a permissão foi concedida
136
+ * @throws {Error} Quando a permissão é negada ou há erro no acesso
137
+ */
138
+ export declare const solicitarPermissaoCamera: () => Promise<boolean>;
139
+ export declare const style: CSSProperties;