@cristianmpx/react-import-sheet-ui-raw 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js ADDED
@@ -0,0 +1,1766 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ DataTableContext: () => DataTableContext,
24
+ EditLogContext: () => EditLogContext,
25
+ IMPORTER_ABORTED_EVENT: () => import_react_import_sheet_headless19.IMPORTER_ABORTED_EVENT,
26
+ IMPORTER_PROGRESS_EVENT: () => import_react_import_sheet_headless19.IMPORTER_PROGRESS_EVENT,
27
+ ImporterProvider: () => import_react_import_sheet_headless19.ImporterProvider,
28
+ LayoutContext: () => LayoutContext,
29
+ LayoutProvider: () => LayoutProvider,
30
+ RawAbortButton: () => RawAbortButton,
31
+ RawDataTableProvider: () => RawDataTableProvider,
32
+ RawEditLogPanel: () => RawEditLogPanel,
33
+ RawEditLogProvider: () => RawEditLogProvider,
34
+ RawErrorBoundary: () => RawErrorBoundary,
35
+ RawFilePicker: () => RawFilePicker,
36
+ RawImportAction: () => RawImportAction,
37
+ RawImporterRoot: () => RawImporterRoot,
38
+ RawImporterWorkflow: () => RawImporterWorkflow,
39
+ RawMappingRow: () => RawMappingRow,
40
+ RawMappingSuggest: () => RawMappingSuggest,
41
+ RawMappingTable: () => RawMappingTable,
42
+ RawProgressDisplay: () => RawProgressDisplay,
43
+ RawStatusGuard: () => RawStatusGuard,
44
+ RawStatusIndicator: () => RawStatusIndicator,
45
+ RawViewPhaseProvider: () => RawViewPhaseProvider,
46
+ RootConfigContext: () => RootConfigContext,
47
+ RootConfigProvider: () => RootConfigProvider,
48
+ ViewPhaseContext: () => ViewPhaseContext,
49
+ getLayoutFieldOptions: () => getLayoutFieldOptions,
50
+ getViewFromState: () => getViewFromState,
51
+ useConvert: () => import_react_import_sheet_headless19.useConvert,
52
+ useImportSheet: () => import_react_import_sheet_headless19.useImportSheet,
53
+ useImporter: () => import_react_import_sheet_headless19.useImporter,
54
+ useImporterEventTarget: () => import_react_import_sheet_headless19.useImporterEventTarget,
55
+ useImporterMetrics: () => useImporterMetrics,
56
+ useImporterProgressSubscription: () => import_react_import_sheet_headless19.useImporterProgressSubscription,
57
+ useImporterStatus: () => import_react_import_sheet_headless19.useImporterStatus,
58
+ useRawAbort: () => useRawAbort,
59
+ useRawCell: () => useRawCell,
60
+ useRawDataTable: () => useRawDataTable,
61
+ useRawEditLog: () => useRawEditLog,
62
+ useRawErrorBadge: () => useRawErrorBadge,
63
+ useRawExport: () => useRawExport,
64
+ useRawFilePicker: () => useRawFilePicker,
65
+ useRawFilterToggle: () => useRawFilterToggle,
66
+ useRawImportAction: () => useRawImportAction,
67
+ useRawImporterRoot: () => useRawImporterRoot,
68
+ useRawMappingRow: () => useRawMappingRow,
69
+ useRawMappingSuggest: () => useRawMappingSuggest,
70
+ useRawMappingTable: () => useRawMappingTable,
71
+ useRawPagination: () => useRawPagination,
72
+ useRawPersistence: () => useRawPersistence,
73
+ useRawProgress: () => useRawProgress,
74
+ useRawRemoveRow: () => useRawRemoveRow,
75
+ useRawStatus: () => useRawStatus,
76
+ useRawSubmitStatus: () => useRawSubmitStatus,
77
+ useRawTableBody: () => useRawTableBody,
78
+ useRawTableHead: () => useRawTableHead,
79
+ useRawTableRow: () => useRawTableRow,
80
+ useSheetData: () => import_react_import_sheet_headless19.useSheetData,
81
+ useSheetEditor: () => import_react_import_sheet_headless19.useSheetEditor,
82
+ useSheetView: () => import_react_import_sheet_headless19.useSheetView,
83
+ useStatusView: () => useStatusView
84
+ });
85
+ module.exports = __toCommonJS(index_exports);
86
+
87
+ // src/hooks/useRawImporterRoot/useRawImporterRoot.ts
88
+ var import_react = require("react");
89
+ var defaultStages = {};
90
+ function useRawImporterRoot(options = {}) {
91
+ const {
92
+ layout,
93
+ engine,
94
+ persist,
95
+ persistKey,
96
+ fuzzyMatch = true,
97
+ editingEnabled = true,
98
+ stages = defaultStages,
99
+ autoApplyMappingWhenMismatchesAtMost = "never",
100
+ showErrorWhenMismatchesAbove,
101
+ onSubmit,
102
+ submitKeyMap
103
+ } = options;
104
+ const providerProps = (0, import_react.useMemo)(
105
+ () => ({
106
+ layout,
107
+ engine,
108
+ persist,
109
+ persistKey,
110
+ onSubmit,
111
+ submitKeyMap
112
+ }),
113
+ [layout, engine, persist, persistKey, onSubmit, submitKeyMap]
114
+ );
115
+ const rootConfig = (0, import_react.useMemo)(
116
+ () => ({
117
+ fuzzyMatch,
118
+ editingEnabled,
119
+ stages: { ...defaultStages, ...stages },
120
+ autoApplyMappingWhenMismatchesAtMost,
121
+ showErrorWhenMismatchesAbove
122
+ }),
123
+ [
124
+ fuzzyMatch,
125
+ editingEnabled,
126
+ stages,
127
+ autoApplyMappingWhenMismatchesAtMost,
128
+ showErrorWhenMismatchesAbove
129
+ ]
130
+ );
131
+ return { providerProps, rootConfig };
132
+ }
133
+
134
+ // src/hooks/useRawImporterRoot/RootConfigContext.tsx
135
+ var import_react2 = require("react");
136
+ var import_jsx_runtime = require("react/jsx-runtime");
137
+ var defaultConfig = {
138
+ fuzzyMatch: true,
139
+ editingEnabled: true,
140
+ stages: {},
141
+ autoApplyMappingWhenMismatchesAtMost: "never",
142
+ showErrorWhenMismatchesAbove: void 0
143
+ };
144
+ var RootConfigContext = (0, import_react2.createContext)(defaultConfig);
145
+ var LayoutContext = (0, import_react2.createContext)(null);
146
+ function RootConfigProvider({ rootConfig, children }) {
147
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RootConfigContext.Provider, { value: rootConfig, children });
148
+ }
149
+ function LayoutProvider({ layout, children }) {
150
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(LayoutContext.Provider, { value: layout, children });
151
+ }
152
+
153
+ // src/hooks/useStatusView/useStatusView.ts
154
+ var import_react3 = require("react");
155
+ var import_react_import_sheet_headless = require("@cristianmpx/react-import-sheet-headless");
156
+
157
+ // src/shared/types/status-views.ts
158
+ function getViewFromState(status, convertResult) {
159
+ if (convertResult !== null && convertResult !== void 0) {
160
+ return "mapping";
161
+ }
162
+ switch (status) {
163
+ case "idle":
164
+ case "loading":
165
+ case "parsing":
166
+ return "idle";
167
+ case "validating":
168
+ case "transforming":
169
+ return "process";
170
+ case "success":
171
+ return "result";
172
+ case "error":
173
+ case "cancelled":
174
+ return "error";
175
+ default:
176
+ return "idle";
177
+ }
178
+ }
179
+
180
+ // src/hooks/useStatusView/useStatusView.ts
181
+ function applyStages(view, stages) {
182
+ if (view === "mapping" && stages.mapping === false) return "idle";
183
+ if (view === "process" && stages.process === false) return "idle";
184
+ if (view === "result" && stages.result === false) return "idle";
185
+ return view;
186
+ }
187
+ function resolveMappingView(rawView, mismatchCount, autoApply, showErrorAbove) {
188
+ if (rawView !== "mapping") {
189
+ return { view: rawView, mappingErrorDetail: null };
190
+ }
191
+ if (showErrorAbove != null && mismatchCount > showErrorAbove) {
192
+ return {
193
+ view: "error",
194
+ mappingErrorDetail: {
195
+ code: "TOO_MANY_MISMATCHES",
196
+ mismatchCount,
197
+ maxAllowed: showErrorAbove
198
+ }
199
+ };
200
+ }
201
+ if (autoApply !== "never" && typeof autoApply === "number" && mismatchCount <= autoApply) {
202
+ return { view: "process", mappingErrorDetail: null };
203
+ }
204
+ return { view: "mapping", mappingErrorDetail: null };
205
+ }
206
+ function useStatusView() {
207
+ const rootConfig = (0, import_react3.useContext)(RootConfigContext);
208
+ const { status, progressEventTarget } = (0, import_react_import_sheet_headless.useImporterStatus)();
209
+ const { convertResult } = (0, import_react_import_sheet_headless.useConvert)();
210
+ const mismatchCount = (0, import_react3.useMemo)(
211
+ () => convertResult?.mismatches?.length ?? 0,
212
+ [convertResult]
213
+ );
214
+ const { view, mappingErrorDetail } = (0, import_react3.useMemo)(() => {
215
+ const raw = getViewFromState(status, convertResult);
216
+ const afterStages = applyStages(raw, rootConfig.stages);
217
+ return resolveMappingView(
218
+ afterStages,
219
+ mismatchCount,
220
+ rootConfig.autoApplyMappingWhenMismatchesAtMost,
221
+ rootConfig.showErrorWhenMismatchesAbove
222
+ );
223
+ }, [
224
+ status,
225
+ convertResult,
226
+ rootConfig.stages,
227
+ mismatchCount,
228
+ rootConfig.autoApplyMappingWhenMismatchesAtMost,
229
+ rootConfig.showErrorWhenMismatchesAbove
230
+ ]);
231
+ const appliedRef = (0, import_react3.useRef)(null);
232
+ (0, import_react3.useEffect)(() => {
233
+ const autoApply = rootConfig.autoApplyMappingWhenMismatchesAtMost;
234
+ if (convertResult != null && autoApply !== "never" && typeof autoApply === "number" && mismatchCount <= autoApply && appliedRef.current !== convertResult) {
235
+ appliedRef.current = convertResult;
236
+ convertResult.applyMapping();
237
+ }
238
+ if (convertResult == null) {
239
+ appliedRef.current = null;
240
+ }
241
+ }, [convertResult, mismatchCount, rootConfig.autoApplyMappingWhenMismatchesAtMost]);
242
+ return (0, import_react3.useMemo)(
243
+ () => ({
244
+ view,
245
+ status,
246
+ progressEventTarget,
247
+ convertResult,
248
+ mappingErrorDetail
249
+ }),
250
+ [view, status, progressEventTarget, convertResult, mappingErrorDetail]
251
+ );
252
+ }
253
+
254
+ // src/hooks/useRawFilePicker/useRawFilePicker.ts
255
+ var import_react4 = require("react");
256
+ var import_react_import_sheet_headless2 = require("@cristianmpx/react-import-sheet-headless");
257
+ function useRawFilePicker(options = {}) {
258
+ const { accept } = options;
259
+ const { processFile } = (0, import_react_import_sheet_headless2.useImporter)();
260
+ const [isDragging, setIsDragging] = (0, import_react4.useState)(false);
261
+ const rootRef = (0, import_react4.useRef)(null);
262
+ const inputRef = (0, import_react4.useRef)(null);
263
+ const setRootRef = (0, import_react4.useCallback)((el) => {
264
+ rootRef.current = el;
265
+ }, []);
266
+ const setInputRef = (0, import_react4.useCallback)((el) => {
267
+ inputRef.current = el;
268
+ }, []);
269
+ const handleDrop = (0, import_react4.useCallback)(
270
+ (e) => {
271
+ e.preventDefault();
272
+ e.stopPropagation();
273
+ setIsDragging(false);
274
+ const file = e.dataTransfer?.files?.[0];
275
+ if (file) processFile(file);
276
+ },
277
+ [processFile]
278
+ );
279
+ const handleDragOver = (0, import_react4.useCallback)((e) => {
280
+ e.preventDefault();
281
+ e.stopPropagation();
282
+ e.dataTransfer.dropEffect = "copy";
283
+ setIsDragging(true);
284
+ }, []);
285
+ const handleDragLeave = (0, import_react4.useCallback)((e) => {
286
+ e.preventDefault();
287
+ e.stopPropagation();
288
+ if (!rootRef.current?.contains(e.relatedTarget)) {
289
+ setIsDragging(false);
290
+ }
291
+ }, []);
292
+ const handleChange = (0, import_react4.useCallback)(
293
+ (e) => {
294
+ const file = e.target.files?.[0];
295
+ if (file) processFile(file);
296
+ e.target.value = "";
297
+ },
298
+ [processFile]
299
+ );
300
+ const handleRootClick = (0, import_react4.useCallback)((e) => {
301
+ if (e.target !== inputRef.current) {
302
+ inputRef.current?.click();
303
+ }
304
+ }, []);
305
+ const getRootProps = (0, import_react4.useCallback)(
306
+ (opts) => ({
307
+ ref: setRootRef,
308
+ onClick: handleRootClick,
309
+ onDragOver: handleDragOver,
310
+ onDragLeave: handleDragLeave,
311
+ onDrop: handleDrop,
312
+ role: "button",
313
+ "aria-label": "Drop zone for file import",
314
+ "data-dropzone": "true",
315
+ className: opts?.className,
316
+ style: opts?.style
317
+ }),
318
+ [handleRootClick, handleDragOver, handleDragLeave, handleDrop, setRootRef]
319
+ );
320
+ const getInputProps = (0, import_react4.useCallback)(
321
+ () => ({
322
+ ref: setInputRef,
323
+ type: "file",
324
+ onChange: handleChange,
325
+ accept: accept ?? ".xlsx,.xls,.csv",
326
+ tabIndex: -1,
327
+ "aria-label": "Select file to import"
328
+ }),
329
+ [handleChange, setInputRef, accept]
330
+ );
331
+ return {
332
+ isDragging,
333
+ getRootProps,
334
+ getInputProps
335
+ };
336
+ }
337
+
338
+ // src/hooks/useRawMappingTable/useRawMappingTable.ts
339
+ var import_react5 = require("react");
340
+ var import_react_import_sheet_headless3 = require("@cristianmpx/react-import-sheet-headless");
341
+ function useRawMappingTable() {
342
+ const { convertResult } = (0, import_react_import_sheet_headless3.useConvert)();
343
+ const rows = (0, import_react5.useMemo)(() => {
344
+ if (!convertResult?.headersFound?.length) return [];
345
+ return convertResult.headersFound.map((headerOriginal, columnIndex) => ({
346
+ headerOriginal,
347
+ columnIndex
348
+ }));
349
+ }, [convertResult]);
350
+ const hasMappingData = convertResult != null && rows.length > 0;
351
+ return (0, import_react5.useMemo)(
352
+ () => ({
353
+ rows,
354
+ hasMappingData
355
+ }),
356
+ [rows, hasMappingData]
357
+ );
358
+ }
359
+
360
+ // src/hooks/useRawMappingRow/useRawMappingRow.ts
361
+ var import_react6 = require("react");
362
+ var import_react_import_sheet_headless4 = require("@cristianmpx/react-import-sheet-headless");
363
+
364
+ // src/shared/types/input-phase.ts
365
+ function getLayoutFieldOptions(layout) {
366
+ if (!layout?.fields) return [];
367
+ return Object.entries(layout.fields).map(([id, field]) => ({
368
+ id,
369
+ label: field.name ?? id
370
+ }));
371
+ }
372
+
373
+ // src/hooks/useRawMappingRow/useRawMappingRow.ts
374
+ function useRawMappingRow(options) {
375
+ const { rowContext } = options;
376
+ const { headerOriginal, columnIndex } = rowContext;
377
+ const layout = (0, import_react6.useContext)(LayoutContext);
378
+ const { convertResult } = (0, import_react_import_sheet_headless4.useConvert)();
379
+ const optionsList = (0, import_react6.useMemo)(() => getLayoutFieldOptions(layout), [layout]);
380
+ const usedByOtherColumns = (0, import_react6.useMemo)(() => {
381
+ if (!convertResult?.headerToFieldMap) return /* @__PURE__ */ new Set();
382
+ return new Set(
383
+ Object.entries(convertResult.headerToFieldMap).filter(([header]) => header !== headerOriginal).map(([, fieldId]) => fieldId).filter(Boolean)
384
+ );
385
+ }, [convertResult?.headerToFieldMap, headerOriginal]);
386
+ const mappingOptions = (0, import_react6.useMemo)(
387
+ () => optionsList.map((opt) => ({
388
+ ...opt,
389
+ disabled: usedByOtherColumns.has(opt.id)
390
+ })),
391
+ [optionsList, usedByOtherColumns]
392
+ );
393
+ const value = (0, import_react6.useMemo)(() => {
394
+ if (!convertResult?.headerToFieldMap) return null;
395
+ return convertResult.headerToFieldMap[headerOriginal] ?? null;
396
+ }, [convertResult, headerOriginal]);
397
+ const onChange = (0, import_react6.useCallback)(
398
+ (fieldId) => {
399
+ convertResult?.renameColumn(headerOriginal, fieldId);
400
+ },
401
+ [convertResult, headerOriginal]
402
+ );
403
+ const mappingStatus = (0, import_react6.useMemo)(() => {
404
+ if (value == null || value === "") return "unmapped";
405
+ const mismatches = convertResult?.mismatches ?? [];
406
+ const stillMismatch = mismatches.some((m) => m.expected === value);
407
+ return stillMismatch ? "invalid" : "valid";
408
+ }, [value, convertResult?.mismatches]);
409
+ return (0, import_react6.useMemo)(
410
+ () => ({
411
+ headerOriginal,
412
+ columnIndex,
413
+ options: mappingOptions,
414
+ value,
415
+ onChange,
416
+ mappingStatus
417
+ }),
418
+ [headerOriginal, columnIndex, mappingOptions, value, onChange, mappingStatus]
419
+ );
420
+ }
421
+
422
+ // src/hooks/useRawMappingSuggest/useRawMappingSuggest.ts
423
+ var import_react7 = require("react");
424
+
425
+ // src/shared/utils/fuzzy-similarity.ts
426
+ function normalize(s) {
427
+ return s.trim().toLowerCase().normalize("NFD").replace(/\p{Diacritic}/gu, "");
428
+ }
429
+ function levenshtein(a, b) {
430
+ if (a.length === 0) return b.length;
431
+ if (b.length === 0) return a.length;
432
+ let prev = Array.from({ length: b.length + 1 }, (_, i) => i);
433
+ for (let i = 1; i <= a.length; i++) {
434
+ const curr = [i];
435
+ for (let j = 1; j <= b.length; j++) {
436
+ const cost = a[i - 1] === b[j - 1] ? 0 : 1;
437
+ curr[j] = Math.min(curr[j - 1] + 1, prev[j] + 1, prev[j - 1] + cost);
438
+ }
439
+ prev = curr;
440
+ }
441
+ return prev[b.length];
442
+ }
443
+ function getSimilarity(s1, s2) {
444
+ const a = normalize(s1);
445
+ const b = normalize(s2);
446
+ if (a.length === 0 && b.length === 0) return 1;
447
+ const longer = a.length >= b.length ? a : b;
448
+ const shorter = a.length < b.length ? a : b;
449
+ if (longer.length === 0) return 1;
450
+ const distance = levenshtein(longer, shorter);
451
+ return (longer.length - distance) / longer.length;
452
+ }
453
+
454
+ // src/hooks/useRawMappingSuggest/useRawMappingSuggest.ts
455
+ var DEFAULT_FUZZY_THRESHOLD = 0.8;
456
+ function useRawMappingSuggest(options) {
457
+ const { columnContext } = options;
458
+ const { fileHeader } = columnContext;
459
+ const rootConfig = (0, import_react7.useContext)(RootConfigContext);
460
+ const layout = (0, import_react7.useContext)(LayoutContext);
461
+ return (0, import_react7.useMemo)(() => {
462
+ if (rootConfig.fuzzyMatch === false) {
463
+ return { matchScore: 0, suggestedFieldId: null, suggestedFieldLabel: null };
464
+ }
465
+ const optionsList = getLayoutFieldOptions(layout);
466
+ let bestScore = 0;
467
+ let bestId = null;
468
+ let bestLabel = null;
469
+ for (const opt of optionsList) {
470
+ const score = getSimilarity(fileHeader, opt.label);
471
+ if (score >= DEFAULT_FUZZY_THRESHOLD && score > bestScore) {
472
+ bestScore = score;
473
+ bestId = opt.id;
474
+ bestLabel = opt.label;
475
+ }
476
+ }
477
+ const matchScore = Math.round(bestScore * 100);
478
+ return {
479
+ matchScore: bestId != null ? matchScore : 0,
480
+ suggestedFieldId: bestId,
481
+ suggestedFieldLabel: bestLabel
482
+ };
483
+ }, [rootConfig.fuzzyMatch, layout, fileHeader]);
484
+ }
485
+
486
+ // src/hooks/useRawImportAction/useRawImportAction.ts
487
+ var import_react8 = require("react");
488
+ var import_react_import_sheet_headless5 = require("@cristianmpx/react-import-sheet-headless");
489
+ function useRawImportAction() {
490
+ const { convertResult } = (0, import_react_import_sheet_headless5.useConvert)();
491
+ const { status } = (0, import_react_import_sheet_headless5.useImporterStatus)();
492
+ const isProcessing = status === "loading" || status === "parsing" || status === "validating" || status === "transforming";
493
+ const disabled = (0, import_react8.useMemo)(() => {
494
+ if (isProcessing) return true;
495
+ if (!convertResult) return true;
496
+ if (typeof convertResult.layoutError === "boolean") {
497
+ return convertResult.layoutError === true;
498
+ }
499
+ return convertResult.mismatches.length > 0;
500
+ }, [isProcessing, convertResult]);
501
+ const runImport = (0, import_react8.useCallback)(() => {
502
+ if (convertResult && !disabled) {
503
+ convertResult.applyMapping();
504
+ }
505
+ }, [convertResult, disabled]);
506
+ return (0, import_react8.useMemo)(
507
+ () => ({
508
+ disabled,
509
+ runImport
510
+ }),
511
+ [disabled, runImport]
512
+ );
513
+ }
514
+
515
+ // src/hooks/useRawProgress/useRawProgress.ts
516
+ var import_react9 = require("react");
517
+ var import_react_import_sheet_headless6 = require("@cristianmpx/react-import-sheet-headless");
518
+ function useRawProgress(options = {}) {
519
+ const { onProgress } = options;
520
+ const { progressEventTarget } = (0, import_react_import_sheet_headless6.useImporterStatus)();
521
+ const progressRef = (0, import_react9.useRef)(null);
522
+ (0, import_react9.useEffect)(() => {
523
+ const target = progressEventTarget;
524
+ const handleProgress = (e) => {
525
+ const detail = e.detail;
526
+ progressRef.current = detail ?? null;
527
+ onProgress?.(detail);
528
+ };
529
+ const handleAborted = () => {
530
+ progressRef.current = null;
531
+ };
532
+ target.addEventListener(import_react_import_sheet_headless6.IMPORTER_PROGRESS_EVENT, handleProgress);
533
+ target.addEventListener(import_react_import_sheet_headless6.IMPORTER_ABORTED_EVENT, handleAborted);
534
+ return () => {
535
+ target.removeEventListener(import_react_import_sheet_headless6.IMPORTER_PROGRESS_EVENT, handleProgress);
536
+ target.removeEventListener(import_react_import_sheet_headless6.IMPORTER_ABORTED_EVENT, handleAborted);
537
+ };
538
+ }, [progressEventTarget, onProgress]);
539
+ return {
540
+ progressRef,
541
+ ...onProgress ? { onProgress } : {}
542
+ };
543
+ }
544
+
545
+ // src/hooks/useRawStatus/useRawStatus.ts
546
+ var import_react10 = require("react");
547
+ var import_react_import_sheet_headless7 = require("@cristianmpx/react-import-sheet-headless");
548
+ function useRawStatus() {
549
+ const { status } = (0, import_react_import_sheet_headless7.useImporterStatus)();
550
+ return (0, import_react10.useMemo)(
551
+ () => ({
552
+ status,
553
+ // When headless exposes lastError / errorDetail, wire it here for status === 'error'
554
+ errorDetail: void 0
555
+ }),
556
+ [status]
557
+ );
558
+ }
559
+
560
+ // src/hooks/useRawAbort/useRawAbort.ts
561
+ var import_react_import_sheet_headless8 = require("@cristianmpx/react-import-sheet-headless");
562
+ function useRawAbort() {
563
+ const { abort } = (0, import_react_import_sheet_headless8.useImporter)();
564
+ return { abort };
565
+ }
566
+
567
+ // src/hooks/useRawDataTable/useRawDataTable.ts
568
+ var import_react11 = require("react");
569
+ var import_react_import_sheet_headless9 = require("@cristianmpx/react-import-sheet-headless");
570
+ function useRawDataTable(options = {}) {
571
+ const { onNavigateToIndex } = options;
572
+ const layout = (0, import_react11.useContext)(LayoutContext);
573
+ const rootConfig = (0, import_react11.useContext)(RootConfigContext);
574
+ const { sheet } = (0, import_react_import_sheet_headless9.useSheetData)();
575
+ const [focusedRowIndex, setFocusedRowIndex] = (0, import_react11.useState)(null);
576
+ const [focusedCellKey, setFocusedCellKey] = (0, import_react11.useState)(null);
577
+ const [pendingCell, setPendingCell] = (0, import_react11.useState)(
578
+ null
579
+ );
580
+ const headerIds = (0, import_react11.useMemo)(() => {
581
+ if (!layout?.fields) return [];
582
+ return Object.keys(layout.fields);
583
+ }, [layout?.fields]);
584
+ const totalRowCount = sheet?.rows?.length ?? 0;
585
+ const editingEnabled = rootConfig.editingEnabled ?? true;
586
+ const headers = (0, import_react11.useMemo)(
587
+ () => getLayoutFieldOptions(layout).map((o) => ({ id: o.id, label: o.label })),
588
+ [layout]
589
+ );
590
+ const setFocused = (0, import_react11.useCallback)((rowIndex, cellKey) => {
591
+ setFocusedRowIndex(rowIndex);
592
+ setFocusedCellKey(cellKey);
593
+ }, []);
594
+ const getKeyDownHandler = (0, import_react11.useCallback)(
595
+ (rowIndex, cellKey) => {
596
+ return (e) => {
597
+ const key = e.key;
598
+ if (key !== "ArrowLeft" && key !== "ArrowRight" && key !== "ArrowUp" && key !== "ArrowDown") {
599
+ return;
600
+ }
601
+ e.preventDefault();
602
+ const colIdx = headerIds.indexOf(cellKey);
603
+ if (colIdx === -1) return;
604
+ if (key === "ArrowLeft" && colIdx > 0) {
605
+ setFocused(rowIndex, headerIds[colIdx - 1] ?? null);
606
+ return;
607
+ }
608
+ if (key === "ArrowRight" && colIdx < headerIds.length - 1) {
609
+ setFocused(rowIndex, headerIds[colIdx + 1] ?? null);
610
+ return;
611
+ }
612
+ if (key === "ArrowUp" && rowIndex > 0) {
613
+ const nextIndex = rowIndex - 1;
614
+ setFocused(nextIndex, cellKey);
615
+ onNavigateToIndex?.(nextIndex);
616
+ return;
617
+ }
618
+ if (key === "ArrowDown" && rowIndex < totalRowCount - 1) {
619
+ const nextIndex = rowIndex + 1;
620
+ setFocused(nextIndex, cellKey);
621
+ onNavigateToIndex?.(nextIndex);
622
+ return;
623
+ }
624
+ };
625
+ },
626
+ [headerIds, totalRowCount, setFocused, onNavigateToIndex]
627
+ );
628
+ const value = (0, import_react11.useMemo)(
629
+ () => ({
630
+ editingEnabled,
631
+ headerIds,
632
+ totalRowCount,
633
+ focusedRowIndex,
634
+ focusedCellKey,
635
+ setFocused,
636
+ pendingCell,
637
+ setPendingCell,
638
+ getKeyDownHandler,
639
+ onNavigateToIndex
640
+ }),
641
+ [
642
+ editingEnabled,
643
+ headerIds,
644
+ totalRowCount,
645
+ focusedRowIndex,
646
+ focusedCellKey,
647
+ setFocused,
648
+ pendingCell,
649
+ getKeyDownHandler,
650
+ onNavigateToIndex
651
+ ]
652
+ );
653
+ return (0, import_react11.useMemo)(
654
+ () => ({
655
+ ...value,
656
+ headers
657
+ }),
658
+ [value, headers]
659
+ );
660
+ }
661
+
662
+ // src/hooks/useRawDataTable/DataTableContext.tsx
663
+ var import_react12 = require("react");
664
+ var defaultContext = {
665
+ editingEnabled: true,
666
+ headerIds: [],
667
+ totalRowCount: 0,
668
+ focusedRowIndex: null,
669
+ focusedCellKey: null,
670
+ setFocused: () => {
671
+ },
672
+ pendingCell: null,
673
+ setPendingCell: () => {
674
+ },
675
+ getKeyDownHandler: () => () => {
676
+ }
677
+ };
678
+ var DataTableContext = (0, import_react12.createContext)(defaultContext);
679
+
680
+ // src/hooks/useRawDataTable/RawDataTableProvider.tsx
681
+ var import_react13 = require("react");
682
+ var import_react_import_sheet_headless10 = require("@cristianmpx/react-import-sheet-headless");
683
+ var import_jsx_runtime2 = require("react/jsx-runtime");
684
+ function RawDataTableProvider({ children, onNavigateToIndex }) {
685
+ const editor = (0, import_react_import_sheet_headless10.useSheetEditor)();
686
+ const tableValue = useRawDataTable({ onNavigateToIndex });
687
+ const canEdit = editor.canEdit !== false;
688
+ const effectiveEditing = tableValue.editingEnabled && canEdit;
689
+ const value = (0, import_react13.useMemo)(
690
+ () => ({ ...tableValue, editingEnabled: effectiveEditing }),
691
+ [tableValue, effectiveEditing]
692
+ );
693
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(DataTableContext.Provider, { value, children });
694
+ }
695
+
696
+ // src/hooks/useRawTableHead/useRawTableHead.ts
697
+ var import_react14 = require("react");
698
+ function useRawTableHead() {
699
+ const layout = (0, import_react14.useContext)(LayoutContext);
700
+ const headers = (0, import_react14.useMemo)(
701
+ () => getLayoutFieldOptions(layout).map((o) => ({ id: o.id, label: o.label })),
702
+ [layout]
703
+ );
704
+ return (0, import_react14.useMemo)(() => ({ headers }), [headers]);
705
+ }
706
+
707
+ // src/hooks/useRawTableBody/useRawTableBody.ts
708
+ var import_react15 = require("react");
709
+ var import_react_import_sheet_headless11 = require("@cristianmpx/react-import-sheet-headless");
710
+ function useRawTableBody() {
711
+ const { sheet } = (0, import_react_import_sheet_headless11.useSheetData)();
712
+ const totalRowCount = sheet?.rows?.length ?? 0;
713
+ const isPlaceholder = (0, import_react15.useCallback)(
714
+ (index) => index < 0 || index >= totalRowCount,
715
+ [totalRowCount]
716
+ );
717
+ const getRowProps = (0, import_react15.useCallback)(
718
+ (options) => {
719
+ const { index, style } = options;
720
+ const row = sheet?.rows?.[index];
721
+ const hasErrors = (row?.errors?.length ?? 0) > 0;
722
+ const placeholder = isPlaceholder(index);
723
+ return {
724
+ "data-row-index": index,
725
+ "data-has-errors": hasErrors || void 0,
726
+ "data-placeholder": placeholder || void 0,
727
+ style,
728
+ role: "row",
729
+ "aria-rowindex": index + 1
730
+ };
731
+ },
732
+ [sheet?.rows, isPlaceholder]
733
+ );
734
+ return (0, import_react15.useMemo)(
735
+ () => ({
736
+ totalRowCount,
737
+ getRowProps,
738
+ isPlaceholder
739
+ }),
740
+ [totalRowCount, getRowProps, isPlaceholder]
741
+ );
742
+ }
743
+
744
+ // src/hooks/useRawTableRow/useRawTableRow.ts
745
+ var import_react16 = require("react");
746
+ var import_react_import_sheet_headless12 = require("@cristianmpx/react-import-sheet-headless");
747
+ function useRawTableRow(options) {
748
+ const { index, style } = options;
749
+ const { sheet } = (0, import_react_import_sheet_headless12.useSheetData)();
750
+ const { getRowProps: bodyGetRowProps, isPlaceholder } = useRawTableBody();
751
+ const row = (0, import_react16.useMemo)(() => {
752
+ if (options.row !== void 0) return options.row;
753
+ if (!sheet?.rows) return null;
754
+ if (isPlaceholder(index)) return null;
755
+ return sheet.rows[index] ?? null;
756
+ }, [options.row, sheet?.rows, index, isPlaceholder]);
757
+ const getRowProps = (0, import_react16.useCallback)(
758
+ (merge) => {
759
+ const base = bodyGetRowProps({ index, style });
760
+ return {
761
+ ...base,
762
+ ...merge?.className != null && { className: merge.className },
763
+ ...merge?.style != null && { style: { ...base.style, ...merge.style } }
764
+ };
765
+ },
766
+ [bodyGetRowProps, index, style]
767
+ );
768
+ const rowErrors = row?.errors ?? [];
769
+ return (0, import_react16.useMemo)(
770
+ () => ({
771
+ getRowProps,
772
+ row: row ?? void 0,
773
+ rowErrors
774
+ }),
775
+ [getRowProps, row, rowErrors]
776
+ );
777
+ }
778
+
779
+ // src/hooks/useRawCell/useRawCell.ts
780
+ var import_react17 = require("react");
781
+ var import_react_import_sheet_headless13 = require("@cristianmpx/react-import-sheet-headless");
782
+ function useRawCell(options) {
783
+ const { rowIndex, fieldId } = options;
784
+ const { sheet } = (0, import_react_import_sheet_headless13.useSheetData)();
785
+ const { editCell: editorEditCell } = (0, import_react_import_sheet_headless13.useSheetEditor)();
786
+ const ctx = (0, import_react17.useContext)(DataTableContext);
787
+ const row = sheet?.rows?.[rowIndex];
788
+ const cell = (0, import_react17.useMemo)(() => row?.cells?.find((c) => c.key === fieldId), [row?.cells, fieldId]);
789
+ const value = cell?.value;
790
+ const errors = cell?.errors ?? [];
791
+ const isPending = ctx.pendingCell?.rowIndex === rowIndex && ctx.pendingCell?.fieldId === fieldId;
792
+ const isFocused = ctx.focusedRowIndex === rowIndex && ctx.focusedCellKey === fieldId;
793
+ const isEditing = (ctx.editingEnabled ?? true) && isFocused;
794
+ const editCell = (0, import_react17.useCallback)(
795
+ (newValue) => {
796
+ if (!(ctx.editingEnabled ?? true)) return;
797
+ ctx.setPendingCell({ rowIndex, fieldId });
798
+ const p = editorEditCell({
799
+ rowIndex,
800
+ cellKey: fieldId,
801
+ value: newValue
802
+ });
803
+ if (p && typeof p.then === "function") {
804
+ p.then(
805
+ () => ctx.setPendingCell(null),
806
+ () => ctx.setPendingCell(null)
807
+ );
808
+ } else {
809
+ ctx.setPendingCell(null);
810
+ }
811
+ },
812
+ [ctx.editingEnabled, ctx.setPendingCell, editorEditCell, rowIndex, fieldId]
813
+ );
814
+ const localValueRef = (0, import_react17.useRef)(value);
815
+ const displayValue = isPending ? localValueRef.current : value;
816
+ if (!isPending) localValueRef.current = value;
817
+ const getCellProps = (0, import_react17.useCallback)(
818
+ (opts) => {
819
+ const base = {
820
+ role: "gridcell",
821
+ tabIndex: isFocused ? 0 : -1,
822
+ "data-pending": isPending ? "true" : "false",
823
+ "data-has-error": errors.length > 0 ? "true" : void 0,
824
+ "aria-invalid": errors.length > 0 ? "true" : void 0,
825
+ "data-cell-key": fieldId,
826
+ "data-row-index": rowIndex,
827
+ onKeyDown: ctx.getKeyDownHandler(rowIndex, fieldId),
828
+ onFocus: () => ctx.setFocused(rowIndex, fieldId),
829
+ ...opts?.className != null && { className: opts.className },
830
+ ...opts?.style != null && { style: opts.style }
831
+ };
832
+ return base;
833
+ },
834
+ [isFocused, isPending, errors.length, fieldId, rowIndex, ctx.getKeyDownHandler, ctx.setFocused]
835
+ );
836
+ const getEditInputProps = (0, import_react17.useCallback)(() => {
837
+ return {
838
+ value: displayValue ?? "",
839
+ onChange: (e) => {
840
+ const v = e.target.value;
841
+ localValueRef.current = v;
842
+ editCell(v);
843
+ },
844
+ onBlur: () => {
845
+ },
846
+ "aria-label": fieldId
847
+ };
848
+ }, [displayValue, fieldId, editCell]);
849
+ const getErrorProps = (0, import_react17.useCallback)(
850
+ () => ({
851
+ role: "alert",
852
+ "aria-live": "polite",
853
+ "aria-atomic": true,
854
+ "data-ris-ui": "raw-cell-error-message"
855
+ }),
856
+ []
857
+ );
858
+ return (0, import_react17.useMemo)(
859
+ () => ({
860
+ value: displayValue,
861
+ errors,
862
+ isPending,
863
+ isEditing,
864
+ getCellProps,
865
+ getEditInputProps,
866
+ getErrorProps,
867
+ editCell
868
+ }),
869
+ [
870
+ displayValue,
871
+ errors,
872
+ isPending,
873
+ isEditing,
874
+ getCellProps,
875
+ getEditInputProps,
876
+ getErrorProps,
877
+ editCell
878
+ ]
879
+ );
880
+ }
881
+
882
+ // src/hooks/useRawErrorBadge/useRawErrorBadge.ts
883
+ var import_react18 = require("react");
884
+ function useRawErrorBadge(options) {
885
+ const { error, translateError } = options;
886
+ const message = (0, import_react18.useMemo)(() => {
887
+ if (!error) return "";
888
+ if (translateError) return translateError(error.code, error.params);
889
+ return error.message ?? error.code;
890
+ }, [error, translateError]);
891
+ return (0, import_react18.useMemo)(
892
+ () => ({
893
+ error,
894
+ message,
895
+ translateError
896
+ }),
897
+ [error, message, translateError]
898
+ );
899
+ }
900
+
901
+ // src/hooks/useRawPagination/useRawPagination.ts
902
+ var import_react20 = require("react");
903
+
904
+ // src/hooks/useRawPagination/ViewPhaseContext.tsx
905
+ var import_react19 = require("react");
906
+ var ViewPhaseContext = (0, import_react19.createContext)(null);
907
+
908
+ // src/hooks/useRawPagination/useRawPagination.ts
909
+ var VIEW_PHASE_ERROR = "useRawPagination must be used within RawViewPhaseProvider (e.g. in RESULT view).";
910
+ function useRawPagination() {
911
+ const ctx = (0, import_react20.useContext)(ViewPhaseContext);
912
+ if (!ctx) throw new Error(VIEW_PHASE_ERROR);
913
+ return {
914
+ page: ctx.page,
915
+ pageSize: ctx.pageSize,
916
+ totalRows: ctx.totalRows,
917
+ visibleSheetIndices: ctx.visibleSheetIndices,
918
+ setPage: ctx.setPage,
919
+ setPageSize: ctx.setPageSize
920
+ };
921
+ }
922
+
923
+ // src/hooks/useRawPagination/useRawSubmitStatus.ts
924
+ var import_react21 = require("react");
925
+ var VIEW_PHASE_ERROR2 = "useRawSubmitStatus must be used within RawViewPhaseProvider (e.g. in RESULT view).";
926
+ function useRawSubmitStatus() {
927
+ const ctx = (0, import_react21.useContext)(ViewPhaseContext);
928
+ if (!ctx) throw new Error(VIEW_PHASE_ERROR2);
929
+ return {
930
+ isSubmitted: ctx.isSubmitted,
931
+ markSubmitted: ctx.markSubmitted,
932
+ canSubmit: ctx.canSubmit
933
+ };
934
+ }
935
+
936
+ // src/hooks/useRawPagination/RawViewPhaseProvider.tsx
937
+ var import_react22 = require("react");
938
+ var import_react_import_sheet_headless14 = require("@cristianmpx/react-import-sheet-headless");
939
+ var import_jsx_runtime3 = require("react/jsx-runtime");
940
+ function hasRowErrors(row) {
941
+ if (!row) return false;
942
+ if ((row.errors?.length ?? 0) > 0) return true;
943
+ return row.cells?.some((c) => (c?.errors?.length ?? 0) > 0) ?? false;
944
+ }
945
+ function escapeCsvCell(value) {
946
+ const s = value == null ? "" : String(value);
947
+ if (/[",\r\n]/.test(s)) return `"${s.replace(/"/g, '""')}"`;
948
+ return s;
949
+ }
950
+ function buildErrorsOnlyCSV(options, rowsWithErrors) {
951
+ const headerLine = options.map((o) => o.label).map(escapeCsvCell).join(",");
952
+ const dataLines = rowsWithErrors.map(
953
+ (row) => options.map((o) => row.cells?.find((c) => c.key === o.id)).map((c) => escapeCsvCell(c?.value)).join(",")
954
+ );
955
+ return [headerLine, ...dataLines].join("\r\n");
956
+ }
957
+ function buildErrorsOnlyJSON(rowsWithErrors) {
958
+ const arr = rowsWithErrors.map((row) => {
959
+ const obj = {};
960
+ (row.cells ?? []).forEach((c) => {
961
+ obj[c.key] = c.value;
962
+ });
963
+ return obj;
964
+ });
965
+ return JSON.stringify(arr, null, 2);
966
+ }
967
+ function downloadBlob(blob, filename) {
968
+ const url = URL.createObjectURL(blob);
969
+ const a = document.createElement("a");
970
+ a.href = url;
971
+ a.download = filename;
972
+ a.click();
973
+ URL.revokeObjectURL(url);
974
+ }
975
+ function RawViewPhaseProvider({
976
+ children,
977
+ initialPage = 1,
978
+ defaultPageSize = 25,
979
+ defaultFilterMode = "all"
980
+ }) {
981
+ const [filterMode, setFilterMode] = (0, import_react22.useState)(defaultFilterMode);
982
+ const [pageSize, setPageSize] = (0, import_react22.useState)(defaultPageSize);
983
+ const layout = (0, import_react22.useContext)(LayoutContext);
984
+ const { sheet } = (0, import_react_import_sheet_headless14.useSheetData)();
985
+ const { submitDone, submit, canSubmit } = (0, import_react_import_sheet_headless14.useImporter)();
986
+ const view = (0, import_react_import_sheet_headless14.useSheetView)({
987
+ page: initialPage,
988
+ defaultPageSize: pageSize,
989
+ filterMode
990
+ });
991
+ const layoutOptions = (0, import_react22.useMemo)(() => getLayoutFieldOptions(layout), [layout]);
992
+ const rowsWithErrors = (0, import_react22.useMemo)(
993
+ () => (sheet?.rows ?? []).filter((row) => hasRowErrors(row)),
994
+ [sheet?.rows]
995
+ );
996
+ const downloadCSVErrorsOnly = (0, import_react22.useCallback)(
997
+ (opts) => {
998
+ if (rowsWithErrors.length === 0) return;
999
+ const csv = buildErrorsOnlyCSV(layoutOptions, rowsWithErrors);
1000
+ const blob = new Blob([csv], { type: "text/csv;charset=utf-8" });
1001
+ downloadBlob(blob, opts?.filename ?? "errors-only.csv");
1002
+ },
1003
+ [layoutOptions, rowsWithErrors]
1004
+ );
1005
+ const downloadJSONErrorsOnly = (0, import_react22.useCallback)(
1006
+ (opts) => {
1007
+ if (rowsWithErrors.length === 0) return;
1008
+ const json = buildErrorsOnlyJSON(rowsWithErrors);
1009
+ const blob = new Blob([json], { type: "application/json;charset=utf-8" });
1010
+ downloadBlob(blob, opts?.filename ?? "errors-only.json");
1011
+ },
1012
+ [rowsWithErrors]
1013
+ );
1014
+ const visibleSheetIndices = (0, import_react22.useMemo)(() => {
1015
+ const rows = sheet?.rows ?? [];
1016
+ return view.paginatedRows.map((row) => rows.indexOf(row)).filter((i) => i >= 0);
1017
+ }, [sheet?.rows, view.paginatedRows]);
1018
+ const value = (0, import_react22.useMemo)(
1019
+ () => ({
1020
+ page: view.page,
1021
+ setPage: view.setPage,
1022
+ pageSize: view.pageSize,
1023
+ setPageSize,
1024
+ totalRows: view.totalRows,
1025
+ visibleSheetIndices,
1026
+ filterMode,
1027
+ setFilterMode,
1028
+ downloadCSV: view.downloadCSV,
1029
+ downloadJSON: view.downloadJSON,
1030
+ downloadCSVErrorsOnly,
1031
+ downloadJSONErrorsOnly,
1032
+ hasRowsWithErrors: rowsWithErrors.length > 0,
1033
+ hasRecoverableSession: view.hasRecoverableSession,
1034
+ recoverSession: view.recoverSession,
1035
+ clearSession: view.clearPersistedState,
1036
+ isSubmitted: submitDone ?? false,
1037
+ markSubmitted: submit ?? (() => {
1038
+ }),
1039
+ canSubmit: canSubmit ?? false
1040
+ }),
1041
+ [
1042
+ view.page,
1043
+ view.setPage,
1044
+ view.pageSize,
1045
+ view.totalRows,
1046
+ visibleSheetIndices,
1047
+ view.downloadCSV,
1048
+ view.downloadJSON,
1049
+ view.hasRecoverableSession,
1050
+ view.recoverSession,
1051
+ view.clearPersistedState,
1052
+ filterMode,
1053
+ pageSize,
1054
+ downloadCSVErrorsOnly,
1055
+ downloadJSONErrorsOnly,
1056
+ rowsWithErrors.length,
1057
+ submitDone,
1058
+ submit,
1059
+ canSubmit
1060
+ ]
1061
+ );
1062
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ViewPhaseContext.Provider, { value, children });
1063
+ }
1064
+
1065
+ // src/hooks/useRawRemoveRow/useRawRemoveRow.ts
1066
+ var import_react23 = require("react");
1067
+ var import_react_import_sheet_headless15 = require("@cristianmpx/react-import-sheet-headless");
1068
+ function useRawRemoveRow() {
1069
+ const editor = (0, import_react_import_sheet_headless15.useSheetEditor)();
1070
+ const removeRowFn = editor.removeRow;
1071
+ const canRemoveRow = typeof removeRowFn === "function";
1072
+ const removeRow = (0, import_react23.useCallback)(
1073
+ (rowIndex) => {
1074
+ if (typeof removeRowFn === "function") {
1075
+ removeRowFn(rowIndex);
1076
+ }
1077
+ },
1078
+ [removeRowFn]
1079
+ );
1080
+ return { removeRow, canRemoveRow };
1081
+ }
1082
+
1083
+ // src/hooks/useRawEditLog/useRawEditLog.ts
1084
+ var import_react_import_sheet_headless16 = require("@cristianmpx/react-import-sheet-headless");
1085
+ function useRawEditLog() {
1086
+ const editor = (0, import_react_import_sheet_headless16.useSheetEditor)();
1087
+ const entries = editor.changeLog ?? [];
1088
+ const changeLogAsText = editor.changeLogAsText ?? "";
1089
+ return {
1090
+ entries,
1091
+ changeLogAsText,
1092
+ clearLog: () => {
1093
+ }
1094
+ };
1095
+ }
1096
+
1097
+ // src/hooks/useRawEditLog/EditLogContext.tsx
1098
+ var import_react24 = require("react");
1099
+ var EditLogContext = (0, import_react24.createContext)(null);
1100
+
1101
+ // src/hooks/useRawEditLog/RawEditLogProvider.tsx
1102
+ var import_react25 = require("react");
1103
+ var import_jsx_runtime4 = require("react/jsx-runtime");
1104
+ function RawEditLogProvider({ children }) {
1105
+ const [entries, setEntries] = (0, import_react25.useState)([]);
1106
+ const appendCellUpdate = (0, import_react25.useCallback)(
1107
+ (params) => {
1108
+ setEntries((prev) => [
1109
+ ...prev,
1110
+ {
1111
+ type: "cell_update",
1112
+ ...params,
1113
+ timestamp: Date.now()
1114
+ }
1115
+ ]);
1116
+ },
1117
+ []
1118
+ );
1119
+ const appendRowRemoved = (0, import_react25.useCallback)((params) => {
1120
+ setEntries((prev) => [
1121
+ ...prev,
1122
+ {
1123
+ type: "row_removed",
1124
+ ...params,
1125
+ timestamp: Date.now()
1126
+ }
1127
+ ]);
1128
+ }, []);
1129
+ const clearLog = (0, import_react25.useCallback)(() => setEntries([]), []);
1130
+ const value = (0, import_react25.useMemo)(
1131
+ () => ({ entries, appendCellUpdate, appendRowRemoved, clearLog }),
1132
+ [entries, appendCellUpdate, appendRowRemoved, clearLog]
1133
+ );
1134
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(EditLogContext.Provider, { value, children });
1135
+ }
1136
+
1137
+ // src/hooks/useRawFilterToggle/useRawFilterToggle.ts
1138
+ var import_react26 = require("react");
1139
+ var VIEW_PHASE_ERROR3 = "useRawFilterToggle must be used within RawViewPhaseProvider (e.g. in RESULT view).";
1140
+ function useRawFilterToggle() {
1141
+ const ctx = (0, import_react26.useContext)(ViewPhaseContext);
1142
+ if (!ctx) throw new Error(VIEW_PHASE_ERROR3);
1143
+ return {
1144
+ filterMode: ctx.filterMode,
1145
+ setFilterMode: ctx.setFilterMode
1146
+ };
1147
+ }
1148
+
1149
+ // src/hooks/useRawExport/useRawExport.ts
1150
+ var import_react27 = require("react");
1151
+ var VIEW_PHASE_ERROR4 = "useRawExport must be used within RawViewPhaseProvider (e.g. in RESULT view).";
1152
+ function useRawExport() {
1153
+ const ctx = (0, import_react27.useContext)(ViewPhaseContext);
1154
+ if (!ctx) throw new Error(VIEW_PHASE_ERROR4);
1155
+ return {
1156
+ downloadCSV: ctx.downloadCSV,
1157
+ downloadJSON: ctx.downloadJSON,
1158
+ downloadCSVErrorsOnly: ctx.downloadCSVErrorsOnly,
1159
+ downloadJSONErrorsOnly: ctx.downloadJSONErrorsOnly,
1160
+ hasRowsWithErrors: ctx.hasRowsWithErrors
1161
+ };
1162
+ }
1163
+
1164
+ // src/hooks/useRawPersistence/useRawPersistence.ts
1165
+ var import_react28 = require("react");
1166
+ var VIEW_PHASE_ERROR5 = "useRawPersistence must be used within RawViewPhaseProvider (e.g. in RESULT view).";
1167
+ function useRawPersistence() {
1168
+ const ctx = (0, import_react28.useContext)(ViewPhaseContext);
1169
+ if (!ctx) throw new Error(VIEW_PHASE_ERROR5);
1170
+ return {
1171
+ hasRecoverableSession: ctx.hasRecoverableSession,
1172
+ recoverSession: ctx.recoverSession,
1173
+ clearSession: ctx.clearSession
1174
+ };
1175
+ }
1176
+
1177
+ // src/hooks/useImporterMetrics/useImporterMetrics.ts
1178
+ var import_react_import_sheet_headless17 = require("@cristianmpx/react-import-sheet-headless");
1179
+ function useImporterMetrics() {
1180
+ const { metrics } = (0, import_react_import_sheet_headless17.useImporter)();
1181
+ return metrics;
1182
+ }
1183
+
1184
+ // src/components/RawImporterRoot/RawImporterRoot.tsx
1185
+ var import_react29 = require("react");
1186
+ var import_react_import_sheet_headless18 = require("@cristianmpx/react-import-sheet-headless");
1187
+ var import_jsx_runtime5 = require("react/jsx-runtime");
1188
+ var RawImporterRoot = (0, import_react29.forwardRef)(
1189
+ function RawImporterRoot2({ children, className, style, ...options }, ref) {
1190
+ const { providerProps, rootConfig } = useRawImporterRoot(options);
1191
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_import_sheet_headless18.ImporterProvider, { ...providerProps, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(LayoutProvider, { layout: providerProps.layout ?? null, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(RootConfigProvider, { rootConfig, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { ref, className, style, "data-ris-ui": "raw-importer-root", children }) }) }) });
1192
+ }
1193
+ );
1194
+
1195
+ // src/components/RawStatusGuard/RawStatusGuard.tsx
1196
+ var import_react30 = require("react");
1197
+ var import_jsx_runtime6 = require("react/jsx-runtime");
1198
+ var RawStatusGuard = (0, import_react30.forwardRef)(
1199
+ function RawStatusGuard2({ renderIdle, renderMapping, renderProcess, renderResult, renderError, className, style }, ref) {
1200
+ const data = useStatusView();
1201
+ const { view } = data;
1202
+ let content = null;
1203
+ if (view === "idle" && renderIdle) content = renderIdle(data);
1204
+ else if (view === "mapping" && renderMapping) content = renderMapping(data);
1205
+ else if (view === "process" && renderProcess) content = renderProcess(data);
1206
+ else if (view === "result" && renderResult) content = renderResult(data);
1207
+ else if (view === "error" && renderError) content = renderError(data);
1208
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { ref, className, style, "data-ris-ui": "raw-status-guard", children: content });
1209
+ }
1210
+ );
1211
+
1212
+ // src/components/RawFilePicker/RawFilePicker.tsx
1213
+ var import_react31 = require("react");
1214
+ var import_jsx_runtime7 = require("react/jsx-runtime");
1215
+ var RawFilePicker = (0, import_react31.forwardRef)(function RawFilePicker2({ children, className, style }, ref) {
1216
+ const state = useRawFilePicker();
1217
+ const rootProps = state.getRootProps({ className, style });
1218
+ const { ref: rootRef, ...restRootProps } = rootProps;
1219
+ const setRef = (0, import_react31.useCallback)(
1220
+ (el) => {
1221
+ rootRef(el);
1222
+ if (typeof ref === "function") ref(el);
1223
+ else if (ref) ref.current = el;
1224
+ },
1225
+ [rootRef, ref]
1226
+ );
1227
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { ref: setRef, ...restRootProps, "data-ris-ui": "raw-file-picker", children: [
1228
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("input", { ...state.getInputProps() }),
1229
+ children(state)
1230
+ ] });
1231
+ });
1232
+
1233
+ // src/components/RawMappingTable/RawMappingTable.tsx
1234
+ var import_react32 = require("react");
1235
+ var import_jsx_runtime8 = require("react/jsx-runtime");
1236
+ var RawMappingTable = (0, import_react32.forwardRef)(
1237
+ function RawMappingTable2({ children, className, style }, ref) {
1238
+ const state = useRawMappingTable();
1239
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { ref, className, style, "data-ris-ui": "raw-mapping-table", children: children(state) });
1240
+ }
1241
+ );
1242
+
1243
+ // src/components/RawMappingRow/RawMappingRow.tsx
1244
+ var import_react33 = require("react");
1245
+ var import_jsx_runtime9 = require("react/jsx-runtime");
1246
+ var RawMappingRow = (0, import_react33.forwardRef)(function RawMappingRow2({ rowContext, children, className, style }, ref) {
1247
+ const state = useRawMappingRow({ rowContext });
1248
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { ref, className, style, "data-ris-ui": "raw-mapping-row", children: children(state) });
1249
+ });
1250
+
1251
+ // src/components/RawMappingSuggest/RawMappingSuggest.tsx
1252
+ var import_react34 = require("react");
1253
+ var import_jsx_runtime10 = require("react/jsx-runtime");
1254
+ var RawMappingSuggest = (0, import_react34.forwardRef)(
1255
+ function RawMappingSuggest2({ columnContext, children, className, style }, ref) {
1256
+ const state = useRawMappingSuggest({ columnContext });
1257
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { ref, className, style, "data-ris-ui": "raw-mapping-suggest", children: children(state) });
1258
+ }
1259
+ );
1260
+
1261
+ // src/components/RawImportAction/RawImportAction.tsx
1262
+ var import_react35 = require("react");
1263
+ var import_jsx_runtime11 = require("react/jsx-runtime");
1264
+ var RawImportAction = (0, import_react35.forwardRef)(
1265
+ function RawImportAction2({ children, className, style }, ref) {
1266
+ const state = useRawImportAction();
1267
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { ref, className, style, "data-ris-ui": "raw-import-action", children: children(state) });
1268
+ }
1269
+ );
1270
+
1271
+ // src/components/RawErrorBoundary/RawErrorBoundary.tsx
1272
+ var import_react36 = require("react");
1273
+ var import_jsx_runtime12 = require("react/jsx-runtime");
1274
+ var RawErrorBoundary = class extends import_react36.Component {
1275
+ constructor(props) {
1276
+ super(props);
1277
+ this.state = { error: null, errorInfo: null };
1278
+ }
1279
+ static getDerivedStateFromError(error) {
1280
+ return { error, errorInfo: null };
1281
+ }
1282
+ componentDidCatch(error, errorInfo) {
1283
+ this.setState((s) => ({ ...s, errorInfo }));
1284
+ this.props.onError?.(error, errorInfo);
1285
+ }
1286
+ render() {
1287
+ const { error, errorInfo } = this.state;
1288
+ const { children, fallback } = this.props;
1289
+ if (error) {
1290
+ const content = typeof fallback === "function" ? fallback(error, errorInfo ?? { componentStack: "" }) : fallback;
1291
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { "data-ris-ui": "raw-error-boundary", children: content });
1292
+ }
1293
+ return children;
1294
+ }
1295
+ };
1296
+
1297
+ // src/components/RawProgressDisplay/RawProgressDisplay.tsx
1298
+ var import_react37 = require("react");
1299
+ var import_jsx_runtime13 = require("react/jsx-runtime");
1300
+ var RawProgressDisplay = (0, import_react37.forwardRef)(
1301
+ function RawProgressDisplay2({ children, className, style, onProgress }, ref) {
1302
+ const state = useRawProgress({ onProgress });
1303
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { ref, className, style, "data-ris-ui": "raw-progress-display", children: children(state) });
1304
+ }
1305
+ );
1306
+
1307
+ // src/components/RawStatusIndicator/RawStatusIndicator.tsx
1308
+ var import_react38 = require("react");
1309
+ var import_jsx_runtime14 = require("react/jsx-runtime");
1310
+ var RawStatusIndicator = (0, import_react38.forwardRef)(
1311
+ function RawStatusIndicator2({ children, className, style }, ref) {
1312
+ const state = useRawStatus();
1313
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { ref, className, style, "data-ris-ui": "raw-status-indicator", children: children(state) });
1314
+ }
1315
+ );
1316
+
1317
+ // src/components/RawAbortButton/RawAbortButton.tsx
1318
+ var import_react39 = require("react");
1319
+ var import_jsx_runtime15 = require("react/jsx-runtime");
1320
+ var PROCESSING_STATUSES = ["loading", "parsing", "validating", "transforming"];
1321
+ var RawAbortButton = (0, import_react39.forwardRef)(
1322
+ function RawAbortButton2({ children, className, style, disabled: disabledProp, "aria-label": ariaLabel }, ref) {
1323
+ const { abort } = useRawAbort();
1324
+ const { status } = useRawStatus();
1325
+ const isProcessing = PROCESSING_STATUSES.includes(
1326
+ status
1327
+ );
1328
+ const disabled = disabledProp ?? !isProcessing;
1329
+ const buttonProps = (0, import_react39.useMemo)(
1330
+ () => ({
1331
+ type: "button",
1332
+ onClick: abort,
1333
+ disabled,
1334
+ className,
1335
+ style,
1336
+ "aria-label": ariaLabel ?? "Cancel import"
1337
+ }),
1338
+ [abort, disabled, className, style, ariaLabel]
1339
+ );
1340
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("button", { ref, ...buttonProps, "data-ris-ui": "raw-abort-button", children: children ?? "Cancel" });
1341
+ }
1342
+ );
1343
+
1344
+ // src/components/RawImporterWorkflow/RawImporterWorkflow.tsx
1345
+ var import_react41 = require("react");
1346
+
1347
+ // src/components/RawEditLogPanel/RawEditLogPanel.tsx
1348
+ var import_react40 = require("react");
1349
+ var import_jsx_runtime16 = require("react/jsx-runtime");
1350
+ var RawEditLogPanel = (0, import_react40.forwardRef)(
1351
+ function RawEditLogPanel2({ className, style, children }, ref) {
1352
+ const { entries, changeLogAsText } = useRawEditLog();
1353
+ if (children) {
1354
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
1355
+ "div",
1356
+ {
1357
+ ref,
1358
+ className,
1359
+ style,
1360
+ "data-ris-ui": "raw-edit-log-panel",
1361
+ role: "log",
1362
+ "aria-label": "Edit log",
1363
+ children: children({ entries, changeLogAsText, clearLog: () => {
1364
+ } })
1365
+ }
1366
+ );
1367
+ }
1368
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
1369
+ "div",
1370
+ {
1371
+ ref,
1372
+ className,
1373
+ style,
1374
+ "data-ris-ui": "raw-edit-log-panel",
1375
+ role: "log",
1376
+ "aria-label": "Edit log",
1377
+ children: [
1378
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { "data-ris-ui": "raw-edit-log-header", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { children: [
1379
+ "Edit log (",
1380
+ entries.length,
1381
+ " changes)"
1382
+ ] }) }),
1383
+ changeLogAsText ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("pre", { "data-ris-ui": "raw-edit-log-list", children: changeLogAsText }) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("ul", { "data-ris-ui": "raw-edit-log-list", children: entries.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("li", { "data-ris-ui": "raw-edit-log-entry", children: "No changes yet." }) : null })
1384
+ ]
1385
+ }
1386
+ );
1387
+ }
1388
+ );
1389
+
1390
+ // src/components/RawImporterWorkflow/RawImporterWorkflow.tsx
1391
+ var import_jsx_runtime17 = require("react/jsx-runtime");
1392
+ function BackToFileButton({
1393
+ children = "Choose another file",
1394
+ "aria-label": ariaLabel = "Cancel and choose another file"
1395
+ }) {
1396
+ const { abort } = useRawAbort();
1397
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1398
+ "button",
1399
+ {
1400
+ type: "button",
1401
+ onClick: abort,
1402
+ "aria-label": ariaLabel,
1403
+ "data-ris-ui": "raw-workflow-back-button",
1404
+ children
1405
+ }
1406
+ );
1407
+ }
1408
+ function DefaultIdle() {
1409
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(RawFilePicker, { children: (state) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { "data-ris-ui": "raw-file-picker-prompt", children: state.isDragging ? "Drop file here" : "Click or drop file here" }) });
1410
+ }
1411
+ function DefaultMapping() {
1412
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(RawMappingTable, { children: (state) => state.rows.map((rowContext) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(RawMappingRow, { rowContext, children: (rowState) => /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
1413
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { children: rowState.headerOriginal }),
1414
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1415
+ RawMappingSuggest,
1416
+ {
1417
+ columnContext: {
1418
+ fileHeader: rowContext.headerOriginal,
1419
+ columnIndex: rowContext.columnIndex
1420
+ },
1421
+ children: (suggestState) => suggestState.suggestedFieldId != null ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("span", { "data-ris-ui": "raw-mapping-suggest-badge", children: [
1422
+ suggestState.suggestedFieldLabel,
1423
+ " (",
1424
+ suggestState.matchScore,
1425
+ "%)"
1426
+ ] }) : null
1427
+ }
1428
+ ),
1429
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
1430
+ "select",
1431
+ {
1432
+ value: rowState.value ?? "",
1433
+ onChange: (e) => rowState.onChange(e.target.value),
1434
+ "aria-label": `Map ${rowState.headerOriginal}`,
1435
+ children: [
1436
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("option", { value: "", children: "\u2014" }),
1437
+ rowState.options.map((opt) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("option", { value: opt.id, disabled: opt.disabled, children: opt.label }, opt.id))
1438
+ ]
1439
+ }
1440
+ )
1441
+ ] }) }, rowContext.columnIndex)) });
1442
+ }
1443
+ function DefaultMappingWithAction() {
1444
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
1445
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(DefaultMapping, {}),
1446
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { "data-ris-ui": "raw-workflow-mapping-actions", role: "group", children: [
1447
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(RawImportAction, { children: (state) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1448
+ "button",
1449
+ {
1450
+ type: "button",
1451
+ disabled: state.disabled,
1452
+ onClick: state.runImport,
1453
+ "aria-label": "Run import",
1454
+ children: "Import"
1455
+ }
1456
+ ) }),
1457
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(BackToFileButton, { children: "Choose another file" })
1458
+ ] })
1459
+ ] });
1460
+ }
1461
+ function DefaultProcess() {
1462
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
1463
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(RawProgressDisplay, { children: (state) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { "data-ris-ui": "raw-progress", children: String(state.progressRef?.current ?? 0) }) }),
1464
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(RawStatusIndicator, { children: (state) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { "data-ris-ui": "raw-status", children: state.status }) }),
1465
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(RawAbortButton, {})
1466
+ ] });
1467
+ }
1468
+ function ResultToolbar({
1469
+ submitLabel = "Submit"
1470
+ } = {}) {
1471
+ const filter = useRawFilterToggle();
1472
+ const exportApi = useRawExport();
1473
+ const { isSubmitted, markSubmitted, canSubmit } = useRawSubmitStatus();
1474
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { "data-ris-ui": "raw-workflow-toolbar", role: "toolbar", children: [
1475
+ isSubmitted ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { "data-ris-ui": "raw-workflow-submitted-message", role: "status", children: "Submitted. You can download the file below." }) : null,
1476
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(BackToFileButton, { "aria-label": "Import another file", children: "New file" }),
1477
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1478
+ "button",
1479
+ {
1480
+ type: "button",
1481
+ onClick: () => filter.setFilterMode(filter.filterMode === "all" ? "errors-only" : "all"),
1482
+ "aria-pressed": filter.filterMode === "errors-only",
1483
+ children: filter.filterMode === "all" ? "All" : "Errors only"
1484
+ }
1485
+ ),
1486
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("button", { type: "button", onClick: () => exportApi.downloadCSV?.(), children: "Export CSV" }),
1487
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("button", { type: "button", onClick: () => exportApi.downloadJSON?.(), children: "Export JSON" }),
1488
+ exportApi.downloadCSVErrorsOnly != null ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1489
+ "button",
1490
+ {
1491
+ type: "button",
1492
+ disabled: !exportApi.hasRowsWithErrors || isSubmitted,
1493
+ onClick: () => exportApi.downloadCSVErrorsOnly?.(),
1494
+ title: exportApi.hasRowsWithErrors ? void 0 : "No hay filas con errores",
1495
+ children: "Export CSV (errors only)"
1496
+ }
1497
+ ) : null,
1498
+ exportApi.downloadJSONErrorsOnly != null ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1499
+ "button",
1500
+ {
1501
+ type: "button",
1502
+ disabled: !exportApi.hasRowsWithErrors || isSubmitted,
1503
+ onClick: () => exportApi.downloadJSONErrorsOnly?.(),
1504
+ title: exportApi.hasRowsWithErrors ? void 0 : "No hay filas con errores",
1505
+ children: "Export JSON (errors only)"
1506
+ }
1507
+ ) : null,
1508
+ !isSubmitted ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1509
+ "button",
1510
+ {
1511
+ type: "button",
1512
+ disabled: !canSubmit,
1513
+ onClick: () => markSubmitted(),
1514
+ "data-ris-ui": "raw-workflow-submit",
1515
+ "aria-label": typeof submitLabel === "string" ? submitLabel : "Submit",
1516
+ children: submitLabel
1517
+ }
1518
+ ) : null
1519
+ ] });
1520
+ }
1521
+ function ResultGrid({
1522
+ cellErrorPlacement = "inline"
1523
+ }) {
1524
+ const { headers } = useRawTableHead();
1525
+ const { visibleSheetIndices } = useRawPagination();
1526
+ const { canRemoveRow } = useRawRemoveRow();
1527
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("table", { "data-ris-ui": "raw-workflow-grid", role: "grid", children: [
1528
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("tr", { role: "row", children: [
1529
+ headers.map((h) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("th", { scope: "col", role: "columnheader", children: h.label }, h.id)),
1530
+ canRemoveRow ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("th", { scope: "col", role: "columnheader", "data-ris-ui": "raw-workflow-row-actions-header", children: "Actions" }) : null
1531
+ ] }) }),
1532
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("tbody", { children: visibleSheetIndices.map((sheetIndex) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1533
+ ResultRow,
1534
+ {
1535
+ index: sheetIndex,
1536
+ headerIds: headers.map((h) => h.id),
1537
+ showRemoveAction: canRemoveRow,
1538
+ cellErrorPlacement
1539
+ },
1540
+ sheetIndex
1541
+ )) })
1542
+ ] });
1543
+ }
1544
+ function ResultRow({
1545
+ index,
1546
+ headerIds,
1547
+ showRemoveAction,
1548
+ cellErrorPlacement = "inline"
1549
+ }) {
1550
+ const row = useRawTableRow({ index });
1551
+ const { removeRow, canRemoveRow } = useRawRemoveRow();
1552
+ const { isSubmitted } = useRawSubmitStatus();
1553
+ const showDelete = showRemoveAction && canRemoveRow && !isSubmitted;
1554
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("tr", { ...row.getRowProps(), children: [
1555
+ headerIds.map((fieldId) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1556
+ ResultCell,
1557
+ {
1558
+ rowIndex: index,
1559
+ fieldId,
1560
+ cellErrorPlacement
1561
+ },
1562
+ fieldId
1563
+ )),
1564
+ showDelete ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("td", { role: "gridcell", "data-ris-ui": "raw-workflow-row-remove-cell", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1565
+ "button",
1566
+ {
1567
+ type: "button",
1568
+ onClick: () => removeRow(index),
1569
+ "aria-label": `Remove row ${index + 1}`,
1570
+ "data-ris-ui": "raw-workflow-remove-row",
1571
+ children: "Remove row"
1572
+ }
1573
+ ) }) : null
1574
+ ] }, index);
1575
+ }
1576
+ function ResultCell({
1577
+ rowIndex,
1578
+ fieldId,
1579
+ cellErrorPlacement = "inline"
1580
+ }) {
1581
+ const cell = useRawCell({ rowIndex, fieldId });
1582
+ const error = cell.errors?.[0];
1583
+ const badge = useRawErrorBadge({
1584
+ error: error ?? null,
1585
+ translateError: void 0
1586
+ });
1587
+ const showError = cellErrorPlacement !== "none" && badge.message;
1588
+ const errorSlot = showError && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { ...cell.getErrorProps(), children: badge.message });
1589
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("td", { ...cell.getCellProps(), children: cellErrorPlacement === "below" ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
1590
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { "data-ris-ui": "raw-cell-value-line", children: cell.isEditing ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("input", { ...cell.getEditInputProps() }) : /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { children: String(cell.value ?? "") }) }),
1591
+ showError ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { "data-ris-ui": "raw-cell-error-line", children: errorSlot }) : null
1592
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
1593
+ cell.isEditing ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("input", { ...cell.getEditInputProps() }) : /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { children: String(cell.value ?? "") }),
1594
+ cellErrorPlacement === "inline" && errorSlot
1595
+ ] }) });
1596
+ }
1597
+ function ResultFooter() {
1598
+ const pagination = useRawPagination();
1599
+ const persistence = useRawPersistence();
1600
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { "data-ris-ui": "raw-workflow-footer", role: "contentinfo", children: [
1601
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { "data-ris-ui": "raw-workflow-pagination", children: [
1602
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1603
+ "button",
1604
+ {
1605
+ type: "button",
1606
+ disabled: pagination.page <= 1,
1607
+ onClick: () => pagination.setPage(pagination.page - 1),
1608
+ "aria-label": "Previous page",
1609
+ children: "Previous"
1610
+ }
1611
+ ),
1612
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("span", { children: [
1613
+ "Page ",
1614
+ pagination.page,
1615
+ " of",
1616
+ " ",
1617
+ Math.max(1, Math.ceil(pagination.totalRows / pagination.pageSize))
1618
+ ] }),
1619
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1620
+ "button",
1621
+ {
1622
+ type: "button",
1623
+ disabled: pagination.page >= Math.ceil(pagination.totalRows / pagination.pageSize),
1624
+ onClick: () => pagination.setPage(pagination.page + 1),
1625
+ "aria-label": "Next page",
1626
+ children: "Next"
1627
+ }
1628
+ )
1629
+ ] }),
1630
+ persistence.hasRecoverableSession ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { "data-ris-ui": "raw-workflow-persistence", children: [
1631
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("button", { type: "button", onClick: persistence.recoverSession, children: "Recover session" }),
1632
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("button", { type: "button", onClick: persistence.clearSession, children: "Clear" })
1633
+ ] }) : null
1634
+ ] });
1635
+ }
1636
+ function DefaultResult({
1637
+ submitLabel,
1638
+ cellErrorPlacement = "inline"
1639
+ } = {}) {
1640
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(RawViewPhaseProvider, { children: [
1641
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(ResultToolbar, { submitLabel }),
1642
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(RawEditLogPanel, {}),
1643
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(RawDataTableProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(ResultGrid, { cellErrorPlacement }) }),
1644
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(ResultFooter, {})
1645
+ ] });
1646
+ }
1647
+ function DefaultError({ mappingErrorDetail }) {
1648
+ if (mappingErrorDetail?.code === "TOO_MANY_MISMATCHES") {
1649
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { "data-ris-ui": "raw-workflow-mapping-error", role: "alert", children: [
1650
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("p", { children: [
1651
+ "Too many column mismatches (",
1652
+ mappingErrorDetail.mismatchCount,
1653
+ "). Maximum allowed:",
1654
+ " ",
1655
+ mappingErrorDetail.maxAllowed,
1656
+ "."
1657
+ ] }),
1658
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(BackToFileButton, { children: "Choose another file" })
1659
+ ] });
1660
+ }
1661
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(DefaultIdle, {});
1662
+ }
1663
+ var RawImporterWorkflow = (0, import_react41.forwardRef)(
1664
+ function RawImporterWorkflow2({
1665
+ className,
1666
+ style,
1667
+ renderIdle,
1668
+ renderMapping,
1669
+ renderProcess,
1670
+ renderResult,
1671
+ renderError,
1672
+ submitLabel,
1673
+ cellErrorPlacement = "inline"
1674
+ }, ref) {
1675
+ const { view, mappingErrorDetail } = useStatusView();
1676
+ let content;
1677
+ switch (view) {
1678
+ case "idle":
1679
+ content = renderIdle ? renderIdle() : /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(DefaultIdle, {});
1680
+ break;
1681
+ case "mapping":
1682
+ content = renderMapping ? renderMapping() : /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(DefaultMappingWithAction, {});
1683
+ break;
1684
+ case "process":
1685
+ content = renderProcess ? renderProcess() : /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(DefaultProcess, {});
1686
+ break;
1687
+ case "result":
1688
+ content = renderResult ? renderResult() : /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(DefaultResult, { submitLabel, cellErrorPlacement });
1689
+ break;
1690
+ case "error":
1691
+ content = renderError ? renderError({ mappingErrorDetail }) : /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(DefaultError, { mappingErrorDetail });
1692
+ break;
1693
+ default:
1694
+ content = renderIdle ? renderIdle() : /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(DefaultIdle, {});
1695
+ }
1696
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { ref, className, style, "data-ris-ui": "raw-importer-workflow", children: content });
1697
+ }
1698
+ );
1699
+
1700
+ // src/index.ts
1701
+ var import_react_import_sheet_headless19 = require("@cristianmpx/react-import-sheet-headless");
1702
+ // Annotate the CommonJS export names for ESM import in node:
1703
+ 0 && (module.exports = {
1704
+ DataTableContext,
1705
+ EditLogContext,
1706
+ IMPORTER_ABORTED_EVENT,
1707
+ IMPORTER_PROGRESS_EVENT,
1708
+ ImporterProvider,
1709
+ LayoutContext,
1710
+ LayoutProvider,
1711
+ RawAbortButton,
1712
+ RawDataTableProvider,
1713
+ RawEditLogPanel,
1714
+ RawEditLogProvider,
1715
+ RawErrorBoundary,
1716
+ RawFilePicker,
1717
+ RawImportAction,
1718
+ RawImporterRoot,
1719
+ RawImporterWorkflow,
1720
+ RawMappingRow,
1721
+ RawMappingSuggest,
1722
+ RawMappingTable,
1723
+ RawProgressDisplay,
1724
+ RawStatusGuard,
1725
+ RawStatusIndicator,
1726
+ RawViewPhaseProvider,
1727
+ RootConfigContext,
1728
+ RootConfigProvider,
1729
+ ViewPhaseContext,
1730
+ getLayoutFieldOptions,
1731
+ getViewFromState,
1732
+ useConvert,
1733
+ useImportSheet,
1734
+ useImporter,
1735
+ useImporterEventTarget,
1736
+ useImporterMetrics,
1737
+ useImporterProgressSubscription,
1738
+ useImporterStatus,
1739
+ useRawAbort,
1740
+ useRawCell,
1741
+ useRawDataTable,
1742
+ useRawEditLog,
1743
+ useRawErrorBadge,
1744
+ useRawExport,
1745
+ useRawFilePicker,
1746
+ useRawFilterToggle,
1747
+ useRawImportAction,
1748
+ useRawImporterRoot,
1749
+ useRawMappingRow,
1750
+ useRawMappingSuggest,
1751
+ useRawMappingTable,
1752
+ useRawPagination,
1753
+ useRawPersistence,
1754
+ useRawProgress,
1755
+ useRawRemoveRow,
1756
+ useRawStatus,
1757
+ useRawSubmitStatus,
1758
+ useRawTableBody,
1759
+ useRawTableHead,
1760
+ useRawTableRow,
1761
+ useSheetData,
1762
+ useSheetEditor,
1763
+ useSheetView,
1764
+ useStatusView
1765
+ });
1766
+ //# sourceMappingURL=index.js.map